Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,6 @@ jobs:
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
GO_VERSION=1.26.5
GO_VERSION=1.26.6
SENTINEL_HARNESS_BASE_IMAGE_REPO=ghcr.io/pluralsh/sentinel-harness-base
SENTINEL_HARNESS_BASE_IMAGE_TAG=${{ needs.publish-base-image.outputs.version }}
SENTINEL_HARNESS_BASE_IMAGE_TAG=${{ needs.publish-base-image.outputs.version }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/.idea
/.vscode/**/*
!/.vscode/settings.json
/.codex

# System
.DS_Store
Expand Down
4 changes: 3 additions & 1 deletion charts/console/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -637,8 +637,10 @@ cloudQuery:

resources:
requests:
memory: 250Mi
memory: 512Mi
cpu: 100m
limits:
memory: 1Gi

livenessProbe: ~

Expand Down
2 changes: 1 addition & 1 deletion go/ai-proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build the binary
FROM golang:1.26.5 as builder
FROM golang:1.26.6 as builder

Check warning on line 2 in go/ai-proxy/Dockerfile

View workflow job for this annotation

GitHub Actions / Build ai-proxy image (linux/arm64, ubuntu-24.04-arm)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/

Check warning on line 2 in go/ai-proxy/Dockerfile

View workflow job for this annotation

GitHub Actions / Build ai-proxy image (linux/amd64, ubuntu-24.04)

The 'as' keyword should match the case of the 'from' keyword

FromAsCasing: 'as' and 'FROM' keywords' casing do not match More info: https://docs.docker.com/go/dockerfile/rule/from-as-casing/
ARG TARGETOS
ARG TARGETARCH
ARG VERSION
Expand Down
16 changes: 14 additions & 2 deletions go/ai-proxy/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/pluralsh/console/go/ai-proxy

go 1.26.5
go 1.26.6

replace github.com/pluralsh/console/go/polly => ../polly

Expand Down Expand Up @@ -36,14 +36,26 @@ require (
github.com/aws/aws-sdk-go-v2/service/sts v1.42.2 // indirect
github.com/aws/smithy-go v1.27.1 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/buger/jsonparser v1.1.2 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/golang-jwt/jwt/v5 v5.3.1 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/mailru/easyjson v0.9.1 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/prometheus/client_golang v1.23.2 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.1 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
golang.org/x/crypto v0.53.0 // indirect
golang.org/x/net v0.56.0 // indirect
golang.org/x/sys v0.46.0 // indirect
golang.org/x/text v0.39.0 // indirect
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
22 changes: 17 additions & 5 deletions go/ai-proxy/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -36,37 +36,44 @@ github.com/aws/smithy-go v1.27.1 h1:4T340VFndXtADGF52gYa1POyL7s9E4Z1OeZ1hCscIw8=
github.com/aws/smithy-go v1.27.1/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk=
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk=
github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/mailru/easyjson v0.9.1 h1:LbtsOm5WAswyWbvTEOqhypdPeZzHavpZx96/n553mR8=
github.com/mailru/easyjson v0.9.1/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
github.com/ollama/ollama v0.21.1 h1:kF0PLEBucnoRDYADS1NmcQXGqC/B7M9WJy8ZyNIr/NA=
github.com/ollama/ollama v0.21.1/go.mod h1:274niu48upWz/M7vL53i1WFe+TJRRw5oo4GiacbIYrA=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.15.0 h1:D0RCU5rMAp+SpgkiNdrjfJ+LX4J1M32V2NeCY7EJ6hc=
github.com/rogpeppe/go-internal v1.15.0/go.mod h1:DrUVZyrJU+txYW5/1kwtXQSMFio52ZOxX7yM1VHvnxs=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/sigv4 v0.4.1 h1:EIc3j+8NBea9u1iV6O5ZAN8uvPq2xOIUPcqCTivHuXs=
github.com/prometheus/sigv4 v0.4.1/go.mod h1:eu+ZbRvsc5TPiHwqh77OWuCnWK73IdkETYY46P4dXOU=
github.com/rogpeppe/go-internal v1.15.0 h1:D0RCU5rMAp+SpgkiNdrjfJ+LX4J1M32V2NeCY7EJ6hc=
github.com/rogpeppe/go-internal v1.15.0/go.mod h1:DrUVZyrJU+txYW5/1kwtXQSMFio52ZOxX7yM1VHvnxs=
github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM=
github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
Expand All @@ -77,8 +84,11 @@ github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ=
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
Expand All @@ -87,9 +97,11 @@ golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus=
golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc=
Expand Down
2 changes: 1 addition & 1 deletion go/build.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.26.5
FROM golang:1.26.6

ARG MODULE_PATH

Expand Down
4 changes: 2 additions & 2 deletions go/client/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/pluralsh/console/go/client

go 1.26.5
go 1.26.6

require (
github.com/99designs/gqlgen v0.17.78
Expand Down Expand Up @@ -86,7 +86,7 @@ require (
golang.org/x/sys v0.46.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 // indirect
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect
gopkg.in/ini.v1 v1.67.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
3 changes: 1 addition & 2 deletions go/client/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,7 @@ golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhS
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d h1:wT2n40TBqFY6wiwazVK9/iTWbsQrgk5ZfCSVFLO9LQA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260406210006-6f92a3bedf2d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260414002931-afd174a4e478 h1:RmoJA1ujG+/lRGNfUnOMfhCy5EipVMyvUE+KNbPbTlw=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI=
google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
2 changes: 1 addition & 1 deletion go/cloud-query/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.26.5 AS builder
FROM golang:1.26.6 AS builder

WORKDIR /workspace

Expand Down
14 changes: 13 additions & 1 deletion go/cloud-query/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,20 @@ Cloud Query is a service part of the Plural Console ecosystem that provides clou
- Query cloud resources across multiple providers
- Embedded PostgreSQL database for data storage and retrieval through PostgreSQL FDW steampipe extension
- gRPC API for integration with other services
- Sandboxed execution for Lua and Monty's limited Python subset
- Containerized deployment for easy scaling

CloudQuery provider support includes AWS, Azure, GCP, and VMware vSphere.

## Prerequisites

- Go 1.24.2 or higher
- Go 1.26.6 or higher
- Docker (for containerized deployment)
- Make

Running the complete service locally requires a writable temporary directory.
The Python worker extracts gomonty's embedded native library there on first use.

## Getting Started

### Local Development
Expand Down Expand Up @@ -89,6 +93,14 @@ Cloud-Query also exposes ToolQuery gRPC endpoints for observability tools (metri

ToolQuery also supports cloud function invocation via `InvokeLambda` for AWS Lambda, GCP Cloud Run services (Gen2), and Azure Functions using canonical identifiers and cloud connection credentials.

### Sandboxed Python execution

`RunPython` executes Monty's limited Python subset in a crash-isolated `cloud-query python-worker` subprocess. The request's optional JSON object is available as `input`; `output` starts as an empty dictionary and must remain a JSON-serializable dictionary. The response returns that dictionary as `result_json` and standard-output text from `print()` separately as `stdout`.

This is not CPython. The sandbox has no host filesystem, environment, network, subprocess, shell, `pip`, third-party packages, or callback access. Two workers start with only `TMPDIR=/tmp`; each request gets a fresh gomonty REPL. Failed or canceled workers are killed and replaced, and healthy workers are periodically recycled. Source is limited to 64 KiB, input and result JSON to 1 MiB, stdout to 64 KiB, interpreter execution to 60 seconds, interpreter-managed memory to 100 MiB, and recursion to 100 frames. Two runs execute concurrently and up to 16 more wait in a FIFO queue. A full queue is rejected. A parent watchdog ends a run after 65 seconds or the caller's earlier deadline.

The image embeds gomonty `v0.0.14` and its platform-specific glibc library, built against official Monty commit `c9802b5f30d11fecf9f153feb1dfdab3abda070e`. It contains no separate `monty` executable. Both pins are recorded in OCI labels. Monty's memory limit covers interpreter-managed allocations rather than total pod RSS; operators should measure the workload before reducing the default cloud-query memory allocation.

### Tool Provider Credentials and Permissions

- `Dynatrace`:
Expand Down
17 changes: 17 additions & 0 deletions go/cloud-query/api/proto/toolquery.proto
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,22 @@ message RunLuaOutput {
string result_json = 1;
}

message RunPythonInput {
// Python source. Write structured results to the global `output` dictionary.
string script = 1;

// Optional JSON object exposed as the global `input` dictionary. Empty means `{}`.
string input_json = 2;
}

message RunPythonOutput {
// JSON-encoded contents of the global `output` dictionary.
string result_json = 1;

// Text emitted by print() during the user script.
string stdout = 2;
}

service ToolQuery {
rpc Metrics(MetricsQueryInput) returns (MetricsQueryOutput) {}
rpc MetricsSearch(MetricsSearchInput) returns (MetricsSearchOutput) {}
Expand All @@ -308,4 +324,5 @@ service ToolQuery {
rpc Traces(TracesQueryInput) returns (TracesQueryOutput) {}
rpc InvokeLambda(InvokeLambdaInput) returns (InvokeLambdaOutput) {}
rpc RunLua(RunLuaInput) returns (RunLuaOutput) {}
rpc RunPython(RunPythonInput) returns (RunPythonOutput) {}
}
17 changes: 13 additions & 4 deletions go/cloud-query/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/pluralsh/console/go/cloud-query/internal/pool"
"github.com/pluralsh/console/go/cloud-query/internal/server"
"github.com/pluralsh/console/go/cloud-query/internal/service"
pythontools "github.com/pluralsh/console/go/cloud-query/internal/tools/python"
)

func startHealthzHandler() {
Expand All @@ -27,9 +28,20 @@ func startHealthzHandler() {
}

func main() {
if len(os.Args) == 2 && os.Args[1] == "python-worker" {
if err := pythontools.NewWorker().Run(os.Stdin, os.Stdout); err != nil {
os.Exit(1)
}
return
}

startHealthzHandler()

services := []service.Service{service.NewToolQueryService()}
toolQueryService, err := service.NewToolQueryService(context.Background())
if err != nil {
klog.Fatalf("failed to initialize tool query service: %v", err)
}
services := []service.Service{toolQueryService}

if args.DatabaseEnabled() {
p, err := pool.NewConnectionPool(args.DatabaseConnectionTTL())
Expand Down Expand Up @@ -67,8 +79,5 @@ func handleShutdown(cancel context.CancelFunc, s *server.Server) {
<-signalChan
klog.Info("received shutdown signal, shutting down gracefully...")

s.Stop()
cancel()
klog.Info("stopped gracefully")
os.Exit(0)
}
2 changes: 1 addition & 1 deletion go/cloud-query/db.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
ARG POSTGRES_MAJOR_VERSION=15
ARG POSTGRES_VERSION=${POSTGRES_MAJOR_VERSION}.18

FROM golang:1.26.5 AS libraries
FROM golang:1.26.6 AS libraries

# Configure versions for Steampipe extensions
# Do not use latest versions here, as they may not be compatible
Expand Down
20 changes: 20 additions & 0 deletions go/cloud-query/docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,8 @@ service ToolQuery {
rpc Logs(LogsQueryInput) returns (LogsQueryOutput) {}
rpc Traces(TracesQueryInput) returns (TracesQueryOutput) {}
rpc InvokeLambda(InvokeLambdaInput) returns (InvokeLambdaOutput) {}
rpc RunLua(RunLuaInput) returns (RunLuaOutput) {}
rpc RunPython(RunPythonInput) returns (RunPythonOutput) {}
}
```

Expand Down Expand Up @@ -1507,6 +1509,24 @@ message JaegerTracesOptions {
}
```

## Run Python

`RunPython` synchronously executes Monty's limited Python subset in a fresh logical sandbox session. `input_json` is optional but, when present, must encode an object. It is exposed as the global `input`; scripts write their structured response to the global `output` dictionary. Printed text is returned separately.

```protobuf
message RunPythonInput {
string script = 1;
string input_json = 2;
}

message RunPythonOutput {
string result_json = 1;
string stdout = 2;
}
```

The runtime exposes no host filesystem, environment, network, subprocess, shell, package installation, third-party package, or host-tool callback. It limits source to 64 KiB, input and result JSON to 1 MiB, stdout to 64 KiB, execution to 60 seconds, memory to 100 MiB, recursion to 100 frames, wall time to 65 seconds, and concurrency to two runs per process. Up to 16 additional requests wait in a bounded FIFO queue. It uses gomonty `v0.0.14`, built against official Monty commit `c9802b5f30d11fecf9f153feb1dfdab3abda070e`; it is not CPython.

## Invoke Lambda

`InvokeLambda` invokes serverless functions using canonical provider identifiers only.
Expand Down
6 changes: 5 additions & 1 deletion go/cloud-query/go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/pluralsh/console/go/cloud-query

go 1.26.5
go 1.26.6

require (
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.1
Expand All @@ -18,6 +18,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/lambda v1.89.1
github.com/aws/aws-sdk-go-v2/service/sts v1.42.2
github.com/elastic/go-elasticsearch/v9 v9.3.1
github.com/ewhauser/gomonty v0.0.14
github.com/gofrs/uuid v4.4.0+incompatible
github.com/lib/pq v1.12.3
github.com/orcaman/concurrent-map/v2 v2.0.1
Expand Down Expand Up @@ -58,6 +59,7 @@ require (
github.com/aws/smithy-go v1.27.1 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/ebitengine/purego v0.10.0 // indirect
github.com/elastic/elastic-transport-go/v8 v8.8.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.3 // indirect
Expand All @@ -80,6 +82,8 @@ require (
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/procfs v0.20.1 // indirect
github.com/rogpeppe/go-internal v1.15.0 // indirect
github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
Expand Down
Loading
Loading