mirror of
https://github.com/hatchet-dev/hatchet.git
synced 2025-12-21 08:40:10 -06:00
feat: v1 engine (#1318)
This commit is contained in:
6
.github/workflows/app.yml
vendored
6
.github/workflows/app.yml
vendored
@@ -1,5 +1,9 @@
|
||||
name: "frontend / app"
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'sdks/**'
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
24
.github/workflows/build.yml
vendored
24
.github/workflows/build.yml
vendored
@@ -1,5 +1,9 @@
|
||||
name: build
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'sdks/**'
|
||||
|
||||
jobs:
|
||||
frontend:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -63,7 +67,7 @@ jobs:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Build migrate
|
||||
run: docker build -f ./build/package/migrate.dockerfile .
|
||||
run: docker build -f ./build/package/servers.dockerfile . --build-arg SERVER_TARGET=migrate
|
||||
|
||||
migrate-arm:
|
||||
runs-on: hatchet-arm64-2
|
||||
@@ -71,7 +75,7 @@ jobs:
|
||||
- name: Clone repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Build migrate
|
||||
run: docker build -f ./build/package/migrate.dockerfile .
|
||||
run: docker build -f ./build/package/servers.dockerfile . --build-arg SERVER_TARGET=migrate
|
||||
|
||||
lite-arm:
|
||||
runs-on: hatchet-arm64-2
|
||||
@@ -92,11 +96,18 @@ jobs:
|
||||
-t hatchet-admin-tmp:arm64 \
|
||||
. &
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/servers.dockerfile \
|
||||
--build-arg SERVER_TARGET=migrate \
|
||||
--platform linux/arm64 \
|
||||
-t hatchet-migrate-tmp:arm64 \
|
||||
. &
|
||||
|
||||
wait
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/lite.dockerfile \
|
||||
--build-arg HATCHET_LITE_IMAGE=hatchet-lite-tmp:arm64 \
|
||||
--build-arg HATCHET_ADMIN_IMAGE=hatchet-admin-tmp:arm64 \
|
||||
--build-arg HATCHET_MIGRATE_IMAGE=hatchet-migrate-tmp:arm64 \
|
||||
--platform linux/arm64 \
|
||||
.
|
||||
|
||||
@@ -119,11 +130,18 @@ jobs:
|
||||
-t hatchet-admin-tmp:amd64 \
|
||||
. &
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/servers.dockerfile \
|
||||
--build-arg SERVER_TARGET=migrate \
|
||||
--platform linux/amd64 \
|
||||
-t hatchet-migrate-tmp:amd64 \
|
||||
. &
|
||||
|
||||
wait
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/lite.dockerfile \
|
||||
--build-arg HATCHET_LITE_IMAGE=hatchet-lite-tmp:amd64 \
|
||||
--build-arg HATCHET_ADMIN_IMAGE=hatchet-admin-tmp:amd64 \
|
||||
--build-arg HATCHET_MIGRATE_IMAGE=hatchet-migrate-tmp:amd64 \
|
||||
--platform linux/amd64 \
|
||||
.
|
||||
|
||||
|
||||
5
.github/workflows/docs.yml
vendored
5
.github/workflows/docs.yml
vendored
@@ -1,5 +1,8 @@
|
||||
name: "frontend / docs"
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'sdks/**'
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
5
.github/workflows/lint.yml
vendored
5
.github/workflows/lint.yml
vendored
@@ -1,5 +1,8 @@
|
||||
name: lint all
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'sdks/**'
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
20
.github/workflows/pre-release.yaml
vendored
20
.github/workflows/pre-release.yaml
vendored
@@ -251,7 +251,8 @@ jobs:
|
||||
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
- name: Build
|
||||
run: |
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/migrate.dockerfile \
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/servers.dockerfile \
|
||||
--build-arg SERVER_TARGET=migrate \
|
||||
-t ghcr.io/hatchet-dev/hatchet/hatchet-migrate:${{steps.tag_name.outputs.tag}}-amd64 \
|
||||
--platform linux/amd64 \
|
||||
.
|
||||
@@ -274,7 +275,8 @@ jobs:
|
||||
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
|
||||
- name: Build
|
||||
run: |
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/migrate.dockerfile \
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/servers.dockerfile \
|
||||
--build-arg SERVER_TARGET=migrate \
|
||||
-t ghcr.io/hatchet-dev/hatchet/hatchet-migrate:${{steps.tag_name.outputs.tag}}-arm64 \
|
||||
--platform linux/arm64 \
|
||||
.
|
||||
@@ -413,6 +415,12 @@ jobs:
|
||||
-t hatchet-admin-tmp:amd64 \
|
||||
. &
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/servers.dockerfile \
|
||||
--build-arg SERVER_TARGET=migrate \
|
||||
--platform linux/amd64 \
|
||||
-t hatchet-migrate-tmp:amd64 \
|
||||
. &
|
||||
|
||||
wait
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/lite.dockerfile \
|
||||
@@ -420,6 +428,7 @@ jobs:
|
||||
--platform linux/amd64 \
|
||||
--build-arg HATCHET_LITE_IMAGE=hatchet-lite-tmp:amd64 \
|
||||
--build-arg HATCHET_ADMIN_IMAGE=hatchet-admin-tmp:amd64 \
|
||||
--build-arg HATCHET_MIGRATE_IMAGE=hatchet-migrate-tmp:amd64 \
|
||||
.
|
||||
- name: Push to GHCR
|
||||
run: |
|
||||
@@ -456,6 +465,12 @@ jobs:
|
||||
-t hatchet-admin-tmp:arm64 \
|
||||
. &
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/servers.dockerfile \
|
||||
--build-arg SERVER_TARGET=migrate \
|
||||
--platform linux/arm64 \
|
||||
-t hatchet-migrate-tmp:arm64 \
|
||||
. &
|
||||
|
||||
wait
|
||||
|
||||
DOCKER_BUILDKIT=1 docker build -f ./build/package/lite.dockerfile \
|
||||
@@ -463,6 +478,7 @@ jobs:
|
||||
--platform linux/arm64 \
|
||||
--build-arg HATCHET_LITE_IMAGE=hatchet-lite-tmp:arm64 \
|
||||
--build-arg HATCHET_ADMIN_IMAGE=hatchet-admin-tmp:arm64 \
|
||||
--build-arg HATCHET_MIGRATE_IMAGE=hatchet-migrate-tmp:arm64 \
|
||||
.
|
||||
- name: Push to GHCR
|
||||
run: |
|
||||
|
||||
119
.github/workflows/sdk-python.yml
vendored
Normal file
119
.github/workflows/sdk-python.yml
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
name: python
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- 'sdks/python/**'
|
||||
- '.github/**'
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'sdks/python/**'
|
||||
- '.github/**'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./sdks/python
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.11"
|
||||
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.5.1
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
|
||||
- name: Install linting tools
|
||||
run: poetry install --all-extras
|
||||
|
||||
- name: Run Black
|
||||
run: poetry run black . --check --verbose --diff --color
|
||||
|
||||
- name: Run Isort
|
||||
run: poetry run isort . --check-only --diff
|
||||
|
||||
- name: Run MyPy
|
||||
run: poetry run mypy --config-file=pyproject.toml
|
||||
|
||||
- name: Run Ruff
|
||||
run: poetry run ruff check .
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10", "3.11", "3.12", "3.13"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Run Hatchet Engine
|
||||
run: docker compose up -d
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Display Python version
|
||||
run: python -c "import sys; print(sys.version)"
|
||||
- name: Install Poetry
|
||||
uses: snok/install-poetry@v1
|
||||
with:
|
||||
version: 1.5.1
|
||||
virtualenvs-create: true
|
||||
virtualenvs-in-project: true
|
||||
- name: Install dependencies
|
||||
run: poetry install --no-interaction --all-extras
|
||||
|
||||
- name: Generate Env File
|
||||
run: |
|
||||
cat <<EOF > .env
|
||||
HATCHET_CLIENT_TOKEN="$(docker compose run --no-deps setup-config /hatchet/hatchet-admin token create --config /hatchet/config --tenant-id 707d0855-80ab-4e1f-a156-f1c4546cbf52 | xargs)"
|
||||
HATCHET_CLIENT_TLS_STRATEGY=none
|
||||
EOF
|
||||
|
||||
- name: Set HATCHET_CLIENT_NAMESPACE
|
||||
run: |
|
||||
PYTHON_VERSION=$(python -c "import sys; print(f'py{sys.version_info.major}{sys.version_info.minor}')")
|
||||
SHORT_SHA=$(git rev-parse --short HEAD)
|
||||
echo "HATCHET_CLIENT_NAMESPACE=${PYTHON_VERSION}-${SHORT_SHA}" >> $GITHUB_ENV
|
||||
- name: Run pytest
|
||||
run: |
|
||||
echo "Using HATCHET_CLIENT_NAMESPACE: $HATCHET_CLIENT_NAMESPACE"
|
||||
poetry run pytest -s -vvv --maxfail=5 --timeout=180 --capture=no
|
||||
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint, test]
|
||||
if: github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.x"
|
||||
|
||||
- name: Install Poetry
|
||||
run: |
|
||||
pipx install poetry==1.7.1
|
||||
|
||||
- name: Run publish.sh script
|
||||
run: |
|
||||
sh publish.sh
|
||||
env:
|
||||
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.POETRY_PYPI_TOKEN_PYPI }}
|
||||
1
.github/workflows/spelling.yml
vendored
1
.github/workflows/spelling.yml
vendored
@@ -6,3 +6,4 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: crate-ci/typos@master
|
||||
continue-on-error: true
|
||||
|
||||
17
.github/workflows/test.yml
vendored
17
.github/workflows/test.yml
vendored
@@ -1,5 +1,8 @@
|
||||
name: test
|
||||
on: pull_request
|
||||
on:
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'sdks/**'
|
||||
jobs:
|
||||
generate:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -37,7 +40,7 @@ jobs:
|
||||
|
||||
- name: Generate
|
||||
run: |
|
||||
sh ./hack/db/atlas-apply.sh
|
||||
go run ./cmd/hatchet-migrate
|
||||
task pre-commit-install
|
||||
task generate-all
|
||||
|
||||
@@ -99,7 +102,7 @@ jobs:
|
||||
|
||||
- name: Generate
|
||||
run: |
|
||||
sh ./hack/db/atlas-apply.sh
|
||||
go run ./cmd/hatchet-migrate
|
||||
task generate-go
|
||||
task generate-certs
|
||||
task generate-local-encryption-keys
|
||||
@@ -173,7 +176,7 @@ jobs:
|
||||
|
||||
- name: Generate
|
||||
run: |
|
||||
sh ./hack/db/atlas-apply.sh
|
||||
go run ./cmd/hatchet-migrate
|
||||
task generate-go
|
||||
task generate-certs
|
||||
task generate-local-encryption-keys
|
||||
@@ -262,7 +265,7 @@ jobs:
|
||||
|
||||
- name: Generate
|
||||
run: |
|
||||
sh ./hack/db/atlas-apply.sh
|
||||
go run ./cmd/hatchet-migrate
|
||||
task generate-go
|
||||
task generate-certs
|
||||
task generate-local-encryption-keys
|
||||
@@ -339,7 +342,7 @@ jobs:
|
||||
|
||||
- name: Generate
|
||||
run: |
|
||||
sh ./hack/db/atlas-apply.sh
|
||||
go run ./cmd/hatchet-migrate
|
||||
task generate-go
|
||||
task generate-certs
|
||||
task generate-local-encryption-keys
|
||||
@@ -415,7 +418,7 @@ jobs:
|
||||
|
||||
- name: Generate
|
||||
run: |
|
||||
sh ./hack/db/atlas-apply.sh
|
||||
go run ./cmd/hatchet-migrate
|
||||
task generate-go
|
||||
task generate-certs
|
||||
task generate-local-encryption-keys
|
||||
|
||||
@@ -36,8 +36,7 @@ linters-settings:
|
||||
- "-ST1005"
|
||||
|
||||
issues:
|
||||
exclude-files:
|
||||
- "pkg/repository/prisma/db/db_gen.go"
|
||||
exclude-files: []
|
||||
exclude:
|
||||
- "by other packages, and that stutters; consider calling this"
|
||||
- "var-naming:"
|
||||
|
||||
@@ -6,9 +6,7 @@ repos:
|
||||
- id: mixed-line-ending
|
||||
args: ["--fix=lf"]
|
||||
- id: end-of-file-fixer
|
||||
exclude: prisma/migrations/.*\.sql|sql/migrations/.*\.sql
|
||||
- id: trailing-whitespace
|
||||
exclude: prisma/migrations/.*\.sql|sql/migrations/.*\.sql
|
||||
- id: check-yaml
|
||||
- repo: https://github.com/golangci/golangci-lint
|
||||
rev: v1.62.0
|
||||
|
||||
@@ -70,14 +70,13 @@ tasks:
|
||||
migrate:
|
||||
cmds:
|
||||
- task: generate-sqlc
|
||||
- task: atlas-compare-schema-to-migrations-dir
|
||||
- task: atlas-apply-migrations
|
||||
atlas-compare-schema-to-migrations-dir:
|
||||
- task: goose-migrate
|
||||
atlas-migrate:
|
||||
cmds:
|
||||
- sh ./hack/dev/atlas-migrate.sh {{.CLI_ARGS}}
|
||||
atlas-apply-migrations:
|
||||
goose-migrate:
|
||||
cmds:
|
||||
- DATABASE_URL='postgresql://hatchet:hatchet@127.0.0.1:5431/hatchet' sh ./hack/db/atlas-apply.sh
|
||||
- sh ./hack/dev/migrate.sh
|
||||
seed-dev:
|
||||
cmds:
|
||||
- SEED_DEVELOPMENT=true sh ./hack/dev/run-go-with-env.sh run ./cmd/hatchet-admin seed
|
||||
@@ -150,7 +149,8 @@ tasks:
|
||||
- sh ./generate.sh
|
||||
generate-sqlc:
|
||||
cmds:
|
||||
- go run github.com/sqlc-dev/sqlc/cmd/sqlc@v1.24.0 generate --file pkg/repository/prisma/dbsqlc/sqlc.yaml
|
||||
- go run github.com/sqlc-dev/sqlc/cmd/sqlc@v1.24.0 generate --file pkg/repository/postgres/dbsqlc/sqlc.yaml
|
||||
- go run github.com/sqlc-dev/sqlc/cmd/sqlc@v1.24.0 generate --file pkg/repository/v1/sqlcv1/sqlc.yaml
|
||||
lint:
|
||||
cmds:
|
||||
- task: lint-go
|
||||
@@ -161,9 +161,6 @@ tasks:
|
||||
lint-frontend:
|
||||
cmds:
|
||||
- cd frontend/app/ && pnpm run lint:check
|
||||
kill-query-engines:
|
||||
cmds:
|
||||
- ps -A | grep 'prisma-query-engine-darwin-arm64' | grep -v grep | awk '{print $1}' | xargs kill -9 $1
|
||||
kill-apis:
|
||||
cmds:
|
||||
- ps -A | grep 'cmd/hatchet-api' | grep -v grep | awk '{print $1}' | xargs kill -9 $1
|
||||
|
||||
@@ -292,3 +292,41 @@ WebhookWorkerCreateResponse:
|
||||
$ref: "./webhook_worker.yaml#/WebhookWorkerCreateResponse"
|
||||
WebhookWorkerListResponse:
|
||||
$ref: "./webhook_worker.yaml#/WebhookWorkerListResponse"
|
||||
V1TaskSummaryList:
|
||||
$ref: "./v1/task.yaml#/V1TaskSummaryList"
|
||||
V1WorkflowRunDisplayNameList:
|
||||
$ref: "./v1/task.yaml#/V1WorkflowRunDisplayNameList"
|
||||
V1TaskSummary:
|
||||
$ref: "./v1/task.yaml#/V1TaskSummary"
|
||||
V1DagChildren:
|
||||
$ref: "./v1/task.yaml#/V1DagChildren"
|
||||
V1TaskEventList:
|
||||
$ref: "./v1/task.yaml#/V1TaskEventList"
|
||||
V1TaskStatus:
|
||||
$ref: "./v1/task.yaml#/V1TaskStatus"
|
||||
V1TaskRunMetrics:
|
||||
$ref: "./v1/task.yaml#/V1TaskRunMetrics"
|
||||
V1TaskPointMetric:
|
||||
$ref: "./v1/task.yaml#/V1TaskPointMetric"
|
||||
V1TaskPointMetrics:
|
||||
$ref: "./v1/task.yaml#/V1TaskPointMetrics"
|
||||
V1TaskFilter:
|
||||
$ref: "./v1/task.yaml#/V1TaskFilter"
|
||||
V1CancelTaskRequest:
|
||||
$ref: "./v1/task.yaml#/V1CancelTaskRequest"
|
||||
V1ReplayTaskRequest:
|
||||
$ref: "./v1/task.yaml#/V1ReplayTaskRequest"
|
||||
V1WorkflowRun:
|
||||
$ref: "./v1/workflow_run.yaml#/V1WorkflowRun"
|
||||
V1WorkflowRunDetails:
|
||||
$ref: "./v1/workflow_run.yaml#/V1WorkflowRunDetails"
|
||||
V1TaskRunStatus:
|
||||
$ref: "./workflow_run.yaml#/V1TaskRunStatus"
|
||||
V1TriggerWorkflowRunRequest:
|
||||
$ref: "./v1/workflow_run.yaml#/V1TriggerWorkflowRunRequest"
|
||||
V1LogLine:
|
||||
$ref: "./v1/logs.yaml#/V1LogLine"
|
||||
V1LogLineLevel:
|
||||
$ref: "./v1/logs.yaml#/V1LogLineLevel"
|
||||
V1LogLineList:
|
||||
$ref: "./v1/logs.yaml#/V1LogLineList"
|
||||
|
||||
@@ -14,12 +14,23 @@ Tenant:
|
||||
alertMemberEmails:
|
||||
type: boolean
|
||||
description: Whether to alert tenant members.
|
||||
version:
|
||||
$ref: "#/TenantVersion"
|
||||
description: The version of the tenant.
|
||||
required:
|
||||
- metadata
|
||||
- name
|
||||
- slug
|
||||
- version
|
||||
type: object
|
||||
|
||||
TenantVersion:
|
||||
enum:
|
||||
- "V0"
|
||||
- "V1"
|
||||
type: string
|
||||
|
||||
|
||||
TenantAlertingSettings:
|
||||
properties:
|
||||
metadata:
|
||||
@@ -90,6 +101,9 @@ UpdateTenantRequest:
|
||||
description: The max frequency at which to alert.
|
||||
x-oapi-codegen-extra-tags:
|
||||
validate: "omitnil,duration"
|
||||
version:
|
||||
$ref: "#/TenantVersion"
|
||||
description: The version of the tenant.
|
||||
type: object
|
||||
|
||||
TenantResource:
|
||||
|
||||
33
api-contracts/openapi/components/schemas/v1/logs.yaml
Normal file
33
api-contracts/openapi/components/schemas/v1/logs.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
V1LogLine:
|
||||
properties:
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The creation date of the log line.
|
||||
message:
|
||||
type: string
|
||||
description: The log message.
|
||||
metadata:
|
||||
type: object
|
||||
description: The log metadata.
|
||||
required:
|
||||
- createdAt
|
||||
- message
|
||||
- metadata
|
||||
|
||||
V1LogLineLevel:
|
||||
type: string
|
||||
enum:
|
||||
- DEBUG
|
||||
- INFO
|
||||
- WARN
|
||||
- ERROR
|
||||
|
||||
V1LogLineList:
|
||||
properties:
|
||||
pagination:
|
||||
$ref: "../metadata.yaml#/PaginationResponse"
|
||||
rows:
|
||||
items:
|
||||
$ref: "#/V1LogLine"
|
||||
type: array
|
||||
321
api-contracts/openapi/components/schemas/v1/task.yaml
Normal file
321
api-contracts/openapi/components/schemas/v1/task.yaml
Normal file
@@ -0,0 +1,321 @@
|
||||
V1WorkflowType:
|
||||
type: string
|
||||
enum:
|
||||
- DAG
|
||||
- TASK
|
||||
|
||||
V1TaskSummary:
|
||||
properties:
|
||||
metadata:
|
||||
$ref: ".././metadata.yaml#/APIResourceMeta"
|
||||
additionalMetadata:
|
||||
type: object
|
||||
description: Additional metadata for the task run.
|
||||
children:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/V1TaskSummary"
|
||||
description: The list of children tasks
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The timestamp the task was created.
|
||||
displayName:
|
||||
type: string
|
||||
description: The display name of the task run.
|
||||
duration:
|
||||
type: integer
|
||||
description: The duration of the task run, in milliseconds.
|
||||
errorMessage:
|
||||
type: string
|
||||
description: The error message of the task run (for the latest run)
|
||||
finishedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The timestamp the task run finished.
|
||||
input:
|
||||
type: object
|
||||
description: The input of the task run.
|
||||
numSpawnedChildren:
|
||||
type: integer
|
||||
description: The number of spawned children tasks
|
||||
output:
|
||||
type: object
|
||||
description: The output of the task run (for the latest run)
|
||||
status:
|
||||
$ref: "#/V1TaskStatus"
|
||||
startedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The timestamp the task run started.
|
||||
stepId:
|
||||
type: string
|
||||
description: The step ID of the task.
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
taskExternalId:
|
||||
type: string
|
||||
description: The external ID of the task.
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
taskId:
|
||||
type: integer
|
||||
description: The ID of the task.
|
||||
taskInsertedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The timestamp the task was inserted.
|
||||
tenantId:
|
||||
type: string
|
||||
description: The ID of the tenant.
|
||||
example: bb214807-246e-43a5-a25d-41761d1cff9e
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
format: uuid
|
||||
type:
|
||||
$ref: "#/V1WorkflowType"
|
||||
description: The type of the workflow (whether it's a DAG or a task)
|
||||
workflowId:
|
||||
type: string
|
||||
format: uuid
|
||||
workflowName:
|
||||
type: string
|
||||
workflowRunExternalId:
|
||||
type: string
|
||||
format: uuid
|
||||
description: The external ID of the workflow run
|
||||
workflowVersionId:
|
||||
type: string
|
||||
format: uuid
|
||||
description: The version ID of the workflow
|
||||
required:
|
||||
- metadata
|
||||
- createdAt
|
||||
- displayName
|
||||
- id
|
||||
- input
|
||||
- numSpawnedChildren
|
||||
- output
|
||||
- status
|
||||
- taskExternalId
|
||||
- taskId
|
||||
- taskInsertedAt
|
||||
- tenantId
|
||||
- type
|
||||
- workflowId
|
||||
|
||||
V1WorkflowRunDisplayName:
|
||||
properties:
|
||||
metadata:
|
||||
$ref: ".././metadata.yaml#/APIResourceMeta"
|
||||
displayName:
|
||||
type: string
|
||||
required:
|
||||
- metadata
|
||||
- displayName
|
||||
|
||||
V1DagChildren:
|
||||
type: object
|
||||
properties:
|
||||
dagId:
|
||||
type: string
|
||||
format: uuid
|
||||
children:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/V1TaskSummary"
|
||||
|
||||
V1TaskSummaryList:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: ".././metadata.yaml#/PaginationResponse"
|
||||
rows:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/V1TaskSummary"
|
||||
description: The list of tasks
|
||||
required:
|
||||
- pagination
|
||||
- rows
|
||||
|
||||
V1WorkflowRunDisplayNameList:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: ".././metadata.yaml#/PaginationResponse"
|
||||
rows:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/V1WorkflowRunDisplayName"
|
||||
description: The list of display names
|
||||
required:
|
||||
- pagination
|
||||
- rows
|
||||
|
||||
V1TaskEventList:
|
||||
properties:
|
||||
pagination:
|
||||
$ref: ".././metadata.yaml#/PaginationResponse"
|
||||
rows:
|
||||
items:
|
||||
$ref: "#/V1TaskEvent"
|
||||
type: array
|
||||
|
||||
V1TaskEvent:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: integer
|
||||
taskId:
|
||||
type: string
|
||||
format: uuid
|
||||
timestamp:
|
||||
type: string
|
||||
format: date-time
|
||||
eventType:
|
||||
$ref: "#/V1TaskEventType"
|
||||
message:
|
||||
type: string
|
||||
errorMessage:
|
||||
type: string
|
||||
output:
|
||||
type: string
|
||||
workerId:
|
||||
type: string
|
||||
format: uuid
|
||||
taskDisplayName:
|
||||
type: string
|
||||
required:
|
||||
- id
|
||||
- taskId
|
||||
- timestamp
|
||||
- eventType
|
||||
- message
|
||||
|
||||
V1TaskStatus:
|
||||
type: string
|
||||
enum:
|
||||
- QUEUED
|
||||
- RUNNING
|
||||
- COMPLETED
|
||||
- CANCELLED
|
||||
- FAILED
|
||||
|
||||
V1TaskEventType:
|
||||
type: string
|
||||
enum:
|
||||
- REQUEUED_NO_WORKER
|
||||
- REQUEUED_RATE_LIMIT
|
||||
- SCHEDULING_TIMED_OUT
|
||||
- ASSIGNED
|
||||
- STARTED
|
||||
- FINISHED
|
||||
- FAILED
|
||||
- RETRYING
|
||||
- CANCELLED
|
||||
- TIMED_OUT
|
||||
- REASSIGNED
|
||||
- SLOT_RELEASED
|
||||
- TIMEOUT_REFRESHED
|
||||
- RETRIED_BY_USER
|
||||
- SENT_TO_WORKER
|
||||
- RATE_LIMIT_ERROR
|
||||
- ACKNOWLEDGED
|
||||
- CREATED
|
||||
- QUEUED
|
||||
- SKIPPED
|
||||
|
||||
V1TaskRunMetrics:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/V1TaskRunMetric"
|
||||
|
||||
V1TaskRunMetric:
|
||||
type: object
|
||||
properties:
|
||||
status:
|
||||
$ref: "#/V1TaskStatus"
|
||||
count:
|
||||
type: integer
|
||||
required:
|
||||
- status
|
||||
- count
|
||||
|
||||
V1TaskPointMetric:
|
||||
type: object
|
||||
properties:
|
||||
time:
|
||||
type: string
|
||||
format: date-time
|
||||
SUCCEEDED:
|
||||
type: integer
|
||||
FAILED:
|
||||
type: integer
|
||||
required:
|
||||
- time
|
||||
- SUCCEEDED
|
||||
- FAILED
|
||||
|
||||
V1TaskPointMetrics:
|
||||
type: object
|
||||
properties:
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/V1TaskPointMetric"
|
||||
|
||||
V1TaskFilter:
|
||||
type: object
|
||||
properties:
|
||||
since:
|
||||
type: string
|
||||
format: date-time
|
||||
until:
|
||||
type: string
|
||||
format: date-time
|
||||
statuses:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/V1TaskStatus"
|
||||
workflowIds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
additionalMetadata:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
required:
|
||||
- since
|
||||
|
||||
V1CancelTaskRequest:
|
||||
type: object
|
||||
properties:
|
||||
externalIds:
|
||||
type: array
|
||||
description: A list of external IDs, which can refer to either task or workflow run external IDs
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
filter:
|
||||
$ref: "#/V1TaskFilter"
|
||||
|
||||
V1ReplayTaskRequest:
|
||||
type: object
|
||||
properties:
|
||||
externalIds:
|
||||
type: array
|
||||
description: A list of external IDs, which can refer to either task or workflow run external IDs
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
filter:
|
||||
$ref: "#/V1TaskFilter"
|
||||
126
api-contracts/openapi/components/schemas/v1/workflow_run.yaml
Normal file
126
api-contracts/openapi/components/schemas/v1/workflow_run.yaml
Normal file
@@ -0,0 +1,126 @@
|
||||
V1WorkflowRun:
|
||||
properties:
|
||||
metadata:
|
||||
$ref: ".././metadata.yaml#/APIResourceMeta"
|
||||
status:
|
||||
$ref: "./task.yaml#/V1TaskStatus"
|
||||
startedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The timestamp the task run started.
|
||||
finishedAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The timestamp the task run finished.
|
||||
duration:
|
||||
type: integer
|
||||
description: The duration of the task run, in milliseconds.
|
||||
tenantId:
|
||||
type: string
|
||||
description: The ID of the tenant.
|
||||
example: bb214807-246e-43a5-a25d-41761d1cff9e
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
format: uuid
|
||||
additionalMetadata:
|
||||
type: object
|
||||
description: Additional metadata for the task run.
|
||||
displayName:
|
||||
type: string
|
||||
description: The display name of the task run.
|
||||
workflowId:
|
||||
type: string
|
||||
format: uuid
|
||||
output:
|
||||
type: object
|
||||
description: The output of the task run (for the latest run)
|
||||
errorMessage:
|
||||
type: string
|
||||
description: The error message of the task run (for the latest run)
|
||||
workflowVersionId:
|
||||
type: string
|
||||
format: uuid
|
||||
description: The ID of the workflow version.
|
||||
input:
|
||||
type: object
|
||||
description: The input of the task run.
|
||||
createdAt:
|
||||
type: string
|
||||
format: date-time
|
||||
description: The timestamp the task run was created.
|
||||
required:
|
||||
- metadata
|
||||
- id
|
||||
- status
|
||||
- tenantId
|
||||
- displayName
|
||||
- workflowId
|
||||
- output
|
||||
- input
|
||||
|
||||
WorkflowRunShapeItemForWorkflowRunDetails:
|
||||
type: object
|
||||
properties:
|
||||
taskExternalId:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
stepId:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
childrenStepIds:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
taskName:
|
||||
type: string
|
||||
required:
|
||||
- taskExternalId
|
||||
- stepId
|
||||
- childrenStepIds
|
||||
- taskName
|
||||
|
||||
WorkflowRunShapeForWorkflowRunDetails:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/WorkflowRunShapeItemForWorkflowRunDetails"
|
||||
|
||||
V1WorkflowRunDetails:
|
||||
properties:
|
||||
run:
|
||||
$ref: "#/V1WorkflowRun"
|
||||
taskEvents:
|
||||
type: array
|
||||
items:
|
||||
$ref: "./task.yaml#/V1TaskEvent"
|
||||
description: The list of task events for the workflow run
|
||||
shape:
|
||||
$ref: "#/WorkflowRunShapeForWorkflowRunDetails"
|
||||
tasks:
|
||||
type: array
|
||||
items:
|
||||
$ref: "./task.yaml#/V1TaskSummary"
|
||||
required:
|
||||
- run
|
||||
- taskEvents
|
||||
- shape
|
||||
- tasks
|
||||
|
||||
V1TriggerWorkflowRunRequest:
|
||||
properties:
|
||||
workflowName:
|
||||
type: string
|
||||
description: The name of the workflow.
|
||||
input:
|
||||
type: object
|
||||
additionalMetadata:
|
||||
type: object
|
||||
required:
|
||||
- workflowName
|
||||
- input
|
||||
@@ -219,7 +219,6 @@ ScheduledWorkflows:
|
||||
- triggerAt
|
||||
- method
|
||||
|
||||
|
||||
ScheduledWorkflowsMethod:
|
||||
type: string
|
||||
enum:
|
||||
@@ -305,6 +304,20 @@ WorkflowRunsMetricsCounts:
|
||||
CANCELLED:
|
||||
type: integer
|
||||
|
||||
TaskRunMetricsCounts:
|
||||
type: object
|
||||
properties:
|
||||
PENDING:
|
||||
type: integer
|
||||
RUNNING:
|
||||
type: integer
|
||||
SUCCEEDED:
|
||||
type: integer
|
||||
FAILED:
|
||||
type: integer
|
||||
QUEUED:
|
||||
type: integer
|
||||
|
||||
WorkflowRunsMetrics:
|
||||
type: object
|
||||
properties:
|
||||
@@ -335,6 +348,15 @@ JobRunStatus:
|
||||
- CANCELLED
|
||||
- BACKOFF
|
||||
|
||||
V1TaskRunStatus:
|
||||
type: string
|
||||
enum:
|
||||
- PENDING
|
||||
- RUNNING
|
||||
- COMPLETED
|
||||
- FAILED
|
||||
- CANCELLED
|
||||
|
||||
WorkflowRunStatus:
|
||||
type: string
|
||||
enum:
|
||||
|
||||
@@ -20,6 +20,32 @@ components:
|
||||
schemas:
|
||||
$ref: "./components/schemas/_index.yaml"
|
||||
paths:
|
||||
/api/v1/stable/tasks/{task}:
|
||||
$ref: "./paths/v1/tasks/tasks.yaml#/getTask"
|
||||
/api/v1/stable/tasks/{task}/task-events:
|
||||
$ref: "./paths/v1/tasks/tasks.yaml#/listTaskEvents"
|
||||
/api/v1/stable/tasks/{task}/logs:
|
||||
$ref: "./paths/v1/tasks/tasks.yaml#/listLogs"
|
||||
/api/v1/stable/tenants/{tenant}/tasks/cancel:
|
||||
$ref: "./paths/v1/tasks/tasks.yaml#/cancelTasks"
|
||||
/api/v1/stable/tenants/{tenant}/tasks/replay:
|
||||
$ref: "./paths/v1/tasks/tasks.yaml#/replayTasks"
|
||||
/api/v1/stable/dags/tasks:
|
||||
$ref: "./paths/v1/tasks/tasks.yaml#/listTasksByDAGIds"
|
||||
/api/v1/stable/tenants/{tenant}/workflow-runs:
|
||||
$ref: "./paths/v1/workflow-runs/workflow_run.yaml#/listWorkflowRuns"
|
||||
/api/v1/stable/tenants/{tenant}/workflow-runs/display-names:
|
||||
$ref: "./paths/v1/workflow-runs/workflow_run.yaml#/listWorkflowRunDisplayNames"
|
||||
/api/v1/stable/tenants/{tenant}/workflow-runs/trigger:
|
||||
$ref: "./paths/v1/workflow-runs/workflow_run.yaml#/trigger"
|
||||
/api/v1/stable/workflow-runs/{v1-workflow-run}:
|
||||
$ref: "./paths/v1/workflow-runs/workflow_run.yaml#/getWorkflowRunDetails"
|
||||
/api/v1/stable/workflow-runs/{v1-workflow-run}/task-events:
|
||||
$ref: "./paths/v1/workflow-runs/workflow_run.yaml#/listTaskEventsForWorkflowRun"
|
||||
/api/v1/stable/tenants/{tenant}/task-metrics:
|
||||
$ref: "./paths/v1/tasks/tasks.yaml#/getTaskStatusMetrics"
|
||||
/api/v1/stable/tenants/{tenant}/task-point-metrics:
|
||||
$ref: "./paths/v1/tasks/tasks.yaml#/getTaskPointMetrics"
|
||||
/api/ready:
|
||||
$ref: "./paths/metadata/metadata.yaml#/readiness"
|
||||
/api/live:
|
||||
|
||||
443
api-contracts/openapi/paths/v1/tasks/tasks.yaml
Normal file
443
api-contracts/openapi/paths/v1/tasks/tasks.yaml
Normal file
@@ -0,0 +1,443 @@
|
||||
listTasksByDAGIds:
|
||||
get:
|
||||
description: Lists all tasks that belong a specific list of dags
|
||||
operationId: v1-dag:list:tasks
|
||||
parameters:
|
||||
- description: The external id of the DAG
|
||||
in: query
|
||||
name: dag_ids
|
||||
required: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: The tenant id
|
||||
in: query
|
||||
name: tenant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1DagChildren"
|
||||
description: The list of tasks
|
||||
description: Successfully listed the tasks
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: List tasks
|
||||
tags:
|
||||
- Task
|
||||
|
||||
getTask:
|
||||
get:
|
||||
x-resources: ["tenant", "task"]
|
||||
description: Get a task by id
|
||||
operationId: v1-task:get
|
||||
parameters:
|
||||
- description: The task id
|
||||
in: path
|
||||
name: task
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1TaskSummary"
|
||||
description: Successfully retrieved the task
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: The task was not found
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: Get a task
|
||||
tags:
|
||||
- Task
|
||||
|
||||
listTaskEvents:
|
||||
get:
|
||||
x-resources: ["tenant", "task"]
|
||||
description: List events for a task
|
||||
operationId: v1-task-event:list
|
||||
parameters:
|
||||
- description: The task id
|
||||
in: path
|
||||
name: task
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: The number to skip
|
||||
in: query
|
||||
name: offset
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- description: The number to limit by
|
||||
in: query
|
||||
name: limit
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1TaskEventList"
|
||||
description: Successfully retrieved the events
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: The task was not found
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: List events for a task
|
||||
tags:
|
||||
- Task
|
||||
|
||||
getTaskStatusMetrics:
|
||||
get:
|
||||
x-resources: ["tenant"]
|
||||
description: Get a summary of task run metrics for a tenant
|
||||
operationId: v1-task:list:status-metrics
|
||||
parameters:
|
||||
- description: The tenant id
|
||||
in: path
|
||||
name: tenant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: The start time to get metrics for
|
||||
in: query
|
||||
name: since
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- description: The workflow id to find runs for
|
||||
in: query
|
||||
name: workflow_ids
|
||||
required: false
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: The parent task's external id
|
||||
in: query
|
||||
name: parent_task_external_id
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1TaskRunMetrics"
|
||||
description: Successfully retrieved the task run metrics
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: Get task metrics
|
||||
tags:
|
||||
- Task
|
||||
|
||||
getTaskPointMetrics:
|
||||
get:
|
||||
x-resources: ["tenant"]
|
||||
description: Get a minute by minute breakdown of task metrics for a tenant
|
||||
operationId: v1-task:get:point-metrics
|
||||
parameters:
|
||||
- description: The tenant id
|
||||
in: path
|
||||
name: tenant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: The time after the task was created
|
||||
in: query
|
||||
name: createdAfter
|
||||
example: "2021-01-01T00:00:00Z"
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- description: The time before the task was completed
|
||||
in: query
|
||||
name: finishedBefore
|
||||
example: "2021-01-01T00:00:00Z"
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1TaskPointMetrics"
|
||||
description: Successfully retrieved the task point metrics
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: Get task point metrics
|
||||
tags:
|
||||
- Task
|
||||
cancelTasks:
|
||||
post:
|
||||
x-resources: ["tenant"]
|
||||
description: Cancel tasks
|
||||
operationId: v1-task:cancel
|
||||
parameters:
|
||||
- description: The tenant id
|
||||
in: path
|
||||
name: tenant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1CancelTaskRequest"
|
||||
description: The tasks to cancel
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully cancelled the tasks
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: The task was not found
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: Cancel tasks
|
||||
tags:
|
||||
- Task
|
||||
replayTasks:
|
||||
post:
|
||||
x-resources: ["tenant"]
|
||||
description: Replay tasks
|
||||
operationId: v1-task:replay
|
||||
parameters:
|
||||
- description: The tenant id
|
||||
in: path
|
||||
name: tenant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1ReplayTaskRequest"
|
||||
description: The tasks to replay
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
description: Successfully replayed the tasks
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"404":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: The task was not found
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: Replay tasks
|
||||
tags:
|
||||
- Task
|
||||
|
||||
listLogs:
|
||||
get:
|
||||
x-resources: ["tenant", "task"]
|
||||
description: Lists log lines for a task
|
||||
operationId: v1-log-line:list
|
||||
parameters:
|
||||
- description: The task id
|
||||
in: path
|
||||
name: task
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1LogLineList"
|
||||
description: Successfully listed the events
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
summary: List log lines
|
||||
tags:
|
||||
- Log
|
||||
324
api-contracts/openapi/paths/v1/workflow-runs/workflow_run.yaml
Normal file
324
api-contracts/openapi/paths/v1/workflow-runs/workflow_run.yaml
Normal file
@@ -0,0 +1,324 @@
|
||||
listWorkflowRuns:
|
||||
get:
|
||||
x-resources: ["tenant"]
|
||||
description: Lists workflow runs for a tenant.
|
||||
operationId: v1-workflow-run:list
|
||||
parameters:
|
||||
- description: The tenant id
|
||||
in: path
|
||||
name: tenant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: The number to skip
|
||||
in: query
|
||||
name: offset
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- description: The number to limit by
|
||||
in: query
|
||||
name: limit
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- description: A list of statuses to filter by
|
||||
in: query
|
||||
name: statuses
|
||||
required: false
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1TaskStatus"
|
||||
- description: The earliest date to filter by
|
||||
in: query
|
||||
name: since
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- description: The latest date to filter by
|
||||
in: query
|
||||
name: until
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: date-time
|
||||
- description: Additional metadata k-v pairs to filter by
|
||||
in: query
|
||||
name: additional_metadata
|
||||
required: false
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
- description: The workflow ids to find runs for
|
||||
in: query
|
||||
name: workflow_ids
|
||||
required: false
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: The worker id to filter by
|
||||
in: query
|
||||
name: worker_id
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: Whether to include DAGs or only to include tasks
|
||||
in: query
|
||||
name: only_tasks
|
||||
required: true
|
||||
schema:
|
||||
type: boolean
|
||||
- description: The parent task external id to filter by
|
||||
in: query
|
||||
name: parent_task_external_id
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1TaskSummaryList"
|
||||
description: Successfully listed the tasks
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: List workflow runs
|
||||
tags:
|
||||
- Workflow Runs
|
||||
|
||||
listWorkflowRunDisplayNames:
|
||||
get:
|
||||
x-resources: ["tenant"]
|
||||
description: Lists displayable names of workflow runs for a tenant
|
||||
operationId: v1-workflow-run:display-names:list
|
||||
parameters:
|
||||
- description: The tenant id
|
||||
in: path
|
||||
name: tenant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
- description: The external ids of the workflow runs to get display names for
|
||||
in: query
|
||||
name: external_ids
|
||||
required: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1WorkflowRunDisplayNameList"
|
||||
description: Successfully listed the tasks
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: List workflow runs
|
||||
tags:
|
||||
- Workflow Runs
|
||||
|
||||
listTaskEventsForWorkflowRun:
|
||||
get:
|
||||
x-resources: ["tenant", "v1-workflow-run"]
|
||||
description: List all tasks for a workflow run
|
||||
operationId: v1-workflow-run:task-events:list
|
||||
parameters:
|
||||
- description: The number to skip
|
||||
in: query
|
||||
name: offset
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- description: The number to limit by
|
||||
in: query
|
||||
name: limit
|
||||
required: false
|
||||
schema:
|
||||
type: integer
|
||||
format: int64
|
||||
- description: The workflow run id to find runs for
|
||||
in: path
|
||||
name: v1-workflow-run
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1TaskEventList"
|
||||
description: Successfully listed the tasks
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: List tasks
|
||||
tags:
|
||||
- Workflow Runs
|
||||
|
||||
getWorkflowRunDetails:
|
||||
get:
|
||||
x-resources: ["tenant", "v1-workflow-run"]
|
||||
description: Get a workflow run and its metadata to display on the "detail" page
|
||||
operationId: v1-workflow-run:get
|
||||
parameters:
|
||||
- description: The workflow run id to get
|
||||
in: path
|
||||
name: v1-workflow-run
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1WorkflowRunDetails"
|
||||
description: Successfully listed the tasks
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
"501":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Not implemented
|
||||
summary: List tasks
|
||||
tags:
|
||||
- Workflow Runs
|
||||
|
||||
trigger:
|
||||
post:
|
||||
x-resources: ["tenant"]
|
||||
description: Trigger a new workflow run
|
||||
operationId: v1-workflow-run:create
|
||||
parameters:
|
||||
- description: The tenant id
|
||||
in: path
|
||||
name: tenant
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1TriggerWorkflowRunRequest"
|
||||
description: The workflow run to create
|
||||
required: true
|
||||
responses:
|
||||
"200":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/V1WorkflowRunDetails"
|
||||
description: Successfully created the workflow run
|
||||
"400":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: A malformed or bad request
|
||||
"403":
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "../../../components/schemas/_index.yaml#/APIErrors"
|
||||
description: Forbidden
|
||||
summary: Create workflow run
|
||||
tags:
|
||||
- Workflow Runs
|
||||
48
api-contracts/workflows/v1-admin.proto
Normal file
48
api-contracts/workflows/v1-admin.proto
Normal file
@@ -0,0 +1,48 @@
|
||||
syntax = "proto3";
|
||||
|
||||
option go_package = "github.com/hatchet-dev/hatchet/internal/services/admin/v1/contracts";
|
||||
|
||||
import "google/protobuf/timestamp.proto";
|
||||
|
||||
// AdminService represents a set of RPCs for admin management of tasks, workflows, etc.
|
||||
service AdminService {
|
||||
rpc CancelTasks(CancelTasksRequest) returns (CancelTasksResponse);
|
||||
rpc ReplayTasks(ReplayTasksRequest) returns (ReplayTasksResponse);
|
||||
rpc TriggerWorkflowRun(TriggerWorkflowRunRequest) returns (TriggerWorkflowRunResponse);
|
||||
}
|
||||
|
||||
message CancelTasksRequest {
|
||||
repeated string externalIds = 1; // a list of external UUIDs
|
||||
optional TasksFilter filter = 2;
|
||||
}
|
||||
|
||||
message ReplayTasksRequest {
|
||||
repeated string externalIds = 1; // a list of external UUIDs
|
||||
optional TasksFilter filter = 2;
|
||||
}
|
||||
|
||||
message TasksFilter {
|
||||
repeated string statuses = 1;
|
||||
google.protobuf.Timestamp since = 2;
|
||||
optional google.protobuf.Timestamp until = 3;
|
||||
repeated string workflow_ids = 4;
|
||||
repeated string additional_metadata = 5;
|
||||
}
|
||||
|
||||
message CancelTasksResponse {
|
||||
repeated string cancelled_tasks = 1;
|
||||
}
|
||||
|
||||
message ReplayTasksResponse {
|
||||
repeated string replayed_tasks = 1;
|
||||
}
|
||||
|
||||
message TriggerWorkflowRunRequest {
|
||||
string workflow_name = 1;
|
||||
bytes input = 2;
|
||||
bytes additional_metadata = 3;
|
||||
}
|
||||
|
||||
message TriggerWorkflowRunResponse {
|
||||
string external_id = 1;
|
||||
}
|
||||
@@ -6,13 +6,15 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/middleware"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/middleware/redirect"
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/server"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
type AuthN struct {
|
||||
@@ -144,11 +146,11 @@ func (a *AuthN) handleCookieAuth(c echo.Context) error {
|
||||
return forbidden
|
||||
}
|
||||
|
||||
user, err := a.config.APIRepository.User().GetUserByID(userID)
|
||||
user, err := a.config.APIRepository.User().GetUserByID(c.Request().Context(), userID)
|
||||
if err != nil {
|
||||
a.l.Debug().Err(err).Msg("error getting user by id")
|
||||
|
||||
if errors.Is(err, db.ErrNotFound) {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return forbidden
|
||||
}
|
||||
|
||||
@@ -167,7 +169,7 @@ func (a *AuthN) handleBearerAuth(c echo.Context) error {
|
||||
|
||||
// a tenant id must exist in the context in order for the bearer auth to succeed, since
|
||||
// these tokens are tenant-scoped
|
||||
queriedTenant, ok := c.Get("tenant").(*db.TenantModel)
|
||||
queriedTenant, ok := c.Get("tenant").(*dbsqlc.Tenant)
|
||||
|
||||
if !ok {
|
||||
a.l.Debug().Msgf("tenant not found in context")
|
||||
@@ -194,7 +196,7 @@ func (a *AuthN) handleBearerAuth(c echo.Context) error {
|
||||
|
||||
// Verify that the tenant id which exists in the context is the same as the tenant id
|
||||
// in the token.
|
||||
if queriedTenant.ID != tenantId {
|
||||
if sqlchelpers.UUIDToStr(queriedTenant.ID) != tenantId {
|
||||
a.l.Debug().Msgf("tenant id in token does not match tenant id in context")
|
||||
|
||||
return forbidden
|
||||
|
||||
@@ -8,7 +8,8 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/server"
|
||||
"github.com/hatchet-dev/hatchet/pkg/random"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
type SessionHelpers struct {
|
||||
@@ -21,7 +22,7 @@ func NewSessionHelpers(config *server.ServerConfig) *SessionHelpers {
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SessionHelpers) SaveAuthenticated(c echo.Context, user *db.UserModel) error {
|
||||
func (s *SessionHelpers) SaveAuthenticated(c echo.Context, user *dbsqlc.User) error {
|
||||
session, err := s.config.SessionStore.Get(c.Request(), s.config.SessionStore.GetName())
|
||||
|
||||
if err != nil {
|
||||
@@ -29,7 +30,7 @@ func (s *SessionHelpers) SaveAuthenticated(c echo.Context, user *db.UserModel) e
|
||||
}
|
||||
|
||||
session.Values["authenticated"] = true
|
||||
session.Values["user_id"] = user.ID
|
||||
session.Values["user_id"] = sqlchelpers.UUIDToStr(user.ID)
|
||||
|
||||
return session.Save(c.Request(), c.Response())
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/middleware"
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/server"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
type AuthZ struct {
|
||||
@@ -64,8 +65,8 @@ func (a *AuthZ) handleCookieAuth(c echo.Context, r *middleware.RouteInfo) error
|
||||
}
|
||||
|
||||
// if tenant is set in the context, verify that the user is a member of the tenant
|
||||
if tenant, ok := c.Get("tenant").(*db.TenantModel); ok {
|
||||
user, ok := c.Get("user").(*db.UserModel)
|
||||
if tenant, ok := c.Get("tenant").(*dbsqlc.Tenant); ok {
|
||||
user, ok := c.Get("user").(*dbsqlc.User)
|
||||
|
||||
if !ok {
|
||||
a.l.Debug().Msgf("user not found in context")
|
||||
@@ -74,7 +75,7 @@ func (a *AuthZ) handleCookieAuth(c echo.Context, r *middleware.RouteInfo) error
|
||||
}
|
||||
|
||||
// check if the user is a member of the tenant
|
||||
tenantMember, err := a.config.APIRepository.Tenant().GetTenantMemberByUserID(tenant.ID, user.ID)
|
||||
tenantMember, err := a.config.APIRepository.Tenant().GetTenantMemberByUserID(c.Request().Context(), sqlchelpers.UUIDToStr(tenant.ID), sqlchelpers.UUIDToStr(user.ID))
|
||||
|
||||
if err != nil {
|
||||
a.l.Debug().Err(err).Msgf("error getting tenant member")
|
||||
@@ -125,7 +126,7 @@ var permittedWithUnverifiedEmail = []string{
|
||||
}
|
||||
|
||||
func (a *AuthZ) ensureVerifiedEmail(c echo.Context, r *middleware.RouteInfo) error {
|
||||
user, ok := c.Get("user").(*db.UserModel)
|
||||
user, ok := c.Get("user").(*dbsqlc.User)
|
||||
|
||||
if !ok {
|
||||
return nil
|
||||
@@ -154,15 +155,15 @@ var adminAndOwnerOnly = []string{
|
||||
"ApiTokenUpdateRevoke",
|
||||
}
|
||||
|
||||
func (a *AuthZ) authorizeTenantOperations(tenant *db.TenantModel, tenantMember *db.TenantMemberModel, r *middleware.RouteInfo) error {
|
||||
func (a *AuthZ) authorizeTenantOperations(tenant *dbsqlc.Tenant, tenantMember *dbsqlc.PopulateTenantMembersRow, r *middleware.RouteInfo) error {
|
||||
// if the user is an owner, they can do anything
|
||||
if tenantMember.Role == db.TenantMemberRoleOwner {
|
||||
if tenantMember.Role == dbsqlc.TenantMemberRoleOWNER {
|
||||
return nil
|
||||
}
|
||||
|
||||
// if the user is an admin, they can do anything at the moment. Some downstream handlers will case on
|
||||
// admin roles, for example admins cannot mark users as owners.
|
||||
if tenantMember.Role == db.TenantMemberRoleAdmin {
|
||||
if tenantMember.Role == dbsqlc.TenantMemberRoleADMIN {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (a *APITokenService) ApiTokenCreate(ctx echo.Context, request gen.ApiTokenCreateRequestObject) (gen.ApiTokenCreateResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
// validate the request
|
||||
if apiErrors, err := a.config.Validator.ValidateAPI(request.Body); err != nil {
|
||||
@@ -34,7 +36,7 @@ func (a *APITokenService) ApiTokenCreate(ctx echo.Context, request gen.ApiTokenC
|
||||
expiresAt = &e
|
||||
}
|
||||
|
||||
token, err := a.config.Auth.JWTManager.GenerateTenantToken(ctx.Request().Context(), tenant.ID, request.Body.Name, false, expiresAt)
|
||||
token, err := a.config.Auth.JWTManager.GenerateTenantToken(ctx.Request().Context(), tenantId, request.Body.Name, false, expiresAt)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,13 +5,15 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (a *APITokenService) ApiTokenList(ctx echo.Context, request gen.ApiTokenListRequestObject) (gen.ApiTokenListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
tokens, err := a.config.APIRepository.APIToken().ListAPITokensByTenant(tenant.ID)
|
||||
tokens, err := a.config.APIRepository.APIToken().ListAPITokensByTenant(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -20,7 +22,7 @@ func (a *APITokenService) ApiTokenList(ctx echo.Context, request gen.ApiTokenLis
|
||||
rows := make([]gen.APIToken, len(tokens))
|
||||
|
||||
for i := range tokens {
|
||||
rows[i] = *transformers.ToAPIToken(&tokens[i])
|
||||
rows[i] = *transformers.ToAPIToken(tokens[i])
|
||||
}
|
||||
|
||||
return gen.ApiTokenList200JSONResponse(
|
||||
|
||||
@@ -5,11 +5,12 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (a *APITokenService) ApiTokenUpdateRevoke(ctx echo.Context, request gen.ApiTokenUpdateRevokeRequestObject) (gen.ApiTokenUpdateRevokeResponseObject, error) {
|
||||
apiToken := ctx.Get("api-token").(*db.APITokenModel)
|
||||
apiToken := ctx.Get("api-token").(*dbsqlc.APIToken)
|
||||
|
||||
if apiToken.Internal {
|
||||
return gen.ApiTokenUpdateRevoke403JSONResponse(
|
||||
@@ -17,7 +18,7 @@ func (a *APITokenService) ApiTokenUpdateRevoke(ctx echo.Context, request gen.Api
|
||||
), nil
|
||||
}
|
||||
|
||||
err := a.config.APIRepository.APIToken().RevokeAPIToken(apiToken.ID)
|
||||
err := a.config.APIRepository.APIToken().RevokeAPIToken(ctx.Request().Context(), sqlchelpers.UUIDToStr(apiToken.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -10,11 +10,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/metered"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *EventService) EventCreateBulk(ctx echo.Context, request gen.EventCreateBulkRequestObject) (gen.EventCreateBulkResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
eventOpts := make([]*repository.CreateEventOpts, len(request.Body.Events))
|
||||
|
||||
@@ -36,13 +38,13 @@ func (t *EventService) EventCreateBulk(ctx echo.Context, request gen.EventCreate
|
||||
}
|
||||
|
||||
eventOpts[i] = &repository.CreateEventOpts{
|
||||
TenantId: tenant.ID,
|
||||
TenantId: tenantId,
|
||||
Key: event.Key,
|
||||
Data: dataBytes,
|
||||
AdditionalMetadata: additionalMetadata,
|
||||
}
|
||||
}
|
||||
events, err := t.config.Ingestor.BulkIngestEvent(ctx.Request().Context(), tenant.ID, eventOpts)
|
||||
events, err := t.config.Ingestor.BulkIngestEvent(ctx.Request().Context(), tenant, eventOpts)
|
||||
|
||||
if err != nil {
|
||||
|
||||
|
||||
@@ -12,12 +12,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/internal/msgqueue"
|
||||
"github.com/hatchet-dev/hatchet/internal/services/shared/tasktypes"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *EventService) EventUpdateCancel(ctx echo.Context, request gen.EventUpdateCancelRequestObject) (gen.EventUpdateCancelResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
eventIds := make([]string, len(request.Body.EventIds))
|
||||
|
||||
@@ -30,7 +31,7 @@ func (t *EventService) EventUpdateCancel(ctx echo.Context, request gen.EventUpda
|
||||
for i := range eventIds {
|
||||
eventId := eventIds[i]
|
||||
|
||||
runs, err := t.config.EngineRepository.WorkflowRun().ListWorkflowRuns(ctx.Request().Context(), tenant.ID, &repository.ListWorkflowRunsOpts{
|
||||
runs, err := t.config.EngineRepository.WorkflowRun().ListWorkflowRuns(ctx.Request().Context(), tenantId, &repository.ListWorkflowRunsOpts{
|
||||
EventId: &eventId,
|
||||
})
|
||||
|
||||
@@ -56,7 +57,7 @@ func (t *EventService) EventUpdateCancel(ctx echo.Context, request gen.EventUpda
|
||||
defer wg.Done()
|
||||
|
||||
// Lookup step runs for the workflow run
|
||||
jobRun, err := t.config.EngineRepository.JobRun().ListJobRunsForWorkflowRun(ctx.Request().Context(), tenant.ID, runId)
|
||||
jobRun, err := t.config.EngineRepository.JobRun().ListJobRunsForWorkflowRun(ctx.Request().Context(), tenantId, runId)
|
||||
if err != nil {
|
||||
returnErr = multierror.Append(err, fmt.Errorf("failed to list job runs for workflow run %s", runId))
|
||||
return
|
||||
@@ -70,7 +71,7 @@ func (t *EventService) EventUpdateCancel(ctx echo.Context, request gen.EventUpda
|
||||
err = t.config.MessageQueue.AddMessage(
|
||||
ctx.Request().Context(),
|
||||
msgqueue.JOB_PROCESSING_QUEUE,
|
||||
tasktypes.JobRunCancelledToTask(tenant.ID, jobRunId, &reason),
|
||||
tasktypes.JobRunCancelledToTask(tenantId, jobRunId, &reason),
|
||||
)
|
||||
if err != nil {
|
||||
returnErr = multierror.Append(err, fmt.Errorf("failed to send cancel task for job run %s", jobRunId))
|
||||
|
||||
@@ -9,12 +9,12 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/metered"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *EventService) EventCreate(ctx echo.Context, request gen.EventCreateRequestObject) (gen.EventCreateResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
|
||||
// marshal the data object to bytes
|
||||
dataBytes, err := json.Marshal(request.Body.Data)
|
||||
@@ -33,7 +33,7 @@ func (t *EventService) EventCreate(ctx echo.Context, request gen.EventCreateRequ
|
||||
}
|
||||
}
|
||||
|
||||
newEvent, err := t.config.Ingestor.IngestEvent(ctx.Request().Context(), tenant.ID, request.Body.Key, dataBytes, additionalMetadata)
|
||||
newEvent, err := t.config.Ingestor.IngestEvent(ctx.Request().Context(), tenant, request.Body.Key, dataBytes, additionalMetadata)
|
||||
|
||||
if err != nil {
|
||||
if err == metered.ErrResourceExhausted {
|
||||
@@ -45,13 +45,13 @@ func (t *EventService) EventCreate(ctx echo.Context, request gen.EventCreateRequ
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dbNewEvent, err := t.config.APIRepository.Event().GetEventById(sqlchelpers.UUIDToStr(newEvent.ID))
|
||||
dbNewEvent, err := t.config.APIRepository.Event().GetEventById(ctx.Request().Context(), sqlchelpers.UUIDToStr(newEvent.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gen.EventCreate200JSONResponse(
|
||||
*transformers.ToEvent(dbNewEvent),
|
||||
transformers.ToEvent(dbNewEvent),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -5,13 +5,13 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
)
|
||||
|
||||
func (t *EventService) EventGet(ctx echo.Context, request gen.EventGetRequestObject) (gen.EventGetResponseObject, error) {
|
||||
event := ctx.Get("event").(*db.EventModel)
|
||||
event := ctx.Get("event").(*dbsqlc.Event)
|
||||
|
||||
return gen.EventGet200JSONResponse(
|
||||
*transformers.ToEvent(event),
|
||||
transformers.ToEvent(event),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
package events
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
)
|
||||
|
||||
func (t *EventService) EventDataGet(ctx echo.Context, request gen.EventDataGetRequestObject) (gen.EventDataGetResponseObject, error) {
|
||||
event := ctx.Get("event").(*db.EventModel)
|
||||
event := ctx.Get("event").(*dbsqlc.Event)
|
||||
|
||||
var dataStr string
|
||||
|
||||
if dataType, ok := event.Data(); ok {
|
||||
dataStr = string(json.RawMessage(dataType))
|
||||
if len(event.Data) > 0 {
|
||||
dataStr = string(event.Data)
|
||||
}
|
||||
|
||||
return gen.EventDataGet200JSONResponse(
|
||||
|
||||
@@ -14,11 +14,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *EventService) EventList(ctx echo.Context, request gen.EventListRequestObject) (gen.EventListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
limit := 50
|
||||
offset := 0
|
||||
@@ -59,10 +61,10 @@ func (t *EventService) EventList(ctx echo.Context, request gen.EventListRequestO
|
||||
}
|
||||
|
||||
if request.Params.Statuses != nil {
|
||||
statuses := make([]db.WorkflowRunStatus, len(*request.Params.Statuses))
|
||||
statuses := make([]dbsqlc.WorkflowRunStatus, len(*request.Params.Statuses))
|
||||
|
||||
for i, status := range *request.Params.Statuses {
|
||||
statuses[i] = db.WorkflowRunStatus(status)
|
||||
statuses[i] = dbsqlc.WorkflowRunStatus(status)
|
||||
}
|
||||
|
||||
listOpts.WorkflowRunStatus = statuses
|
||||
@@ -105,7 +107,7 @@ func (t *EventService) EventList(ctx echo.Context, request gen.EventListRequestO
|
||||
dbCtx, cancel := context.WithTimeout(ctx.Request().Context(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
listRes, err := t.config.APIRepository.Event().ListEvents(dbCtx, tenant.ID, listOpts)
|
||||
listRes, err := t.config.APIRepository.Event().ListEvents(dbCtx, tenantId, listOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -4,13 +4,15 @@ import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *EventService) EventKeyList(ctx echo.Context, request gen.EventKeyListRequestObject) (gen.EventKeyListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
eventKeys, err := t.config.APIRepository.Event().ListEventKeys(tenant.ID)
|
||||
eventKeys, err := t.config.APIRepository.Event().ListEventKeys(tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -8,12 +8,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/metered"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *EventService) EventUpdateReplay(ctx echo.Context, request gen.EventUpdateReplayRequestObject) (gen.EventUpdateReplayResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
eventIds := make([]string, len(request.Body.EventIds))
|
||||
|
||||
@@ -21,7 +22,7 @@ func (t *EventService) EventUpdateReplay(ctx echo.Context, request gen.EventUpda
|
||||
eventIds[i] = request.Body.EventIds[i].String()
|
||||
}
|
||||
|
||||
events, err := t.config.EngineRepository.Event().ListEventsByIds(ctx.Request().Context(), tenant.ID, eventIds)
|
||||
events, err := t.config.EngineRepository.Event().ListEventsByIds(ctx.Request().Context(), tenantId, eventIds)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -34,7 +35,7 @@ func (t *EventService) EventUpdateReplay(ctx echo.Context, request gen.EventUpda
|
||||
for i := range events {
|
||||
event := events[i]
|
||||
|
||||
newEvent, err := t.config.Ingestor.IngestReplayedEvent(ctx.Request().Context(), tenant.ID, event)
|
||||
newEvent, err := t.config.Ingestor.IngestReplayedEvent(ctx.Request().Context(), tenant, event)
|
||||
|
||||
if err == metered.ErrResourceExhausted {
|
||||
return gen.EventUpdateReplay429JSONResponse(
|
||||
@@ -53,7 +54,7 @@ func (t *EventService) EventUpdateReplay(ctx echo.Context, request gen.EventUpda
|
||||
return nil, allErrs
|
||||
}
|
||||
|
||||
newEvents, err := t.config.APIRepository.Event().ListEventsById(tenant.ID, newEventIds)
|
||||
newEvents, err := t.config.APIRepository.Event().ListEventsById(ctx.Request().Context(), tenantId, newEventIds)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -62,7 +63,7 @@ func (t *EventService) EventUpdateReplay(ctx echo.Context, request gen.EventUpda
|
||||
rows := make([]gen.Event, len(newEvents))
|
||||
|
||||
for i := range newEvents {
|
||||
rows[i] = *transformers.ToEvent(&newEvents[i])
|
||||
rows[i] = transformers.ToEvent(newEvents[i])
|
||||
}
|
||||
|
||||
return gen.EventUpdateReplay200JSONResponse(
|
||||
|
||||
@@ -34,7 +34,7 @@ func (i *IngestorsService) SnsUpdate(ctx echo.Context, req gen.SnsUpdateRequestO
|
||||
tenantId := req.Tenant.String()
|
||||
|
||||
// verify that the tenant and the topic ARN are set in the database
|
||||
snsInt, err := i.config.APIRepository.SNS().GetSNSIntegration(tenantId, payload.TopicArn)
|
||||
snsInt, err := i.config.APIRepository.SNS().GetSNSIntegration(ctx.Request().Context(), tenantId, payload.TopicArn)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -44,6 +44,12 @@ func (i *IngestorsService) SnsUpdate(ctx echo.Context, req gen.SnsUpdateRequestO
|
||||
return nil, fmt.Errorf("SNS integration not found for tenant %s and topic ARN %s", tenantId, payload.TopicArn)
|
||||
}
|
||||
|
||||
tenant, err := i.config.APIRepository.Tenant().GetTenantByID(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch payload.Type {
|
||||
case "SubscriptionConfirmation":
|
||||
_, err := payload.Subscribe()
|
||||
@@ -58,7 +64,7 @@ func (i *IngestorsService) SnsUpdate(ctx echo.Context, req gen.SnsUpdateRequestO
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
_, err := i.config.Ingestor.IngestEvent(ctx.Request().Context(), req.Tenant.String(), req.Event, body, nil)
|
||||
_, err := i.config.Ingestor.IngestEvent(ctx.Request().Context(), tenant, req.Event, body, nil)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,11 +7,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (i *IngestorsService) SnsCreate(ctx echo.Context, req gen.SnsCreateRequestObject) (gen.SnsCreateResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
// validate the request
|
||||
if apiErrors, err := i.config.Validator.ValidateAPI(req.Body); err != nil {
|
||||
@@ -25,7 +27,7 @@ func (i *IngestorsService) SnsCreate(ctx echo.Context, req gen.SnsCreateRequestO
|
||||
}
|
||||
|
||||
// create the SNS integration
|
||||
snsIntegration, err := i.config.APIRepository.SNS().CreateSNSIntegration(tenant.ID, opts)
|
||||
snsIntegration, err := i.config.APIRepository.SNS().CreateSNSIntegration(ctx.Request().Context(), tenantId, opts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,15 +5,17 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (i *IngestorsService) SnsDelete(ctx echo.Context, req gen.SnsDeleteRequestObject) (gen.SnsDeleteResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
sns := ctx.Get("sns").(*db.SNSIntegrationModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
sns := ctx.Get("sns").(*dbsqlc.SNSIntegration)
|
||||
|
||||
// create the SNS integration
|
||||
err := i.config.APIRepository.SNS().DeleteSNSIntegration(tenant.ID, sns.ID)
|
||||
err := i.config.APIRepository.SNS().DeleteSNSIntegration(ctx.Request().Context(), tenantId, sqlchelpers.UUIDToStr(sns.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,15 +5,16 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (i *IngestorsService) SnsList(ctx echo.Context, req gen.SnsListRequestObject) (gen.SnsListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
// create the SNS integration
|
||||
snsIntegrations, err := i.config.APIRepository.SNS().ListSNSIntegrations(tenant.ID)
|
||||
snsIntegrations, err := i.config.APIRepository.SNS().ListSNSIntegrations(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -24,7 +25,7 @@ func (i *IngestorsService) SnsList(ctx echo.Context, req gen.SnsListRequestObjec
|
||||
serverUrl := i.config.Runtime.ServerURL
|
||||
|
||||
for i := range snsIntegrations {
|
||||
rows[i] = *transformers.ToSNSIntegration(&snsIntegrations[i], serverUrl)
|
||||
rows[i] = *transformers.ToSNSIntegration(snsIntegrations[i], serverUrl)
|
||||
}
|
||||
|
||||
return gen.SnsList200JSONResponse(
|
||||
|
||||
@@ -9,12 +9,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *LogService) LogLineList(ctx echo.Context, request gen.LogLineListRequestObject) (gen.LogLineListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
stepRun := ctx.Get("step-run").(*repository.GetStepRunFull)
|
||||
|
||||
limit := 1000
|
||||
@@ -60,7 +61,7 @@ func (t *LogService) LogLineList(ctx echo.Context, request gen.LogLineListReques
|
||||
listOpts.Offset = &offset
|
||||
}
|
||||
|
||||
listRes, err := t.config.APIRepository.Log().ListLogLines(tenant.ID, listOpts)
|
||||
listRes, err := t.config.APIRepository.Log().ListLogLines(tenantId, listOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -16,9 +16,8 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/pkg/client"
|
||||
clientconfig "github.com/hatchet-dev/hatchet/pkg/config/client"
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/shared"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/worker"
|
||||
)
|
||||
|
||||
@@ -28,9 +27,10 @@ func (m *MonitoringService) MonitoringPostRunProbe(ctx echo.Context, request gen
|
||||
return gen.MonitoringPostRunProbe403JSONResponse{}, nil
|
||||
}
|
||||
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
if !slices.Contains[[]string](m.permittedTenants, tenant.ID) {
|
||||
if !slices.Contains[[]string](m.permittedTenants, tenantId) {
|
||||
|
||||
err := fmt.Errorf("tenant is not a monitoring tenant for this instance")
|
||||
|
||||
@@ -59,7 +59,7 @@ func (m *MonitoringService) MonitoringPostRunProbe(ctx echo.Context, request gen
|
||||
|
||||
cf := clientconfig.ClientConfigFile{
|
||||
Token: token,
|
||||
TenantId: tenant.ID,
|
||||
TenantId: tenantId,
|
||||
Namespace: randomNamespace(),
|
||||
TLS: clientconfig.ClientTLSConfigFile{
|
||||
Base: shared.TLSConfigFile{
|
||||
|
||||
@@ -11,11 +11,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *RateLimitService) RateLimitList(ctx echo.Context, request gen.RateLimitListRequestObject) (gen.RateLimitListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
limit := 50
|
||||
offset := 0
|
||||
@@ -50,7 +52,7 @@ func (t *RateLimitService) RateLimitList(ctx echo.Context, request gen.RateLimit
|
||||
dbCtx, cancel := context.WithTimeout(ctx.Request().Context(), 30*time.Second)
|
||||
defer cancel()
|
||||
|
||||
listRes, err := t.config.EngineRepository.RateLimit().ListRateLimits(dbCtx, tenant.ID, listOpts)
|
||||
listRes, err := t.config.EngineRepository.RateLimit().ListRateLimits(dbCtx, tenantId, listOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -62,6 +62,7 @@ func (g *SlackAppService) UserUpdateSlackOauthCallback(ctx echo.Context, _ gen.U
|
||||
}
|
||||
|
||||
_, err = g.config.APIRepository.Slack().UpsertSlackWebhook(
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
&repository.UpsertSlackWebhookOpts{
|
||||
TeamId: resp.Team.ID,
|
||||
|
||||
@@ -7,12 +7,14 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/authn"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/middleware/redirect"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
// Note: we want all errors to redirect, otherwise the user will be greeted with raw JSON in the middle of the login flow.
|
||||
func (g *SlackAppService) UserUpdateSlackOauthStart(ctx echo.Context, _ gen.UserUpdateSlackOauthStartRequestObject) (gen.UserUpdateSlackOauthStartResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
oauth, ok := g.config.AdditionalOAuthConfigs["slack"]
|
||||
|
||||
@@ -22,7 +24,7 @@ func (g *SlackAppService) UserUpdateSlackOauthStart(ctx echo.Context, _ gen.User
|
||||
|
||||
sh := authn.NewSessionHelpers(g.config)
|
||||
|
||||
if err := sh.SaveKV(ctx, "tenant", tenant.ID); err != nil {
|
||||
if err := sh.SaveKV(ctx, "tenant", tenantId); err != nil {
|
||||
return nil, redirect.GetRedirectWithError(ctx, g.config.Logger, err, "Could not get cookie. Please make sure cookies are enabled.")
|
||||
}
|
||||
|
||||
|
||||
@@ -5,14 +5,16 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (i *SlackAppService) SlackWebhookDelete(ctx echo.Context, req gen.SlackWebhookDeleteRequestObject) (gen.SlackWebhookDeleteResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
slack := ctx.Get("slack").(*db.SlackAppWebhookModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
slack := ctx.Get("slack").(*dbsqlc.SlackAppWebhook)
|
||||
|
||||
err := i.config.APIRepository.Slack().DeleteSlackWebhook(tenant.ID, slack.ID)
|
||||
err := i.config.APIRepository.Slack().DeleteSlackWebhook(ctx.Request().Context(), tenantId, sqlchelpers.UUIDToStr(slack.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,14 +5,15 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (s *SlackAppService) SlackWebhookList(ctx echo.Context, req gen.SlackWebhookListRequestObject) (gen.SlackWebhookListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
webhooks, err := s.config.APIRepository.Slack().ListSlackWebhooks(tenant.ID)
|
||||
webhooks, err := s.config.APIRepository.Slack().ListSlackWebhooks(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -21,7 +22,7 @@ func (s *SlackAppService) SlackWebhookList(ctx echo.Context, req gen.SlackWebhoo
|
||||
rows := make([]gen.SlackWebhook, len(webhooks))
|
||||
|
||||
for i := range webhooks {
|
||||
rows[i] = *transformers.ToSlackWebhook(&webhooks[i])
|
||||
rows[i] = *transformers.ToSlackWebhook(webhooks[i])
|
||||
}
|
||||
|
||||
return gen.SlackWebhookList200JSONResponse(
|
||||
|
||||
@@ -12,13 +12,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/internal/msgqueue"
|
||||
"github.com/hatchet-dev/hatchet/internal/services/shared/tasktypes"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *StepRunService) StepRunUpdateCancel(ctx echo.Context, request gen.StepRunUpdateCancelRequestObject) (gen.StepRunUpdateCancelResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
stepRun := ctx.Get("step-run").(*repository.GetStepRunFull)
|
||||
|
||||
// check to see if the step run is in a running or pending state
|
||||
@@ -36,7 +36,7 @@ func (t *StepRunService) StepRunUpdateCancel(ctx echo.Context, request gen.StepR
|
||||
|
||||
engineStepRun, err := t.config.EngineRepository.StepRun().GetStepRunForEngine(
|
||||
ctx.Request().Context(),
|
||||
tenant.ID,
|
||||
tenantId,
|
||||
sqlchelpers.UUIDToStr(stepRun.ID),
|
||||
)
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *StepRunService) StepRunListArchives(ctx echo.Context, request gen.StepRunListArchivesRequestObject) (gen.StepRunListArchivesResponseObject, error) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *StepRunService) StepRunListEvents(ctx echo.Context, request gen.StepRunListEventsRequestObject) (gen.StepRunListEventsResponseObject, error) {
|
||||
|
||||
@@ -8,11 +8,13 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *StepRunService) WorkflowRunListStepRunEvents(ctx echo.Context, request gen.WorkflowRunListStepRunEventsRequestObject) (gen.WorkflowRunListStepRunEventsResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
reqCtx, cancel := context.WithTimeout(ctx.Request().Context(), 5*time.Second)
|
||||
defer cancel()
|
||||
@@ -21,7 +23,7 @@ func (t *StepRunService) WorkflowRunListStepRunEvents(ctx echo.Context, request
|
||||
|
||||
listRes, err := t.config.APIRepository.StepRun().ListStepRunEventsByWorkflowRunId(
|
||||
reqCtx,
|
||||
tenant.ID,
|
||||
tenantId,
|
||||
request.WorkflowRun.String(),
|
||||
lastId,
|
||||
)
|
||||
|
||||
@@ -15,18 +15,19 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/internal/msgqueue"
|
||||
"github.com/hatchet-dev/hatchet/internal/services/shared/tasktypes"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *StepRunService) StepRunUpdateRerun(ctx echo.Context, request gen.StepRunUpdateRerunRequestObject) (gen.StepRunUpdateRerunResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
stepRun := ctx.Get("step-run").(*repository.GetStepRunFull)
|
||||
|
||||
// preflight check to verify step run status and worker availability
|
||||
err := t.config.EngineRepository.StepRun().PreflightCheckReplayStepRun(
|
||||
ctx.Request().Context(),
|
||||
tenant.ID,
|
||||
tenantId,
|
||||
sqlchelpers.UUIDToStr(stepRun.ID),
|
||||
)
|
||||
|
||||
@@ -80,7 +81,7 @@ func (t *StepRunService) StepRunUpdateRerun(ctx echo.Context, request gen.StepRu
|
||||
|
||||
engineStepRun, err := t.config.EngineRepository.StepRun().GetStepRunForEngine(
|
||||
ctx.Request().Context(),
|
||||
tenant.ID,
|
||||
tenantId,
|
||||
sqlchelpers.UUIDToStr(stepRun.ID),
|
||||
)
|
||||
|
||||
|
||||
@@ -4,18 +4,19 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantCreate(ctx echo.Context, request gen.TenantCreateRequestObject) (gen.TenantCreateResponseObject, error) {
|
||||
user := ctx.Get("user").(*db.UserModel)
|
||||
user := ctx.Get("user").(*dbsqlc.User)
|
||||
|
||||
if !t.config.Runtime.AllowCreateTenant {
|
||||
return gen.TenantCreate400JSONResponse(
|
||||
@@ -31,16 +32,16 @@ func (t *TenantService) TenantCreate(ctx echo.Context, request gen.TenantCreateR
|
||||
}
|
||||
|
||||
// determine if a tenant with the slug already exists
|
||||
existingTenant, err := t.config.APIRepository.Tenant().GetTenantBySlug(request.Body.Slug)
|
||||
_, err := t.config.APIRepository.Tenant().GetTenantBySlug(ctx.Request().Context(), request.Body.Slug)
|
||||
|
||||
if err != nil && !errors.Is(err, db.ErrNotFound) {
|
||||
if err != nil && !errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existingTenant != nil {
|
||||
if err == nil {
|
||||
// just return bad request
|
||||
return gen.TenantCreate400JSONResponse(
|
||||
apierrors.NewAPIErrors("Tenant with the slug already exists."),
|
||||
apierrors.NewAPIErrors("Tenant with that slug already exists."),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -54,7 +55,7 @@ func (t *TenantService) TenantCreate(ctx echo.Context, request gen.TenantCreateR
|
||||
}
|
||||
|
||||
// write the user to the db
|
||||
tenant, err := t.config.APIRepository.Tenant().CreateTenant(createOpts)
|
||||
tenant, err := t.config.APIRepository.Tenant().CreateTenant(ctx.Request().Context(), createOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -69,8 +70,8 @@ func (t *TenantService) TenantCreate(ctx echo.Context, request gen.TenantCreateR
|
||||
}
|
||||
|
||||
// add the user as an owner of the tenant
|
||||
_, err = t.config.APIRepository.Tenant().CreateTenantMember(tenantId, &repository.CreateTenantMemberOpts{
|
||||
UserId: user.ID,
|
||||
_, err = t.config.APIRepository.Tenant().CreateTenantMember(ctx.Request().Context(), tenantId, &repository.CreateTenantMemberOpts{
|
||||
UserId: sqlchelpers.UUIDToStr(user.ID),
|
||||
Role: "OWNER",
|
||||
})
|
||||
|
||||
@@ -85,12 +86,12 @@ func (t *TenantService) TenantCreate(ctx echo.Context, request gen.TenantCreateR
|
||||
|
||||
t.config.Analytics.Enqueue(
|
||||
"tenant:create",
|
||||
user.ID,
|
||||
sqlchelpers.UUIDToStr(user.ID),
|
||||
&tenantId,
|
||||
nil,
|
||||
)
|
||||
|
||||
return gen.TenantCreate200JSONResponse(
|
||||
*transformers.ToTenantSqlc(tenant),
|
||||
*transformers.ToTenant(tenant),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) AlertEmailGroupCreate(ctx echo.Context, request gen.AlertEmailGroupCreateRequestObject) (gen.AlertEmailGroupCreateResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
// validate the request
|
||||
if apiErrors, err := t.config.Validator.ValidateAPI(request.Body); err != nil {
|
||||
@@ -24,7 +26,7 @@ func (t *TenantService) AlertEmailGroupCreate(ctx echo.Context, request gen.Aler
|
||||
Emails: request.Body.Emails,
|
||||
}
|
||||
|
||||
emailGroup, err := t.config.APIRepository.TenantAlertingSettings().CreateTenantAlertGroup(tenant.ID, createOpts)
|
||||
emailGroup, err := t.config.APIRepository.TenantAlertingSettings().CreateTenantAlertGroup(ctx.Request().Context(), tenantId, createOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -11,13 +11,15 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/internal/integrations/email"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantInviteCreate(ctx echo.Context, request gen.TenantInviteCreateRequestObject) (gen.TenantInviteCreateResponseObject, error) {
|
||||
user := ctx.Get("user").(*db.UserModel)
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenantMember := ctx.Get("tenant-member").(*db.TenantMemberModel)
|
||||
user := ctx.Get("user").(*dbsqlc.User)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
tenantMember := ctx.Get("tenant-member").(*dbsqlc.PopulateTenantMembersRow)
|
||||
if !t.config.Runtime.AllowInvites {
|
||||
t.config.Logger.Warn().Msg("tenant invites are disabled")
|
||||
return gen.TenantInviteCreate400JSONResponse(
|
||||
@@ -34,7 +36,7 @@ func (t *TenantService) TenantInviteCreate(ctx echo.Context, request gen.TenantI
|
||||
}
|
||||
|
||||
// ensure that this user isn't already a member of the tenant
|
||||
if _, err := t.config.APIRepository.Tenant().GetTenantMemberByEmail(tenant.ID, request.Body.Email); err == nil {
|
||||
if _, err := t.config.APIRepository.Tenant().GetTenantMemberByEmail(ctx.Request().Context(), tenantId, request.Body.Email); err == nil {
|
||||
t.config.Logger.Warn().Msg("this user is already a member of this tenant")
|
||||
return gen.TenantInviteCreate400JSONResponse(
|
||||
apierrors.NewAPIErrors("this user is already a member of this tenant"),
|
||||
@@ -42,7 +44,7 @@ func (t *TenantService) TenantInviteCreate(ctx echo.Context, request gen.TenantI
|
||||
}
|
||||
|
||||
// if user is not an owner, they cannot change a role to owner
|
||||
if tenantMember.Role != db.TenantMemberRoleOwner && request.Body.Role == gen.OWNER {
|
||||
if tenantMember.Role != dbsqlc.TenantMemberRoleOWNER && request.Body.Role == gen.OWNER {
|
||||
t.config.Logger.Warn().Msg("only an owner can change a role to owner")
|
||||
return gen.TenantInviteCreate400JSONResponse(
|
||||
apierrors.NewAPIErrors("only an owner can change a role to owner"),
|
||||
@@ -59,7 +61,7 @@ func (t *TenantService) TenantInviteCreate(ctx echo.Context, request gen.TenantI
|
||||
}
|
||||
|
||||
// create the invite
|
||||
invite, err := t.config.APIRepository.TenantInvite().CreateTenantInvite(tenant.ID, createOpts)
|
||||
invite, err := t.config.APIRepository.TenantInvite().CreateTenantInvite(ctx.Request().Context(), tenantId, createOpts)
|
||||
|
||||
if err != nil {
|
||||
t.config.Logger.Err(err).Msg("could not create tenant invite")
|
||||
@@ -76,8 +78,8 @@ func (t *TenantService) TenantInviteCreate(ctx echo.Context, request gen.TenantI
|
||||
|
||||
name := user.Email
|
||||
|
||||
if userName, ok := user.Name(); ok && userName != "" {
|
||||
name = userName
|
||||
if user.Name.Valid {
|
||||
name = user.Name.String
|
||||
}
|
||||
|
||||
if err := t.config.Email.SendTenantInviteEmail(emailCtx, invite.InviteeEmail, email.TenantInviteEmailData{
|
||||
@@ -90,8 +92,8 @@ func (t *TenantService) TenantInviteCreate(ctx echo.Context, request gen.TenantI
|
||||
}()
|
||||
|
||||
t.config.Analytics.Enqueue("user-invite:create",
|
||||
user.ID,
|
||||
&invite.TenantID,
|
||||
sqlchelpers.UUIDToStr(user.ID),
|
||||
&tenantId,
|
||||
nil,
|
||||
)
|
||||
|
||||
|
||||
@@ -4,15 +4,17 @@ import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) AlertEmailGroupDelete(ctx echo.Context, request gen.AlertEmailGroupDeleteRequestObject) (gen.AlertEmailGroupDeleteResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
emailGroup := ctx.Get("alert-email-group").(*db.TenantAlertEmailGroupModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
emailGroup := ctx.Get("alert-email-group").(*dbsqlc.TenantAlertEmailGroup)
|
||||
|
||||
// delete the invite
|
||||
err := t.config.APIRepository.TenantAlertingSettings().DeleteTenantAlertGroup(tenant.ID, emailGroup.ID)
|
||||
err := t.config.APIRepository.TenantAlertingSettings().DeleteTenantAlertGroup(ctx.Request().Context(), tenantId, sqlchelpers.UUIDToStr(emailGroup.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,14 +5,15 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantInviteDelete(ctx echo.Context, request gen.TenantInviteDeleteRequestObject) (gen.TenantInviteDeleteResponseObject, error) {
|
||||
invite := ctx.Get("tenant-invite").(*db.TenantInviteLinkModel)
|
||||
invite := ctx.Get("tenant-invite").(*dbsqlc.TenantInviteLink)
|
||||
|
||||
// delete the invite
|
||||
err := t.config.APIRepository.TenantInvite().DeleteTenantInvite(invite.ID)
|
||||
err := t.config.APIRepository.TenantInvite().DeleteTenantInvite(ctx.Request().Context(), sqlchelpers.UUIDToStr(invite.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,38 +5,40 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantMemberDelete(ctx echo.Context, request gen.TenantMemberDeleteRequestObject) (gen.TenantMemberDeleteResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenantMember := ctx.Get("tenant-member").(*db.TenantMemberModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
tenantMember := ctx.Get("tenant-member").(*dbsqlc.PopulateTenantMembersRow)
|
||||
|
||||
if tenantMember.Role != db.TenantMemberRoleOwner {
|
||||
if tenantMember.Role != dbsqlc.TenantMemberRoleOWNER {
|
||||
return gen.TenantMemberDelete403JSONResponse(
|
||||
apierrors.NewAPIErrors("Only owners can delete members"),
|
||||
), nil
|
||||
}
|
||||
|
||||
memberToDelete, err := t.config.APIRepository.Tenant().GetTenantMemberByID(request.Member.String())
|
||||
memberToDelete, err := t.config.APIRepository.Tenant().GetTenantMemberByID(ctx.Request().Context(), request.Member.String())
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if tenantMember.UserID == memberToDelete.UserID {
|
||||
if sqlchelpers.UUIDToStr(tenantMember.UserId) == sqlchelpers.UUIDToStr(memberToDelete.UserId) {
|
||||
return gen.TenantMemberDelete403JSONResponse(
|
||||
apierrors.NewAPIErrors("You cannot delete yourself"),
|
||||
), nil
|
||||
}
|
||||
|
||||
if memberToDelete.TenantID != tenant.ID {
|
||||
if sqlchelpers.UUIDToStr(memberToDelete.TenantId) != tenantId {
|
||||
return gen.TenantMemberDelete404JSONResponse(
|
||||
apierrors.NewAPIErrors("Member not found"),
|
||||
), nil
|
||||
}
|
||||
|
||||
_, err = t.config.APIRepository.Tenant().DeleteTenantMember(memberToDelete.ID)
|
||||
err = t.config.APIRepository.Tenant().DeleteTenantMember(ctx.Request().Context(), sqlchelpers.UUIDToStr(memberToDelete.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,19 +5,21 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantAlertingSettingsGet(ctx echo.Context, request gen.TenantAlertingSettingsGetRequestObject) (gen.TenantAlertingSettingsGetResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
tenantAlerting, err := t.config.APIRepository.TenantAlertingSettings().GetTenantAlertingSettings(tenant.ID)
|
||||
tenantAlerting, err := t.config.APIRepository.TenantAlertingSettings().GetTenantAlertingSettings(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gen.TenantAlertingSettingsGet200JSONResponse(
|
||||
*transformers.ToTenantAlertingSettings(tenantAlerting),
|
||||
*transformers.ToTenantAlertingSettings(tenantAlerting.Settings),
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantGetQueueMetrics(ctx echo.Context, request gen.TenantGetQueueMetricsRequestObject) (gen.TenantGetQueueMetricsResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
opts := repository.GetQueueMetricsOpts{}
|
||||
|
||||
@@ -38,13 +40,13 @@ func (t *TenantService) TenantGetQueueMetrics(ctx echo.Context, request gen.Tena
|
||||
opts.WorkflowIds = *request.Params.Workflows
|
||||
}
|
||||
|
||||
metrics, err := t.config.APIRepository.Tenant().GetQueueMetrics(ctx.Request().Context(), tenant.ID, &opts)
|
||||
metrics, err := t.config.APIRepository.Tenant().GetQueueMetrics(ctx.Request().Context(), tenantId, &opts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stepRunQueueCounts, err := t.config.EngineRepository.StepRun().GetQueueCounts(ctx.Request().Context(), tenant.ID)
|
||||
stepRunQueueCounts, err := t.config.EngineRepository.StepRun().GetQueueCounts(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,13 +7,15 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantResourcePolicyGet(ctx echo.Context, request gen.TenantResourcePolicyGetRequestObject) (gen.TenantResourcePolicyGetResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
limits, err := t.config.EntitlementRepository.TenantLimit().GetLimits(context.Background(), tenant.ID)
|
||||
limits, err := t.config.EntitlementRepository.TenantLimit().GetLimits(context.Background(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,16 +1,48 @@
|
||||
package tenants
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantGetStepRunQueueMetrics(ctx echo.Context, request gen.TenantGetStepRunQueueMetricsRequestObject) (gen.TenantGetStepRunQueueMetricsResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
|
||||
stepRunQueueCounts, err := t.config.EngineRepository.StepRun().GetQueueCounts(ctx.Request().Context(), tenant.ID)
|
||||
switch tenant.Version {
|
||||
case dbsqlc.TenantMajorEngineVersionV0:
|
||||
return t.tenantGetStepRunQueueMetricsV0(ctx, tenant, request)
|
||||
case dbsqlc.TenantMajorEngineVersionV1:
|
||||
return t.tenantGetStepRunQueueMetricsV1(ctx, tenant, request)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported tenant version: %s", string(tenant.Version))
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TenantService) tenantGetStepRunQueueMetricsV0(ctx echo.Context, tenant *dbsqlc.Tenant, request gen.TenantGetStepRunQueueMetricsRequestObject) (gen.TenantGetStepRunQueueMetricsResponseObject, error) {
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
stepRunQueueCounts, err := t.config.EngineRepository.StepRun().GetQueueCounts(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
resp := gen.TenantStepRunQueueMetrics{
|
||||
Queues: &stepRunQueueCounts,
|
||||
}
|
||||
|
||||
return gen.TenantGetStepRunQueueMetrics200JSONResponse(resp), nil
|
||||
}
|
||||
|
||||
func (t *TenantService) tenantGetStepRunQueueMetricsV1(ctx echo.Context, tenant *dbsqlc.Tenant, request gen.TenantGetStepRunQueueMetricsRequestObject) (gen.TenantGetStepRunQueueMetricsResponseObject, error) {
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
stepRunQueueCounts, err := t.config.V1.Tasks().GetQueueCounts(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,13 +5,15 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) AlertEmailGroupList(ctx echo.Context, request gen.AlertEmailGroupListRequestObject) (gen.AlertEmailGroupListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
emailGroups, err := t.config.APIRepository.TenantAlertingSettings().ListTenantAlertGroups(tenant.ID)
|
||||
emailGroups, err := t.config.APIRepository.TenantAlertingSettings().ListTenantAlertGroups(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -20,7 +22,7 @@ func (t *TenantService) AlertEmailGroupList(ctx echo.Context, request gen.AlertE
|
||||
rows := make([]gen.TenantAlertEmailGroup, len(emailGroups))
|
||||
|
||||
for i := range emailGroups {
|
||||
rows[i] = *transformers.ToTenantAlertEmailGroup(&emailGroups[i])
|
||||
rows[i] = *transformers.ToTenantAlertEmailGroup(emailGroups[i])
|
||||
}
|
||||
|
||||
return gen.AlertEmailGroupList200JSONResponse{
|
||||
|
||||
@@ -6,13 +6,15 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantInviteList(ctx echo.Context, request gen.TenantInviteListRequestObject) (gen.TenantInviteListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
tenantInvites, err := t.config.APIRepository.TenantInvite().ListTenantInvitesByTenantId(tenant.ID, &repository.ListTenantInvitesOpts{
|
||||
tenantInvites, err := t.config.APIRepository.TenantInvite().ListTenantInvitesByTenantId(ctx.Request().Context(), tenantId, &repository.ListTenantInvitesOpts{
|
||||
Expired: repository.BoolPtr(false),
|
||||
Status: repository.StringPtr("PENDING"),
|
||||
})
|
||||
@@ -24,7 +26,7 @@ func (t *TenantService) TenantInviteList(ctx echo.Context, request gen.TenantInv
|
||||
rows := make([]gen.TenantInvite, len(tenantInvites))
|
||||
|
||||
for i := range tenantInvites {
|
||||
rows[i] = *transformers.ToTenantInviteLink(&tenantInvites[i])
|
||||
rows[i] = *transformers.ToTenantInviteLink(tenantInvites[i])
|
||||
}
|
||||
|
||||
return gen.TenantInviteList200JSONResponse{
|
||||
|
||||
@@ -5,13 +5,15 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantMemberList(ctx echo.Context, request gen.TenantMemberListRequestObject) (gen.TenantMemberListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
members, err := t.config.APIRepository.Tenant().ListTenantMembers(tenant.ID)
|
||||
members, err := t.config.APIRepository.Tenant().ListTenantMembers(ctx.Request().Context(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -20,7 +22,7 @@ func (t *TenantService) TenantMemberList(ctx echo.Context, request gen.TenantMem
|
||||
rows := make([]gen.TenantMember, len(members))
|
||||
|
||||
for i := range members {
|
||||
rows[i] = *transformers.ToTenantMember(&members[i])
|
||||
rows[i] = *transformers.ToTenantMember(members[i])
|
||||
}
|
||||
|
||||
return gen.TenantMemberList200JSONResponse{
|
||||
|
||||
@@ -6,11 +6,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantUpdate(ctx echo.Context, request gen.TenantUpdateRequestObject) (gen.TenantUpdateResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
// validate the request
|
||||
if apiErrors, err := t.config.Validator.ValidateAPI(request.Body); err != nil {
|
||||
@@ -34,8 +36,15 @@ func (t *TenantService) TenantUpdate(ctx echo.Context, request gen.TenantUpdateR
|
||||
updateOpts.Name = request.Body.Name
|
||||
}
|
||||
|
||||
if request.Body.Version != nil {
|
||||
updateOpts.Version = &dbsqlc.NullTenantMajorEngineVersion{
|
||||
Valid: true,
|
||||
TenantMajorEngineVersion: dbsqlc.TenantMajorEngineVersion(*request.Body.Version),
|
||||
}
|
||||
}
|
||||
|
||||
// update the tenant
|
||||
tenant, err := t.config.APIRepository.Tenant().UpdateTenant(tenant.ID, updateOpts)
|
||||
tenant, err := t.config.APIRepository.Tenant().UpdateTenant(ctx.Request().Context(), tenantId, updateOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -47,7 +56,8 @@ func (t *TenantService) TenantUpdate(ctx echo.Context, request gen.TenantUpdateR
|
||||
request.Body.EnableWorkflowRunFailureAlerts != nil {
|
||||
|
||||
_, err = t.config.APIRepository.TenantAlertingSettings().UpsertTenantAlertingSettings(
|
||||
tenant.ID,
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
&repository.UpsertTenantAlertingSettingsOpts{
|
||||
MaxFrequency: request.Body.MaxAlertingFrequency,
|
||||
EnableExpiringTokenAlerts: request.Body.EnableExpiringTokenAlerts,
|
||||
|
||||
@@ -6,11 +6,12 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) AlertEmailGroupUpdate(ctx echo.Context, request gen.AlertEmailGroupUpdateRequestObject) (gen.AlertEmailGroupUpdateResponseObject, error) {
|
||||
emailGroup := ctx.Get("alert-email-group").(*db.TenantAlertEmailGroupModel)
|
||||
emailGroup := ctx.Get("alert-email-group").(*dbsqlc.TenantAlertEmailGroup)
|
||||
|
||||
// validate the request
|
||||
if apiErrors, err := t.config.Validator.ValidateAPI(request.Body); err != nil {
|
||||
@@ -24,7 +25,7 @@ func (t *TenantService) AlertEmailGroupUpdate(ctx echo.Context, request gen.Aler
|
||||
Emails: request.Body.Emails,
|
||||
}
|
||||
|
||||
emailGroup, err := t.config.APIRepository.TenantAlertingSettings().UpdateTenantAlertGroup(emailGroup.ID, updateOpts)
|
||||
emailGroup, err := t.config.APIRepository.TenantAlertingSettings().UpdateTenantAlertGroup(ctx.Request().Context(), sqlchelpers.UUIDToStr(emailGroup.ID), updateOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -7,12 +7,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *TenantService) TenantInviteUpdate(ctx echo.Context, request gen.TenantInviteUpdateRequestObject) (gen.TenantInviteUpdateResponseObject, error) {
|
||||
tenantMember := ctx.Get("tenant-member").(*db.TenantMemberModel)
|
||||
invite := ctx.Get("tenant-invite").(*db.TenantInviteLinkModel)
|
||||
tenantMember := ctx.Get("tenant-member").(*dbsqlc.PopulateTenantMembersRow)
|
||||
invite := ctx.Get("tenant-invite").(*dbsqlc.TenantInviteLink)
|
||||
|
||||
// validate the request
|
||||
if apiErrors, err := t.config.Validator.ValidateAPI(request.Body); err != nil {
|
||||
@@ -22,7 +23,7 @@ func (t *TenantService) TenantInviteUpdate(ctx echo.Context, request gen.TenantI
|
||||
}
|
||||
|
||||
// if user is not an owner, they cannot change a role to owner
|
||||
if tenantMember.Role != db.TenantMemberRoleOwner && request.Body.Role == gen.OWNER {
|
||||
if tenantMember.Role != dbsqlc.TenantMemberRoleOWNER && request.Body.Role == gen.OWNER {
|
||||
return gen.TenantInviteUpdate400JSONResponse(
|
||||
apierrors.NewAPIErrors("only an owner can change a role to owner"),
|
||||
), nil
|
||||
@@ -34,7 +35,7 @@ func (t *TenantService) TenantInviteUpdate(ctx echo.Context, request gen.TenantI
|
||||
}
|
||||
|
||||
// update the invite
|
||||
invite, err := t.config.APIRepository.TenantInvite().UpdateTenantInvite(invite.ID, updateOpts)
|
||||
invite, err := t.config.APIRepository.TenantInvite().UpdateTenantInvite(ctx.Request().Context(), sqlchelpers.UUIDToStr(invite.ID), updateOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -4,16 +4,19 @@ import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (u *UserService) TenantInviteAccept(ctx echo.Context, request gen.TenantInviteAcceptRequestObject) (gen.TenantInviteAcceptResponseObject, error) {
|
||||
user := ctx.Get("user").(*db.UserModel)
|
||||
user := ctx.Get("user").(*dbsqlc.User)
|
||||
userId := sqlchelpers.UUIDToStr(user.ID)
|
||||
|
||||
// validate the request
|
||||
if apiErrors, err := u.config.Validator.ValidateAPI(request.Body); err != nil {
|
||||
@@ -29,7 +32,7 @@ func (u *UserService) TenantInviteAccept(ctx echo.Context, request gen.TenantInv
|
||||
}
|
||||
|
||||
// get the invite
|
||||
invite, err := u.config.APIRepository.TenantInvite().GetTenantInvite(inviteId)
|
||||
invite, err := u.config.APIRepository.TenantInvite().GetTenantInvite(ctx.Request().Context(), inviteId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -41,19 +44,19 @@ func (u *UserService) TenantInviteAccept(ctx echo.Context, request gen.TenantInv
|
||||
}
|
||||
|
||||
// ensure the invite is not expired
|
||||
if invite.Expires.Before(time.Now()) {
|
||||
if invite.Expires.Time.Before(time.Now()) {
|
||||
return gen.TenantInviteAccept400JSONResponse(apierrors.NewAPIErrors("invite is expired")), nil
|
||||
}
|
||||
|
||||
// ensure invite is in a pending state
|
||||
if invite.Status != db.InviteLinkStatusPending {
|
||||
if invite.Status != dbsqlc.InviteLinkStatusPENDING {
|
||||
return gen.TenantInviteAccept400JSONResponse(apierrors.NewAPIErrors("invite has already been used")), nil
|
||||
}
|
||||
|
||||
// ensure the user is not already a member of the tenant
|
||||
_, err = u.config.APIRepository.Tenant().GetTenantMemberByEmail(invite.TenantID, user.Email)
|
||||
_, err = u.config.APIRepository.Tenant().GetTenantMemberByEmail(ctx.Request().Context(), sqlchelpers.UUIDToStr(invite.TenantId), user.Email)
|
||||
|
||||
if err != nil && !errors.Is(err, db.ErrNotFound) {
|
||||
if err != nil && !errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, err
|
||||
} else if err == nil {
|
||||
return gen.TenantInviteAccept400JSONResponse(apierrors.NewAPIErrors("user is already a member of the tenant")), nil
|
||||
@@ -61,19 +64,19 @@ func (u *UserService) TenantInviteAccept(ctx echo.Context, request gen.TenantInv
|
||||
|
||||
// construct the database query
|
||||
updateOpts := &repository.UpdateTenantInviteOpts{
|
||||
Status: repository.StringPtr(string(db.InviteLinkStatusAccepted)),
|
||||
Status: repository.StringPtr(string(dbsqlc.InviteLinkStatusACCEPTED)),
|
||||
}
|
||||
|
||||
// update the invite
|
||||
invite, err = u.config.APIRepository.TenantInvite().UpdateTenantInvite(invite.ID, updateOpts)
|
||||
invite, err = u.config.APIRepository.TenantInvite().UpdateTenantInvite(ctx.Request().Context(), sqlchelpers.UUIDToStr(invite.ID), updateOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// add the user to the tenant
|
||||
_, err = u.config.APIRepository.Tenant().CreateTenantMember(invite.TenantID, &repository.CreateTenantMemberOpts{
|
||||
UserId: user.ID,
|
||||
_, err = u.config.APIRepository.Tenant().CreateTenantMember(ctx.Request().Context(), sqlchelpers.UUIDToStr(invite.TenantId), &repository.CreateTenantMemberOpts{
|
||||
UserId: userId,
|
||||
Role: string(invite.Role),
|
||||
})
|
||||
|
||||
@@ -81,10 +84,12 @@ func (u *UserService) TenantInviteAccept(ctx echo.Context, request gen.TenantInv
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tenantId := sqlchelpers.UUIDToStr(invite.TenantId)
|
||||
|
||||
u.config.Analytics.Enqueue(
|
||||
"user-invite:reject",
|
||||
user.ID,
|
||||
&invite.TenantID,
|
||||
"user-invite:accept",
|
||||
userId,
|
||||
&tenantId,
|
||||
nil,
|
||||
)
|
||||
|
||||
|
||||
@@ -3,13 +3,14 @@ package users
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/authn"
|
||||
)
|
||||
@@ -35,13 +36,13 @@ func (u *UserService) UserCreate(ctx echo.Context, request gen.UserCreateRequest
|
||||
}
|
||||
|
||||
// determine if the user exists before attempting to write the user
|
||||
existingUser, err := u.config.APIRepository.User().GetUserByEmail(string(request.Body.Email))
|
||||
_, err := u.config.APIRepository.User().GetUserByEmail(ctx.Request().Context(), string(request.Body.Email))
|
||||
|
||||
if err != nil && !errors.Is(err, db.ErrNotFound) {
|
||||
if err != nil && !errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if existingUser != nil {
|
||||
if err == nil {
|
||||
// just return bad request
|
||||
return gen.UserCreate400JSONResponse(
|
||||
apierrors.NewAPIErrors("Email is already registered."),
|
||||
@@ -66,7 +67,7 @@ func (u *UserService) UserCreate(ctx echo.Context, request gen.UserCreateRequest
|
||||
}
|
||||
|
||||
// write the user to the db
|
||||
user, err := u.config.APIRepository.User().CreateUser(createOpts)
|
||||
user, err := u.config.APIRepository.User().CreateUser(ctx.Request().Context(), createOpts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -79,7 +80,7 @@ func (u *UserService) UserCreate(ctx echo.Context, request gen.UserCreateRequest
|
||||
|
||||
u.config.Analytics.Enqueue(
|
||||
"user:create",
|
||||
user.ID,
|
||||
sqlchelpers.UUIDToStr(user.ID),
|
||||
nil,
|
||||
map[string]interface{}{
|
||||
"email": request.Body.Email,
|
||||
|
||||
@@ -6,25 +6,28 @@ import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (u *UserService) UserGetCurrent(ctx echo.Context, request gen.UserGetCurrentRequestObject) (gen.UserGetCurrentResponseObject, error) {
|
||||
user := ctx.Get("user").(*db.UserModel)
|
||||
user := ctx.Get("user").(*dbsqlc.User)
|
||||
userId := sqlchelpers.UUIDToStr(user.ID)
|
||||
|
||||
var hasPass bool
|
||||
|
||||
pass, err := u.config.APIRepository.User().GetUserPassword(user.ID)
|
||||
_, err := u.config.APIRepository.User().GetUserPassword(ctx.Request().Context(), userId)
|
||||
|
||||
if err != nil && !errors.Is(err, db.ErrNotFound) {
|
||||
if err != nil && !errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if pass != nil {
|
||||
if err == nil {
|
||||
hasPass = true
|
||||
}
|
||||
|
||||
@@ -42,7 +45,7 @@ func (u *UserService) UserGetCurrent(ctx echo.Context, request gen.UserGetCurren
|
||||
|
||||
u.config.Analytics.Enqueue(
|
||||
"user:current",
|
||||
user.ID,
|
||||
userId,
|
||||
nil,
|
||||
map[string]interface{}{
|
||||
"email": user.Email,
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
githubsdk "github.com/google/go-github/v57/github"
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -14,7 +15,8 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/server"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
// Note: we want all errors to redirect, otherwise the user will be greeted with raw JSON in the middle of the login flow.
|
||||
@@ -35,7 +37,7 @@ func (u *UserService) UserUpdateGithubOauthCallback(ctx echo.Context, _ gen.User
|
||||
return nil, redirect.GetRedirectWithError(ctx, u.config.Logger, fmt.Errorf("invalid token"), "Forbidden")
|
||||
}
|
||||
|
||||
user, err := u.upsertGithubUserFromToken(u.config, token)
|
||||
user, err := u.upsertGithubUserFromToken(ctx.Request().Context(), u.config, token)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrNotInRestrictedDomain) {
|
||||
@@ -66,7 +68,7 @@ func (u *UserService) UserUpdateGithubOauthCallback(ctx echo.Context, _ gen.User
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (u *UserService) upsertGithubUserFromToken(config *server.ServerConfig, tok *oauth2.Token) (*db.UserModel, error) {
|
||||
func (u *UserService) upsertGithubUserFromToken(ctx context.Context, config *server.ServerConfig, tok *oauth2.Token) (*dbsqlc.User, error) {
|
||||
gInfo, err := u.getGithubEmailFromToken(tok)
|
||||
|
||||
if err != nil {
|
||||
@@ -96,15 +98,15 @@ func (u *UserService) upsertGithubUserFromToken(config *server.ServerConfig, tok
|
||||
Provider: "github",
|
||||
ProviderUserId: gInfo.ID,
|
||||
AccessToken: accessTokenEncrypted,
|
||||
RefreshToken: &refreshTokenEncrypted,
|
||||
RefreshToken: refreshTokenEncrypted,
|
||||
ExpiresAt: &expiresAt,
|
||||
}
|
||||
|
||||
user, err := u.config.APIRepository.User().GetUserByEmail(gInfo.Email)
|
||||
user, err := u.config.APIRepository.User().GetUserByEmail(ctx, gInfo.Email)
|
||||
|
||||
switch err {
|
||||
case nil:
|
||||
user, err = u.config.APIRepository.User().UpdateUser(user.ID, &repository.UpdateUserOpts{
|
||||
user, err = u.config.APIRepository.User().UpdateUser(ctx, sqlchelpers.UUIDToStr(user.ID), &repository.UpdateUserOpts{
|
||||
EmailVerified: repository.BoolPtr(gInfo.EmailVerified),
|
||||
Name: repository.StringPtr(gInfo.Name),
|
||||
OAuth: oauthOpts,
|
||||
@@ -113,8 +115,8 @@ func (u *UserService) upsertGithubUserFromToken(config *server.ServerConfig, tok
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update user: %s", err.Error())
|
||||
}
|
||||
case db.ErrNotFound:
|
||||
user, err = u.config.APIRepository.User().CreateUser(&repository.CreateUserOpts{
|
||||
case pgx.ErrNoRows:
|
||||
user, err = u.config.APIRepository.User().CreateUser(ctx, &repository.CreateUserOpts{
|
||||
Email: gInfo.Email,
|
||||
EmailVerified: repository.BoolPtr(gInfo.EmailVerified),
|
||||
Name: repository.StringPtr(gInfo.Name),
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
"golang.org/x/oauth2"
|
||||
|
||||
@@ -16,7 +17,8 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/server"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
// Note: we want all errors to redirect, otherwise the user will be greeted with raw JSON in the middle of the login flow.
|
||||
@@ -37,7 +39,7 @@ func (u *UserService) UserUpdateGoogleOauthCallback(ctx echo.Context, _ gen.User
|
||||
return nil, redirect.GetRedirectWithError(ctx, u.config.Logger, fmt.Errorf("invalid token"), "Forbidden")
|
||||
}
|
||||
|
||||
user, err := u.upsertGoogleUserFromToken(u.config, token)
|
||||
user, err := u.upsertGoogleUserFromToken(ctx.Request().Context(), u.config, token)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrNotInRestrictedDomain) {
|
||||
@@ -60,7 +62,7 @@ func (u *UserService) UserUpdateGoogleOauthCallback(ctx echo.Context, _ gen.User
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (u *UserService) upsertGoogleUserFromToken(config *server.ServerConfig, tok *oauth2.Token) (*db.UserModel, error) {
|
||||
func (u *UserService) upsertGoogleUserFromToken(ctx context.Context, config *server.ServerConfig, tok *oauth2.Token) (*dbsqlc.User, error) {
|
||||
gInfo, err := getGoogleUserInfoFromToken(tok)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -89,15 +91,15 @@ func (u *UserService) upsertGoogleUserFromToken(config *server.ServerConfig, tok
|
||||
Provider: "google",
|
||||
ProviderUserId: gInfo.Sub,
|
||||
AccessToken: accessTokenEncrypted,
|
||||
RefreshToken: &refreshTokenEncrypted,
|
||||
RefreshToken: refreshTokenEncrypted,
|
||||
ExpiresAt: &expiresAt,
|
||||
}
|
||||
|
||||
user, err := u.config.APIRepository.User().GetUserByEmail(gInfo.Email)
|
||||
user, err := u.config.APIRepository.User().GetUserByEmail(ctx, gInfo.Email)
|
||||
|
||||
switch err {
|
||||
case nil:
|
||||
user, err = u.config.APIRepository.User().UpdateUser(user.ID, &repository.UpdateUserOpts{
|
||||
user, err = u.config.APIRepository.User().UpdateUser(ctx, sqlchelpers.UUIDToStr(user.ID), &repository.UpdateUserOpts{
|
||||
EmailVerified: repository.BoolPtr(gInfo.EmailVerified),
|
||||
Name: repository.StringPtr(gInfo.Name),
|
||||
OAuth: oauthOpts,
|
||||
@@ -106,8 +108,8 @@ func (u *UserService) upsertGoogleUserFromToken(config *server.ServerConfig, tok
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update user: %s", err.Error())
|
||||
}
|
||||
case db.ErrNotFound:
|
||||
user, err = u.config.APIRepository.User().CreateUser(&repository.CreateUserOpts{
|
||||
case pgx.ErrNoRows:
|
||||
user, err = u.config.APIRepository.User().CreateUser(ctx, &repository.CreateUserOpts{
|
||||
Email: gInfo.Email,
|
||||
EmailVerified: repository.BoolPtr(gInfo.EmailVerified),
|
||||
Name: repository.StringPtr(gInfo.Name),
|
||||
|
||||
@@ -5,13 +5,15 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *UserService) TenantMembershipsList(ctx echo.Context, request gen.TenantMembershipsListRequestObject) (gen.TenantMembershipsListResponseObject, error) {
|
||||
user := ctx.Get("user").(*db.UserModel)
|
||||
user := ctx.Get("user").(*dbsqlc.User)
|
||||
userId := sqlchelpers.UUIDToStr(user.ID)
|
||||
|
||||
memberships, err := t.config.APIRepository.User().ListTenantMemberships(user.ID)
|
||||
memberships, err := t.config.APIRepository.User().ListTenantMemberships(ctx.Request().Context(), userId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -20,8 +22,7 @@ func (t *UserService) TenantMembershipsList(ctx echo.Context, request gen.Tenant
|
||||
rows := make([]gen.TenantMember, len(memberships))
|
||||
|
||||
for i, membership := range memberships {
|
||||
membershipCp := membership
|
||||
rows[i] = *transformers.ToTenantMember(&membershipCp)
|
||||
rows[i] = *transformers.ToTenantMember(membership)
|
||||
}
|
||||
|
||||
return gen.TenantMembershipsList200JSONResponse(
|
||||
|
||||
@@ -5,13 +5,13 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
)
|
||||
|
||||
func (t *UserService) UserListTenantInvites(ctx echo.Context, request gen.UserListTenantInvitesRequestObject) (gen.UserListTenantInvitesResponseObject, error) {
|
||||
user := ctx.Get("user").(*db.UserModel)
|
||||
user := ctx.Get("user").(*dbsqlc.User)
|
||||
|
||||
invites, err := t.config.APIRepository.TenantInvite().ListTenantInvitesByEmail(user.Email)
|
||||
invites, err := t.config.APIRepository.TenantInvite().ListTenantInvitesByEmail(ctx.Request().Context(), user.Email)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -20,7 +20,7 @@ func (t *UserService) UserListTenantInvites(ctx echo.Context, request gen.UserLi
|
||||
rows := make([]gen.TenantInvite, len(invites))
|
||||
|
||||
for i := range invites {
|
||||
rows[i] = *transformers.ToTenantInviteLink(&invites[i])
|
||||
rows[i] = *transformers.ToTenantInviteLink(invites[i])
|
||||
}
|
||||
|
||||
return gen.UserListTenantInvites200JSONResponse(gen.TenantInviteList200JSONResponse{
|
||||
|
||||
@@ -9,11 +9,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (u *UserService) TenantInviteReject(ctx echo.Context, request gen.TenantInviteRejectRequestObject) (gen.TenantInviteRejectResponseObject, error) {
|
||||
user := ctx.Get("user").(*db.UserModel)
|
||||
user := ctx.Get("user").(*dbsqlc.User)
|
||||
userId := sqlchelpers.UUIDToStr(user.ID)
|
||||
|
||||
// validate the request
|
||||
if apiErrors, err := u.config.Validator.ValidateAPI(request.Body); err != nil {
|
||||
@@ -29,7 +31,7 @@ func (u *UserService) TenantInviteReject(ctx echo.Context, request gen.TenantInv
|
||||
}
|
||||
|
||||
// get the invite
|
||||
invite, err := u.config.APIRepository.TenantInvite().GetTenantInvite(inviteId)
|
||||
invite, err := u.config.APIRepository.TenantInvite().GetTenantInvite(ctx.Request().Context(), inviteId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -41,31 +43,33 @@ func (u *UserService) TenantInviteReject(ctx echo.Context, request gen.TenantInv
|
||||
}
|
||||
|
||||
// ensure the invite is not expired
|
||||
if invite.Expires.Before(time.Now()) {
|
||||
if invite.Expires.Time.Before(time.Now()) {
|
||||
return gen.TenantInviteReject400JSONResponse(apierrors.NewAPIErrors("invite is expired")), nil
|
||||
}
|
||||
|
||||
// ensure invite is in a pending state
|
||||
if invite.Status != db.InviteLinkStatusPending {
|
||||
if invite.Status != dbsqlc.InviteLinkStatusPENDING {
|
||||
return gen.TenantInviteReject400JSONResponse(apierrors.NewAPIErrors("invite has already been used")), nil
|
||||
}
|
||||
|
||||
// construct the database query
|
||||
updateOpts := &repository.UpdateTenantInviteOpts{
|
||||
Status: repository.StringPtr(string(db.InviteLinkStatusRejected)),
|
||||
Status: repository.StringPtr(string(dbsqlc.InviteLinkStatusREJECTED)),
|
||||
}
|
||||
|
||||
// update the invite
|
||||
invite, err = u.config.APIRepository.TenantInvite().UpdateTenantInvite(invite.ID, updateOpts)
|
||||
invite, err = u.config.APIRepository.TenantInvite().UpdateTenantInvite(ctx.Request().Context(), sqlchelpers.UUIDToStr(invite.ID), updateOpts)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tenantId := sqlchelpers.UUIDToStr(invite.TenantId)
|
||||
|
||||
u.config.Analytics.Enqueue(
|
||||
"user-invite:accept",
|
||||
user.ID,
|
||||
&invite.TenantID,
|
||||
"user-invite:reject",
|
||||
userId,
|
||||
&tenantId,
|
||||
nil,
|
||||
)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/authn"
|
||||
@@ -11,7 +12,7 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (u *UserService) UserUpdateLogin(ctx echo.Context, request gen.UserUpdateLoginRequestObject) (gen.UserUpdateLoginResponseObject, error) {
|
||||
@@ -36,16 +37,16 @@ func (u *UserService) UserUpdateLogin(ctx echo.Context, request gen.UserUpdateLo
|
||||
}
|
||||
|
||||
// determine if the user exists before attempting to write the user
|
||||
existingUser, err := u.config.APIRepository.User().GetUserByEmail(string(request.Body.Email))
|
||||
existingUser, err := u.config.APIRepository.User().GetUserByEmail(ctx.Request().Context(), string(request.Body.Email))
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrNotFound) {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return gen.UserUpdateLogin400JSONResponse(apierrors.NewAPIErrors("user not found")), nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
userPass, err := u.config.APIRepository.User().GetUserPassword(existingUser.ID)
|
||||
userPass, err := u.config.APIRepository.User().GetUserPassword(ctx.Request().Context(), sqlchelpers.UUIDToStr(existingUser.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get user password: %w", err)
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/authn"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
)
|
||||
|
||||
func (u *UserService) UserUpdateLogout(ctx echo.Context, request gen.UserUpdateLogoutRequestObject) (gen.UserUpdateLogoutResponseObject, error) {
|
||||
user := ctx.Get("user").(*db.UserModel)
|
||||
user := ctx.Get("user").(*dbsqlc.User)
|
||||
|
||||
if err := authn.NewSessionHelpers(u.config).SaveUnauthenticated(ctx); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -9,12 +9,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (u *UserService) UserUpdatePassword(ctx echo.Context, request gen.UserUpdatePasswordRequestObject) (gen.UserUpdatePasswordResponseObject, error) {
|
||||
// determine if the user exists before attempting to write the user
|
||||
existingUser := ctx.Get("user").(*db.UserModel)
|
||||
existingUser := ctx.Get("user").(*dbsqlc.User)
|
||||
|
||||
if !u.config.Runtime.AllowChangePassword {
|
||||
return gen.UserUpdatePassword405JSONResponse(
|
||||
@@ -36,7 +37,9 @@ func (u *UserService) UserUpdatePassword(ctx echo.Context, request gen.UserUpdat
|
||||
return gen.UserUpdatePassword400JSONResponse(*apiErrors), nil
|
||||
}
|
||||
|
||||
userPass, err := u.config.APIRepository.User().GetUserPassword(existingUser.ID)
|
||||
userId := sqlchelpers.UUIDToStr(existingUser.ID)
|
||||
|
||||
userPass, err := u.config.APIRepository.User().GetUserPassword(ctx.Request().Context(), userId)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not get user password: %w", err)
|
||||
@@ -54,7 +57,7 @@ func (u *UserService) UserUpdatePassword(ctx echo.Context, request gen.UserUpdat
|
||||
return nil, fmt.Errorf("could not hash user password: %w", err)
|
||||
}
|
||||
|
||||
user, err := u.config.APIRepository.User().UpdateUser(existingUser.ID, &repository.UpdateUserOpts{
|
||||
user, err := u.config.APIRepository.User().UpdateUser(ctx.Request().Context(), userId, &repository.UpdateUserOpts{
|
||||
Password: newPass,
|
||||
})
|
||||
|
||||
|
||||
63
api/v1/server/handlers/v1/proxy/proxy.go
Normal file
63
api/v1/server/handlers/v1/proxy/proxy.go
Normal file
@@ -0,0 +1,63 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
client "github.com/hatchet-dev/hatchet/pkg/client/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/server"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
type Proxy[in, out any] struct {
|
||||
config *server.ServerConfig
|
||||
method func(ctx context.Context, cli *client.GRPCClient, input *in) (*out, error)
|
||||
}
|
||||
|
||||
func NewProxy[in, out any](config *server.ServerConfig, method func(ctx context.Context, cli *client.GRPCClient, input *in) (*out, error)) *Proxy[in, out] {
|
||||
return &Proxy[in, out]{
|
||||
config: config,
|
||||
method: method,
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Proxy[in, out]) Do(ctx context.Context, tenant *dbsqlc.Tenant, input *in) (*out, error) {
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
expiresAt := time.Now().Add(5 * time.Minute).UTC()
|
||||
|
||||
// generate the API token for the proxy request
|
||||
tok, err := p.config.Auth.JWTManager.GenerateTenantToken(ctx, tenantId, "proxy", true, &expiresAt)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
deleteCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// delete the API token
|
||||
err = p.config.APIRepository.APIToken().DeleteAPIToken(deleteCtx, tenantId, tok.TokenId)
|
||||
|
||||
if err != nil {
|
||||
p.config.Logger.Error().Err(err).Msg("failed to delete API token")
|
||||
}
|
||||
}()
|
||||
|
||||
c, err := p.config.InternalClientFactory.NewGRPCClient(tok.Token)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// call the client method
|
||||
res, err := p.method(client.AuthContext(ctx, tok.Token), c, input)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
||||
74
api/v1/server/handlers/v1/tasks/cancel.go
Normal file
74
api/v1/server/handlers/v1/tasks/cancel.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/internal/services/admin/contracts/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
)
|
||||
|
||||
func (t *TasksService) V1TaskCancel(ctx echo.Context, request gen.V1TaskCancelRequestObject) (gen.V1TaskCancelResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
|
||||
var err error
|
||||
|
||||
grpcReq := &contracts.CancelTasksRequest{}
|
||||
|
||||
if request.Body.ExternalIds != nil {
|
||||
externalIds := make([]string, 0)
|
||||
|
||||
for _, id := range *request.Body.ExternalIds {
|
||||
externalIds = append(externalIds, id.String())
|
||||
}
|
||||
|
||||
grpcReq.ExternalIds = externalIds
|
||||
}
|
||||
|
||||
if request.Body.Filter != nil {
|
||||
filter := &contracts.TasksFilter{
|
||||
Since: timestamppb.New(request.Body.Filter.Since),
|
||||
}
|
||||
|
||||
if request.Body.Filter.Until != nil {
|
||||
filter.Until = timestamppb.New(*request.Body.Filter.Until)
|
||||
}
|
||||
|
||||
if request.Body.Filter.Statuses != nil {
|
||||
filter.Statuses = make([]string, len(*request.Body.Filter.Statuses))
|
||||
|
||||
for i, status := range *request.Body.Filter.Statuses {
|
||||
filter.Statuses[i] = string(status)
|
||||
}
|
||||
}
|
||||
|
||||
if request.Body.Filter.WorkflowIds != nil {
|
||||
filter.WorkflowIds = make([]string, len(*request.Body.Filter.WorkflowIds))
|
||||
|
||||
for i, id := range *request.Body.Filter.WorkflowIds {
|
||||
filter.WorkflowIds[i] = id.String()
|
||||
}
|
||||
}
|
||||
|
||||
if request.Body.Filter.AdditionalMetadata != nil {
|
||||
filter.AdditionalMetadata = make([]string, len(*request.Body.Filter.AdditionalMetadata))
|
||||
|
||||
copy(filter.AdditionalMetadata, *request.Body.Filter.AdditionalMetadata)
|
||||
}
|
||||
|
||||
grpcReq.Filter = filter
|
||||
}
|
||||
|
||||
_, err = t.proxyCancel.Do(
|
||||
ctx.Request().Context(),
|
||||
tenant,
|
||||
grpcReq,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gen.V1TaskCancel200Response{}, nil
|
||||
}
|
||||
26
api/v1/server/handlers/v1/tasks/get.go
Normal file
26
api/v1/server/handlers/v1/tasks/get.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/v1/sqlcv1"
|
||||
|
||||
transformers "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
)
|
||||
|
||||
func (t *TasksService) V1TaskGet(ctx echo.Context, request gen.V1TaskGetRequestObject) (gen.V1TaskGetResponseObject, error) {
|
||||
task := ctx.Get("task").(*sqlcv1.V1TasksOlap)
|
||||
|
||||
taskWithData, workflowRunExternalId, err := t.config.V1.OLAP().ReadTaskRunData(ctx.Request().Context(), task.TenantID, task.ID, task.InsertedAt)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := transformers.ToTask(taskWithData, workflowRunExternalId)
|
||||
|
||||
return gen.V1TaskGet200JSONResponse(
|
||||
result,
|
||||
), nil
|
||||
}
|
||||
51
api/v1/server/handlers/v1/tasks/get_metrics.go
Normal file
51
api/v1/server/handlers/v1/tasks/get_metrics.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
v1 "github.com/hatchet-dev/hatchet/pkg/repository/v1"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
transformers "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
)
|
||||
|
||||
func (t *TasksService) V1TaskListStatusMetrics(ctx echo.Context, request gen.V1TaskListStatusMetricsRequestObject) (gen.V1TaskListStatusMetricsResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
var workflowIds []uuid.UUID
|
||||
|
||||
if request.Params.WorkflowIds != nil {
|
||||
workflowIds = *request.Params.WorkflowIds
|
||||
}
|
||||
|
||||
var parentTaskExternalId *pgtype.UUID
|
||||
|
||||
if request.Params.ParentTaskExternalId != nil {
|
||||
uuidPtr := *request.Params.ParentTaskExternalId
|
||||
uuidVal := sqlchelpers.UUIDFromStr(uuidPtr.String())
|
||||
parentTaskExternalId = &uuidVal
|
||||
}
|
||||
|
||||
metrics, err := t.config.V1.OLAP().ReadTaskRunMetrics(ctx.Request().Context(), tenantId, v1.ReadTaskRunMetricsOpts{
|
||||
CreatedAfter: request.Params.Since,
|
||||
WorkflowIds: workflowIds,
|
||||
ParentTaskExternalID: parentTaskExternalId,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := transformers.ToTaskRunMetrics(&metrics)
|
||||
|
||||
// Search for api errors to see how we handle errors in other cases
|
||||
return gen.V1TaskListStatusMetrics200JSONResponse(
|
||||
result,
|
||||
), nil
|
||||
}
|
||||
124
api/v1/server/handlers/v1/tasks/get_point_metrics.go
Normal file
124
api/v1/server/handlers/v1/tasks/get_point_metrics.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/v1/sqlcv1"
|
||||
)
|
||||
|
||||
func (t *TasksService) V1TaskGetPointMetrics(ctx echo.Context, request gen.V1TaskGetPointMetricsRequestObject) (gen.V1TaskGetPointMetricsResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
// 24 hours ago, rounded to the nearest minute
|
||||
lowerBound := time.Now().UTC().Add(-24 * time.Hour).Truncate(30 * time.Minute)
|
||||
upperBound := time.Now().UTC()
|
||||
|
||||
if request.Params.CreatedAfter != nil {
|
||||
lowerBound = request.Params.CreatedAfter.UTC()
|
||||
}
|
||||
if request.Params.FinishedBefore != nil {
|
||||
upperBound = request.Params.FinishedBefore.UTC()
|
||||
}
|
||||
|
||||
// determine a bucket interval based on the time range. If the time range is less than 1 hour, use 1 minute intervals.
|
||||
// If the time range is less than 1 day, use 5 minute intervals. Otherwise, use 30 minute intervals.
|
||||
var bucketInterval time.Duration
|
||||
|
||||
switch {
|
||||
case upperBound.Sub(lowerBound) < 61*time.Minute:
|
||||
bucketInterval = time.Minute
|
||||
lowerBound = lowerBound.Truncate(time.Minute)
|
||||
case upperBound.Sub(lowerBound) < 12*time.Hour:
|
||||
bucketInterval = 5 * time.Minute
|
||||
lowerBound = lowerBound.Truncate(5 * time.Minute)
|
||||
case upperBound.Sub(lowerBound) < 48*time.Hour:
|
||||
bucketInterval = 30 * time.Minute
|
||||
lowerBound = lowerBound.Truncate(30 * time.Minute)
|
||||
case upperBound.Sub(lowerBound) < 8*24*time.Hour:
|
||||
bucketInterval = 8 * time.Hour
|
||||
lowerBound = lowerBound.Truncate(8 * time.Hour)
|
||||
default:
|
||||
bucketInterval = 24 * time.Hour
|
||||
lowerBound = lowerBound.Truncate(24 * time.Hour)
|
||||
}
|
||||
|
||||
metrics, err := t.config.V1.OLAP().GetTaskPointMetrics(ctx.Request().Context(), tenantId, &lowerBound, &upperBound, bucketInterval)
|
||||
|
||||
if err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return gen.V1TaskGetPointMetrics400JSONResponse(
|
||||
apierrors.NewAPIErrors("workflow not found"),
|
||||
), nil
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Fill missing minutes with 0 values
|
||||
convertedMetrics := fillMissingMinutesWithZero(lowerBound, upperBound, convertToGenMetrics(metrics), bucketInterval)
|
||||
|
||||
return gen.V1TaskGetPointMetrics200JSONResponse{
|
||||
Results: &convertedMetrics,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type WorkflowRunEventsMetrics struct {
|
||||
Results *[]gen.V1TaskPointMetric `json:"results,omitempty"`
|
||||
}
|
||||
|
||||
func convertToGenMetrics(metrics []*sqlcv1.GetTaskPointMetricsRow) []gen.V1TaskPointMetric {
|
||||
converted := make([]gen.V1TaskPointMetric, len(metrics))
|
||||
|
||||
for i, metric := range metrics {
|
||||
if metric == nil || !metric.Bucket2.Valid {
|
||||
continue
|
||||
}
|
||||
|
||||
timeMinute := metric.Bucket2.Time.UTC()
|
||||
|
||||
converted[i] = gen.V1TaskPointMetric{
|
||||
FAILED: int(metric.FailedCount),
|
||||
SUCCEEDED: int(metric.CompletedCount),
|
||||
Time: timeMinute,
|
||||
}
|
||||
}
|
||||
|
||||
return converted
|
||||
}
|
||||
|
||||
// fillMissingMinutesWithZero fills in missing minutes between lowerBound and upperBound with 0 values.
|
||||
func fillMissingMinutesWithZero(lowerBound, upperBound time.Time, metrics []gen.V1TaskPointMetric, bucketInterval time.Duration) []gen.V1TaskPointMetric {
|
||||
result := []gen.V1TaskPointMetric{}
|
||||
|
||||
metricMap := make(map[time.Time]gen.V1TaskPointMetric)
|
||||
|
||||
for _, metric := range metrics {
|
||||
if !metric.Time.IsZero() {
|
||||
metricMap[(metric.Time).UTC()] = metric
|
||||
}
|
||||
}
|
||||
|
||||
for t := lowerBound; t.Before(upperBound) || t.Equal(upperBound); t = t.Add(bucketInterval) {
|
||||
if metric, exists := metricMap[t]; exists {
|
||||
result = append(result, metric)
|
||||
} else {
|
||||
timeCopy := t
|
||||
result = append(result, gen.V1TaskPointMetric{
|
||||
FAILED: int(0),
|
||||
SUCCEEDED: int(0),
|
||||
Time: timeCopy,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
38
api/v1/server/handlers/v1/tasks/list_by_dag_id.go
Normal file
38
api/v1/server/handlers/v1/tasks/list_by_dag_id.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
|
||||
transformers "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
)
|
||||
|
||||
func (t *TasksService) V1DagListTasks(ctx echo.Context, request gen.V1DagListTasksRequestObject) (gen.V1DagListTasksResponseObject, error) {
|
||||
tenantId := request.Params.Tenant.String()
|
||||
dagIds := request.Params.DagIds
|
||||
|
||||
pguuids := make([]pgtype.UUID, 0)
|
||||
for _, dagId := range dagIds {
|
||||
pguuids = append(pguuids, sqlchelpers.UUIDFromStr(dagId.String()))
|
||||
}
|
||||
|
||||
tasks, taskIdToDagExternalId, err := t.config.V1.OLAP().ListTasksByDAGId(
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
pguuids,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := transformers.ToDagChildren(tasks, taskIdToDagExternalId)
|
||||
|
||||
// Search for api errors to see how we handle errors in other cases
|
||||
return gen.V1DagListTasks200JSONResponse(
|
||||
result,
|
||||
), nil
|
||||
}
|
||||
30
api/v1/server/handlers/v1/tasks/list_events.go
Normal file
30
api/v1/server/handlers/v1/tasks/list_events.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/v1/sqlcv1"
|
||||
|
||||
transformers "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
)
|
||||
|
||||
func (t *TasksService) V1TaskEventList(ctx echo.Context, request gen.V1TaskEventListRequestObject) (gen.V1TaskEventListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
task := ctx.Get("task").(*sqlcv1.V1TasksOlap)
|
||||
|
||||
taskRunEvents, err := t.config.V1.OLAP().ListTaskRunEvents(ctx.Request().Context(), tenantId, task.ID, task.InsertedAt, *request.Params.Limit, *request.Params.Offset)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := transformers.ToTaskRunEventMany(taskRunEvents, sqlchelpers.UUIDToStr(task.ExternalID))
|
||||
|
||||
return gen.V1TaskEventList200JSONResponse(
|
||||
result,
|
||||
), nil
|
||||
}
|
||||
47
api/v1/server/handlers/v1/tasks/list_logs.go
Normal file
47
api/v1/server/handlers/v1/tasks/list_logs.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
v1 "github.com/hatchet-dev/hatchet/pkg/repository/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/v1/sqlcv1"
|
||||
|
||||
transformers "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
)
|
||||
|
||||
func (t *TasksService) V1LogLineList(ctx echo.Context, request gen.V1LogLineListRequestObject) (gen.V1LogLineListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
task := ctx.Get("task").(*sqlcv1.V1TasksOlap)
|
||||
|
||||
logLines, err := t.config.V1.Logs().ListLogLines(ctx.Request().Context(), tenantId, task.ID, task.InsertedAt, &v1.ListLogsOpts{})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows := make([]gen.V1LogLine, len(logLines))
|
||||
|
||||
for i, log := range logLines {
|
||||
rows[i] = *transformers.ToV1LogLine(log)
|
||||
}
|
||||
|
||||
// use the total rows and limit to calculate the total pages
|
||||
totalPages := int64(1)
|
||||
currPage := int64(1)
|
||||
nextPage := int64(1)
|
||||
|
||||
return gen.V1LogLineList200JSONResponse(
|
||||
gen.V1LogLineList{
|
||||
Rows: &rows,
|
||||
Pagination: &gen.PaginationResponse{
|
||||
NumPages: &totalPages,
|
||||
CurrentPage: &currPage,
|
||||
NextPage: &nextPage,
|
||||
},
|
||||
},
|
||||
), nil
|
||||
}
|
||||
74
api/v1/server/handlers/v1/tasks/replay.go
Normal file
74
api/v1/server/handlers/v1/tasks/replay.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/internal/services/admin/contracts/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
)
|
||||
|
||||
func (t *TasksService) V1TaskReplay(ctx echo.Context, request gen.V1TaskReplayRequestObject) (gen.V1TaskReplayResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
|
||||
var err error
|
||||
|
||||
grpcReq := &contracts.ReplayTasksRequest{}
|
||||
|
||||
if request.Body.ExternalIds != nil {
|
||||
externalIds := make([]string, 0)
|
||||
|
||||
for _, id := range *request.Body.ExternalIds {
|
||||
externalIds = append(externalIds, id.String())
|
||||
}
|
||||
|
||||
grpcReq.ExternalIds = externalIds
|
||||
}
|
||||
|
||||
if request.Body.Filter != nil {
|
||||
filter := &contracts.TasksFilter{
|
||||
Since: timestamppb.New(request.Body.Filter.Since),
|
||||
}
|
||||
|
||||
if request.Body.Filter.Until != nil {
|
||||
filter.Until = timestamppb.New(*request.Body.Filter.Until)
|
||||
}
|
||||
|
||||
if request.Body.Filter.Statuses != nil {
|
||||
filter.Statuses = make([]string, len(*request.Body.Filter.Statuses))
|
||||
|
||||
for i, status := range *request.Body.Filter.Statuses {
|
||||
filter.Statuses[i] = string(status)
|
||||
}
|
||||
}
|
||||
|
||||
if request.Body.Filter.WorkflowIds != nil {
|
||||
filter.WorkflowIds = make([]string, len(*request.Body.Filter.WorkflowIds))
|
||||
|
||||
for i, id := range *request.Body.Filter.WorkflowIds {
|
||||
filter.WorkflowIds[i] = id.String()
|
||||
}
|
||||
}
|
||||
|
||||
if request.Body.Filter.AdditionalMetadata != nil {
|
||||
filter.AdditionalMetadata = make([]string, len(*request.Body.Filter.AdditionalMetadata))
|
||||
|
||||
copy(filter.AdditionalMetadata, *request.Body.Filter.AdditionalMetadata)
|
||||
}
|
||||
|
||||
grpcReq.Filter = filter
|
||||
}
|
||||
|
||||
_, err = t.proxyReplay.Do(
|
||||
ctx.Request().Context(),
|
||||
tenant,
|
||||
grpcReq,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gen.V1TaskReplay200Response{}, nil
|
||||
}
|
||||
33
api/v1/server/handlers/v1/tasks/service.go
Normal file
33
api/v1/server/handlers/v1/tasks/service.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/handlers/v1/proxy"
|
||||
admincontracts "github.com/hatchet-dev/hatchet/internal/services/admin/contracts/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/server"
|
||||
|
||||
client "github.com/hatchet-dev/hatchet/pkg/client/v1"
|
||||
)
|
||||
|
||||
type TasksService struct {
|
||||
config *server.ServerConfig
|
||||
proxyCancel *proxy.Proxy[admincontracts.CancelTasksRequest, admincontracts.CancelTasksResponse]
|
||||
proxyReplay *proxy.Proxy[admincontracts.ReplayTasksRequest, admincontracts.ReplayTasksResponse]
|
||||
}
|
||||
|
||||
func NewTasksService(config *server.ServerConfig) *TasksService {
|
||||
proxyCancel := proxy.NewProxy(config, func(ctx context.Context, cli *client.GRPCClient, in *admincontracts.CancelTasksRequest) (*admincontracts.CancelTasksResponse, error) {
|
||||
return cli.Admin().CancelTasks(ctx, in)
|
||||
})
|
||||
|
||||
proxyReplay := proxy.NewProxy(config, func(ctx context.Context, cli *client.GRPCClient, in *admincontracts.ReplayTasksRequest) (*admincontracts.ReplayTasksResponse, error) {
|
||||
return cli.Admin().ReplayTasks(ctx, in)
|
||||
})
|
||||
|
||||
return &TasksService{
|
||||
config: config,
|
||||
proxyCancel: proxyCancel,
|
||||
proxyReplay: proxyReplay,
|
||||
}
|
||||
}
|
||||
92
api/v1/server/handlers/v1/workflow-runs/get.go
Normal file
92
api/v1/server/handlers/v1/workflow-runs/get.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package workflowruns
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
v1 "github.com/hatchet-dev/hatchet/pkg/repository/v1"
|
||||
|
||||
transformers "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
)
|
||||
|
||||
func (t *V1WorkflowRunsService) V1WorkflowRunGet(ctx echo.Context, request gen.V1WorkflowRunGetRequestObject) (gen.V1WorkflowRunGetResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
rawWorkflowRun := ctx.Get("v1-workflow-run").(*v1.V1WorkflowRunPopulator)
|
||||
|
||||
requestContext := ctx.Request().Context()
|
||||
|
||||
details, err := t.getWorkflowRunDetails(
|
||||
requestContext,
|
||||
tenantId,
|
||||
rawWorkflowRun,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Search for api errors to see how we handle errors in other cases
|
||||
return gen.V1WorkflowRunGet200JSONResponse(
|
||||
*details,
|
||||
), nil
|
||||
}
|
||||
|
||||
func (t *V1WorkflowRunsService) getWorkflowRunDetails(
|
||||
ctx context.Context,
|
||||
tenantId string,
|
||||
rawWorkflowRun *v1.V1WorkflowRunPopulator,
|
||||
) (*gen.V1WorkflowRunDetails, error) {
|
||||
workflowRun := rawWorkflowRun.WorkflowRun
|
||||
taskMetadata := rawWorkflowRun.TaskMetadata
|
||||
workflowRunId := workflowRun.ExternalID
|
||||
|
||||
taskRunEvents, err := t.config.V1.OLAP().ListTaskRunEventsByWorkflowRunId(
|
||||
ctx,
|
||||
tenantId,
|
||||
workflowRunId,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tasks, err := t.config.V1.OLAP().ListTasksByIdAndInsertedAt(
|
||||
ctx,
|
||||
tenantId,
|
||||
taskMetadata,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stepIdToTaskExternalId := make(map[pgtype.UUID]pgtype.UUID)
|
||||
for _, task := range tasks {
|
||||
stepIdToTaskExternalId[task.StepID] = task.ExternalID
|
||||
}
|
||||
|
||||
workflowVersionId := uuid.MustParse(sqlchelpers.UUIDToStr(workflowRun.WorkflowVersionId))
|
||||
|
||||
shape, err := t.config.APIRepository.WorkflowRun().GetWorkflowRunShape(
|
||||
ctx, workflowVersionId,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := transformers.ToWorkflowRunDetails(taskRunEvents, workflowRun, shape, tasks, stepIdToTaskExternalId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
37
api/v1/server/handlers/v1/workflow-runs/list-task-events.go
Normal file
37
api/v1/server/handlers/v1/workflow-runs/list-task-events.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package workflowruns
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
v1 "github.com/hatchet-dev/hatchet/pkg/repository/v1"
|
||||
|
||||
transformers "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
)
|
||||
|
||||
func (t *V1WorkflowRunsService) V1WorkflowRunTaskEventsList(ctx echo.Context, request gen.V1WorkflowRunTaskEventsListRequestObject) (gen.V1WorkflowRunTaskEventsListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
rawWorkflowRun := ctx.Get("v1-workflow-run").(*v1.V1WorkflowRunPopulator)
|
||||
|
||||
workflowRun := rawWorkflowRun.WorkflowRun
|
||||
|
||||
taskRunEvents, err := t.config.V1.OLAP().ListTaskRunEventsByWorkflowRunId(
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
workflowRun.ExternalID,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := transformers.ToWorkflowRunTaskRunEventsMany(taskRunEvents)
|
||||
|
||||
// Search for api errors to see how we handle errors in other cases
|
||||
return gen.V1WorkflowRunTaskEventsList200JSONResponse(
|
||||
result,
|
||||
), nil
|
||||
}
|
||||
281
api/v1/server/handlers/v1/workflow-runs/list.go
Normal file
281
api/v1/server/handlers/v1/workflow-runs/list.go
Normal file
@@ -0,0 +1,281 @@
|
||||
package workflowruns
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgtype"
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
v1 "github.com/hatchet-dev/hatchet/pkg/repository/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/v1/sqlcv1"
|
||||
|
||||
transformers "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
)
|
||||
|
||||
func (t *V1WorkflowRunsService) WithDags(ctx echo.Context, request gen.V1WorkflowRunListRequestObject) (gen.V1WorkflowRunListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
var (
|
||||
statuses = []sqlcv1.V1ReadableStatusOlap{
|
||||
sqlcv1.V1ReadableStatusOlapQUEUED,
|
||||
sqlcv1.V1ReadableStatusOlapRUNNING,
|
||||
sqlcv1.V1ReadableStatusOlapFAILED,
|
||||
sqlcv1.V1ReadableStatusOlapCOMPLETED,
|
||||
sqlcv1.V1ReadableStatusOlapCANCELLED,
|
||||
}
|
||||
since = request.Params.Since
|
||||
workflowIds = []uuid.UUID{}
|
||||
limit int64 = 50
|
||||
offset int64
|
||||
)
|
||||
|
||||
if request.Params.Statuses != nil {
|
||||
if len(*request.Params.Statuses) > 0 {
|
||||
statuses = []sqlcv1.V1ReadableStatusOlap{}
|
||||
for _, status := range *request.Params.Statuses {
|
||||
statuses = append(statuses, sqlcv1.V1ReadableStatusOlap(status))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if request.Params.Limit != nil {
|
||||
limit = *request.Params.Limit
|
||||
}
|
||||
|
||||
if request.Params.Offset != nil {
|
||||
offset = *request.Params.Offset
|
||||
}
|
||||
|
||||
if request.Params.WorkflowIds != nil {
|
||||
workflowIds = *request.Params.WorkflowIds
|
||||
}
|
||||
|
||||
opts := v1.ListWorkflowRunOpts{
|
||||
CreatedAfter: since,
|
||||
Statuses: statuses,
|
||||
WorkflowIds: workflowIds,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
}
|
||||
|
||||
additionalMetadataFilters := make(map[string]interface{})
|
||||
|
||||
if request.Params.AdditionalMetadata != nil {
|
||||
for _, v := range *request.Params.AdditionalMetadata {
|
||||
kv_pairs := strings.Split(v, ":")
|
||||
if len(kv_pairs) == 2 {
|
||||
additionalMetadataFilters[kv_pairs[0]] = kv_pairs[1]
|
||||
}
|
||||
}
|
||||
|
||||
opts.AdditionalMetadata = additionalMetadataFilters
|
||||
}
|
||||
|
||||
if request.Params.Until != nil {
|
||||
opts.FinishedBefore = request.Params.Until
|
||||
}
|
||||
|
||||
if request.Params.ParentTaskExternalId != nil {
|
||||
parentTaskExternalId := request.Params.ParentTaskExternalId.String()
|
||||
id := sqlchelpers.UUIDFromStr(parentTaskExternalId)
|
||||
opts.ParentTaskExternalId = &id
|
||||
}
|
||||
|
||||
dags, total, err := t.config.V1.OLAP().ListWorkflowRuns(
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
opts,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dagExternalIds := make([]pgtype.UUID, 0)
|
||||
|
||||
for _, dag := range dags {
|
||||
if dag.Kind == sqlcv1.V1RunKindDAG {
|
||||
dagExternalIds = append(dagExternalIds, dag.ExternalID)
|
||||
}
|
||||
}
|
||||
|
||||
tasks, taskIdToDagExternalId, err := t.config.V1.OLAP().ListTasksByDAGId(
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
dagExternalIds,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pgWorkflowIds := make([]pgtype.UUID, 0)
|
||||
|
||||
for _, wf := range dags {
|
||||
pgWorkflowIds = append(pgWorkflowIds, wf.WorkflowID)
|
||||
}
|
||||
|
||||
workflowNames, err := t.config.V1.Workflows().ListWorkflowNamesByIds(
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
pgWorkflowIds,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
taskIdToWorkflowName := make(map[int64]string)
|
||||
|
||||
for _, task := range tasks {
|
||||
if name, ok := workflowNames[task.WorkflowID]; ok {
|
||||
taskIdToWorkflowName[task.ID] = name
|
||||
}
|
||||
}
|
||||
|
||||
parsedTasks := transformers.TaskRunDataRowToWorkflowRunsMany(tasks, taskIdToWorkflowName, total, limit, offset)
|
||||
|
||||
dagChildren := make(map[uuid.UUID][]gen.V1TaskSummary)
|
||||
|
||||
for _, task := range parsedTasks.Rows {
|
||||
dagExternalId := taskIdToDagExternalId[int64(task.TaskId)]
|
||||
existing, ok := dagChildren[dagExternalId]
|
||||
|
||||
if ok {
|
||||
dagChildren[dagExternalId] = append(existing, task)
|
||||
} else {
|
||||
dagChildren[dagExternalId] = []gen.V1TaskSummary{task}
|
||||
}
|
||||
}
|
||||
|
||||
result := transformers.ToWorkflowRunMany(dags, dagChildren, workflowNames, total, limit, offset)
|
||||
|
||||
// Search for api errors to see how we handle errors in other cases
|
||||
return gen.V1WorkflowRunList200JSONResponse(
|
||||
result,
|
||||
), nil
|
||||
}
|
||||
|
||||
func (t *V1WorkflowRunsService) OnlyTasks(ctx echo.Context, request gen.V1WorkflowRunListRequestObject) (gen.V1WorkflowRunListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
var (
|
||||
statuses = []sqlcv1.V1ReadableStatusOlap{
|
||||
sqlcv1.V1ReadableStatusOlapQUEUED,
|
||||
sqlcv1.V1ReadableStatusOlapRUNNING,
|
||||
sqlcv1.V1ReadableStatusOlapFAILED,
|
||||
sqlcv1.V1ReadableStatusOlapCOMPLETED,
|
||||
sqlcv1.V1ReadableStatusOlapCANCELLED,
|
||||
}
|
||||
since = request.Params.Since
|
||||
workflowIds = []uuid.UUID{}
|
||||
limit int64 = 50
|
||||
offset int64
|
||||
)
|
||||
|
||||
if request.Params.Statuses != nil {
|
||||
if len(*request.Params.Statuses) > 0 {
|
||||
statuses = []sqlcv1.V1ReadableStatusOlap{}
|
||||
for _, status := range *request.Params.Statuses {
|
||||
statuses = append(statuses, sqlcv1.V1ReadableStatusOlap(status))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if request.Params.Limit != nil {
|
||||
limit = *request.Params.Limit
|
||||
}
|
||||
|
||||
if request.Params.Offset != nil {
|
||||
offset = *request.Params.Offset
|
||||
}
|
||||
|
||||
if request.Params.WorkflowIds != nil {
|
||||
workflowIds = *request.Params.WorkflowIds
|
||||
}
|
||||
|
||||
opts := v1.ListTaskRunOpts{
|
||||
CreatedAfter: since,
|
||||
Statuses: statuses,
|
||||
WorkflowIds: workflowIds,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
WorkerId: request.Params.WorkerId,
|
||||
}
|
||||
|
||||
additionalMetadataFilters := make(map[string]interface{})
|
||||
|
||||
if request.Params.AdditionalMetadata != nil {
|
||||
for _, v := range *request.Params.AdditionalMetadata {
|
||||
kv_pairs := strings.Split(v, ":")
|
||||
if len(kv_pairs) == 2 {
|
||||
additionalMetadataFilters[kv_pairs[0]] = kv_pairs[1]
|
||||
}
|
||||
}
|
||||
|
||||
opts.AdditionalMetadata = additionalMetadataFilters
|
||||
}
|
||||
|
||||
if request.Params.Until != nil {
|
||||
opts.FinishedBefore = request.Params.Until
|
||||
}
|
||||
|
||||
tasks, total, err := t.config.V1.OLAP().ListTasks(
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
opts,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
taskIdToWorkflowName := make(map[int64]string)
|
||||
|
||||
result := transformers.TaskRunDataRowToWorkflowRunsMany(tasks, taskIdToWorkflowName, total, limit, offset)
|
||||
|
||||
// Search for api errors to see how we handle errors in other cases
|
||||
return gen.V1WorkflowRunList200JSONResponse(
|
||||
result,
|
||||
), nil
|
||||
}
|
||||
|
||||
func (t *V1WorkflowRunsService) V1WorkflowRunList(ctx echo.Context, request gen.V1WorkflowRunListRequestObject) (gen.V1WorkflowRunListResponseObject, error) {
|
||||
if request.Params.OnlyTasks {
|
||||
return t.OnlyTasks(ctx, request)
|
||||
} else {
|
||||
return t.WithDags(ctx, request)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *V1WorkflowRunsService) V1WorkflowRunDisplayNamesList(ctx echo.Context, request gen.V1WorkflowRunDisplayNamesListRequestObject) (gen.V1WorkflowRunDisplayNamesListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
|
||||
externalIds := make([]pgtype.UUID, len(request.Params.ExternalIds))
|
||||
|
||||
for i, id := range request.Params.ExternalIds {
|
||||
externalIds[i] = sqlchelpers.UUIDFromStr(id.String())
|
||||
}
|
||||
|
||||
displayNames, err := t.config.V1.OLAP().ListWorkflowRunDisplayNames(
|
||||
ctx.Request().Context(),
|
||||
tenant.ID,
|
||||
externalIds,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result := transformers.ToWorkflowRunDisplayNamesList(displayNames)
|
||||
|
||||
return gen.V1WorkflowRunDisplayNamesList200JSONResponse(
|
||||
result,
|
||||
), nil
|
||||
}
|
||||
27
api/v1/server/handlers/v1/workflow-runs/service.go
Normal file
27
api/v1/server/handlers/v1/workflow-runs/service.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package workflowruns
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/handlers/v1/proxy"
|
||||
admincontracts "github.com/hatchet-dev/hatchet/internal/services/admin/contracts/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/config/server"
|
||||
|
||||
client "github.com/hatchet-dev/hatchet/pkg/client/v1"
|
||||
)
|
||||
|
||||
type V1WorkflowRunsService struct {
|
||||
config *server.ServerConfig
|
||||
proxyTrigger *proxy.Proxy[admincontracts.TriggerWorkflowRunRequest, admincontracts.TriggerWorkflowRunResponse]
|
||||
}
|
||||
|
||||
func NewV1WorkflowRunsService(config *server.ServerConfig) *V1WorkflowRunsService {
|
||||
proxyTrigger := proxy.NewProxy(config, func(ctx context.Context, cli *client.GRPCClient, in *admincontracts.TriggerWorkflowRunRequest) (*admincontracts.TriggerWorkflowRunResponse, error) {
|
||||
return cli.Admin().TriggerWorkflowRun(ctx, in)
|
||||
})
|
||||
|
||||
return &V1WorkflowRunsService{
|
||||
config: config,
|
||||
proxyTrigger: proxyTrigger,
|
||||
}
|
||||
}
|
||||
118
api/v1/server/handlers/v1/workflow-runs/trigger.go
Normal file
118
api/v1/server/handlers/v1/workflow-runs/trigger.go
Normal file
@@ -0,0 +1,118 @@
|
||||
package workflowruns
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jackc/pgx/v5"
|
||||
"github.com/labstack/echo/v4"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/apierrors"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/internal/services/admin/contracts/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
v1 "github.com/hatchet-dev/hatchet/pkg/repository/v1"
|
||||
)
|
||||
|
||||
func (t *V1WorkflowRunsService) V1WorkflowRunCreate(ctx echo.Context, request gen.V1WorkflowRunCreateRequestObject) (gen.V1WorkflowRunCreateResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
// make sure input can be marshalled and unmarshalled to input type
|
||||
inputBytes, err := json.Marshal(request.Body.Input)
|
||||
|
||||
if err != nil {
|
||||
return gen.V1WorkflowRunCreate400JSONResponse(
|
||||
apierrors.NewAPIErrors("Invalid input"),
|
||||
), nil
|
||||
}
|
||||
|
||||
var additionalMetadataBytes []byte
|
||||
|
||||
if request.Body.AdditionalMetadata != nil {
|
||||
|
||||
additionalMetadataBytes, err = json.Marshal(request.Body.AdditionalMetadata)
|
||||
|
||||
if err != nil {
|
||||
return gen.V1WorkflowRunCreate400JSONResponse(
|
||||
apierrors.NewAPIErrors("Invalid additional metadata"),
|
||||
), nil
|
||||
}
|
||||
}
|
||||
|
||||
grpcReq := &contracts.TriggerWorkflowRunRequest{
|
||||
WorkflowName: request.Body.WorkflowName,
|
||||
Input: inputBytes,
|
||||
AdditionalMetadata: additionalMetadataBytes,
|
||||
}
|
||||
|
||||
resp, err := t.proxyTrigger.Do(
|
||||
ctx.Request().Context(),
|
||||
tenant,
|
||||
grpcReq,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
if e, ok := status.FromError(err); ok {
|
||||
switch e.Code() { // nolint: gocritic
|
||||
case codes.InvalidArgument:
|
||||
return gen.V1WorkflowRunCreate400JSONResponse(
|
||||
apierrors.NewAPIErrors(e.Message()),
|
||||
), nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// loop for workflow to be created in the OLAP database
|
||||
var rawWorkflowRun *v1.V1WorkflowRunPopulator
|
||||
retries := 0
|
||||
|
||||
for retries < 10 {
|
||||
rawWorkflowRun, err = t.config.V1.OLAP().ReadWorkflowRun(
|
||||
ctx.Request().Context(),
|
||||
sqlchelpers.UUIDFromStr(resp.ExternalId),
|
||||
)
|
||||
|
||||
if err != nil && !errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err != nil && errors.Is(err, pgx.ErrNoRows) {
|
||||
retries++
|
||||
time.Sleep(1 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
if rawWorkflowRun == nil || rawWorkflowRun.WorkflowRun == nil {
|
||||
return nil, fmt.Errorf("rawWorkflowRun not populated, we are likely seeing high latency in creating tasks")
|
||||
}
|
||||
|
||||
if sqlchelpers.UUIDToStr(rawWorkflowRun.WorkflowRun.TenantID) != tenantId {
|
||||
return nil, fmt.Errorf("tenantId mismatch in the triggered workflow run")
|
||||
}
|
||||
|
||||
details, err := t.getWorkflowRunDetails(
|
||||
ctx.Request().Context(),
|
||||
tenantId,
|
||||
rawWorkflowRun,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Search for api errors to see how we handle errors in other cases
|
||||
return gen.V1WorkflowRunCreate200JSONResponse(
|
||||
*details,
|
||||
), nil
|
||||
}
|
||||
@@ -10,11 +10,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/random"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (i *WebhookWorkersService) WebhookCreate(ctx echo.Context, request gen.WebhookCreateRequestObject) (gen.WebhookCreateResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
var secret string
|
||||
if request.Body.Secret == nil {
|
||||
@@ -27,13 +29,13 @@ func (i *WebhookWorkersService) WebhookCreate(ctx echo.Context, request gen.Webh
|
||||
secret = *request.Body.Secret
|
||||
}
|
||||
|
||||
encSecret, err := i.config.Encryption.EncryptString(secret, tenant.ID)
|
||||
encSecret, err := i.config.Encryption.EncryptString(secret, tenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ww, err := i.config.EngineRepository.WebhookWorker().CreateWebhookWorker(ctx.Request().Context(), &repository.CreateWebhookWorkerOpts{
|
||||
TenantId: tenant.ID,
|
||||
TenantId: tenantId,
|
||||
Name: request.Body.Name,
|
||||
URL: request.Body.Url,
|
||||
Secret: encSecret,
|
||||
|
||||
@@ -4,14 +4,16 @@ import (
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (i *WebhookWorkersService) WebhookDelete(ctx echo.Context, request gen.WebhookDeleteRequestObject) (gen.WebhookDeleteResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
webhook := ctx.Get("webhook").(*db.WebhookWorkerModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
webhook := ctx.Get("webhook").(*dbsqlc.WebhookWorker)
|
||||
|
||||
err := i.config.EngineRepository.WebhookWorker().SoftDeleteWebhookWorker(ctx.Request().Context(), webhook.ID, tenant.ID)
|
||||
err := i.config.EngineRepository.WebhookWorker().SoftDeleteWebhookWorker(ctx.Request().Context(), sqlchelpers.UUIDToStr(webhook.ID), tenantId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -7,13 +7,15 @@ import (
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (i *WebhookWorkersService) WebhookList(ctx echo.Context, request gen.WebhookListRequestObject) (gen.WebhookListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
webhooks, err := i.config.EngineRepository.WebhookWorker().ListActiveWebhookWorkers(context.Background(), tenant.ID)
|
||||
webhooks, err := i.config.EngineRepository.WebhookWorker().ListActiveWebhookWorkers(context.Background(), tenantId)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
transformersv1 "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *WorkerService) WorkerGet(ctx echo.Context, request gen.WorkerGetRequestObject) (gen.WorkerGetResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
|
||||
switch tenant.Version {
|
||||
case dbsqlc.TenantMajorEngineVersionV0:
|
||||
return t.workerGetV0(ctx, tenant, request)
|
||||
case dbsqlc.TenantMajorEngineVersionV1:
|
||||
return t.workerGetV1(ctx, tenant, request)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported tenant version: %s", string(tenant.Version))
|
||||
}
|
||||
}
|
||||
|
||||
func (t *WorkerService) workerGetV0(ctx echo.Context, tenant *dbsqlc.Tenant, request gen.WorkerGetRequestObject) (gen.WorkerGetResponseObject, error) {
|
||||
worker := ctx.Get("worker").(*dbsqlc.GetWorkerByIdRow)
|
||||
|
||||
slotState, recent, err := t.config.APIRepository.Worker().ListWorkerState(
|
||||
@@ -63,3 +79,64 @@ func (t *WorkerService) WorkerGet(ctx echo.Context, request gen.WorkerGetRequest
|
||||
|
||||
return gen.WorkerGet200JSONResponse(workerResp), nil
|
||||
}
|
||||
|
||||
func (t *WorkerService) workerGetV1(ctx echo.Context, tenant *dbsqlc.Tenant, request gen.WorkerGetRequestObject) (gen.WorkerGetResponseObject, error) {
|
||||
workerV0 := ctx.Get("worker").(*dbsqlc.GetWorkerByIdRow)
|
||||
|
||||
worker, err := t.config.V1.Workers().GetWorkerById(sqlchelpers.UUIDToStr(workerV0.Worker.ID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
slotState, recent, err := t.config.V1.Workers().ListWorkerState(
|
||||
sqlchelpers.UUIDToStr(worker.Worker.TenantId),
|
||||
sqlchelpers.UUIDToStr(worker.Worker.ID),
|
||||
int(worker.Worker.MaxRuns),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
actions, err := t.config.APIRepository.Worker().GetWorkerActionsByWorkerId(
|
||||
sqlchelpers.UUIDToStr(worker.Worker.TenantId),
|
||||
sqlchelpers.UUIDToStr(worker.Worker.ID),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respStepRuns := make([]gen.RecentStepRuns, len(recent))
|
||||
|
||||
for i := range recent {
|
||||
genStepRun, err := transformers.ToRecentStepRun(recent[i])
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
respStepRuns[i] = *genStepRun
|
||||
}
|
||||
|
||||
slots := int(worker.RemainingSlots)
|
||||
|
||||
workerResp := *transformersv1.ToWorkerSqlc(&worker.Worker, &slots, &worker.WebhookUrl.String, actions)
|
||||
|
||||
workerResp.RecentStepRuns = &respStepRuns
|
||||
workerResp.Slots = transformersv1.ToSlotState(slotState, slots)
|
||||
|
||||
affinity, err := t.config.APIRepository.Worker().ListWorkerLabels(
|
||||
sqlchelpers.UUIDToStr(worker.Worker.TenantId),
|
||||
sqlchelpers.UUIDToStr(worker.Worker.ID),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
workerResp.Labels = transformers.ToWorkerLabels(affinity)
|
||||
|
||||
return gen.WorkerGet200JSONResponse(workerResp), nil
|
||||
}
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
package workers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
transformersv1 "github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers/v1"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *WorkerService) WorkerList(ctx echo.Context, request gen.WorkerListRequestObject) (gen.WorkerListResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
|
||||
switch tenant.Version {
|
||||
case dbsqlc.TenantMajorEngineVersionV0:
|
||||
return t.workerListV0(ctx, tenant, request)
|
||||
case dbsqlc.TenantMajorEngineVersionV1:
|
||||
return t.workerListV1(ctx, tenant, request)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported tenant version: %s", string(tenant.Version))
|
||||
}
|
||||
}
|
||||
|
||||
func (t *WorkerService) workerListV0(ctx echo.Context, tenant *dbsqlc.Tenant, request gen.WorkerListRequestObject) (gen.WorkerListResponseObject, error) {
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
sixSecAgo := time.Now().Add(-24 * time.Hour)
|
||||
|
||||
workers, err := t.config.APIRepository.Worker().ListWorkers(tenant.ID, &repository.ListWorkersOpts{
|
||||
workers, err := t.config.APIRepository.Worker().ListWorkers(tenantId, &repository.ListWorkersOpts{
|
||||
LastHeartbeatAfter: &sixSecAgo,
|
||||
})
|
||||
|
||||
@@ -39,3 +55,32 @@ func (t *WorkerService) WorkerList(ctx echo.Context, request gen.WorkerListReque
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (t *WorkerService) workerListV1(ctx echo.Context, tenant *dbsqlc.Tenant, request gen.WorkerListRequestObject) (gen.WorkerListResponseObject, error) {
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
sixSecAgo := time.Now().Add(-24 * time.Hour)
|
||||
|
||||
workers, err := t.config.V1.Workers().ListWorkers(tenantId, &repository.ListWorkersOpts{
|
||||
LastHeartbeatAfter: &sixSecAgo,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows := make([]gen.Worker, len(workers))
|
||||
|
||||
for i, worker := range workers {
|
||||
workerCp := worker
|
||||
slots := int(worker.RemainingSlots)
|
||||
|
||||
rows[i] = *transformersv1.ToWorkerSqlc(&workerCp.Worker, &slots, &workerCp.WebhookUrl.String, nil)
|
||||
}
|
||||
|
||||
return gen.WorkerList200JSONResponse(
|
||||
gen.WorkerList{
|
||||
Rows: &rows,
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/gen"
|
||||
"github.com/hatchet-dev/hatchet/api/v1/server/oas/transformers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *WorkerService) WorkerUpdate(ctx echo.Context, request gen.WorkerUpdateRequestObject) (gen.WorkerUpdateResponseObject, error) {
|
||||
|
||||
@@ -12,12 +12,13 @@ import (
|
||||
"github.com/hatchet-dev/hatchet/internal/msgqueue"
|
||||
"github.com/hatchet-dev/hatchet/internal/services/shared/tasktypes"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/db"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/prisma/sqlchelpers"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/dbsqlc"
|
||||
"github.com/hatchet-dev/hatchet/pkg/repository/postgres/sqlchelpers"
|
||||
)
|
||||
|
||||
func (t *WorkflowRunsService) WorkflowRunUpdateReplay(ctx echo.Context, request gen.WorkflowRunUpdateReplayRequestObject) (gen.WorkflowRunUpdateReplayResponseObject, error) {
|
||||
tenant := ctx.Get("tenant").(*db.TenantModel)
|
||||
tenant := ctx.Get("tenant").(*dbsqlc.Tenant)
|
||||
tenantId := sqlchelpers.UUIDToStr(tenant.ID)
|
||||
|
||||
workflowRunIds := make([]string, len(request.Body.WorkflowRunIds))
|
||||
|
||||
@@ -28,7 +29,7 @@ func (t *WorkflowRunsService) WorkflowRunUpdateReplay(ctx echo.Context, request
|
||||
limit := 500
|
||||
|
||||
// make sure all workflow runs belong to the tenant
|
||||
filteredWorkflowRuns, err := t.config.EngineRepository.WorkflowRun().ListWorkflowRuns(ctx.Request().Context(), tenant.ID, &repository.ListWorkflowRunsOpts{
|
||||
filteredWorkflowRuns, err := t.config.EngineRepository.WorkflowRun().ListWorkflowRuns(ctx.Request().Context(), tenantId, &repository.ListWorkflowRunsOpts{
|
||||
Ids: workflowRunIds,
|
||||
Limit: &limit,
|
||||
})
|
||||
@@ -44,7 +45,7 @@ func (t *WorkflowRunsService) WorkflowRunUpdateReplay(ctx echo.Context, request
|
||||
err = t.config.MessageQueue.AddMessage(
|
||||
ctx.Request().Context(),
|
||||
msgqueue.WORKFLOW_PROCESSING_QUEUE,
|
||||
tasktypes.WorkflowRunReplayToTask(tenant.ID, sqlchelpers.UUIDToStr(filteredWorkflowRuns.Rows[i].WorkflowRun.ID)),
|
||||
tasktypes.WorkflowRunReplayToTask(tenantId, sqlchelpers.UUIDToStr(filteredWorkflowRuns.Rows[i].WorkflowRun.ID)),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
@@ -59,7 +60,7 @@ func (t *WorkflowRunsService) WorkflowRunUpdateReplay(ctx echo.Context, request
|
||||
dbCtx, cancel := context.WithTimeout(ctx.Request().Context(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
||||
newWorkflowRuns, err := t.config.APIRepository.WorkflowRun().ListWorkflowRuns(dbCtx, tenant.ID, &repository.ListWorkflowRunsOpts{
|
||||
newWorkflowRuns, err := t.config.APIRepository.WorkflowRun().ListWorkflowRuns(dbCtx, tenantId, &repository.ListWorkflowRunsOpts{
|
||||
Ids: workflowRunIds,
|
||||
Limit: &limit,
|
||||
})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user