diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..8a24b7e --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,115 @@ +# This workflow builds and pushes a multi-arch image to Quay.io +# Adapted from actions-arm64-native-example by @gartnera +# ref: https://github.com/gartnera/actions-arm64-native-example/blob/main/.github/workflows/build.yml + +name: build + +on: + push: + pull_request: + +env: + QUAY_REPO: quay.io/${{ github.repository_owner }}/${{ github.event.repository.name }} + +jobs: + build: + strategy: + fail-fast: false + matrix: + include: + - platform: linux/amd64 + runner: ubuntu-22.04 + - platform: linux/arm64 + runner: ubuntu-22.04-arm + runs-on: ${{ matrix.runner || 'ubuntu-22.04' }} + steps: + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.QUAY_REPO }} + + - name: Login to Quay.io + uses: docker/login-action@v3 + with: + registry: quay.io + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_ROBOT_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push by digest + id: build + uses: docker/build-push-action@v6 + with: + platforms: ${{ matrix.platform }} + labels: ${{ steps.meta.outputs.labels }} + outputs: type=image,name=${{ env.QUAY_REPO }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + run: | + mkdir -p ${{ runner.temp }}/digests + digest="${{ steps.build.outputs.digest }}" + touch "${{ runner.temp }}/digests/${digest#sha256:}" + + - name: Upload digest + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: ${{ runner.temp }}/digests/* + if-no-files-found: error + retention-days: 1 + + merge: + runs-on: ubuntu-latest + needs: + - build + steps: + - name: Download digests + uses: actions/download-artifact@v4 + with: + path: ${{ runner.temp }}/digests + pattern: digests-* + merge-multiple: true + + - name: Login to Quay.io + uses: docker/login-action@v3 + with: + registry: quay.io + username: ${{ secrets.QUAY_USERNAME }} + password: ${{ secrets.QUAY_ROBOT_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Docker meta + id: meta + uses: docker/metadata-action@v5 + with: + images: | + ${{ env.QUAY_REPO }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + + - name: Create manifest list and push + working-directory: ${{ runner.temp }}/digests + run: | + docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \ + $(printf '${{ env.QUAY_REPO }}@sha256:%s ' *) + + - name: Inspect image + run: | + docker buildx imagetools inspect ${{ env.QUAY_REPO }}:${{ steps.meta.outputs.version }} diff --git a/.gitignore b/.gitignore index 4440394..3eb5a86 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,5 @@ go.work.sum .env build/ +*.DS_Store +*funnel.db diff --git a/Dockerfile b/Dockerfile index 3156480..1d668f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Use the official Golang image as the base image -FROM golang:1.23-alpine +FROM golang:1.24.2-alpine # Set the Current Working Directory inside the container WORKDIR /app @@ -20,4 +20,4 @@ RUN mkdir -p ./build/plugins RUN go build -o ./build/cli . # Build the plugin -RUN go build -o ./build/plugins/authorizer ./plugin +RUN go build -o ./build/plugins/authorizer ./plugin-go diff --git a/Makefile b/Makefile index 9f5d242..f65938b 100644 --- a/Makefile +++ b/Makefile @@ -20,12 +20,13 @@ clean: rm -rf $(DIR)/* build: - # Build CLI + # Build CLI go build -o $(DIR)/cli # Build Plugin go build -o $(DIR)/plugins/authorizer ./plugin-go + tests: # Build test server go build -o $(DIR)/test-server ./tests/test-server.go diff --git a/README.md b/README.md index ba88ab8..91cd47e 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ First build and run the test User Database server: > | `test-server` | the Test Server used for storing user and credentials (called by the plugin) | > | `plugins/authorizer` | the plugin binary | -## 2. Start the Test Server +## 2. Start the Test Server ```sh ➜ ./test-server @@ -106,15 +106,16 @@ sequenceDiagram ## Overview 🌀 The following includes examples and resources for writing Plugins (in Go, Python, or any other [supported language](https://grpc.io/docs/languages/)!) -  + - [gRPC Example](https://github.com/hashicorp/go-plugin/tree/main/examples/grpc) (this is largely what Funnel Plugins is based off of, along with this [manager](https://github.com/eliben/code-for-blog/blob/main/2023/go-plugin-htmlize-rpc/plugin/manager.go#L28-L83) snippet by [Eli Bendersky](https://eli.thegreenplace.net/2023/rpc-based-plugins-in-go/) for loading the plugin binaries) -  + - [Intro](https://github.com/hashicorp/go-plugin/blob/main/docs/extensive-go-plugin-tutorial.md) (super helpful reference from beginning to end) ## Communicating with Funnel > [!WARNING] > TODO: Add the following to the docs 🚧 +> > - API "contract" between the Plugin and Funnel Server": > - What exactly will the Plugin require for inputs and outputs (`Config`)? > - What functions will plugin authors need to implement (e.g. `Get`)? @@ -146,13 +147,14 @@ For authoring custom plugins in Python, see the [example Python plugin](./plugin > [!TIP] > Understanding gRPC and protobufs isn't necessary to writing plugins, but it can be helpful when errors or bugs arise 🐛 -Under the hood, all communication between the Plugin and the Funnel Server happens over gRPC using Protocal Buffers (*protobufs*). +Under the hood, all communication between the Plugin and the Funnel Server happens over gRPC using Protocal Buffers (_protobufs_). - [Protobuf Overview](https://protobuf.dev/) -   + - Tutorials for [Go](https://protobuf.dev/getting-started/gotutorial/) and [Python](https://protobuf.dev/getting-started/pythontutorial/) -  + - [Awesome gRPC](https://github.com/grpc-ecosystem/awesome-grpc#protocol-buffers) — pretty up-to-date resource for all things Protobuf and gRPC! 😎 + # Additional Resources 📚 - https://github.com/hashicorp/go-plugin @@ -160,3 +162,49 @@ Under the hood, all communication between the Plugin and the Funnel Server happe - https://eli.thegreenplace.net/2023/rpc-based-plugins-in-go - https://github.com/eliben/code-for-blog/tree/main/2023/go-plugin-htmlize-rpc +## Local testing + +Assuming funnel is running `funnel server run -c config.yaml` +with a plugin enabled in the config like + +``` +Plugins: + Path: build/plugins/authorizer + Params: + Host: http://localhost:8080/token?user= +``` + +Create a task that will pass through the plugin with + +``` +curl -X POST \ + http://localhost:8000/v1/tasks \ + -H "Content-Type: application/json" \ + -H "Authorization: testauthz" \ + -d @tests/plugin-test.json +``` + +where tests/plugin-test.json is a basic json test like: + +``` +{ + "name": "Hello world", + "description": "Demonstrates the most basic echo task.", + "executors": [ + { + "image": "alpine", + "command": ["echo", "hello world"] + } + ], + "tags": { + "user": "foo" + } +} +``` + +This should hit the plugin, contact whatever endpoint is specified, +and return the response packet from the specified server. + +Any special headers that are passed when creating the task should be accessible in the example test server run with + +`go run tests/test-server.go --users-csv tests/example-users.csv` diff --git a/buf.gen.yaml b/buf.gen.yaml deleted file mode 100644 index 08adf1b..0000000 --- a/buf.gen.yaml +++ /dev/null @@ -1,23 +0,0 @@ -version: v1 -plugins: - # Go (Protobuf) - - plugin: buf.build/protocolbuffers/go - out: . - opt: - - paths=source_relative - - # Go (gRPC) - - plugin: buf.build/grpc/go:v1.3.0 - out: . - opt: - - paths=source_relative - - require_unimplemented_servers=false - - # Python (Protobuf) - - plugin: buf.build/protocolbuffers/python:v24.4 - out: plugin-python - - # Python (gRPC) - - plugin: buf.build/grpc/python:v1.58.1 - out: plugin-python - diff --git a/go.mod b/go.mod index cf7445e..2afb199 100644 --- a/go.mod +++ b/go.mod @@ -1,42 +1,49 @@ -module example.com +module github.com/ohsu-comp-bio/funnel-plugins -go 1.22 +go 1.24.0 -toolchain go1.22.5 +toolchain go1.24.2 require ( - github.com/hashicorp/go-plugin v1.4.9 - github.com/ohsu-comp-bio/funnel v0.0.0-20250226001524-3169fd6d9435 + github.com/hashicorp/go-plugin v1.6.3 + github.com/ohsu-comp-bio/funnel v0.0.0-20250514233149-7f362add7305 + google.golang.org/protobuf v1.36.6 ) require ( - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect + github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect - github.com/ghodss/yaml v1.0.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.8 // indirect + github.com/getlantern/deepcopy v0.0.0-20160317154340-7f45deb8130a // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.26.0 // indirect + github.com/goccy/go-yaml v1.17.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect - github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/rs/xid v1.6.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - golang.org/x/crypto v0.31.0 // indirect - golang.org/x/term v0.27.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.35.0 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/term v0.31.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e // indirect ) require ( - github.com/fatih/color v1.7.0 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/hashicorp/go-hclog v0.14.1 - github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb // indirect - github.com/mattn/go-colorable v0.1.7 // indirect - github.com/mattn/go-isatty v0.0.12 // indirect - github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/oklog/run v1.0.0 // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/text v0.22.0 // indirect - google.golang.org/grpc v1.70.0 - google.golang.org/protobuf v1.36.5 + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/grpc v1.72.0 // indirect ) diff --git a/go.sum b/go.sum index 7455d73..042e245 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= +github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -7,52 +9,59 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= +github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= github.com/getlantern/deepcopy v0.0.0-20160317154340-7f45deb8130a h1:yU/FENpkHYISWsQrbr3pcZOBj0EuRjPzNc1+dTCLu44= github.com/getlantern/deepcopy v0.0.0-20160317154340-7f45deb8130a/go.mod h1:AEugkNu3BjBxyz958nJ5holD9PRjta6iprcoUauDbU4= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k= +github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo= +github.com/goccy/go-yaml v1.17.1 h1:LI34wktB2xEE3ONG/2Ar54+/HJVBriAGJ55PHls4YuY= +github.com/goccy/go-yaml v1.17.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= -github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= -github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-plugin v1.4.9 h1:ESiK220/qE0aGxWdzKIvRH69iLiuN/PjoLTm69RoWtU= -github.com/hashicorp/go-plugin v1.4.9/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= -github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-plugin v1.6.3 h1:xgHB+ZUSYeuJi96WtxEjzi23uh7YQpznjGh0U0UUrwg= +github.com/hashicorp/go-plugin v1.6.3/go.mod h1:MRobyh+Wc/nYy1V4KAXUiYfzxoYhs7V1mlH1Z7iY2h0= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381 h1:bqDmpDG49ZRnB5PcgP0RXtQvnMSgIF14M7CBd2shtXs= -github.com/logrusorgru/aurora v0.0.0-20200102142835-e9ef32dff381/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77 h1:7GoSOOW2jpsfkntVKaS2rAr1TJqfcxotyaUcuxoZSzg= -github.com/mitchellh/go-testing-interface v0.0.0-20171004221916-a61a99592b77/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/ohsu-comp-bio/funnel v0.0.0-20250226001524-3169fd6d9435 h1:DJ55H6U96qLVabKOTbozJich1fDjpp5zI4gPhYaOHJI= -github.com/ohsu-comp-bio/funnel v0.0.0-20250226001524-3169fd6d9435/go.mod h1:L7tQc/evzdSveo0Wy0i2lnVYq9do6AxO5lvydCbE5lA= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/ohsu-comp-bio/funnel v0.0.0-20250514233149-7f362add7305 h1:hTDS5Y4T19R/02HLY4vlfgmeIzOoa2ifTc07i+TBoBI= +github.com/ohsu-comp-bio/funnel v0.0.0-20250514233149-7f362add7305/go.mod h1:1xXcKLg2vVMEcNT9VkjfeR2N9s74XcKn09FhRy+hQWw= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -60,58 +69,62 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc= -github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -go.opentelemetry.io/otel v1.32.0 h1:WnBN+Xjcteh0zdk01SVqV55d/m62NJLJdIyb4y/WO5U= -go.opentelemetry.io/otel v1.32.0/go.mod h1:00DCVSB0RQcnzlwyTfqtxSm+DRr9hpYrHjNGiBHVQIg= -go.opentelemetry.io/otel/metric v1.32.0 h1:xV2umtmNcThh2/a/aCP+h64Xx5wsj8qqnkYZktzNa0M= -go.opentelemetry.io/otel/metric v1.32.0/go.mod h1:jH7CIbbK6SH2V2wE16W05BHCtIDzauciCRLoc/SyMv8= -go.opentelemetry.io/otel/sdk v1.32.0 h1:RNxepc9vK59A8XsgZQouW8ue8Gkb4jpWtJm9ge5lEG4= -go.opentelemetry.io/otel/sdk v1.32.0/go.mod h1:LqgegDBjKMmb2GC6/PrTnteJG39I8/vJCAP9LlJXEjU= -go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= -go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= -go.opentelemetry.io/otel/trace v1.32.0 h1:WIC9mYrXf8TmY/EXuULKc8hR17vE+Hjv2cssQDe03fM= -go.opentelemetry.io/otel/trace v1.32.0/go.mod h1:+i4rkvCraA+tG6AzwloGaCtkx53Fa+L+V8e9a7YvhT8= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY= +go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o= +go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/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-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= -google.golang.org/genproto v0.0.0-20240116215550-a9fa1716bcac h1:ZL/Teoy/ZGnzyrqK/Optxxp2pmVh+fmJ97slxSRyzUg= -google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a h1:OAiGFfOiA0v9MRYsSidp3ubZaBnteRUyn3xB2ZQ5G/E= -google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a/go.mod h1:jehYqy3+AhJU9ve55aNOaSml7wUXjF9x6z2LcCfpAhY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= -google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= -google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= -google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= +golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e h1:ztQaXfzEXTmCBvbtWYRhJxW+0iJcz2qXfd38/e9l7bA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250414145226-207652e42e2e/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM= +google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -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= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index cd72a7a..131f33b 100644 --- a/main.go +++ b/main.go @@ -1,35 +1,32 @@ package main import ( - "bytes" - "encoding/json" "fmt" "os" - "example.com/shared" + "github.com/ohsu-comp-bio/funnel/config" + "github.com/ohsu-comp-bio/funnel/plugins/proto" + "github.com/ohsu-comp-bio/funnel/plugins/shared" + "github.com/ohsu-comp-bio/funnel/tes" ) -func run(user string, host string, dir string) (string, error) { +func run(params map[string]string, header map[string]*proto.StringList, + config *config.Config, task *tes.Task, + taskType proto.Type, dir string) (string, error) { + m := &shared.Manager{} defer m.Close() - authorize, err := m.Client(dir) if err != nil { return "", fmt.Errorf("failed to get client: %w", err) } - resp, err := authorize.Get(user, host) + resp, err := authorize.PluginAction(params, header, config, task, taskType) if err != nil { return "", fmt.Errorf("failed to authorize: %w", err) } - // Pretty print directly from raw JSON response - var out bytes.Buffer - if err := json.Indent(&out, resp, "", " "); err != nil { - return "", fmt.Errorf("error formatting JSON: %w", err) - } - - return out.String(), nil + return resp.String(), nil } func main() { @@ -37,18 +34,25 @@ func main() { fmt.Printf("Usage: %s \n", os.Args[0]) os.Exit(1) } - user := os.Args[1] - // "http://localhost:8080/token?user=" host := os.Args[2] dir := "build/plugins" + params := map[string]string{ + "user": user, + "host": host, + } + + headers := map[string]*proto.StringList{} + config := config.DefaultConfig() + var task *tes.Task + var taskType proto.Type - out, err := run(user, host, dir) + out, err := run(params, headers, config, task, taskType, dir) if err != nil { fmt.Println("Error calling plugin:", err) os.Exit(1) } - fmt.Println(out) + fmt.Println("OUT: ", out) os.Exit(0) } diff --git a/plugin-go/auth_impl.go b/plugin-go/auth_impl.go index 629f339..41eb5bb 100644 --- a/plugin-go/auth_impl.go +++ b/plugin-go/auth_impl.go @@ -1,40 +1,134 @@ package main import ( + "bytes" + "encoding/gob" "fmt" "io" + "log" "net/http" - "example.com/shared" + "github.com/ohsu-comp-bio/funnel/config" + "github.com/ohsu-comp-bio/funnel/plugins/proto" + "github.com/ohsu-comp-bio/funnel/plugins/shared" + "google.golang.org/protobuf/encoding/protojson" + "github.com/hashicorp/go-plugin" + "github.com/ohsu-comp-bio/funnel/tes" ) // Here is a real implementation of Authorize that retrieves a "Secret" value for a user type Authorize struct{} -func (Authorize) Get(user string, host string) ([]byte, error) { - if user == "" { - return nil, fmt.Errorf("user is required (e.g. ./authorize )") +func (a Authorize) PluginAction(params map[string]string, headers map[string]*proto.StringList, config *config.Config, task *tes.Task, taskType proto.Type) (*proto.JobResponse, error) { + shared.Logger.Debug("Params: ", params) + shared.Logger.Debug("Headers: ", headers) + shared.Logger.Debug("Config: ", config) + shared.Logger.Debug("Task: ", task) + + host, ok := params["Host"] + if !ok || host == "" { + return &proto.JobResponse{ + Code: 400, + Message: "host is required in params (e.g. params['host'])"}, + fmt.Errorf("host is required in params (e.g. params['host'])") + } + user := headers["authorization"].Values[0] + if !ok || user == "" { + return &proto.JobResponse{ + Code: 400, + Message: "user is required in the Auth header"}, + fmt.Errorf("user is required in the Auth header") + } + shared.Logger.Info("GET", "user", user, "host", host) + Body := &proto.Job{ + Config: config, + Task: task, + Headers: headers, + Params: params, + Type: taskType, } - shared.Logger.Info("Get", "user", user, "host", host) - resp, err := http.Get(host + user) + var requestBody []byte + var err error + marshalOptions := protojson.MarshalOptions{} + requestBody, err = marshalOptions.Marshal(Body) if err != nil { - return nil, fmt.Errorf("error making request: %w", err) + return &proto.JobResponse{ + Code: 400, + Message: fmt.Sprintf("error marshaling JSON body: %#v", Body)}, + fmt.Errorf("error marshaling JSON body: %w. Should be of type proto.Job", err) + } + + var req *http.Request + var method string + switch taskType { + case proto.Type_CREATE: + method = "PUT" + case proto.Type_GET: + method = "GET" + case proto.Type_CANCEL: + method = "DELETE" + default: + return &proto.JobResponse{ + Code: 400, + Message: fmt.Sprintf("unsupported task type: %v", taskType)}, + fmt.Errorf("unsupported task type: %v", taskType) + } + + req, err = http.NewRequest(method, host+user, bytes.NewBuffer(requestBody)) + if err != nil { + return &proto.JobResponse{ + Code: 500, + Message: fmt.Sprintf("error creating request: %w", err)}, + fmt.Errorf("error creating request: %w", err) } - defer resp.Body.Close() + req.Header.Set("Content-Type", "application/json") + for k, v := range headers { + for _, val := range v.Values { + req.Header.Add(k, val) + } + } + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return &proto.JobResponse{ + Code: 500, + Message: fmt.Sprintf("error receiving request: %w", err)}, + fmt.Errorf("error receiving request: %w", err) + } + + defer resp.Body.Close() shared.Logger.Info("Response", "status", resp.Status) body, err := io.ReadAll(resp.Body) if err != nil { - return nil, fmt.Errorf("error reading response body: %w", err) + return &proto.JobResponse{ + Code: 500, + Message: fmt.Sprintf("%w", err)}, + fmt.Errorf("%w", err) + } + receivedData := &proto.JobResponse{} + unmarshalOptions := protojson.UnmarshalOptions{ + DiscardUnknown: true, + } + err = unmarshalOptions.Unmarshal(body, receivedData) + if err != nil { + return &proto.JobResponse{ + Code: 500, + Message: fmt.Sprintf("%w", err)}, + fmt.Errorf("%w", err) } - shared.Logger.Info("Response", "body", string(body)) - return body, nil + shared.Logger.Info("+++++++++++++++++++++++++++++RESP: ", receivedData) + return receivedData, nil } func main() { + log.Println("Server: registering gob types") + gob.Register(&config.TimeoutConfig_Duration{}) + gob.Register(&config.TimeoutConfig_Disabled{}) + plugin.Serve(&plugin.ServeConfig{ HandshakeConfig: shared.Handshake, Plugins: map[string]plugin.Plugin{ diff --git a/plugin-go/auth_impl_test.go b/plugin-go/auth_impl_test.go index a9105c7..7f739ff 100644 --- a/plugin-go/auth_impl_test.go +++ b/plugin-go/auth_impl_test.go @@ -5,31 +5,25 @@ import ( "reflect" "testing" - "example.com/shared" "github.com/ohsu-comp-bio/funnel/config" + "github.com/ohsu-comp-bio/funnel/plugins/proto" ) var host = "http://localhost:8080/token?user=" func TestAuthorizedUser(t *testing.T) { auth := Authorize{} - raw, err := auth.Get("example", host) + actual, err := auth.Get("example", host) if err != nil { t.Fatalf("expected no error, got %v", err) } - // Parse actual JSON response - var actual shared.Response - if err := json.Unmarshal(raw, &actual); err != nil { - t.Fatalf("failed to parse JSON response: %v", err) - } - // Define expected response c := config.Config{} c.AmazonS3.AWSConfig.Key = "key1" c.AmazonS3.AWSConfig.Secret = "secret1" - expected := shared.Response{ + expected := proto.GetResponse{ Code: 200, Config: &c, } @@ -48,13 +42,13 @@ func TestUnauthorizedUser(t *testing.T) { } // Parse actual JSON response - var actual shared.Response + var actual proto.GetResponse if err := json.Unmarshal(raw, &actual); err != nil { t.Fatalf("failed to parse JSON response: %v", err) } // Define expected response - expected := shared.Response{ + expected := proto.GetResponse{ Code: 401, Message: "User not authorized", } diff --git a/plugin-python/compute/scheduler/scheduler_pb2.py b/plugin-python/compute/scheduler/scheduler_pb2.py new file mode 100644 index 0000000..2b3a046 --- /dev/null +++ b/plugin-python/compute/scheduler/scheduler_pb2.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: compute/scheduler/scheduler.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!compute/scheduler/scheduler.proto\x12\tscheduler\x1a\x1cgoogle/api/annotations.proto\"O\n\tResources\x12\x12\n\x04\x63pus\x18\x01 \x01(\rR\x04\x63pus\x12\x15\n\x06ram_gb\x18\x02 \x01(\x01R\x05ramGb\x12\x17\n\x07\x64isk_gb\x18\x03 \x01(\x01R\x06\x64iskGb\"\xc6\x03\n\x04Node\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x32\n\tresources\x18\x05 \x01(\x0b\x32\x14.scheduler.ResourcesR\tresources\x12\x32\n\tavailable\x18\x06 \x01(\x0b\x32\x14.scheduler.ResourcesR\tavailable\x12*\n\x05state\x18\x08 \x01(\x0e\x32\x14.scheduler.NodeStateR\x05state\x12 \n\x0bpreemptible\x18\t \x01(\x08R\x0bpreemptible\x12\x12\n\x04zone\x18\x0b \x01(\tR\x04zone\x12\x1a\n\x08hostname\x18\r \x01(\tR\x08hostname\x12\x18\n\x07version\x18\x0e \x01(\x03R\x07version\x12\x39\n\x08metadata\x18\x0f \x03(\x0b\x32\x1d.scheduler.Node.MetadataEntryR\x08metadata\x12\x19\n\x08task_ids\x18\x10 \x03(\tR\x07taskIds\x12\x1b\n\tlast_ping\x18\x11 \x01(\x03R\x08lastPing\x1a;\n\rMetadataEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\" \n\x0eGetNodeRequest\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\"\x12\n\x10ListNodesRequest\":\n\x11ListNodesResponse\x12%\n\x05nodes\x18\x01 \x03(\x0b\x32\x0f.scheduler.NodeR\x05nodes\"\x11\n\x0fPutNodeResponse\"\x14\n\x12\x44\x65leteNodeResponse*Z\n\tNodeState\x12\x11\n\rUNINITIALIZED\x10\x00\x12\t\n\x05\x41LIVE\x10\x01\x12\x08\n\x04\x44\x45\x41\x44\x10\x02\x12\x08\n\x04GONE\x10\x03\x12\x10\n\x0cINITIALIZING\x10\x04\x12\t\n\x05\x44RAIN\x10\x05\x32\xb6\x02\n\x10SchedulerService\x12\x38\n\x07PutNode\x12\x0f.scheduler.Node\x1a\x1a.scheduler.PutNodeResponse\"\x00\x12>\n\nDeleteNode\x12\x0f.scheduler.Node\x1a\x1d.scheduler.DeleteNodeResponse\"\x00\x12Y\n\tListNodes\x12\x1b.scheduler.ListNodesRequest\x1a\x1c.scheduler.ListNodesResponse\"\x11\x82\xd3\xe4\x93\x02\x0b\x12\t/v1/nodes\x12M\n\x07GetNode\x12\x19.scheduler.GetNodeRequest\x1a\x0f.scheduler.Node\"\x16\x82\xd3\xe4\x93\x02\x10\x12\x0e/v1/nodes/{id}B3Z1github.com/ohsu-comp-bio/funnel/compute/schedulerb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'compute.scheduler.scheduler_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'Z1github.com/ohsu-comp-bio/funnel/compute/scheduler' + _globals['_NODE_METADATAENTRY']._options = None + _globals['_NODE_METADATAENTRY']._serialized_options = b'8\001' + _globals['_SCHEDULERSERVICE'].methods_by_name['ListNodes']._options = None + _globals['_SCHEDULERSERVICE'].methods_by_name['ListNodes']._serialized_options = b'\202\323\344\223\002\013\022\t/v1/nodes' + _globals['_SCHEDULERSERVICE'].methods_by_name['GetNode']._options = None + _globals['_SCHEDULERSERVICE'].methods_by_name['GetNode']._serialized_options = b'\202\323\344\223\002\020\022\016/v1/nodes/{id}' + _globals['_NODESTATE']._serialized_start=771 + _globals['_NODESTATE']._serialized_end=861 + _globals['_RESOURCES']._serialized_start=78 + _globals['_RESOURCES']._serialized_end=157 + _globals['_NODE']._serialized_start=160 + _globals['_NODE']._serialized_end=614 + _globals['_NODE_METADATAENTRY']._serialized_start=555 + _globals['_NODE_METADATAENTRY']._serialized_end=614 + _globals['_GETNODEREQUEST']._serialized_start=616 + _globals['_GETNODEREQUEST']._serialized_end=648 + _globals['_LISTNODESREQUEST']._serialized_start=650 + _globals['_LISTNODESREQUEST']._serialized_end=668 + _globals['_LISTNODESRESPONSE']._serialized_start=670 + _globals['_LISTNODESRESPONSE']._serialized_end=728 + _globals['_PUTNODERESPONSE']._serialized_start=730 + _globals['_PUTNODERESPONSE']._serialized_end=747 + _globals['_DELETENODERESPONSE']._serialized_start=749 + _globals['_DELETENODERESPONSE']._serialized_end=769 + _globals['_SCHEDULERSERVICE']._serialized_start=864 + _globals['_SCHEDULERSERVICE']._serialized_end=1174 +# @@protoc_insertion_point(module_scope) diff --git a/plugin-python/compute/scheduler/scheduler_pb2_grpc.py b/plugin-python/compute/scheduler/scheduler_pb2_grpc.py new file mode 100644 index 0000000..be8c623 --- /dev/null +++ b/plugin-python/compute/scheduler/scheduler_pb2_grpc.py @@ -0,0 +1,171 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from compute.scheduler import scheduler_pb2 as compute_dot_scheduler_dot_scheduler__pb2 + + +class SchedulerServiceStub(object): + """* + Scheduler Service + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.PutNode = channel.unary_unary( + '/scheduler.SchedulerService/PutNode', + request_serializer=compute_dot_scheduler_dot_scheduler__pb2.Node.SerializeToString, + response_deserializer=compute_dot_scheduler_dot_scheduler__pb2.PutNodeResponse.FromString, + ) + self.DeleteNode = channel.unary_unary( + '/scheduler.SchedulerService/DeleteNode', + request_serializer=compute_dot_scheduler_dot_scheduler__pb2.Node.SerializeToString, + response_deserializer=compute_dot_scheduler_dot_scheduler__pb2.DeleteNodeResponse.FromString, + ) + self.ListNodes = channel.unary_unary( + '/scheduler.SchedulerService/ListNodes', + request_serializer=compute_dot_scheduler_dot_scheduler__pb2.ListNodesRequest.SerializeToString, + response_deserializer=compute_dot_scheduler_dot_scheduler__pb2.ListNodesResponse.FromString, + ) + self.GetNode = channel.unary_unary( + '/scheduler.SchedulerService/GetNode', + request_serializer=compute_dot_scheduler_dot_scheduler__pb2.GetNodeRequest.SerializeToString, + response_deserializer=compute_dot_scheduler_dot_scheduler__pb2.Node.FromString, + ) + + +class SchedulerServiceServicer(object): + """* + Scheduler Service + """ + + def PutNode(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def DeleteNode(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListNodes(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetNode(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_SchedulerServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'PutNode': grpc.unary_unary_rpc_method_handler( + servicer.PutNode, + request_deserializer=compute_dot_scheduler_dot_scheduler__pb2.Node.FromString, + response_serializer=compute_dot_scheduler_dot_scheduler__pb2.PutNodeResponse.SerializeToString, + ), + 'DeleteNode': grpc.unary_unary_rpc_method_handler( + servicer.DeleteNode, + request_deserializer=compute_dot_scheduler_dot_scheduler__pb2.Node.FromString, + response_serializer=compute_dot_scheduler_dot_scheduler__pb2.DeleteNodeResponse.SerializeToString, + ), + 'ListNodes': grpc.unary_unary_rpc_method_handler( + servicer.ListNodes, + request_deserializer=compute_dot_scheduler_dot_scheduler__pb2.ListNodesRequest.FromString, + response_serializer=compute_dot_scheduler_dot_scheduler__pb2.ListNodesResponse.SerializeToString, + ), + 'GetNode': grpc.unary_unary_rpc_method_handler( + servicer.GetNode, + request_deserializer=compute_dot_scheduler_dot_scheduler__pb2.GetNodeRequest.FromString, + response_serializer=compute_dot_scheduler_dot_scheduler__pb2.Node.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'scheduler.SchedulerService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class SchedulerService(object): + """* + Scheduler Service + """ + + @staticmethod + def PutNode(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/scheduler.SchedulerService/PutNode', + compute_dot_scheduler_dot_scheduler__pb2.Node.SerializeToString, + compute_dot_scheduler_dot_scheduler__pb2.PutNodeResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def DeleteNode(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/scheduler.SchedulerService/DeleteNode', + compute_dot_scheduler_dot_scheduler__pb2.Node.SerializeToString, + compute_dot_scheduler_dot_scheduler__pb2.DeleteNodeResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ListNodes(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/scheduler.SchedulerService/ListNodes', + compute_dot_scheduler_dot_scheduler__pb2.ListNodesRequest.SerializeToString, + compute_dot_scheduler_dot_scheduler__pb2.ListNodesResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetNode(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/scheduler.SchedulerService/GetNode', + compute_dot_scheduler_dot_scheduler__pb2.GetNodeRequest.SerializeToString, + compute_dot_scheduler_dot_scheduler__pb2.Node.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/plugin-python/config/config_pb2.py b/plugin-python/config/config_pb2.py new file mode 100644 index 0000000..cfae15c --- /dev/null +++ b/plugin-python/config/config_pb2.py @@ -0,0 +1,106 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: config/config.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.protobuf import duration_pb2 as google_dot_protobuf_dot_duration__pb2 +from logger import logger_pb2 as logger_dot_logger__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13\x63onfig/config.proto\x12\x06\x63onfig\x1a\x1egoogle/protobuf/duration.proto\x1a\x13logger/logger.proto\"L\n\nGridEngine\x12\x1a\n\x08Template\x18\x01 \x01(\tR\x08Template\x12\"\n\x0cTemplateFile\x18\x02 \x01(\tR\x0cTemplateFile\"\xf7\n\n\x06\x43onfig\x12\"\n\x0c\x45ventWriters\x18\x01 \x03(\tR\x0c\x45ventWriters\x12\x1a\n\x08\x44\x61tabase\x18\x02 \x01(\tR\x08\x44\x61tabase\x12\x18\n\x07\x43ompute\x18\x03 \x01(\tR\x07\x43ompute\x12&\n\x06Server\x18\x04 \x01(\x0b\x32\x0e.config.ServerR\x06Server\x12/\n\tRPCClient\x18\x05 \x01(\x0b\x32\x11.config.RPCClientR\tRPCClient\x12/\n\tScheduler\x18\x06 \x01(\x0b\x32\x11.config.SchedulerR\tScheduler\x12 \n\x04Node\x18\x07 \x01(\x0b\x32\x0c.config.NodeR\x04Node\x12&\n\x06Worker\x18\x08 \x01(\x0b\x32\x0e.config.WorkerR\x06Worker\x12,\n\x06Logger\x18\t \x01(\x0b\x32\x14.logger.LoggerConfigR\x06Logger\x12&\n\x06\x42oltDB\x18\n \x01(\x0b\x32\x0e.config.BoltDBR\x06\x42oltDB\x12&\n\x06\x42\x61\x64ger\x18\x0b \x01(\x0b\x32\x0e.config.BadgerR\x06\x42\x61\x64ger\x12,\n\x08\x44ynamoDB\x18\x0c \x01(\x0b\x32\x10.config.DynamoDBR\x08\x44ynamoDB\x12)\n\x07\x45lastic\x18\r \x01(\x0b\x32\x0f.config.ElasticR\x07\x45lastic\x12)\n\x07MongoDB\x18\x0e \x01(\x0b\x32\x0f.config.MongoDBR\x07MongoDB\x12#\n\x05Kafka\x18\x0f \x01(\x0b\x32\r.config.KafkaR\x05Kafka\x12&\n\x06PubSub\x18\x10 \x01(\x0b\x32\x0e.config.PubSubR\x06PubSub\x12/\n\tDatastore\x18\x11 \x01(\x0b\x32\x11.config.DatastoreR\tDatastore\x12.\n\x08HTCondor\x18\x12 \x01(\x0b\x32\x12.config.HPCBackendR\x08HTCondor\x12(\n\x05Slurm\x18\x13 \x01(\x0b\x32\x12.config.HPCBackendR\x05Slurm\x12$\n\x03PBS\x18\x14 \x01(\x0b\x32\x12.config.HPCBackendR\x03PBS\x12\x32\n\nGridEngine\x18\x15 \x01(\x0b\x32\x12.config.GridEngineR\nGridEngine\x12,\n\x08\x41WSBatch\x18\x16 \x01(\x0b\x32\x10.config.AWSBatchR\x08\x41WSBatch\x12\x32\n\nKubernetes\x18\x17 \x01(\x0b\x32\x12.config.KubernetesR\nKubernetes\x12\x38\n\x0cLocalStorage\x18\x18 \x01(\x0b\x32\x14.config.LocalStorageR\x0cLocalStorage\x12\x33\n\x08\x41mazonS3\x18\x19 \x01(\x0b\x32\x17.config.AmazonS3StorageR\x08\x41mazonS3\x12\x36\n\tGenericS3\x18\x1a \x03(\x0b\x32\x18.config.GenericS3StorageR\tGenericS3\x12@\n\rGoogleStorage\x18\x1b \x01(\x0b\x32\x1a.config.GoogleCloudStorageR\rGoogleStorage\x12*\n\x05Swift\x18\x1c \x01(\x0b\x32\x14.config.SwiftStorageR\x05Swift\x12\x35\n\x0bHTTPStorage\x18\x1d \x01(\x0b\x32\x13.config.HTTPStorageR\x0bHTTPStorage\x12\x32\n\nFTPStorage\x18\x1e \x01(\x0b\x32\x12.config.FTPStorageR\nFTPStorage\x12)\n\x07Plugins\x18\x1f \x01(\x0b\x32\x0f.config.PluginsR\x07Plugins\"\xb2\x01\n\x07Plugins\x12\x10\n\x03\x44ir\x18\x01 \x01(\tR\x03\x44ir\x12\x16\n\x06Plugin\x18\x02 \x01(\tR\x06Plugin\x12\x12\n\x04Host\x18\x03 \x01(\tR\x04Host\x12\x1e\n\nJsonConfig\x18\x04 \x01(\tR\nJsonConfig\x12\x14\n\x05Input\x18\x05 \x01(\tR\x05Input\x12\x33\n\x08Response\x18\x06 \x01(\x0b\x32\x17.config.PluginsResponseR\x08Response\"\x11\n\x0fPluginsResponse\"W\n\x0f\x42\x61sicCredential\x12\x12\n\x04User\x18\x01 \x01(\tR\x04User\x12\x1a\n\x08Password\x18\x02 \x01(\tR\x08Password\x12\x14\n\x05\x41\x64min\x18\x03 \x01(\x08R\x05\x41\x64min\"\xfe\x01\n\x08OidcAuth\x12*\n\x10ServiceConfigURL\x18\x01 \x01(\tR\x10ServiceConfigURL\x12\x1a\n\x08\x43lientId\x18\x02 \x01(\tR\x08\x43lientId\x12\"\n\x0c\x43lientSecret\x18\x03 \x01(\tR\x0c\x43lientSecret\x12 \n\x0bRedirectURL\x18\x04 \x01(\tR\x0bRedirectURL\x12\"\n\x0cRequireScope\x18\x05 \x01(\tR\x0cRequireScope\x12(\n\x0fRequireAudience\x18\x06 \x01(\tR\x0fRequireAudience\x12\x16\n\x06\x41\x64mins\x18\x07 \x03(\tR\x06\x41\x64mins\"x\n\rTimeoutConfig\x12\x37\n\x08\x64uration\x18\x01 \x01(\x0b\x32\x19.google.protobuf.DurationH\x00R\x08\x64uration\x12\x1c\n\x08\x64isabled\x18\x02 \x01(\x08H\x00R\x08\x64isabledB\x10\n\x0etimeout_option\"\xbb\x01\n\tRPCClient\x12\x37\n\nCredential\x18\x01 \x01(\x0b\x32\x17.config.BasicCredentialR\nCredential\x12$\n\rServerAddress\x18\x02 \x01(\tR\rServerAddress\x12/\n\x07Timeout\x18\x03 \x01(\x0b\x32\x15.config.TimeoutConfigR\x07Timeout\x12\x1e\n\nMaxRetries\x18\x04 \x01(\rR\nMaxRetries\"\xad\x02\n\x06Server\x12 \n\x0bServiceName\x18\x01 \x01(\tR\x0bServiceName\x12\x1a\n\x08HostName\x18\x02 \x01(\tR\x08HostName\x12\x1a\n\x08HTTPPort\x18\x03 \x01(\tR\x08HTTPPort\x12\x18\n\x07RPCPort\x18\x04 \x01(\tR\x07RPCPort\x12\x35\n\tBasicAuth\x18\x05 \x03(\x0b\x32\x17.config.BasicCredentialR\tBasicAuth\x12,\n\x08OidcAuth\x18\x06 \x01(\x0b\x32\x10.config.OidcAuthR\x08OidcAuth\x12*\n\x10\x44isableHTTPCache\x18\x07 \x01(\x08R\x10\x44isableHTTPCache\x12\x1e\n\nTaskAccess\x18\x08 \x01(\tR\nTaskAccess\"\xb3\x02\n\tScheduler\x12=\n\x0cScheduleRate\x18\x01 \x01(\x0b\x32\x19.google.protobuf.DurationR\x0cScheduleRate\x12$\n\rScheduleChunk\x18\x02 \x01(\x05R\rScheduleChunk\x12?\n\x0fNodePingTimeout\x18\x03 \x01(\x0b\x32\x15.config.TimeoutConfigR\x0fNodePingTimeout\x12?\n\x0fNodeInitTimeout\x18\x04 \x01(\x0b\x32\x15.config.TimeoutConfigR\x0fNodeInitTimeout\x12?\n\x0fNodeDeadTimeout\x18\x05 \x01(\x0b\x32\x15.config.TimeoutConfigR\x0fNodeDeadTimeout\"M\n\tResources\x12\x12\n\x04\x43pus\x18\x01 \x01(\rR\x04\x43pus\x12\x14\n\x05RamGb\x18\x02 \x01(\x01R\x05RamGb\x12\x16\n\x06\x44iskGb\x18\x03 \x01(\x01R\x06\x44iskGb\"\xa8\x02\n\x04Node\x12\x0e\n\x02ID\x18\x01 \x01(\tR\x02ID\x12/\n\tResources\x18\x02 \x01(\x0b\x32\x11.config.ResourcesR\tResources\x12/\n\x07Timeout\x18\x03 \x01(\x0b\x32\x15.config.TimeoutConfigR\x07Timeout\x12\x39\n\nUpdateRate\x18\x04 \x01(\x0b\x32\x19.google.protobuf.DurationR\nUpdateRate\x12\x36\n\x08Metadata\x18\x05 \x03(\x0b\x32\x1a.config.Node.MetadataEntryR\x08Metadata\x1a;\n\rMetadataEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\x99\x03\n\x06Worker\x12\x18\n\x07WorkDir\x18\x01 \x01(\tR\x07WorkDir\x12 \n\x0bScratchPath\x18\x02 \x01(\tR\x0bScratchPath\x12;\n\x0bPollingRate\x18\x03 \x01(\x0b\x32\x19.google.protobuf.DurationR\x0bPollingRate\x12?\n\rLogUpdateRate\x18\x04 \x01(\x0b\x32\x19.google.protobuf.DurationR\rLogUpdateRate\x12 \n\x0bLogTailSize\x18\x05 \x01(\x03R\x0bLogTailSize\x12\"\n\x0cLeaveWorkDir\x18\x06 \x01(\x08R\x0cLeaveWorkDir\x12\x32\n\x14MaxParallelTransfers\x18\x07 \x01(\x05R\x14MaxParallelTransfers\x12\x35\n\tContainer\x18\x08 \x01(\x0b\x32\x17.config.ContainerConfigR\tContainer\x12$\n\rDriverCommand\x18\t \x01(\tR\rDriverCommand\"\xaf\x04\n\x0f\x43ontainerConfig\x12\x0e\n\x02Id\x18\x01 \x01(\tR\x02Id\x12\x14\n\x05Image\x18\x02 \x01(\tR\x05Image\x12\x12\n\x04Name\x18\x03 \x01(\tR\x04Name\x12\x18\n\x07\x43ommand\x18\x04 \x03(\tR\x07\x43ommand\x12\x18\n\x07Workdir\x18\x05 \x01(\tR\x07Workdir\x12(\n\x0fRemoveContainer\x18\x06 \x01(\x08R\x0fRemoveContainer\x12\x32\n\x03\x45nv\x18\x07 \x03(\x0b\x32 .config.ContainerConfig.EnvEntryR\x03\x45nv\x12$\n\rDriverCommand\x18\x08 \x01(\tR\rDriverCommand\x12\x1e\n\nRunCommand\x18\t \x01(\tR\nRunCommand\x12 \n\x0bPullCommand\x18\n \x01(\tR\x0bPullCommand\x12 \n\x0bStopCommand\x18\x0b \x01(\tR\x0bStopCommand\x12\x1e\n\nEnableTags\x18\x0c \x01(\x08R\nEnableTags\x12\x35\n\x04Tags\x18\r \x03(\x0b\x32!.config.ContainerConfig.TagsEntryR\x04Tags\x1a\x36\n\x08\x45nvEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x1a\x37\n\tTagsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\xbb\x01\n\nHPCBackend\x12,\n\x11\x44isableReconciler\x18\x01 \x01(\x08R\x11\x44isableReconciler\x12?\n\rReconcileRate\x18\x02 \x01(\x0b\x32\x19.google.protobuf.DurationR\rReconcileRate\x12\x1a\n\x08Template\x18\x03 \x01(\tR\x08Template\x12\"\n\x0cTemplateFile\x18\x04 \x01(\tR\x0cTemplateFile\"\x1c\n\x06\x42oltDB\x12\x12\n\x04Path\x18\x01 \x01(\tR\x04Path\"\x1c\n\x06\x42\x61\x64ger\x12\x12\n\x04Path\x18\x01 \x01(\tR\x04Path\"\xa4\x01\n\x07MongoDB\x12\x14\n\x05\x41\x64\x64rs\x18\x01 \x03(\tR\x05\x41\x64\x64rs\x12\x1a\n\x08\x44\x61tabase\x18\x02 \x01(\tR\x08\x44\x61tabase\x12/\n\x07Timeout\x18\x03 \x01(\x0b\x32\x15.config.TimeoutConfigR\x07Timeout\x12\x1a\n\x08Username\x18\x04 \x01(\tR\x08Username\x12\x1a\n\x08Password\x18\x05 \x01(\tR\x08Password\"\xcb\x01\n\x07\x45lastic\x12 \n\x0bIndexPrefix\x18\x01 \x01(\tR\x0bIndexPrefix\x12\x10\n\x03URL\x18\x02 \x01(\tR\x03URL\x12\x1a\n\x08Username\x18\x03 \x01(\tR\x08Username\x12\x1a\n\x08Password\x18\x04 \x01(\tR\x08Password\x12\x18\n\x07\x43loudID\x18\x05 \x01(\tR\x07\x43loudID\x12\x16\n\x06\x41PIKey\x18\x06 \x01(\tR\x06\x41PIKey\x12\"\n\x0cServiceToken\x18\x07 \x01(\tR\x0cServiceToken\"7\n\x05Kafka\x12\x18\n\x07Servers\x18\x01 \x03(\tR\x07Servers\x12\x14\n\x05Topic\x18\x02 \x01(\tR\x05Topic\"b\n\x06PubSub\x12\x14\n\x05Topic\x18\x01 \x01(\tR\x05Topic\x12\x18\n\x07Project\x18\x02 \x01(\tR\x07Project\x12(\n\x0f\x43redentialsFile\x18\x03 \x01(\tR\x0f\x43redentialsFile\"\xc7\x01\n\tAWSConfig\x12\x1a\n\x08\x45ndpoint\x18\x01 \x01(\tR\x08\x45ndpoint\x12\x16\n\x06Region\x18\x02 \x01(\tR\x06Region\x12\x1e\n\nMaxRetries\x18\x03 \x01(\x05R\nMaxRetries\x12\x10\n\x03Key\x18\x04 \x01(\tR\x03Key\x12\x16\n\x06Secret\x18\x05 \x01(\tR\x06Secret\x12<\n\x19\x44isableAutoCredentialLoad\x18\x06 \x01(\x08R\x19\x44isableAutoCredentialLoad\"\xec\x01\n\x08\x41WSBatch\x12$\n\rJobDefinition\x18\x01 \x01(\tR\rJobDefinition\x12\x1a\n\x08JobQueue\x18\x02 \x01(\tR\x08JobQueue\x12,\n\x11\x44isableReconciler\x18\x03 \x01(\x08R\x11\x44isableReconciler\x12?\n\rReconcileRate\x18\x04 \x01(\x0b\x32\x19.google.protobuf.DurationR\rReconcileRate\x12/\n\tAWSConfig\x18\x05 \x01(\x0b\x32\x11.config.AWSConfigR\tAWSConfig\"O\n\tDatastore\x12\x18\n\x07Project\x18\x01 \x01(\tR\x07Project\x12(\n\x0f\x43redentialsFile\x18\x02 \x01(\tR\x0f\x43redentialsFile\"a\n\x08\x44ynamoDB\x12$\n\rTableBasename\x18\x01 \x01(\tR\rTableBasename\x12/\n\tAWSConfig\x18\x02 \x01(\x0b\x32\x11.config.AWSConfigR\tAWSConfig\"L\n\x0cLocalStorage\x12\x1a\n\x08\x44isabled\x18\x01 \x01(\x08R\x08\x44isabled\x12 \n\x0b\x41llowedDirs\x18\x02 \x03(\tR\x0b\x41llowedDirs\"Z\n\x12GoogleCloudStorage\x12\x1a\n\x08\x44isabled\x18\x01 \x01(\x08R\x08\x44isabled\x12(\n\x0f\x43redentialsFile\x18\x02 \x01(\tR\x0f\x43redentialsFile\"G\n\x03SSE\x12(\n\x0f\x43ustomerKeyFile\x18\x01 \x01(\tR\x0f\x43ustomerKeyFile\x12\x16\n\x06KMSKey\x18\x02 \x01(\tR\x06KMSKey\"}\n\x0f\x41mazonS3Storage\x12\x1a\n\x08\x44isabled\x18\x01 \x01(\x08R\x08\x44isabled\x12\x1d\n\x03SSE\x18\x02 \x01(\x0b\x32\x0b.config.SSER\x03SSE\x12/\n\tAWSConfig\x18\x03 \x01(\x0b\x32\x11.config.AWSConfigR\tAWSConfig\"t\n\x10GenericS3Storage\x12\x1a\n\x08\x44isabled\x18\x01 \x01(\x08R\x08\x44isabled\x12\x1a\n\x08\x45ndpoint\x18\x02 \x01(\tR\x08\x45ndpoint\x12\x10\n\x03Key\x18\x03 \x01(\tR\x03Key\x12\x16\n\x06Secret\x18\x04 \x01(\tR\x06Secret\"\xa0\x02\n\x0cSwiftStorage\x12\x1a\n\x08\x44isabled\x18\x01 \x01(\x08R\x08\x44isabled\x12\x1a\n\x08UserName\x18\x02 \x01(\tR\x08UserName\x12\x1a\n\x08Password\x18\x03 \x01(\tR\x08Password\x12\x18\n\x07\x41uthURL\x18\x04 \x01(\tR\x07\x41uthURL\x12\x1e\n\nTenantName\x18\x05 \x01(\tR\nTenantName\x12\x1a\n\x08TenantID\x18\x06 \x01(\tR\x08TenantID\x12\x1e\n\nRegionName\x18\x07 \x01(\tR\nRegionName\x12&\n\x0e\x43hunkSizeBytes\x18\x08 \x01(\x03R\x0e\x43hunkSizeBytes\x12\x1e\n\nMaxRetries\x18\t \x01(\x05R\nMaxRetries\"Z\n\x0bHTTPStorage\x12\x1a\n\x08\x44isabled\x18\x01 \x01(\x08R\x08\x44isabled\x12/\n\x07Timeout\x18\x02 \x01(\x0b\x32\x15.config.TimeoutConfigR\x07Timeout\"\x89\x01\n\nFTPStorage\x12\x1a\n\x08\x44isabled\x18\x01 \x01(\x08R\x08\x44isabled\x12/\n\x07Timeout\x18\x02 \x01(\x0b\x32\x15.config.TimeoutConfigR\x07Timeout\x12\x12\n\x04User\x18\x03 \x01(\tR\x04User\x12\x1a\n\x08Password\x18\x04 \x01(\tR\x08Password\"\x91\x05\n\nKubernetes\x12\x16\n\x06\x42ucket\x18\x01 \x01(\tR\x06\x42ucket\x12\x16\n\x06Region\x18\x02 \x01(\tR\x06Region\x12\x1a\n\x08\x45xecutor\x18\x03 \x01(\tR\x08\x45xecutor\x12,\n\x11\x44isableReconciler\x18\x04 \x01(\x08R\x11\x44isableReconciler\x12?\n\rReconcileRate\x18\x05 \x01(\x0b\x32\x19.google.protobuf.DurationR\rReconcileRate\x12,\n\x11\x44isableJobCleanup\x18\x06 \x01(\x08R\x11\x44isableJobCleanup\x12\x1a\n\x08Template\x18\x07 \x01(\tR\x08Template\x12\"\n\x0cTemplateFile\x18\x08 \x01(\tR\x0cTemplateFile\x12*\n\x10\x45xecutorTemplate\x18\t \x01(\tR\x10\x45xecutorTemplate\x12\x32\n\x14\x45xecutorTemplateFile\x18\n \x01(\tR\x14\x45xecutorTemplateFile\x12\x1e\n\nPVTemplate\x18\x0b \x01(\tR\nPVTemplate\x12 \n\x0bPVCTemplate\x18\x0c \x01(\tR\x0bPVCTemplate\x12,\n\x11\x43onfigMapTemplate\x18\r \x01(\tR\x11\x43onfigMapTemplate\x12\x1e\n\nConfigFile\x18\x0e \x01(\tR\nConfigFile\x12\x1c\n\tNamespace\x18\x0f \x01(\tR\tNamespace\x12$\n\rJobsNamespace\x18\x10 \x01(\tR\rJobsNamespace\x12&\n\x0eServiceAccount\x18\x11 \x01(\tR\x0eServiceAccountB(Z&github.com/ohsu-comp-bio/funnel/configb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'config.config_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'Z&github.com/ohsu-comp-bio/funnel/config' + _globals['_NODE_METADATAENTRY']._options = None + _globals['_NODE_METADATAENTRY']._serialized_options = b'8\001' + _globals['_CONTAINERCONFIG_ENVENTRY']._options = None + _globals['_CONTAINERCONFIG_ENVENTRY']._serialized_options = b'8\001' + _globals['_CONTAINERCONFIG_TAGSENTRY']._options = None + _globals['_CONTAINERCONFIG_TAGSENTRY']._serialized_options = b'8\001' + _globals['_GRIDENGINE']._serialized_start=84 + _globals['_GRIDENGINE']._serialized_end=160 + _globals['_CONFIG']._serialized_start=163 + _globals['_CONFIG']._serialized_end=1562 + _globals['_PLUGINS']._serialized_start=1565 + _globals['_PLUGINS']._serialized_end=1743 + _globals['_PLUGINSRESPONSE']._serialized_start=1745 + _globals['_PLUGINSRESPONSE']._serialized_end=1762 + _globals['_BASICCREDENTIAL']._serialized_start=1764 + _globals['_BASICCREDENTIAL']._serialized_end=1851 + _globals['_OIDCAUTH']._serialized_start=1854 + _globals['_OIDCAUTH']._serialized_end=2108 + _globals['_TIMEOUTCONFIG']._serialized_start=2110 + _globals['_TIMEOUTCONFIG']._serialized_end=2230 + _globals['_RPCCLIENT']._serialized_start=2233 + _globals['_RPCCLIENT']._serialized_end=2420 + _globals['_SERVER']._serialized_start=2423 + _globals['_SERVER']._serialized_end=2724 + _globals['_SCHEDULER']._serialized_start=2727 + _globals['_SCHEDULER']._serialized_end=3034 + _globals['_RESOURCES']._serialized_start=3036 + _globals['_RESOURCES']._serialized_end=3113 + _globals['_NODE']._serialized_start=3116 + _globals['_NODE']._serialized_end=3412 + _globals['_NODE_METADATAENTRY']._serialized_start=3353 + _globals['_NODE_METADATAENTRY']._serialized_end=3412 + _globals['_WORKER']._serialized_start=3415 + _globals['_WORKER']._serialized_end=3824 + _globals['_CONTAINERCONFIG']._serialized_start=3827 + _globals['_CONTAINERCONFIG']._serialized_end=4386 + _globals['_CONTAINERCONFIG_ENVENTRY']._serialized_start=4275 + _globals['_CONTAINERCONFIG_ENVENTRY']._serialized_end=4329 + _globals['_CONTAINERCONFIG_TAGSENTRY']._serialized_start=4331 + _globals['_CONTAINERCONFIG_TAGSENTRY']._serialized_end=4386 + _globals['_HPCBACKEND']._serialized_start=4389 + _globals['_HPCBACKEND']._serialized_end=4576 + _globals['_BOLTDB']._serialized_start=4578 + _globals['_BOLTDB']._serialized_end=4606 + _globals['_BADGER']._serialized_start=4608 + _globals['_BADGER']._serialized_end=4636 + _globals['_MONGODB']._serialized_start=4639 + _globals['_MONGODB']._serialized_end=4803 + _globals['_ELASTIC']._serialized_start=4806 + _globals['_ELASTIC']._serialized_end=5009 + _globals['_KAFKA']._serialized_start=5011 + _globals['_KAFKA']._serialized_end=5066 + _globals['_PUBSUB']._serialized_start=5068 + _globals['_PUBSUB']._serialized_end=5166 + _globals['_AWSCONFIG']._serialized_start=5169 + _globals['_AWSCONFIG']._serialized_end=5368 + _globals['_AWSBATCH']._serialized_start=5371 + _globals['_AWSBATCH']._serialized_end=5607 + _globals['_DATASTORE']._serialized_start=5609 + _globals['_DATASTORE']._serialized_end=5688 + _globals['_DYNAMODB']._serialized_start=5690 + _globals['_DYNAMODB']._serialized_end=5787 + _globals['_LOCALSTORAGE']._serialized_start=5789 + _globals['_LOCALSTORAGE']._serialized_end=5865 + _globals['_GOOGLECLOUDSTORAGE']._serialized_start=5867 + _globals['_GOOGLECLOUDSTORAGE']._serialized_end=5957 + _globals['_SSE']._serialized_start=5959 + _globals['_SSE']._serialized_end=6030 + _globals['_AMAZONS3STORAGE']._serialized_start=6032 + _globals['_AMAZONS3STORAGE']._serialized_end=6157 + _globals['_GENERICS3STORAGE']._serialized_start=6159 + _globals['_GENERICS3STORAGE']._serialized_end=6275 + _globals['_SWIFTSTORAGE']._serialized_start=6278 + _globals['_SWIFTSTORAGE']._serialized_end=6566 + _globals['_HTTPSTORAGE']._serialized_start=6568 + _globals['_HTTPSTORAGE']._serialized_end=6658 + _globals['_FTPSTORAGE']._serialized_start=6661 + _globals['_FTPSTORAGE']._serialized_end=6798 + _globals['_KUBERNETES']._serialized_start=6801 + _globals['_KUBERNETES']._serialized_end=7458 +# @@protoc_insertion_point(module_scope) diff --git a/plugin-python/config/config_pb2_grpc.py b/plugin-python/config/config_pb2_grpc.py new file mode 100644 index 0000000..2daafff --- /dev/null +++ b/plugin-python/config/config_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/plugin-python/events/events_pb2.py b/plugin-python/events/events_pb2.py new file mode 100644 index 0000000..e4f83c2 --- /dev/null +++ b/plugin-python/events/events_pb2.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: events/events.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from tes import tes_pb2 as tes_dot_tes__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13\x65vents/events.proto\x12\x06\x65vents\x1a\rtes/tes.proto\"w\n\x08Metadata\x12\x31\n\x05value\x18\x01 \x03(\x0b\x32\x1b.events.Metadata.ValueEntryR\x05value\x1a\x38\n\nValueEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"3\n\x07Outputs\x12(\n\x05value\x18\x01 \x03(\x0b\x32\x12.tes.OutputFileLogR\x05value\"\xa5\x01\n\tSystemLog\x12\x10\n\x03msg\x18\x01 \x01(\tR\x03msg\x12\x14\n\x05level\x18\x02 \x01(\tR\x05level\x12\x35\n\x06\x66ields\x18\x03 \x03(\x0b\x32\x1d.events.SystemLog.FieldsEntryR\x06\x66ields\x1a\x39\n\x0b\x46ieldsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\xf6\x03\n\x05\x45vent\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x1c\n\ttimestamp\x18\x02 \x01(\tR\ttimestamp\x12\"\n\x05state\x18\x03 \x01(\x0e\x32\n.tes.StateH\x00R\x05state\x12\x1f\n\nstart_time\x18\x04 \x01(\tH\x00R\tstartTime\x12\x1b\n\x08\x65nd_time\x18\x05 \x01(\tH\x00R\x07\x65ndTime\x12+\n\x07outputs\x18\x06 \x01(\x0b\x32\x0f.events.OutputsH\x00R\x07outputs\x12.\n\x08metadata\x18\x07 \x01(\x0b\x32\x10.events.MetadataH\x00R\x08metadata\x12\x1d\n\texit_code\x18\n \x01(\x05H\x00R\x08\x65xitCode\x12\x18\n\x06stdout\x18\r \x01(\tH\x00R\x06stdout\x12\x18\n\x06stderr\x18\x0e \x01(\tH\x00R\x06stderr\x12\x32\n\nsystem_log\x18\x0f \x01(\x0b\x32\x11.events.SystemLogH\x00R\tsystemLog\x12\x1f\n\x04task\x18\x13 \x01(\x0b\x32\t.tes.TaskH\x00R\x04task\x12\x18\n\x07\x61ttempt\x18\x10 \x01(\rR\x07\x61ttempt\x12\x14\n\x05index\x18\x11 \x01(\rR\x05index\x12 \n\x04type\x18\x12 \x01(\x0e\x32\x0c.events.TypeR\x04typeB\x06\n\x04\x64\x61ta\"\x14\n\x12WriteEventResponse*\x84\x02\n\x04Type\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0e\n\nTASK_STATE\x10\x01\x12\x13\n\x0fTASK_START_TIME\x10\x02\x12\x11\n\rTASK_END_TIME\x10\x03\x12\x10\n\x0cTASK_OUTPUTS\x10\x04\x12\x11\n\rTASK_METADATA\x10\x05\x12\x17\n\x13\x45XECUTOR_START_TIME\x10\x06\x12\x15\n\x11\x45XECUTOR_END_TIME\x10\x07\x12\x16\n\x12\x45XECUTOR_EXIT_CODE\x10\x08\x12\x13\n\x0f\x45XECUTOR_STDOUT\x10\x0b\x12\x13\n\x0f\x45XECUTOR_STDERR\x10\x0c\x12\x0e\n\nSYSTEM_LOG\x10\r\x12\x10\n\x0cTASK_CREATED\x10\x0e\x32I\n\x0c\x45ventService\x12\x39\n\nWriteEvent\x12\r.events.Event\x1a\x1a.events.WriteEventResponse\"\x00\x42(Z&github.com/ohsu-comp-bio/funnel/eventsb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'events.events_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'Z&github.com/ohsu-comp-bio/funnel/events' + _globals['_METADATA_VALUEENTRY']._options = None + _globals['_METADATA_VALUEENTRY']._serialized_options = b'8\001' + _globals['_SYSTEMLOG_FIELDSENTRY']._options = None + _globals['_SYSTEMLOG_FIELDSENTRY']._serialized_options = b'8\001' + _globals['_TYPE']._serialized_start=916 + _globals['_TYPE']._serialized_end=1176 + _globals['_METADATA']._serialized_start=46 + _globals['_METADATA']._serialized_end=165 + _globals['_METADATA_VALUEENTRY']._serialized_start=109 + _globals['_METADATA_VALUEENTRY']._serialized_end=165 + _globals['_OUTPUTS']._serialized_start=167 + _globals['_OUTPUTS']._serialized_end=218 + _globals['_SYSTEMLOG']._serialized_start=221 + _globals['_SYSTEMLOG']._serialized_end=386 + _globals['_SYSTEMLOG_FIELDSENTRY']._serialized_start=329 + _globals['_SYSTEMLOG_FIELDSENTRY']._serialized_end=386 + _globals['_EVENT']._serialized_start=389 + _globals['_EVENT']._serialized_end=891 + _globals['_WRITEEVENTRESPONSE']._serialized_start=893 + _globals['_WRITEEVENTRESPONSE']._serialized_end=913 + _globals['_EVENTSERVICE']._serialized_start=1178 + _globals['_EVENTSERVICE']._serialized_end=1251 +# @@protoc_insertion_point(module_scope) diff --git a/plugin-python/events/events_pb2_grpc.py b/plugin-python/events/events_pb2_grpc.py new file mode 100644 index 0000000..e0eb3f0 --- /dev/null +++ b/plugin-python/events/events_pb2_grpc.py @@ -0,0 +1,72 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from events import events_pb2 as events_dot_events__pb2 + + +class EventServiceStub(object): + """* + Event Service + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.WriteEvent = channel.unary_unary( + '/events.EventService/WriteEvent', + request_serializer=events_dot_events__pb2.Event.SerializeToString, + response_deserializer=events_dot_events__pb2.WriteEventResponse.FromString, + ) + + +class EventServiceServicer(object): + """* + Event Service + """ + + def WriteEvent(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_EventServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'WriteEvent': grpc.unary_unary_rpc_method_handler( + servicer.WriteEvent, + request_deserializer=events_dot_events__pb2.Event.FromString, + response_serializer=events_dot_events__pb2.WriteEventResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'events.EventService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class EventService(object): + """* + Event Service + """ + + @staticmethod + def WriteEvent(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/events.EventService/WriteEvent', + events_dot_events__pb2.Event.SerializeToString, + events_dot_events__pb2.WriteEventResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/plugin-python/google/api/annotations_pb2.py b/plugin-python/google/api/annotations_pb2.py new file mode 100644 index 0000000..5ed1cb0 --- /dev/null +++ b/plugin-python/google/api/annotations_pb2.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/api/annotations.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.api import http_pb2 as google_dot_api_dot_http__pb2 +from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cgoogle/api/annotations.proto\x12\ngoogle.api\x1a\x15google/api/http.proto\x1a google/protobuf/descriptor.proto:K\n\x04http\x12\x1e.google.protobuf.MethodOptions\x18\xb0\xca\xbc\" \x01(\x0b\x32\x14.google.api.HttpRuleR\x04httpBn\n\x0e\x63om.google.apiB\x10\x41nnotationsProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.api.annotations_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\016com.google.apiB\020AnnotationsProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI' +# @@protoc_insertion_point(module_scope) diff --git a/plugin-python/google/api/annotations_pb2_grpc.py b/plugin-python/google/api/annotations_pb2_grpc.py new file mode 100644 index 0000000..2daafff --- /dev/null +++ b/plugin-python/google/api/annotations_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/plugin-python/google/api/http_pb2.py b/plugin-python/google/api/http_pb2.py new file mode 100644 index 0000000..e11f0f4 --- /dev/null +++ b/plugin-python/google/api/http_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: google/api/http.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15google/api/http.proto\x12\ngoogle.api\"y\n\x04Http\x12*\n\x05rules\x18\x01 \x03(\x0b\x32\x14.google.api.HttpRuleR\x05rules\x12\x45\n\x1f\x66ully_decode_reserved_expansion\x18\x02 \x01(\x08R\x1c\x66ullyDecodeReservedExpansion\"\xda\x02\n\x08HttpRule\x12\x1a\n\x08selector\x18\x01 \x01(\tR\x08selector\x12\x12\n\x03get\x18\x02 \x01(\tH\x00R\x03get\x12\x12\n\x03put\x18\x03 \x01(\tH\x00R\x03put\x12\x14\n\x04post\x18\x04 \x01(\tH\x00R\x04post\x12\x18\n\x06\x64\x65lete\x18\x05 \x01(\tH\x00R\x06\x64\x65lete\x12\x16\n\x05patch\x18\x06 \x01(\tH\x00R\x05patch\x12\x37\n\x06\x63ustom\x18\x08 \x01(\x0b\x32\x1d.google.api.CustomHttpPatternH\x00R\x06\x63ustom\x12\x12\n\x04\x62ody\x18\x07 \x01(\tR\x04\x62ody\x12#\n\rresponse_body\x18\x0c \x01(\tR\x0cresponseBody\x12\x45\n\x13\x61\x64\x64itional_bindings\x18\x0b \x03(\x0b\x32\x14.google.api.HttpRuleR\x12\x61\x64\x64itionalBindingsB\t\n\x07pattern\";\n\x11\x43ustomHttpPattern\x12\x12\n\x04kind\x18\x01 \x01(\tR\x04kind\x12\x12\n\x04path\x18\x02 \x01(\tR\x04pathBg\n\x0e\x63om.google.apiB\tHttpProtoP\x01ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\xa2\x02\x04GAPIb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'google.api.http_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'\n\016com.google.apiB\tHttpProtoP\001ZAgoogle.golang.org/genproto/googleapis/api/annotations;annotations\242\002\004GAPI' + _globals['_HTTP']._serialized_start=37 + _globals['_HTTP']._serialized_end=158 + _globals['_HTTPRULE']._serialized_start=161 + _globals['_HTTPRULE']._serialized_end=507 + _globals['_CUSTOMHTTPPATTERN']._serialized_start=509 + _globals['_CUSTOMHTTPPATTERN']._serialized_end=568 +# @@protoc_insertion_point(module_scope) diff --git a/plugin-python/google/api/http_pb2_grpc.py b/plugin-python/google/api/http_pb2_grpc.py new file mode 100644 index 0000000..2daafff --- /dev/null +++ b/plugin-python/google/api/http_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/plugin-python/logger/logger_pb2.py b/plugin-python/logger/logger_pb2.py new file mode 100644 index 0000000..49a6b5d --- /dev/null +++ b/plugin-python/logger/logger_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: logger/logger.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13logger/logger.proto\x12\x06logger\"j\n\x10JSONFormatConfig\x12+\n\x11\x64isable_timestamp\x18\x01 \x01(\x08R\x10\x64isableTimestamp\x12)\n\x10timestamp_format\x18\x02 \x01(\tR\x0ftimestampFormat\"\x9c\x02\n\x10TextFormatConfig\x12!\n\x0c\x66orce_colors\x18\x01 \x01(\x08R\x0b\x66orceColors\x12%\n\x0e\x64isable_colors\x18\x02 \x01(\x08R\rdisableColors\x12+\n\x11\x64isable_timestamp\x18\x03 \x01(\x08R\x10\x64isableTimestamp\x12%\n\x0e\x66ull_timestamp\x18\x04 \x01(\x08R\rfullTimestamp\x12)\n\x10timestamp_format\x18\x05 \x01(\tR\x0ftimestampFormat\x12\'\n\x0f\x64isable_sorting\x18\x06 \x01(\x08R\x0e\x64isableSorting\x12\x16\n\x06indent\x18\x07 \x01(\tR\x06indent\"\xd9\x01\n\x0cLoggerConfig\x12\x14\n\x05level\x18\x01 \x01(\tR\x05level\x12\x1c\n\tformatter\x18\x02 \x01(\tR\tformatter\x12\x1f\n\x0boutput_file\x18\x03 \x01(\tR\noutputFile\x12\x39\n\x0bjson_format\x18\x04 \x01(\x0b\x32\x18.logger.JSONFormatConfigR\njsonFormat\x12\x39\n\x0btext_format\x18\x05 \x01(\x0b\x32\x18.logger.TextFormatConfigR\ntextFormatB(Z&github.com/ohsu-comp-bio/funnel/loggerb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'logger.logger_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'Z&github.com/ohsu-comp-bio/funnel/logger' + _globals['_JSONFORMATCONFIG']._serialized_start=31 + _globals['_JSONFORMATCONFIG']._serialized_end=137 + _globals['_TEXTFORMATCONFIG']._serialized_start=140 + _globals['_TEXTFORMATCONFIG']._serialized_end=424 + _globals['_LOGGERCONFIG']._serialized_start=427 + _globals['_LOGGERCONFIG']._serialized_end=644 +# @@protoc_insertion_point(module_scope) diff --git a/plugin-python/logger/logger_pb2_grpc.py b/plugin-python/logger/logger_pb2_grpc.py new file mode 100644 index 0000000..2daafff --- /dev/null +++ b/plugin-python/logger/logger_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/plugin-python/proto/auth_pb2.py b/plugin-python/proto/auth_pb2.py index 8d5e2c8..4e7eb8b 100644 --- a/plugin-python/proto/auth_pb2.py +++ b/plugin-python/proto/auth_pb2.py @@ -11,9 +11,11 @@ _sym_db = _symbol_database.Default() +from config import config_pb2 as config_dot_config__pb2 +from tes import tes_pb2 as tes_dot_tes__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10proto/auth.proto\x12\x05proto\"4\n\nGetRequest\x12\x12\n\x04user\x18\x01 \x01(\tR\x04user\x12\x12\n\x04host\x18\x02 \x01(\tR\x04host\"#\n\x0bGetResponse\x12\x14\n\x05value\x18\x01 \x01(\x0cR\x05value\"\x07\n\x05\x45mpty29\n\tAuthorize\x12,\n\x03Get\x12\x11.proto.GetRequest\x1a\x12.proto.GetResponseB\tZ\x07./protob\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10proto/auth.proto\x12\x05proto\x1a\x13\x63onfig/config.proto\x1a\rtes/tes.proto\"$\n\nStringList\x12\x16\n\x06values\x18\x01 \x03(\tR\x06values\"\xce\x02\n\nGetRequest\x12\x38\n\x07headers\x18\x01 \x03(\x0b\x32\x1e.proto.GetRequest.HeadersEntryR\x07headers\x12\x35\n\x06params\x18\x02 \x03(\x0b\x32\x1d.proto.GetRequest.ParamsEntryR\x06params\x12&\n\x06\x63onfig\x18\x03 \x01(\x0b\x32\x0e.config.ConfigR\x06\x63onfig\x12\x1d\n\x04task\x18\x04 \x01(\x0b\x32\t.tes.TaskR\x04task\x1aM\n\x0cHeadersEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\'\n\x05value\x18\x02 \x01(\x0b\x32\x11.proto.StringListR\x05value:\x02\x38\x01\x1a\x39\n\x0bParamsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"#\n\x0bGetResponse\x12\x14\n\x05value\x18\x01 \x01(\x0cR\x05value\"\x07\n\x05\x45mpty29\n\tAuthorize\x12,\n\x03Get\x12\x11.proto.GetRequest\x1a\x12.proto.GetResponseB\tZ\x07./protob\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -21,12 +23,22 @@ if _descriptor._USE_C_DESCRIPTORS == False: _globals['DESCRIPTOR']._options = None _globals['DESCRIPTOR']._serialized_options = b'Z\007./proto' - _globals['_GETREQUEST']._serialized_start=27 - _globals['_GETREQUEST']._serialized_end=79 - _globals['_GETRESPONSE']._serialized_start=81 - _globals['_GETRESPONSE']._serialized_end=116 - _globals['_EMPTY']._serialized_start=118 - _globals['_EMPTY']._serialized_end=125 - _globals['_AUTHORIZE']._serialized_start=127 - _globals['_AUTHORIZE']._serialized_end=184 + _globals['_GETREQUEST_HEADERSENTRY']._options = None + _globals['_GETREQUEST_HEADERSENTRY']._serialized_options = b'8\001' + _globals['_GETREQUEST_PARAMSENTRY']._options = None + _globals['_GETREQUEST_PARAMSENTRY']._serialized_options = b'8\001' + _globals['_STRINGLIST']._serialized_start=63 + _globals['_STRINGLIST']._serialized_end=99 + _globals['_GETREQUEST']._serialized_start=102 + _globals['_GETREQUEST']._serialized_end=436 + _globals['_GETREQUEST_HEADERSENTRY']._serialized_start=300 + _globals['_GETREQUEST_HEADERSENTRY']._serialized_end=377 + _globals['_GETREQUEST_PARAMSENTRY']._serialized_start=379 + _globals['_GETREQUEST_PARAMSENTRY']._serialized_end=436 + _globals['_GETRESPONSE']._serialized_start=438 + _globals['_GETRESPONSE']._serialized_end=473 + _globals['_EMPTY']._serialized_start=475 + _globals['_EMPTY']._serialized_end=482 + _globals['_AUTHORIZE']._serialized_start=484 + _globals['_AUTHORIZE']._serialized_end=541 # @@protoc_insertion_point(module_scope) diff --git a/plugin-python/tes/tes_pb2.py b/plugin-python/tes/tes_pb2.py new file mode 100644 index 0000000..4e2a721 --- /dev/null +++ b/plugin-python/tes/tes_pb2.py @@ -0,0 +1,127 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: tes/tes.proto +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + +from google.api import annotations_pb2 as google_dot_api_dot_annotations__pb2 + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rtes/tes.proto\x12\x03tes\x1a\x1cgoogle/api/annotations.proto\"#\n\x11\x43\x61ncelTaskRequest\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\"\xa9\x02\n\rExecutorBasic\x12\x18\n\x07\x63ommand\x18\x01 \x03(\tR\x07\x63ommand\x12-\n\x03\x65nv\x18\x02 \x03(\x0b\x32\x1b.tes.ExecutorBasic.EnvEntryR\x03\x65nv\x12!\n\x0cignore_error\x18\x03 \x01(\x08R\x0bignoreError\x12\x14\n\x05image\x18\x04 \x01(\tR\x05image\x12\x16\n\x06stderr\x18\x05 \x01(\tR\x06stderr\x12\x14\n\x05stdin\x18\x06 \x01(\tR\x05stdin\x12\x16\n\x06stdout\x18\x07 \x01(\tR\x06stdout\x12\x18\n\x07workdir\x18\x08 \x01(\tR\x07workdir\x1a\x36\n\x08\x45nvEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\x17\n\x15GetServiceInfoRequest\"4\n\x0eGetTaskRequest\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n\x04view\x18\x02 \x01(\tR\x04view\"\xc5\x01\n\nInputBasic\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12\x12\n\x04path\x18\x04 \x01(\tR\x04path\x12\x1e\n\nstreamable\x18\x05 \x01(\x08R\nstreamable\x12!\n\x04type\x18\x06 \x01(\x0e\x32\r.tes.FileTypeR\x04type\x12\x10\n\x03url\x18\x07 \x01(\tR\x03url\"\xdb\x01\n\x10ListTasksRequest\x12\x1f\n\x0bname_prefix\x18\x01 \x01(\tR\nnamePrefix\x12 \n\x05state\x18\x02 \x01(\x0e\x32\n.tes.StateR\x05state\x12\x17\n\x07tag_key\x18\x03 \x03(\tR\x06tagKey\x12\x1b\n\ttag_value\x18\x04 \x03(\tR\x08tagValue\x12\x1b\n\tpage_size\x18\x05 \x01(\x05R\x08pageSize\x12\x1d\n\npage_token\x18\x06 \x01(\tR\tpageToken\x12\x12\n\x04view\x18\x07 \x01(\tR\x04view\"f\n\x16ListTasksResponseBasic\x12&\n\x0fnext_page_token\x18\x01 \x01(\tR\rnextPageToken\x12$\n\x05tasks\x18\x02 \x03(\x0b\x32\x0e.tes.TaskBasicR\x05tasks\"b\n\x14ListTasksResponseMin\x12&\n\x0fnext_page_token\x18\x01 \x01(\tR\rnextPageToken\x12\"\n\x05tasks\x18\x02 \x03(\x0b\x32\x0c.tes.TaskMinR\x05tasks\"\xf0\x03\n\tTaskBasic\x12#\n\rcreation_time\x18\x01 \x01(\tR\x0c\x63reationTime\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x30\n\texecutors\x18\x03 \x03(\x0b\x32\x12.tes.ExecutorBasicR\texecutors\x12\x0e\n\x02id\x18\x04 \x01(\tR\x02id\x12\'\n\x06inputs\x18\x05 \x03(\x0b\x32\x0f.tes.InputBasicR\x06inputs\x12%\n\x04logs\x18\x06 \x03(\x0b\x32\x11.tes.TaskLogBasicR\x04logs\x12\x12\n\x04name\x18\x07 \x01(\tR\x04name\x12%\n\x07outputs\x18\x08 \x03(\x0b\x32\x0b.tes.OutputR\x07outputs\x12,\n\tresources\x18\t \x01(\x0b\x32\x0e.tes.ResourcesR\tresources\x12 \n\x05state\x18\n \x01(\x0e\x32\n.tes.StateR\x05state\x12,\n\x04tags\x18\x0b \x03(\x0b\x32\x18.tes.TaskBasic.TagsEntryR\x04tags\x12\x18\n\x07volumes\x18\x0c \x03(\tR\x07volumes\x1a\x37\n\tTagsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\xb7\x02\n\x0cTaskLogBasic\x12\x19\n\x08\x65nd_time\x18\x01 \x01(\tR\x07\x65ndTime\x12$\n\x04logs\x18\x02 \x03(\x0b\x32\x10.tes.ExecutorLogR\x04logs\x12;\n\x08metadata\x18\x03 \x03(\x0b\x32\x1f.tes.TaskLogBasic.MetadataEntryR\x08metadata\x12,\n\x07outputs\x18\x04 \x03(\x0b\x32\x12.tes.OutputFileLogR\x07outputs\x12\x1d\n\nstart_time\x18\x05 \x01(\tR\tstartTime\x12\x1f\n\x0bsystem_logs\x18\x06 \x03(\tR\nsystemLogs\x1a;\n\rMetadataEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\xdd\x03\n\x07TaskMin\x12#\n\rcreation_time\x18\x01 \x01(\tR\x0c\x63reationTime\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12+\n\texecutors\x18\x03 \x03(\x0b\x32\r.tes.ExecutorR\texecutors\x12\x0e\n\x02id\x18\x04 \x01(\tR\x02id\x12\"\n\x06inputs\x18\x05 \x03(\x0b\x32\n.tes.InputR\x06inputs\x12 \n\x04logs\x18\x06 \x03(\x0b\x32\x0c.tes.TaskLogR\x04logs\x12\x12\n\x04name\x18\x07 \x01(\tR\x04name\x12%\n\x07outputs\x18\x08 \x03(\x0b\x32\x0b.tes.OutputR\x07outputs\x12,\n\tresources\x18\t \x01(\x0b\x32\x0e.tes.ResourcesR\tresources\x12 \n\x05state\x18\n \x01(\x0e\x32\n.tes.StateR\x05state\x12*\n\x04tags\x18\x0b \x03(\x0b\x32\x16.tes.TaskMin.TagsEntryR\x04tags\x12\x18\n\x07volumes\x18\x0c \x03(\tR\x07volumes\x1a\x37\n\tTagsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\x14\n\x12\x43\x61ncelTaskResponse\"$\n\x12\x43reateTaskResponse\x12\x0e\n\x02id\x18\x01 \x01(\tR\x02id\"\x9f\x02\n\x08\x45xecutor\x12\x18\n\x07\x63ommand\x18\x01 \x03(\tR\x07\x63ommand\x12(\n\x03\x65nv\x18\x02 \x03(\x0b\x32\x16.tes.Executor.EnvEntryR\x03\x65nv\x12!\n\x0cignore_error\x18\x03 \x01(\x08R\x0bignoreError\x12\x14\n\x05image\x18\x04 \x01(\tR\x05image\x12\x16\n\x06stderr\x18\x05 \x01(\tR\x06stderr\x12\x14\n\x05stdin\x18\x06 \x01(\tR\x05stdin\x12\x16\n\x06stdout\x18\x07 \x01(\tR\x06stdout\x12\x18\n\x07workdir\x18\x08 \x01(\tR\x07workdir\x1a\x36\n\x08\x45nvEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\x94\x01\n\x0b\x45xecutorLog\x12\x19\n\x08\x65nd_time\x18\x01 \x01(\tR\x07\x65ndTime\x12\x1b\n\texit_code\x18\x02 \x01(\x05R\x08\x65xitCode\x12\x1d\n\nstart_time\x18\x03 \x01(\tR\tstartTime\x12\x16\n\x06stderr\x18\x04 \x01(\tR\x06stderr\x12\x16\n\x06stdout\x18\x05 \x01(\tR\x06stdout\"\xc0\x01\n\x05Input\x12\x18\n\x07\x63ontent\x18\x01 \x01(\tR\x07\x63ontent\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12\x12\n\x04path\x18\x04 \x01(\tR\x04path\x12\x1e\n\nstreamable\x18\x05 \x01(\x08R\nstreamable\x12!\n\x04type\x18\x06 \x01(\x0e\x32\r.tes.FileTypeR\x04type\x12\x10\n\x03url\x18\x07 \x01(\tR\x03url\"\\\n\x11ListTasksResponse\x12&\n\x0fnext_page_token\x18\x01 \x01(\tR\rnextPageToken\x12\x1f\n\x05tasks\x18\x02 \x03(\x0b\x32\t.tes.TaskR\x05tasks\"\xa8\x01\n\x06Output\x12 \n\x0b\x64\x65scription\x18\x01 \x01(\tR\x0b\x64\x65scription\x12\x12\n\x04name\x18\x02 \x01(\tR\x04name\x12\x12\n\x04path\x18\x03 \x01(\tR\x04path\x12\x1f\n\x0bpath_prefix\x18\x04 \x01(\tR\npathPrefix\x12!\n\x04type\x18\x05 \x01(\x0e\x32\r.tes.FileTypeR\x04type\x12\x10\n\x03url\x18\x06 \x01(\tR\x03url\"T\n\rOutputFileLog\x12\x12\n\x04path\x18\x01 \x01(\tR\x04path\x12\x1d\n\nsize_bytes\x18\x02 \x01(\tR\tsizeBytes\x12\x10\n\x03url\x18\x03 \x01(\tR\x03url\"\xe8\x02\n\tResources\x12T\n\x12\x62\x61\x63kend_parameters\x18\x01 \x03(\x0b\x32%.tes.Resources.BackendParametersEntryR\x11\x62\x61\x63kendParameters\x12:\n\x19\x62\x61\x63kend_parameters_strict\x18\x02 \x01(\x08R\x17\x62\x61\x63kendParametersStrict\x12\x1b\n\tcpu_cores\x18\x03 \x01(\x05R\x08\x63puCores\x12\x17\n\x07\x64isk_gb\x18\x04 \x01(\x01R\x06\x64iskGb\x12 \n\x0bpreemptible\x18\x05 \x01(\x08R\x0bpreemptible\x12\x15\n\x06ram_gb\x18\x06 \x01(\x01R\x05ramGb\x12\x14\n\x05zones\x18\x07 \x03(\tR\x05zones\x1a\x44\n\x16\x42\x61\x63kendParametersEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\xa8\x04\n\x0bServiceInfo\x12\x1e\n\ncontactUrl\x18\x01 \x01(\tR\ncontactUrl\x12\x1c\n\tcreatedAt\x18\x02 \x01(\tR\tcreatedAt\x12 \n\x0b\x64\x65scription\x18\x03 \x01(\tR\x0b\x64\x65scription\x12*\n\x10\x64ocumentationUrl\x18\x04 \x01(\tR\x10\x64ocumentationUrl\x12 \n\x0b\x65nvironment\x18\x05 \x01(\tR\x0b\x65nvironment\x12\x0e\n\x02id\x18\x06 \x01(\tR\x02id\x12\x12\n\x04name\x18\x07 \x01(\tR\x04name\x12\x46\n\x0corganization\x18\x08 \x03(\x0b\x32\".tes.ServiceInfo.OrganizationEntryR\x0corganization\x12\x18\n\x07storage\x18\t \x03(\tR\x07storage\x12\x46\n\x1ftesResources_backend_parameters\x18\n \x03(\tR\x1dtesResourcesBackendParameters\x12$\n\x04type\x18\x0b \x01(\x0b\x32\x10.tes.ServiceTypeR\x04type\x12\x1c\n\tupdatedAt\x18\x0c \x01(\tR\tupdatedAt\x12\x18\n\x07version\x18\r \x01(\tR\x07version\x1a?\n\x11OrganizationEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"Y\n\x0bServiceType\x12\x1a\n\x08\x61rtifact\x18\x01 \x01(\tR\x08\x61rtifact\x12\x14\n\x05group\x18\x02 \x01(\tR\x05group\x12\x18\n\x07version\x18\x03 \x01(\tR\x07version\"\xd7\x03\n\x04Task\x12#\n\rcreation_time\x18\x01 \x01(\tR\x0c\x63reationTime\x12 \n\x0b\x64\x65scription\x18\x02 \x01(\tR\x0b\x64\x65scription\x12+\n\texecutors\x18\x03 \x03(\x0b\x32\r.tes.ExecutorR\texecutors\x12\x0e\n\x02id\x18\x04 \x01(\tR\x02id\x12\"\n\x06inputs\x18\x05 \x03(\x0b\x32\n.tes.InputR\x06inputs\x12 \n\x04logs\x18\x06 \x03(\x0b\x32\x0c.tes.TaskLogR\x04logs\x12\x12\n\x04name\x18\x07 \x01(\tR\x04name\x12%\n\x07outputs\x18\x08 \x03(\x0b\x32\x0b.tes.OutputR\x07outputs\x12,\n\tresources\x18\t \x01(\x0b\x32\x0e.tes.ResourcesR\tresources\x12 \n\x05state\x18\n \x01(\x0e\x32\n.tes.StateR\x05state\x12\'\n\x04tags\x18\x0b \x03(\x0b\x32\x13.tes.Task.TagsEntryR\x04tags\x12\x18\n\x07volumes\x18\x0c \x03(\tR\x07volumes\x1a\x37\n\tTagsEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\"\xad\x02\n\x07TaskLog\x12\x19\n\x08\x65nd_time\x18\x01 \x01(\tR\x07\x65ndTime\x12$\n\x04logs\x18\x02 \x03(\x0b\x32\x10.tes.ExecutorLogR\x04logs\x12\x36\n\x08metadata\x18\x03 \x03(\x0b\x32\x1a.tes.TaskLog.MetadataEntryR\x08metadata\x12,\n\x07outputs\x18\x04 \x03(\x0b\x32\x12.tes.OutputFileLogR\x07outputs\x12\x1d\n\nstart_time\x18\x05 \x01(\tR\tstartTime\x12\x1f\n\x0bsystem_logs\x18\x06 \x03(\tR\nsystemLogs\x1a;\n\rMetadataEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01*\xab\x01\n\x05State\x12\x0b\n\x07UNKNOWN\x10\x00\x12\n\n\x06QUEUED\x10\x01\x12\x10\n\x0cINITIALIZING\x10\x02\x12\x0b\n\x07RUNNING\x10\x03\x12\n\n\x06PAUSED\x10\x04\x12\x0c\n\x08\x43OMPLETE\x10\x05\x12\x12\n\x0e\x45XECUTOR_ERROR\x10\x06\x12\x10\n\x0cSYSTEM_ERROR\x10\x07\x12\x0c\n\x08\x43\x41NCELED\x10\x08\x12\r\n\tPREEMPTED\x10\t\x12\r\n\tCANCELING\x10\n*#\n\x08\x46ileType\x12\x08\n\x04\x46ILE\x10\x00\x12\r\n\tDIRECTORY\x10\x01*(\n\x04view\x12\x0b\n\x07MINIMAL\x10\x00\x12\t\n\x05\x42\x41SIC\x10\x01\x12\x08\n\x04\x46ULL\x10\x02\x32\x85\x05\n\x0bTaskService\x12\x87\x01\n\x0eGetServiceInfo\x12\x1a.tes.GetServiceInfoRequest\x1a\x10.tes.ServiceInfo\"G\x82\xd3\xe4\x93\x02\x41\x12\r/service-infoZ\x12\x12\x10/v1/service-infoZ\x1c\x12\x1a/ga4gh/tes/v1/service-info\x12n\n\tListTasks\x12\x15.tes.ListTasksRequest\x1a\x16.tes.ListTasksResponse\"2\x82\xd3\xe4\x93\x02,\x12\x06/tasksZ\x0b\x12\t/v1/tasksZ\x15\x12\x13/ga4gh/tes/v1/tasks\x12m\n\nCreateTask\x12\t.tes.Task\x1a\x17.tes.CreateTaskResponse\";\x82\xd3\xe4\x93\x02\x35\"\x06/tasks:\x01*Z\x0e\"\t/v1/tasks:\x01*Z\x18\"\x13/ga4gh/tes/v1/tasks:\x01*\x12l\n\x07GetTask\x12\x13.tes.GetTaskRequest\x1a\t.tes.Task\"A\x82\xd3\xe4\x93\x02;\x12\x0b/tasks/{id}Z\x10\x12\x0e/v1/tasks/{id}Z\x1a\x12\x18/ga4gh/tes/v1/tasks/{id}\x12\x9e\x01\n\nCancelTask\x12\x16.tes.CancelTaskRequest\x1a\x17.tes.CancelTaskResponse\"_\x82\xd3\xe4\x93\x02Y\"\x12/tasks/{id}:cancel:\x01*Z\x1a\"\x15/v1/tasks/{id}:cancel:\x01*Z$\"\x1f/ga4gh/tes/v1/tasks/{id}:cancel:\x01*B%Z#github.com/ohsu-comp-bio/funnel/tesb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tes.tes_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + _globals['DESCRIPTOR']._options = None + _globals['DESCRIPTOR']._serialized_options = b'Z#github.com/ohsu-comp-bio/funnel/tes' + _globals['_EXECUTORBASIC_ENVENTRY']._options = None + _globals['_EXECUTORBASIC_ENVENTRY']._serialized_options = b'8\001' + _globals['_TASKBASIC_TAGSENTRY']._options = None + _globals['_TASKBASIC_TAGSENTRY']._serialized_options = b'8\001' + _globals['_TASKLOGBASIC_METADATAENTRY']._options = None + _globals['_TASKLOGBASIC_METADATAENTRY']._serialized_options = b'8\001' + _globals['_TASKMIN_TAGSENTRY']._options = None + _globals['_TASKMIN_TAGSENTRY']._serialized_options = b'8\001' + _globals['_EXECUTOR_ENVENTRY']._options = None + _globals['_EXECUTOR_ENVENTRY']._serialized_options = b'8\001' + _globals['_RESOURCES_BACKENDPARAMETERSENTRY']._options = None + _globals['_RESOURCES_BACKENDPARAMETERSENTRY']._serialized_options = b'8\001' + _globals['_SERVICEINFO_ORGANIZATIONENTRY']._options = None + _globals['_SERVICEINFO_ORGANIZATIONENTRY']._serialized_options = b'8\001' + _globals['_TASK_TAGSENTRY']._options = None + _globals['_TASK_TAGSENTRY']._serialized_options = b'8\001' + _globals['_TASKLOG_METADATAENTRY']._options = None + _globals['_TASKLOG_METADATAENTRY']._serialized_options = b'8\001' + _globals['_TASKSERVICE'].methods_by_name['GetServiceInfo']._options = None + _globals['_TASKSERVICE'].methods_by_name['GetServiceInfo']._serialized_options = b'\202\323\344\223\002A\022\r/service-infoZ\022\022\020/v1/service-infoZ\034\022\032/ga4gh/tes/v1/service-info' + _globals['_TASKSERVICE'].methods_by_name['ListTasks']._options = None + _globals['_TASKSERVICE'].methods_by_name['ListTasks']._serialized_options = b'\202\323\344\223\002,\022\006/tasksZ\013\022\t/v1/tasksZ\025\022\023/ga4gh/tes/v1/tasks' + _globals['_TASKSERVICE'].methods_by_name['CreateTask']._options = None + _globals['_TASKSERVICE'].methods_by_name['CreateTask']._serialized_options = b'\202\323\344\223\0025\"\006/tasks:\001*Z\016\"\t/v1/tasks:\001*Z\030\"\023/ga4gh/tes/v1/tasks:\001*' + _globals['_TASKSERVICE'].methods_by_name['GetTask']._options = None + _globals['_TASKSERVICE'].methods_by_name['GetTask']._serialized_options = b'\202\323\344\223\002;\022\013/tasks/{id}Z\020\022\016/v1/tasks/{id}Z\032\022\030/ga4gh/tes/v1/tasks/{id}' + _globals['_TASKSERVICE'].methods_by_name['CancelTask']._options = None + _globals['_TASKSERVICE'].methods_by_name['CancelTask']._serialized_options = b'\202\323\344\223\002Y\"\022/tasks/{id}:cancel:\001*Z\032\"\025/v1/tasks/{id}:cancel:\001*Z$\"\037/ga4gh/tes/v1/tasks/{id}:cancel:\001*' + _globals['_STATE']._serialized_start=5222 + _globals['_STATE']._serialized_end=5393 + _globals['_FILETYPE']._serialized_start=5395 + _globals['_FILETYPE']._serialized_end=5430 + _globals['_VIEW']._serialized_start=5432 + _globals['_VIEW']._serialized_end=5472 + _globals['_CANCELTASKREQUEST']._serialized_start=52 + _globals['_CANCELTASKREQUEST']._serialized_end=87 + _globals['_EXECUTORBASIC']._serialized_start=90 + _globals['_EXECUTORBASIC']._serialized_end=387 + _globals['_EXECUTORBASIC_ENVENTRY']._serialized_start=333 + _globals['_EXECUTORBASIC_ENVENTRY']._serialized_end=387 + _globals['_GETSERVICEINFOREQUEST']._serialized_start=389 + _globals['_GETSERVICEINFOREQUEST']._serialized_end=412 + _globals['_GETTASKREQUEST']._serialized_start=414 + _globals['_GETTASKREQUEST']._serialized_end=466 + _globals['_INPUTBASIC']._serialized_start=469 + _globals['_INPUTBASIC']._serialized_end=666 + _globals['_LISTTASKSREQUEST']._serialized_start=669 + _globals['_LISTTASKSREQUEST']._serialized_end=888 + _globals['_LISTTASKSRESPONSEBASIC']._serialized_start=890 + _globals['_LISTTASKSRESPONSEBASIC']._serialized_end=992 + _globals['_LISTTASKSRESPONSEMIN']._serialized_start=994 + _globals['_LISTTASKSRESPONSEMIN']._serialized_end=1092 + _globals['_TASKBASIC']._serialized_start=1095 + _globals['_TASKBASIC']._serialized_end=1591 + _globals['_TASKBASIC_TAGSENTRY']._serialized_start=1536 + _globals['_TASKBASIC_TAGSENTRY']._serialized_end=1591 + _globals['_TASKLOGBASIC']._serialized_start=1594 + _globals['_TASKLOGBASIC']._serialized_end=1905 + _globals['_TASKLOGBASIC_METADATAENTRY']._serialized_start=1846 + _globals['_TASKLOGBASIC_METADATAENTRY']._serialized_end=1905 + _globals['_TASKMIN']._serialized_start=1908 + _globals['_TASKMIN']._serialized_end=2385 + _globals['_TASKMIN_TAGSENTRY']._serialized_start=1536 + _globals['_TASKMIN_TAGSENTRY']._serialized_end=1591 + _globals['_CANCELTASKRESPONSE']._serialized_start=2387 + _globals['_CANCELTASKRESPONSE']._serialized_end=2407 + _globals['_CREATETASKRESPONSE']._serialized_start=2409 + _globals['_CREATETASKRESPONSE']._serialized_end=2445 + _globals['_EXECUTOR']._serialized_start=2448 + _globals['_EXECUTOR']._serialized_end=2735 + _globals['_EXECUTOR_ENVENTRY']._serialized_start=333 + _globals['_EXECUTOR_ENVENTRY']._serialized_end=387 + _globals['_EXECUTORLOG']._serialized_start=2738 + _globals['_EXECUTORLOG']._serialized_end=2886 + _globals['_INPUT']._serialized_start=2889 + _globals['_INPUT']._serialized_end=3081 + _globals['_LISTTASKSRESPONSE']._serialized_start=3083 + _globals['_LISTTASKSRESPONSE']._serialized_end=3175 + _globals['_OUTPUT']._serialized_start=3178 + _globals['_OUTPUT']._serialized_end=3346 + _globals['_OUTPUTFILELOG']._serialized_start=3348 + _globals['_OUTPUTFILELOG']._serialized_end=3432 + _globals['_RESOURCES']._serialized_start=3435 + _globals['_RESOURCES']._serialized_end=3795 + _globals['_RESOURCES_BACKENDPARAMETERSENTRY']._serialized_start=3727 + _globals['_RESOURCES_BACKENDPARAMETERSENTRY']._serialized_end=3795 + _globals['_SERVICEINFO']._serialized_start=3798 + _globals['_SERVICEINFO']._serialized_end=4350 + _globals['_SERVICEINFO_ORGANIZATIONENTRY']._serialized_start=4287 + _globals['_SERVICEINFO_ORGANIZATIONENTRY']._serialized_end=4350 + _globals['_SERVICETYPE']._serialized_start=4352 + _globals['_SERVICETYPE']._serialized_end=4441 + _globals['_TASK']._serialized_start=4444 + _globals['_TASK']._serialized_end=4915 + _globals['_TASK_TAGSENTRY']._serialized_start=1536 + _globals['_TASK_TAGSENTRY']._serialized_end=1591 + _globals['_TASKLOG']._serialized_start=4918 + _globals['_TASKLOG']._serialized_end=5219 + _globals['_TASKLOG_METADATAENTRY']._serialized_start=1846 + _globals['_TASKLOG_METADATAENTRY']._serialized_end=1905 + _globals['_TASKSERVICE']._serialized_start=5475 + _globals['_TASKSERVICE']._serialized_end=6120 +# @@protoc_insertion_point(module_scope) diff --git a/plugin-python/tes/tes_pb2_grpc.py b/plugin-python/tes/tes_pb2_grpc.py new file mode 100644 index 0000000..408ac18 --- /dev/null +++ b/plugin-python/tes/tes_pb2_grpc.py @@ -0,0 +1,198 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from tes import tes_pb2 as tes_dot_tes__pb2 + + +class TaskServiceStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.GetServiceInfo = channel.unary_unary( + '/tes.TaskService/GetServiceInfo', + request_serializer=tes_dot_tes__pb2.GetServiceInfoRequest.SerializeToString, + response_deserializer=tes_dot_tes__pb2.ServiceInfo.FromString, + ) + self.ListTasks = channel.unary_unary( + '/tes.TaskService/ListTasks', + request_serializer=tes_dot_tes__pb2.ListTasksRequest.SerializeToString, + response_deserializer=tes_dot_tes__pb2.ListTasksResponse.FromString, + ) + self.CreateTask = channel.unary_unary( + '/tes.TaskService/CreateTask', + request_serializer=tes_dot_tes__pb2.Task.SerializeToString, + response_deserializer=tes_dot_tes__pb2.CreateTaskResponse.FromString, + ) + self.GetTask = channel.unary_unary( + '/tes.TaskService/GetTask', + request_serializer=tes_dot_tes__pb2.GetTaskRequest.SerializeToString, + response_deserializer=tes_dot_tes__pb2.Task.FromString, + ) + self.CancelTask = channel.unary_unary( + '/tes.TaskService/CancelTask', + request_serializer=tes_dot_tes__pb2.CancelTaskRequest.SerializeToString, + response_deserializer=tes_dot_tes__pb2.CancelTaskResponse.FromString, + ) + + +class TaskServiceServicer(object): + """Missing associated documentation comment in .proto file.""" + + def GetServiceInfo(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def ListTasks(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CreateTask(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def GetTask(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + def CancelTask(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_TaskServiceServicer_to_server(servicer, server): + rpc_method_handlers = { + 'GetServiceInfo': grpc.unary_unary_rpc_method_handler( + servicer.GetServiceInfo, + request_deserializer=tes_dot_tes__pb2.GetServiceInfoRequest.FromString, + response_serializer=tes_dot_tes__pb2.ServiceInfo.SerializeToString, + ), + 'ListTasks': grpc.unary_unary_rpc_method_handler( + servicer.ListTasks, + request_deserializer=tes_dot_tes__pb2.ListTasksRequest.FromString, + response_serializer=tes_dot_tes__pb2.ListTasksResponse.SerializeToString, + ), + 'CreateTask': grpc.unary_unary_rpc_method_handler( + servicer.CreateTask, + request_deserializer=tes_dot_tes__pb2.Task.FromString, + response_serializer=tes_dot_tes__pb2.CreateTaskResponse.SerializeToString, + ), + 'GetTask': grpc.unary_unary_rpc_method_handler( + servicer.GetTask, + request_deserializer=tes_dot_tes__pb2.GetTaskRequest.FromString, + response_serializer=tes_dot_tes__pb2.Task.SerializeToString, + ), + 'CancelTask': grpc.unary_unary_rpc_method_handler( + servicer.CancelTask, + request_deserializer=tes_dot_tes__pb2.CancelTaskRequest.FromString, + response_serializer=tes_dot_tes__pb2.CancelTaskResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'tes.TaskService', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class TaskService(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def GetServiceInfo(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tes.TaskService/GetServiceInfo', + tes_dot_tes__pb2.GetServiceInfoRequest.SerializeToString, + tes_dot_tes__pb2.ServiceInfo.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def ListTasks(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tes.TaskService/ListTasks', + tes_dot_tes__pb2.ListTasksRequest.SerializeToString, + tes_dot_tes__pb2.ListTasksResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CreateTask(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tes.TaskService/CreateTask', + tes_dot_tes__pb2.Task.SerializeToString, + tes_dot_tes__pb2.CreateTaskResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetTask(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tes.TaskService/GetTask', + tes_dot_tes__pb2.GetTaskRequest.SerializeToString, + tes_dot_tes__pb2.Task.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def CancelTask(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/tes.TaskService/CancelTask', + tes_dot_tes__pb2.CancelTaskRequest.SerializeToString, + tes_dot_tes__pb2.CancelTaskResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/proto/auth.pb.go b/proto/auth.pb.go deleted file mode 100644 index 97fae10..0000000 --- a/proto/auth.pb.go +++ /dev/null @@ -1,221 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.36.6 -// protoc (unknown) -// source: proto/auth.proto - -package proto - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" - unsafe "unsafe" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type GetRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user,omitempty"` - Host string `protobuf:"bytes,2,opt,name=host,proto3" json:"host,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GetRequest) Reset() { - *x = GetRequest{} - mi := &file_proto_auth_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GetRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetRequest) ProtoMessage() {} - -func (x *GetRequest) ProtoReflect() protoreflect.Message { - mi := &file_proto_auth_proto_msgTypes[0] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetRequest.ProtoReflect.Descriptor instead. -func (*GetRequest) Descriptor() ([]byte, []int) { - return file_proto_auth_proto_rawDescGZIP(), []int{0} -} - -func (x *GetRequest) GetUser() string { - if x != nil { - return x.User - } - return "" -} - -func (x *GetRequest) GetHost() string { - if x != nil { - return x.Host - } - return "" -} - -type GetResponse struct { - state protoimpl.MessageState `protogen:"open.v1"` - Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *GetResponse) Reset() { - *x = GetResponse{} - mi := &file_proto_auth_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *GetResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetResponse) ProtoMessage() {} - -func (x *GetResponse) ProtoReflect() protoreflect.Message { - mi := &file_proto_auth_proto_msgTypes[1] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetResponse.ProtoReflect.Descriptor instead. -func (*GetResponse) Descriptor() ([]byte, []int) { - return file_proto_auth_proto_rawDescGZIP(), []int{1} -} - -func (x *GetResponse) GetValue() []byte { - if x != nil { - return x.Value - } - return nil -} - -type Empty struct { - state protoimpl.MessageState `protogen:"open.v1"` - unknownFields protoimpl.UnknownFields - sizeCache protoimpl.SizeCache -} - -func (x *Empty) Reset() { - *x = Empty{} - mi := &file_proto_auth_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) -} - -func (x *Empty) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Empty) ProtoMessage() {} - -func (x *Empty) ProtoReflect() protoreflect.Message { - mi := &file_proto_auth_proto_msgTypes[2] - if x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Empty.ProtoReflect.Descriptor instead. -func (*Empty) Descriptor() ([]byte, []int) { - return file_proto_auth_proto_rawDescGZIP(), []int{2} -} - -var File_proto_auth_proto protoreflect.FileDescriptor - -const file_proto_auth_proto_rawDesc = "" + - "\n" + - "\x10proto/auth.proto\x12\x05proto\"4\n" + - "\n" + - "GetRequest\x12\x12\n" + - "\x04user\x18\x01 \x01(\tR\x04user\x12\x12\n" + - "\x04host\x18\x02 \x01(\tR\x04host\"#\n" + - "\vGetResponse\x12\x14\n" + - "\x05value\x18\x01 \x01(\fR\x05value\"\a\n" + - "\x05Empty29\n" + - "\tAuthorize\x12,\n" + - "\x03Get\x12\x11.proto.GetRequest\x1a\x12.proto.GetResponseB\tZ\a./protob\x06proto3" - -var ( - file_proto_auth_proto_rawDescOnce sync.Once - file_proto_auth_proto_rawDescData []byte -) - -func file_proto_auth_proto_rawDescGZIP() []byte { - file_proto_auth_proto_rawDescOnce.Do(func() { - file_proto_auth_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_proto_auth_proto_rawDesc), len(file_proto_auth_proto_rawDesc))) - }) - return file_proto_auth_proto_rawDescData -} - -var file_proto_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 3) -var file_proto_auth_proto_goTypes = []any{ - (*GetRequest)(nil), // 0: proto.GetRequest - (*GetResponse)(nil), // 1: proto.GetResponse - (*Empty)(nil), // 2: proto.Empty -} -var file_proto_auth_proto_depIdxs = []int32{ - 0, // 0: proto.Authorize.Get:input_type -> proto.GetRequest - 1, // 1: proto.Authorize.Get:output_type -> proto.GetResponse - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_proto_auth_proto_init() } -func file_proto_auth_proto_init() { - if File_proto_auth_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_proto_auth_proto_rawDesc), len(file_proto_auth_proto_rawDesc)), - NumEnums: 0, - NumMessages: 3, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_proto_auth_proto_goTypes, - DependencyIndexes: file_proto_auth_proto_depIdxs, - MessageInfos: file_proto_auth_proto_msgTypes, - }.Build() - File_proto_auth_proto = out.File - file_proto_auth_proto_goTypes = nil - file_proto_auth_proto_depIdxs = nil -} diff --git a/proto/auth.proto b/proto/auth.proto deleted file mode 100644 index d642db2..0000000 --- a/proto/auth.proto +++ /dev/null @@ -1,18 +0,0 @@ -syntax = "proto3"; -package proto; -option go_package = "./proto"; - -message GetRequest { - string user = 1; - string host = 2; -} - -message GetResponse { - bytes value = 1; -} - -message Empty {} - -service Authorize { - rpc Get(GetRequest) returns (GetResponse); -} diff --git a/proto/auth_grpc.pb.go b/proto/auth_grpc.pb.go deleted file mode 100644 index 6c3020c..0000000 --- a/proto/auth_grpc.pb.go +++ /dev/null @@ -1,107 +0,0 @@ -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc (unknown) -// source: proto/auth.proto - -package proto - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -const ( - Authorize_Get_FullMethodName = "/proto.Authorize/Get" -) - -// AuthorizeClient is the client API for Authorize service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type AuthorizeClient interface { - Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) -} - -type authorizeClient struct { - cc grpc.ClientConnInterface -} - -func NewAuthorizeClient(cc grpc.ClientConnInterface) AuthorizeClient { - return &authorizeClient{cc} -} - -func (c *authorizeClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) { - out := new(GetResponse) - err := c.cc.Invoke(ctx, Authorize_Get_FullMethodName, in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// AuthorizeServer is the server API for Authorize service. -// All implementations should embed UnimplementedAuthorizeServer -// for forward compatibility -type AuthorizeServer interface { - Get(context.Context, *GetRequest) (*GetResponse, error) -} - -// UnimplementedAuthorizeServer should be embedded to have forward compatible implementations. -type UnimplementedAuthorizeServer struct { -} - -func (UnimplementedAuthorizeServer) Get(context.Context, *GetRequest) (*GetResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") -} - -// UnsafeAuthorizeServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to AuthorizeServer will -// result in compilation errors. -type UnsafeAuthorizeServer interface { - mustEmbedUnimplementedAuthorizeServer() -} - -func RegisterAuthorizeServer(s grpc.ServiceRegistrar, srv AuthorizeServer) { - s.RegisterService(&Authorize_ServiceDesc, srv) -} - -func _Authorize_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(AuthorizeServer).Get(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: Authorize_Get_FullMethodName, - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(AuthorizeServer).Get(ctx, req.(*GetRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// Authorize_ServiceDesc is the grpc.ServiceDesc for Authorize service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Authorize_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "proto.Authorize", - HandlerType: (*AuthorizeServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Get", - Handler: _Authorize_Get_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "proto/auth.proto", -} diff --git a/shared/grpc.go b/shared/grpc.go deleted file mode 100644 index 14cb668..0000000 --- a/shared/grpc.go +++ /dev/null @@ -1,35 +0,0 @@ -package shared - -import ( - "context" - - "example.com/proto" -) - -// GRPCClient is an implementation of KV that talks over RPC. -type GRPCClient struct{ client proto.AuthorizeClient } - -func (m *GRPCClient) Get(user string, host string) ([]byte, error) { - resp, err := m.client.Get(context.Background(), &proto.GetRequest{ - User: user, - Host: host, - }) - if err != nil { - return nil, err - } - - return resp.Value, nil -} - -// Here is the gRPC server that GRPCClient talks to. -type GRPCServer struct { - // This is the real implementation - Impl Authorize -} - -func (m *GRPCServer) Get( - ctx context.Context, - req *proto.GetRequest) (*proto.GetResponse, error) { - v, err := m.Impl.Get(req.User, req.Host) - return &proto.GetResponse{Value: v}, err -} diff --git a/shared/interface.go b/shared/interface.go deleted file mode 100644 index 6d0c10a..0000000 --- a/shared/interface.go +++ /dev/null @@ -1,77 +0,0 @@ -package shared - -import ( - "context" - "net/rpc" - - "example.com/proto" - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/go-plugin" - "github.com/ohsu-comp-bio/funnel/config" - "google.golang.org/grpc" -) - -// Define a struct that matches the expected JSON response -type Response struct { - Code int `json:"code,omitempty"` - Message string `json:"message,omitempty"` - Config *config.Config `json:"config,omitempty"` -} - -// Handshake is a common handshake that is shared by plugin and host. -var Handshake = plugin.HandshakeConfig{ - // This isn't required when using VersionedPlugins - ProtocolVersion: 1, - MagicCookieKey: "AUTHORIZE_PLUGIN", - MagicCookieValue: "authorize", -} - -// Create an hclog.Logger -var Logger = hclog.New(&hclog.LoggerOptions{ - Name: "plugin", - Level: hclog.Trace, -}) - -// PluginMap is the map of plugins we can dispense. -var PluginMap = map[string]plugin.Plugin{ - "authorize_grpc": &AuthorizeGRPCPlugin{}, - "authorize": &AuthorizePlugin{}, -} - -// Authorize is the interface that we're exposing as a plugin. -type Authorize interface { - Get(user string, host string) ([]byte, error) -} - -// This is the implementation of plugin.Plugin so we can serve/consume this. -type AuthorizePlugin struct { - // Concrete implementation, written in Go. This is only used for plugins - // that are written in Go. - Impl Authorize -} - -func (p *AuthorizePlugin) Server(*plugin.MuxBroker) (interface{}, error) { - return &RPCServer{Impl: p.Impl}, nil -} - -func (*AuthorizePlugin) Client(b *plugin.MuxBroker, c *rpc.Client) (interface{}, error) { - return &RPCClient{client: c}, nil -} - -// This is the implementation of plugin.GRPCPlugin so we can serve/consume this. -type AuthorizeGRPCPlugin struct { - // GRPCPlugin must still implement the Plugin interface - plugin.Plugin - // Concrete implementation, written in Go. This is only used for plugins - // that are written in Go. - Impl Authorize -} - -func (p *AuthorizeGRPCPlugin) GRPCServer(broker *plugin.GRPCBroker, s *grpc.Server) error { - proto.RegisterAuthorizeServer(s, &GRPCServer{Impl: p.Impl}) - return nil -} - -func (p *AuthorizeGRPCPlugin) GRPCClient(ctx context.Context, broker *plugin.GRPCBroker, c *grpc.ClientConn) (interface{}, error) { - return &GRPCClient{client: proto.NewAuthorizeClient(c)}, nil -} diff --git a/shared/manager.go b/shared/manager.go deleted file mode 100644 index bc20e45..0000000 --- a/shared/manager.go +++ /dev/null @@ -1,84 +0,0 @@ -// Plugin manager used by the main application to load and invoke plugins. -// -// Adapted from 'RPC-based plugins in Go' by Eli Bendersky (@eliben): -// ref: https://eli.thegreenplace.net/2023/rpc-based-plugins-in-go/ -// ref: https://github.com/eliben/code-for-blog/blob/main/2023/go-plugin-htmlize-rpc/plugin/manager.go -package shared - -import ( - "fmt" - "os/exec" - - "github.com/hashicorp/go-plugin" - goplugin "github.com/hashicorp/go-plugin" -) - -// Manager loads and manages Authorizer plugins for this application. -// -// After creating a Manager value, call LoadPlugins with a directory path to -// discover and load plugins. At the end of the program call Close to kill and -// clean up all plugin processes. -type Manager struct { - pluginClients []*goplugin.Client -} - -// LoadPlugins takes a directory path and assumes that all files within it -// are plugin binaries. It runs all these binaries in sub-processes, -// establishes RPC communication with the plugins, and registers them for -// the hooks they declare to support. -func (m *Manager) LoadPlugins(path string) error { - binaries, err := goplugin.Discover("*", path) - if err != nil { - return err - } - - for _, bpath := range binaries { - client := plugin.NewClient(&plugin.ClientConfig{ - HandshakeConfig: Handshake, - Plugins: PluginMap, - Logger: Logger, - Cmd: exec.Command(bpath), - AllowedProtocols: []plugin.Protocol{ - plugin.ProtocolNetRPC, plugin.ProtocolGRPC}}) - - m.pluginClients = append(m.pluginClients, client) - } - - return nil -} - -func (m *Manager) Client(dir string) (Authorize, error) { - if err := m.LoadPlugins(dir); err != nil { - return nil, fmt.Errorf("failed to load plugins: %w", err) - } - - if len(m.pluginClients) == 0 { - return nil, fmt.Errorf("no plugins loaded") - } - - // Connect via RPC - // Here we just get the first plugin found in the specified plugin directory. - // In future applications we'll want to have some logic to select the appropriate plugins. - client, err := m.pluginClients[0].Client() - if err != nil { - return nil, fmt.Errorf("failed to create client: %w", err) - } - - // Request the plugin - raw, err := client.Dispense("authorize") - if err != nil { - return nil, fmt.Errorf("failed to dispense plugin: %w", err) - } - - // We should have an Authorize function now! This feels like a normal interface - // implementation but is in fact over an RPC connection. - authorize := raw.(Authorize) - - return authorize, nil -} - -func (m *Manager) Close() { - for _, client := range m.pluginClients { - client.Kill() - } -} diff --git a/shared/rpc.go b/shared/rpc.go deleted file mode 100644 index c613541..0000000 --- a/shared/rpc.go +++ /dev/null @@ -1,32 +0,0 @@ -package shared - -import ( - "fmt" - "net/rpc" -) - -// RPCClient is an implementation of Authorization that talks over RPC. -type RPCClient struct{ client *rpc.Client } - -func (m *RPCClient) Get(user string, host string) ([]byte, error) { - var resp []byte - err := m.client.Call("Plugin.Get", []string{user, host}, &resp) - return resp, err -} - -// Here is the RPC server that RPCClient talks to, conforming to -// the requirements of net/rpc -type RPCServer struct { - // This is the real implementation - Impl Authorize -} - -func (m *RPCServer) Get(args []string, resp *[]byte) error { - if len(args) != 2 { - return fmt.Errorf("expected 2 arguments, got %d", len(args)) - } - user, host := args[0], args[1] - v, err := m.Impl.Get(user, host) - *resp = v - return err -} diff --git a/tests/example-users.csv b/tests/example-users.csv index b5750e0..487ff7c 100644 --- a/tests/example-users.csv +++ b/tests/example-users.csv @@ -1,5 +1,9 @@ -user,key,secret -example,key1,secret1 -foo,key2,secret2 -bar,key3,secret3 -foobar,key4,secret4 \ No newline at end of file +user,key,secret,GET,PUT,DELETE +example,key1,secret1,1,1,1 +foo,key2,secret2,1,0,1 +bar,key3,secret3,0,0,0 +foobar,key4,secret4,0,1,1 +alpha,key5,secret5,1,1,0 +beta,key6,secret6,1,0,0 +gamma,key7,secret7,0,1,0 +delta,key8,secret8,0,0,1 \ No newline at end of file diff --git a/tests/test-server.go b/tests/test-server.go index 5a71fbd..f7d0a56 100644 --- a/tests/test-server.go +++ b/tests/test-server.go @@ -3,22 +3,31 @@ package main import ( "encoding/csv" "encoding/json" + "flag" "fmt" + "io" "net/http" "os" + "strconv" "sync" - "example.com/shared" "github.com/ohsu-comp-bio/funnel/config" + "github.com/ohsu-comp-bio/funnel/plugins/proto" + "github.com/ohsu-comp-bio/funnel/plugins/shared" + "google.golang.org/protobuf/encoding/protojson" +) + +var ( + csvFile = flag.String("users-csv", "example-users.csv", "Path to the CSV file containing user tokens") ) func main() { + flag.Parse() // Parse the command-line flags + http.HandleFunc("/", indexHandler) http.HandleFunc("/token", tokenHandler) - // Currently hardcoding the endpoint of the token service - // TODO: This should be made configurable similar to the plugin (see plugin/auth_impl.go) - fmt.Println("Server is running on http://0.0.0.0:8080") + fmt.Printf("Server is running on http://0.0.0.0:8080 using users from: %s\n", *csvFile) err := http.ListenAndServe("0.0.0.0:8080", nil) if err != nil { fmt.Println("Error starting server:", err) @@ -27,29 +36,69 @@ func main() { // Handler for root endpoint func indexHandler(w http.ResponseWriter, r *http.Request) { - resp := shared.Response{ + resp := &proto.JobResponse{ // Note the pointer here Code: http.StatusOK, Message: "Hello, world! To get a token, send a GET request to /token?user=[USER]", } - json.NewEncoder(w).Encode(resp) + encodeResponse(w, resp) } -// Handler for retrieving user tokens -func tokenHandler(w http.ResponseWriter, r *http.Request) { +func handleRequest(w http.ResponseWriter, r *http.Request, httpMethod string, user string) (*config.Config, int, *proto.Job) { fmt.Println("Received token request:", r) - // Load users from the CSV file - userDB, err := loadUsers("example-users.csv") + bodyBytes, err := io.ReadAll(r.Body) + if err != nil { + http.Error(w, fmt.Sprintf("Failed to read request body: %v", err), http.StatusBadRequest) + return nil, 0, nil + } + defer r.Body.Close() + + receivedData := &proto.Job{} + unmarshalOptions := protojson.UnmarshalOptions{ + DiscardUnknown: true, // Or false, depending on your needs + } + + err = unmarshalOptions.Unmarshal(bodyBytes, receivedData) + if err != nil { + http.Error(w, fmt.Sprintf("Failed to unmarshal GetRequest from JSON using protojson: %v", err), http.StatusBadRequest) + return nil, 0, nil + } + + // Now you can access the parsed config and task objects + fmt.Printf("Received Config: %#v\n", receivedData.Config) + fmt.Printf("Received Task: %#v\n", receivedData.Task) + fmt.Printf("Received Headers: %#v\n", receivedData.Headers) + + // Load users from the CSV file specified by the flag + userConfig, permPass, err := loadUser(*csvFile, httpMethod, user) if err != nil { fmt.Println("Error loading users:", err) - return + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return nil, 0, nil } + return userConfig, permPass, receivedData +} + +// Handler for retrieving user tokens +func tokenHandler(w http.ResponseWriter, r *http.Request) { + var config *config.Config + var authPass int + var receivedData *proto.Job user := r.URL.Query().Get("user") + switch r.Method { + case http.MethodGet: + config, authPass, receivedData = handleRequest(w, r, http.MethodGet, user) + case http.MethodDelete: + config, authPass, receivedData = handleRequest(w, r, http.MethodDelete, user) + case http.MethodPut: + config, authPass, receivedData = handleRequest(w, r, http.MethodPut, user) + default: + http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed) + } - // No user provided in the query (Bad Request: 400) - if user == "" { - resp := shared.Response{ + if config == nil { + resp := proto.JobResponse{ Code: http.StatusBadRequest, Message: "User is required", } @@ -57,59 +106,70 @@ func tokenHandler(w http.ResponseWriter, r *http.Request) { return } - token, found := userDB[user] - - if found { - // User found (OK: 200) - c := config.Config{} - c.AmazonS3.AWSConfig.Key = token.AmazonS3.Key - c.AmazonS3.AWSConfig.Secret = token.AmazonS3.Secret - - resp := shared.Response{ - Code: http.StatusOK, - Config: &c, - } - json.NewEncoder(w).Encode(resp) + if config != nil && authPass == 1 { + shared.Logger.Debug("Found token for user:", user, "config Key:", config.AmazonS3.AWSConfig.Key) + receivedData.Config.AmazonS3.AWSConfig.Key = config.AmazonS3.AWSConfig.Key + receivedData.Config.AmazonS3.AWSConfig.Secret = config.AmazonS3.AWSConfig.Secret + encodeResponse(w, &proto.JobResponse{Code: http.StatusOK, Config: receivedData.Config, Task: receivedData.Task}) } else { - // User not found (Unauthorized: 401) - resp := shared.Response{ - Code: http.StatusUnauthorized, - Message: "User not authorized", - } - json.NewEncoder(w).Encode(resp) + shared.Logger.Warn("User not authorized:", user) + encodeResponse(w, &proto.JobResponse{Code: http.StatusUnauthorized, Message: "User not authorized", Config: receivedData.Config, Task: receivedData.Task}) + } +} + +func encodeResponse(w http.ResponseWriter, resp *proto.JobResponse) { + w.WriteHeader(int(resp.Code)) + marshalOptions := protojson.MarshalOptions{} // You can customize options if needed + responseBody, err := marshalOptions.Marshal(resp) + if err != nil { + shared.Logger.Error("Error marshaling protojson response:", err) + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + return } + w.Header().Set("Content-Type", "application/json") // Important: Set the correct Content-Type + w.Write(responseBody) } // Load user tokens from the CSV file -func loadUsers(filename string) (map[string]config.Config, error) { +func loadUser(filename string, method string, user string) (*config.Config, int, error) { file, err := os.Open(filename) if err != nil { - return nil, fmt.Errorf("failed to open file: %w", err) + return nil, 0, fmt.Errorf("failed to open file: %w", err) } defer file.Close() reader := csv.NewReader(file) records, err := reader.ReadAll() if err != nil { - return nil, fmt.Errorf("failed to read CSV: %w", err) + return nil, 0, fmt.Errorf("failed to read CSV: %w", err) } - userDB := make(map[string]config.Config) + var methodPass int + userConfig := &config.Config{ + AmazonS3: &config.AmazonS3Storage{ + AWSConfig: &config.AWSConfig{}, + }, + } mutex := sync.RWMutex{} for i, row := range records { if i == 0 { continue // Skip header } - mutex.Lock() - userDB[row[0]] = config.Config{ - AmazonS3: config.AmazonS3Storage{ - AWSConfig: config.AWSConfig{ - Key: row[1], - Secret: row[2], - }, - }, + if row[0] == user { + mutex.Lock() + switch method { + case http.MethodGet: + methodPass, _ = strconv.Atoi(row[3]) + case http.MethodPut: + methodPass, _ = strconv.Atoi(row[4]) + case http.MethodDelete: + methodPass, _ = strconv.Atoi(row[5]) + } + userConfig.AmazonS3.AWSConfig.Key = row[1] + userConfig.AmazonS3.AWSConfig.Secret = row[2] + mutex.Unlock() + return userConfig, methodPass, nil } - mutex.Unlock() } - return userDB, nil + return nil, 0, nil }