diff --git a/.github/workflows/check-migrations-generated.yml b/.github/workflows/check-migrations-generated.yml new file mode 100644 index 000000000..bbaf105c5 --- /dev/null +++ b/.github/workflows/check-migrations-generated.yml @@ -0,0 +1,134 @@ +name: Check Migrations Generated + +on: + pull_request: + paths: + - 'taco/internal/query/types/**' + - 'taco/atlas.hcl' + - 'taco/internal/atlas_loader.go' + workflow_dispatch: # Allows manual trigger from GitHub UI + +jobs: + check-migrations: + name: Verify Migrations Were Generated + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 # Need full history to check file changes + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + cache-dependency-path: | + taco/go.sum + go.work.sum + + - name: Install Atlas CLI + run: | + curl -sSf https://atlasgo.sh | sh + atlas version + + - name: Install Atlas GORM Provider + run: go install ariga.io/atlas-provider-gorm@latest + + - name: Check if model files changed + id: check_models + run: | + # Check if any GORM model files changed in this PR + git fetch origin ${{ github.base_ref }} + if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "taco/internal/query/types/"; then + echo "models_changed=true" >> $GITHUB_OUTPUT + echo "✋ GORM models were modified" + else + echo "models_changed=false" >> $GITHUB_OUTPUT + echo "✅ No GORM model changes detected" + fi + + - name: Check if migrations changed + id: check_migrations + if: steps.check_models.outputs.models_changed == 'true' + run: | + # Check if migration files changed in this PR + if git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -q "taco/migrations/"; then + echo "migrations_changed=true" >> $GITHUB_OUTPUT + echo "✅ Migration files were updated" + else + echo "migrations_changed=false" >> $GITHUB_OUTPUT + echo "❌ No migration files were updated" + fi + + - name: Verify migrations were committed with model changes + if: steps.check_models.outputs.models_changed == 'true' + run: | + if [ "${{ steps.check_migrations.outputs.migrations_changed }}" != "true" ]; then + echo "" + echo "❌ ERROR: Model changes detected but no migrations were committed!" + echo "" + echo "📝 You modified GORM models in taco/internal/query/types/" + echo " but didn't generate and commit corresponding migrations." + echo "" + echo "To fix this:" + echo " 1. cd taco" + echo " 2. make atlas-diff-all name=descriptive_name" + echo " 3. git add migrations/" + echo " 4. git commit" + echo "" + echo "Example:" + echo " make atlas-diff-all name=add_user_email_field" + echo "" + exit 1 + else + echo "✅ Model changes have corresponding migration files committed" + fi + + - name: Validate migration files + if: steps.check_migrations.outputs.migrations_changed == 'true' + working-directory: taco + run: | + echo "Ensuring migration checksums are up to date..." + make atlas-hash-all + + echo "Validating migration file format..." + # Just check that .sql files exist and are non-empty + for db in postgres mysql sqlite; do + if [ -d "migrations/$db" ]; then + sql_files=$(find migrations/$db -name "*.sql" -type f) + if [ -z "$sql_files" ]; then + echo "❌ No .sql files found in migrations/$db" + exit 1 + fi + echo "✅ Found migration files in migrations/$db" + fi + done + + echo "✅ All migration files validated" + + - name: Summary + if: always() + run: | + echo "## Migration Check Summary" >> $GITHUB_STEP_SUMMARY + echo "" >> $GITHUB_STEP_SUMMARY + + if [ "${{ steps.check_models.outputs.models_changed }}" = "true" ]; then + echo "- 🔄 GORM models were modified" >> $GITHUB_STEP_SUMMARY + + if [ "${{ steps.check_migrations.outputs.migrations_changed }}" = "true" ]; then + echo "- ✅ Migration files were updated" >> $GITHUB_STEP_SUMMARY + else + echo "- ℹ️ No migration files changed (no schema impact)" >> $GITHUB_STEP_SUMMARY + fi + else + echo "- ℹ️ No GORM model changes detected" >> $GITHUB_STEP_SUMMARY + fi + + echo "" >> $GITHUB_STEP_SUMMARY + echo "### How to generate migrations" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`bash" >> $GITHUB_STEP_SUMMARY + echo "cd taco" >> $GITHUB_STEP_SUMMARY + echo "make atlas-diff-all name=descriptive_name" >> $GITHUB_STEP_SUMMARY + echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + diff --git a/.github/workflows/test-migrations.yml b/.github/workflows/test-migrations.yml new file mode 100644 index 000000000..389b2ecdb --- /dev/null +++ b/.github/workflows/test-migrations.yml @@ -0,0 +1,293 @@ +name: Test Database Migrations + +on: + pull_request: + paths: + - 'taco/internal/query/types/**' + - 'taco/internal/query/migration/**' + - 'taco/internal/queryfactory/**' + - 'taco/atlas.hcl' + - 'taco/internal/atlas_loader.go' + - '.github/workflows/test-migrations.yml' + push: + branches: + - main + paths: + - 'taco/internal/query/types/**' + - 'taco/internal/query/migration/**' + - 'taco/internal/queryfactory/**' + - 'taco/atlas.hcl' + workflow_dispatch: # Allows manual trigger from GitHub UI + +jobs: + test-postgres: + name: Test PostgreSQL Migrations + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:16.1 + env: + POSTGRES_DB: taco + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + cache-dependency-path: | + taco/go.sum + go.work.sum + + - name: Install Atlas CLI + run: | + curl -sSf https://atlasgo.sh | sh + atlas version + + - name: Generate migration checksums for PostgreSQL + working-directory: taco + run: | + echo "Generating checksums for PostgreSQL migrations..." + atlas migrate hash --dir "file://migrations/postgres" + + - name: Apply migrations manually (simulating entrypoint.sh) + working-directory: taco + env: + POSTGRES_URL: postgres://postgres:postgres@localhost:5432/taco?sslmode=disable + run: | + echo "Applying PostgreSQL migrations..." + atlas migrate apply \ + --url "$POSTGRES_URL" \ + --dir "file://migrations/postgres" + + - name: Build statesman binary + working-directory: taco + run: | + CGO_ENABLED=1 go build -o statesman ./cmd/statesman + + - name: Test statesman starts successfully + working-directory: taco + env: + OPENTACO_QUERY_BACKEND: postgres + OPENTACO_POSTGRES_HOST: localhost + OPENTACO_POSTGRES_PORT: 5432 + OPENTACO_POSTGRES_USER: postgres + OPENTACO_POSTGRES_PASSWORD: postgres + OPENTACO_POSTGRES_DATABASE: taco + OPENTACO_POSTGRES_SSLMODE: disable + OPENTACO_AUTH_DISABLE: true + run: | + # Run binary and capture output + echo "Starting statesman binary..." + timeout 30s ./statesman --port 8080 --auth-disable --storage memory > statesman.log 2>&1 || true + + echo "Binary output:" + cat statesman.log + + # Give it time to start + sleep 5 + + - name: Verify statesman started successfully + working-directory: taco + run: | + # Check if statesman started successfully + if grep -i "server started\|server listening\|starting.*server" statesman.log; then + echo "✅ Postgres: Statesman started successfully after migrations" + else + echo "❌ Statesman did not start successfully" + cat statesman.log + exit 1 + fi + + test-mysql: + name: Test MySQL Migrations + runs-on: ubuntu-latest + + services: + mysql: + image: mysql:8 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: taco + MYSQL_USER: mysql + MYSQL_PASSWORD: mysql + ports: + - 3306:3306 + options: >- + --health-cmd "mysqladmin ping" + --health-interval 10s + --health-timeout 5s + --health-retries 5 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + cache-dependency-path: | + taco/go.sum + go.work.sum + + - name: Install Atlas CLI + run: | + curl -sSf https://atlasgo.sh | sh + atlas version + + - name: Generate migration checksums for MySQL + working-directory: taco + run: | + echo "Generating checksums for MySQL migrations..." + atlas migrate hash --dir "file://migrations/mysql" + + - name: Apply migrations manually (simulating entrypoint.sh) + working-directory: taco + env: + MYSQL_URL: mysql://mysql:mysql@localhost:3306/taco + run: | + echo "Applying MySQL migrations..." + atlas migrate apply \ + --url "$MYSQL_URL" \ + --dir "file://migrations/mysql" + + - name: Build statesman binary + working-directory: taco + run: | + CGO_ENABLED=1 go build -o statesman ./cmd/statesman + + - name: Test statesman starts successfully + working-directory: taco + env: + OPENTACO_QUERY_BACKEND: mysql + OPENTACO_MYSQL_HOST: localhost + OPENTACO_MYSQL_PORT: 3306 + OPENTACO_MYSQL_USER: mysql + OPENTACO_MYSQL_PASSWORD: mysql + OPENTACO_MYSQL_DATABASE: taco + OPENTACO_AUTH_DISABLE: true + OPENTACO_JWT_SECRET: test-secret-key-for-ci + run: | + # Run binary and capture output + echo "Starting statesman binary..." + timeout 30s ./statesman --port 8080 --auth-disable --storage memory > statesman.log 2>&1 || true + + echo "Binary output:" + cat statesman.log + + # Give it time to start + sleep 5 + + - name: Verify statesman started successfully + working-directory: taco + run: | + # Check if statesman started successfully + if grep -i "server started\|server listening\|starting.*server" statesman.log; then + echo "✅ MySQL: Statesman started successfully after migrations" + else + echo "❌ Statesman did not start successfully" + cat statesman.log + exit 1 + fi + + test-sqlite: + name: Test SQLite Migrations + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version: '1.22' + cache-dependency-path: | + taco/go.sum + go.work.sum + + - name: Install Atlas CLI + run: | + curl -sSf https://atlasgo.sh | sh + atlas version + + - name: Create SQLite database directory + working-directory: taco + run: | + mkdir -p .data + echo "Created .data directory for SQLite database" + + - name: Generate migration checksums for SQLite + working-directory: taco + run: | + echo "Generating checksums for SQLite migrations..." + atlas migrate hash --dir "file://migrations/sqlite" + + - name: Apply migrations manually (simulating entrypoint.sh) + working-directory: taco + run: | + echo "Applying SQLite migrations to ${{ github.workspace }}/taco/.data/test.db" + atlas migrate apply \ + --url "sqlite://${{ github.workspace }}/taco/.data/test.db" \ + --dir "file://migrations/sqlite" + + # Verify database file was created + ls -lh .data/test.db + echo "✅ Migrations applied successfully" + + - name: Build statesman binary + working-directory: taco + run: | + CGO_ENABLED=1 go build -o statesman ./cmd/statesman + + - name: Test statesman starts successfully + working-directory: taco + env: + OPENTACO_QUERY_BACKEND: sqlite + OPENTACO_SQLITE_DB_PATH: ${{ github.workspace }}/taco/.data/test.db + OPENTACO_AUTH_DISABLE: true + run: | + # Run binary and capture output + echo "Starting statesman binary..." + timeout 30s ./statesman --port 8080 --auth-disable --storage memory > statesman.log 2>&1 || true + + echo "Binary output:" + cat statesman.log + + # Give it time to start + sleep 5 + + - name: Verify statesman started successfully + working-directory: taco + run: | + # Check if statesman started successfully + if grep -i "server started\|server listening\|starting.*server" statesman.log; then + echo "✅ SQLite: Statesman started successfully after migrations" + else + echo "❌ Statesman did not start successfully" + cat statesman.log + exit 1 + fi + + # Summary job that requires all database tests to pass + all-migrations-passed: + name: All Migrations Passed + runs-on: ubuntu-latest + needs: [test-postgres, test-mysql, test-sqlite] + steps: + - name: All tests passed + run: echo "✅ All database migrations tested successfully!" + diff --git a/.gitignore b/.gitignore index bde0c9c51..e10d3e5e5 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,6 @@ data/ taco/data/ + +# Atlas migration checksums (auto-generated) +**/migrations/**/atlas.sum diff --git a/go.work.sum b/go.work.sum index 927ba0f41..634c492d4 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,5 +1,6 @@ ariga.io/atlas v0.14.3-0.20231010104048-0c071bfc9161 h1:xZS2wAf1AzRNA/8iD2LTAXtIZuIDYDXsZRlYBAyBu0A= ariga.io/atlas v0.14.3-0.20231010104048-0c071bfc9161/go.mod h1:isZrlzJ5cpoCoKFoY9knZug7Lq4pP1cm8g3XciLZ0Pw= +ariga.io/atlas v0.32.0/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w= cel.dev/expr v0.15.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= cel.dev/expr v0.16.0/go.mod h1:TRSuuV7DlVCE/uwv5QbAiW/v8l5O8C4eEPHeu7gf7Sg= cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= @@ -722,14 +723,17 @@ github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod github.com/AlecAivazis/survey/v2 v2.3.4 h1:pchTU9rsLUSvWEl2Aq9Pv3k0IE2fkqtGxazskAMd9Ng= github.com/AlecAivazis/survey/v2 v2.3.4/go.mod h1:hrV6Y/kQCLhIZXGcriDCUBtB3wnN7156gMXJ3+b23xM= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28= github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= -github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= @@ -778,6 +782,7 @@ github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjH github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= github.com/alecthomas/kong v0.7.1 h1:azoTh0IOfwlAX3qN9sHWTxACE2oV8Bg2gAwBsMwDQY4= github.com/alecthomas/kong v0.7.1/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U= +github.com/alecthomas/kong v1.9.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= @@ -1038,12 +1043,11 @@ github.com/go-ldap/ldap/v3 v3.1.10 h1:7WsKqasmPThNvdl0Q5GPpbTDD/ZD98CfuawrMIuh7q github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab h1:xveKWz2iaueeTaUgdetzel+U7exyigDYBryyVfV/rZk= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= -github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1 h1:wSt/4CYxs70xbATrGXhokKF1i0tZjENLOo1ioIO13zk= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9 h1:tF+augKRWlWx0J0B7ZyyKSiTyV6E1zZe+7b3qQlcEf8= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501 h1:C1JKChikHGpXwT5UQDFaryIpDtyyGL/CR6C2kB7F1oc= @@ -1072,9 +1076,9 @@ github.com/gofiber/fiber/v2 v2.52.2 h1:b0rYH6b06Df+4NyrbdptQL8ifuxw/Tf2DgfkZkDax github.com/gofiber/fiber/v2 v2.52.2/go.mod h1:KEOE+cXMhXG0zHc9d8+E38hoX+ZN7bhOtgeF2oT6jrQ= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= -github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U= github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= @@ -1149,6 +1153,7 @@ github.com/hashicorp/go-secure-stdlib/password v0.1.1 h1:6JzmBqXprakgFEHwBgdchsj github.com/hashicorp/go-secure-stdlib/tlsutil v0.1.1 h1:Yc026VyMyIpq1UWRnakHRG01U8fJm+nEfEmjoAb00n8= github.com/hashicorp/go-slug v0.4.1 h1:/jAo8dNuLgSImoLXaX7Od7QB4TfYCVPam+OpAt5bZqc= github.com/hashicorp/go-tfe v0.14.0 h1:TJi3tQ3B0qlZN1KqBYlxQ33LgdAbsmPR921ml4H2lDs= +github.com/hashicorp/hcl/v2 v2.13.0/go.mod h1:e4z5nxYlWNPdDSNYX+ph14EvWYMFm3eP0zIUqPc2jr0= github.com/hashicorp/jsonapi v0.0.0-20210420151930-edf82c9774bf h1:EsVVE/vPelkJ83dk/Y3CeMbH/yPR2S8bLzMtxUoMFGI= github.com/hashicorp/memberlist v0.1.0 h1:qSsCiC0WYD39lbSitKNt40e30uorm2Ss/d4JGU1hzH8= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= @@ -1185,8 +1190,10 @@ github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZ github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= github.com/jackc/pgx/v5 v5.3.0/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHozM/8= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= @@ -1313,6 +1320,7 @@ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1f github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/microcosm-cc/bluemonday v1.0.23 h1:SMZe2IGa0NuHvnVNAZ+6B38gsTbi5e4sViiWJyDDqFY= github.com/microcosm-cc/bluemonday v1.0.23/go.mod h1:mN70sk7UkkF8TUr2IGBpNN0jAgStuPzlK76QuruE/z4= +github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= @@ -1454,7 +1462,6 @@ github.com/sebdah/goldie v1.0.0 h1:9GNhIat69MSlz/ndaBg48vl9dF5fI+NBB6kfOxgfkMc= github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4= github.com/segmentio/conf v1.2.0 h1:5OT9+6OyVHLsFLsiJa/2KlqiA1m7mpdUBlkB/qYTMts= github.com/segmentio/conf v1.2.0/go.mod h1:Y3B9O/PqqWqjyxyWWseyj/quPEtMu1zDp/kVbSWWaB0= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shirou/gopsutil/v3 v3.23.2 h1:PAWSuiAszn7IhPMBtXsbSCafej7PqUOvY6YywlQUExU= github.com/shirou/gopsutil/v3 v3.23.2/go.mod h1:gv0aQw33GLo3pG8SiWKiQrbDzbRY1K80RyZJ7V4Th1M= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= @@ -1540,6 +1547,7 @@ github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvV github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vmihailenco/msgpack v3.3.3+incompatible h1:wapg9xDUZDzGCNFlwc5SqI1rvcciqcxEHac4CYj89xI= github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U= +github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= @@ -1576,6 +1584,7 @@ github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18W github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zclconf/go-cty v1.13.0/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= github.com/zclconf/go-cty v1.13.1/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= @@ -1607,6 +1616,7 @@ go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.48.0/go.mod h1:tIKj3DbO8N9Y2xo52og3irLsPI4GW02DSMtrVgNMgxg= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.49.0/go.mod h1:Mjt1i1INqiaoZOMGR1RIUJN+i3ChKoFRqzrRQhlkbs0= @@ -1620,6 +1630,7 @@ go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znn go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0= go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= go.opentelemetry.io/otel/metric v1.19.0/go.mod h1:L5rUsV9kM1IxCj1MmSdS+JQAcVm319EUrDVLrt7jqt8= @@ -1627,6 +1638,7 @@ go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzu go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= @@ -1634,6 +1646,7 @@ go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+ go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= +go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -1643,14 +1656,13 @@ go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221005025214-4161e89ecf1b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= @@ -1661,23 +1673,23 @@ golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDA golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg= +golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= @@ -1689,34 +1701,32 @@ golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= +golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b/go.mod h1:4ZwOYna0/zsOKwuR5X/m0QFOJpSZvAxFfkQT+Erd9D4= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= @@ -1725,11 +1735,14 @@ golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20201211185031-d93e913c1a58/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= +golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +golang.org/x/tools v0.35.0 h1:mBffYraMEf7aa0sB+NuKnuCy8qI/9Bughn8dC2Gu5r0= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= @@ -1822,6 +1835,7 @@ google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHh google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/cheggaaa/pb.v1 v1.0.27 h1:kJdccidYzt3CaHD1crCFTS1hxyhSi059NhOFUf03YFo= gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= @@ -1836,6 +1850,9 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.5.0/go.mod h1:FUZXzO+5Uqg5zzwzv4KK49R8lvGIyscBOqYrtI1Ce9A= +gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= +gorm.io/driver/sqlite v1.5.7/go.mod h1:U+J8craQU6Fzkcvu8oLeAQmi50TkwPEhHDEjQZXDah4= +gorm.io/driver/sqlserver v1.5.4/go.mod h1:+frZ/qYmuna11zHPlh5oc2O6ZA/lS88Keb0XSH1Zh/g= gorm.io/gorm v1.24.7-0.20230306060331-85eaf9eeda11/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= diff --git a/taco/Dockerfile_statesman b/taco/Dockerfile_statesman index 30dafd020..2a55febaa 100644 --- a/taco/Dockerfile_statesman +++ b/taco/Dockerfile_statesman @@ -9,13 +9,17 @@ WORKDIR /go/src/github.com/diggerhq/digger/taco COPY cmd/statesman/ ./cmd/statesman/ COPY internal/ ./internal/ COPY pkg/sdk/ ./pkg/sdk/ +COPY migrations/ ./migrations/ +COPY scripts/ ./scripts/ +COPY atlas.hcl ./atlas.hcl # Download dependencies and build +# Note: CGO is required for SQLite support RUN cd cmd/statesman && \ go mod tidy && \ - CGO_ENABLED=0 GOOS=linux go build \ + CGO_ENABLED=1 GOOS=linux go build \ -ldflags="-X 'main.Version=${COMMIT_SHA}' -s -w" \ - -a -installsuffix cgo \ + -a \ -o statesman . # Multi-stage build - use a minimal image for runtime @@ -23,19 +27,31 @@ FROM ubuntu:24.04 AS runner ARG COMMIT_SHA WORKDIR /app -# Install ca-certificates for HTTPS requests +# Install ca-certificates, curl for HTTPS requests RUN apt-get update && \ - apt-get install -y ca-certificates && \ + apt-get install -y ca-certificates curl && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* RUN echo "commit sha: ${COMMIT_SHA}" +# Install Atlas CLI for migrations +RUN curl -sSf https://atlasgo.sh | sh + # Copy the binary from builder stage COPY --from=builder /go/src/github.com/diggerhq/digger/taco/cmd/statesman/statesman /app/statesman -# Make the binary executable -RUN chmod +x /app/statesman +# Copy migration files +COPY --from=builder /go/src/github.com/diggerhq/digger/taco/migrations /app/migrations + +# Copy entrypoint script +COPY --from=builder /go/src/github.com/diggerhq/digger/taco/scripts/entrypoint.sh /app/entrypoint.sh + +# Copy atlas.hcl for reference +COPY --from=builder /go/src/github.com/diggerhq/digger/taco/atlas.hcl /app/atlas.hcl + +# Make scripts executable +RUN chmod +x /app/statesman /app/entrypoint.sh # Expose the port that statesman runs on EXPOSE 8080 @@ -43,10 +59,12 @@ EXPOSE 8080 # Set environment variables with defaults ENV OPENTACO_PORT=8080 ENV OPENTACO_STORAGE=memory +ENV OPENTACO_QUERY_BACKEND=sqlite +ENV OPENTACO_SQLITE_DB_PATH=/app/data/taco.db # Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:8080/healthz || exit 1 -# Run the statesman binary -ENTRYPOINT ["/app/statesman"] +# Run via entrypoint script (applies migrations then starts statesman) +ENTRYPOINT ["/bin/bash", "/app/entrypoint.sh"] diff --git a/taco/Makefile b/taco/Makefile index 1478774c8..86197fafe 100644 --- a/taco/Makefile +++ b/taco/Makefile @@ -86,4 +86,64 @@ docker-clean: ## Clean Docker images and containers docker rmi statesman:latest 2>/dev/null || true help: ## Show this help - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' \ No newline at end of file + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}' + +# ============================================================================ +# Atlas Migration Targets +# ============================================================================ + +# Migration name variable (use with: make atlas-diff-all name=add_new_feature) +NAME ?= $(shell date +%Y%m%d%H%M%S) + +.PHONY: atlas-install atlas-diff-all atlas-plan atlas-apply-all atlas-lint-all atlas-hash-all + +# Install Atlas CLI and GORM provider +atlas-install: ## Install Atlas CLI and GORM provider + @echo "Installing Atlas CLI and GORM provider..." + @go install ariga.io/atlas/cmd/atlas@latest + @go install ariga.io/atlas-provider-gorm@latest + @echo "✅ Atlas tools installed successfully" + +# Preview migration changes without generating files +atlas-plan: ## Preview what migrations would be generated (use: make atlas-plan name=my_change) + @echo "Previewing migration changes for all databases..." + @if [ -z "$(filter-out $(NAME),$(shell date +%Y%m%d%H%M%S))" ]; then \ + echo "⚠️ Using auto-generated name: $(NAME)"; \ + echo "💡 Tip: Use 'make atlas-plan name=descriptive_name' for better naming"; \ + fi + @echo "\n🔐 Generating checksums for existing migrations..." + @$(MAKE) atlas-hash-all + @echo "\n📊 PostgreSQL (dry-run)..." && atlas migrate diff $(NAME) --env postgres --dry-run || true + @echo "\n📊 MySQL (dry-run)..." && atlas migrate diff $(NAME) --env mysql --dry-run || true + @echo "\n📊 SQLite (dry-run)..." && atlas migrate diff $(NAME) --env sqlite --dry-run || true + @echo "\n✅ Preview complete (no files generated)" + +# Generate migrations for all database dialects (Postgres, MySQL, SQLite) +atlas-diff-all: ## Generate migrations for all databases (use: make atlas-diff-all name=my_change) + @echo "Generating migrations for all databases..." + @if [ -z "$(filter-out $(NAME),$(shell date +%Y%m%d%H%M%S))" ]; then \ + echo "⚠️ Using auto-generated name: $(NAME)"; \ + echo "💡 Tip: Use 'make atlas-diff-all name=descriptive_name' for better naming"; \ + fi + @mkdir -p migrations/postgres migrations/mysql migrations/sqlite + @echo "\n🔐 Generating checksums for existing migrations..." + @$(MAKE) atlas-hash-all + @echo "\n📊 PostgreSQL..." && atlas migrate diff $(NAME) --env postgres + @echo "\n📊 MySQL..." && atlas migrate diff $(NAME) --env mysql + @echo "\n📊 SQLite..." && atlas migrate diff $(NAME) --env sqlite + @echo "\n✅ All migrations generated successfully!" + + +# Validate and lint all migrations +atlas-lint-all: ## Validate and lint all migration files + @echo "Validating and linting migrations..." + @echo "PostgreSQL..." && atlas migrate validate --env postgres + @echo "MySQL..." && atlas migrate validate --env mysql + @echo "SQLite..." && atlas migrate validate --env sqlite + @echo "✅ All migrations validated successfully" + +# Update migration directory hashes (called automatically by atlas-diff-all) +atlas-hash-all: + @atlas migrate hash --dir file://migrations/postgres 2>/dev/null || true + @atlas migrate hash --dir file://migrations/mysql 2>/dev/null || true + @atlas migrate hash --dir file://migrations/sqlite 2>/dev/null || true \ No newline at end of file diff --git a/taco/atlas.hcl b/taco/atlas.hcl new file mode 100644 index 000000000..c7c53f93e --- /dev/null +++ b/taco/atlas.hcl @@ -0,0 +1,114 @@ +variable "DB_URL" { + type = string + default = "postgres://postgres:postgres@localhost:5432/devdb?sslmode=disable" +} + +variable "POSTGRES_MIGRATIONS_DIR" { + type = string + default = "file://migrations/postgres" +} + +variable "MYSQL_MIGRATIONS_DIR" { + type = string + default = "file://migrations/mysql" +} + +variable "SQLITE_MIGRATIONS_DIR" { + type = string + default = "file://migrations/sqlite" +} + +data "external_schema" "gorm_postgres" { + program = [ + "sh", + "-c", + "cd internal && go run ./atlas_loader.go postgres", + ] +} + +env "postgres" { + src = data.external_schema.gorm_postgres.url + url = var.DB_URL + + # IMPORTANT: no env=… params here; keep 5m timeout. + # If your build wants fully-qualified, use docker://docker.io/library/postgres/16 + dev = "docker://postgres/16?timeout=5m" + + schemas = ["public"] + + migration { + dir = var.POSTGRES_MIGRATIONS_DIR + format = "atlas" + } + + lint { + destructive { error = true } + } + + format { + migrate { + diff = "{{ sql . \" \" }}" + } + } +} + +# MySQL configuration +data "external_schema" "gorm_mysql" { + program = [ + "sh", + "-c", + "cd internal && go run ./atlas_loader.go mysql", + ] +} + +env "mysql" { + src = data.external_schema.gorm_mysql.url + + dev = "docker://mysql/8/devdb?timeout=5m" + + migration { + dir = var.MYSQL_MIGRATIONS_DIR + format = "atlas" + } + + lint { + destructive { error = true } + } + + format { + migrate { + diff = "{{ sql . \" \" }}" + } + } +} + +# SQLite configuration +data "external_schema" "gorm_sqlite" { + program = [ + "sh", + "-c", + "cd internal && go run ./atlas_loader.go sqlite", + ] +} + +env "sqlite" { + src = data.external_schema.gorm_sqlite.url + + # SQLite uses in-memory dev database, no Docker needed + dev = "sqlite://file?mode=memory" + + migration { + dir = var.SQLITE_MIGRATIONS_DIR + format = "atlas" + } + + lint { + destructive { error = true } + } + + format { + migrate { + diff = "{{ sql . \" \" }}" + } + } +} diff --git a/taco/cmd/statesman/go.mod b/taco/cmd/statesman/go.mod index c2143882b..c4b47ea3b 100644 --- a/taco/cmd/statesman/go.mod +++ b/taco/cmd/statesman/go.mod @@ -1,6 +1,6 @@ module github.com/diggerhq/digger/opentaco/cmd/statesman -go 1.24 +go 1.24.0 require ( github.com/diggerhq/digger/opentaco/internal v0.0.0 @@ -9,8 +9,12 @@ require ( ) require ( + ariga.io/atlas v0.36.1 // indirect + ariga.io/atlas-go-sdk v0.7.2 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aws/aws-sdk-go-v2 v1.38.1 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.0 // indirect github.com/aws/aws-sdk-go-v2/config v1.31.2 // indirect @@ -29,15 +33,19 @@ require ( github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.38.0 // indirect github.com/aws/smithy-go v1.22.5 // indirect + github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/coreos/go-oidc/v3 v3.11.0 // indirect - github.com/go-jose/go-jose/v4 v4.0.2 // indirect + github.com/go-jose/go-jose/v4 v4.1.2 // indirect + github.com/go-openapi/inflect v0.19.0 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/jsonapi v1.0.0 // indirect github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/hcl/v2 v2.18.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgx/v5 v5.6.0 // indirect @@ -47,18 +55,22 @@ require ( github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.22 // indirect + github.com/mattn/go-sqlite3 v1.14.28 // indirect github.com/microsoft/go-mssqldb v1.8.2 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.7.0 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zclconf/go-cty-yaml v1.1.0 // indirect + golang.org/x/crypto v0.41.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect + golang.org/x/time v0.12.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect gorm.io/driver/mysql v1.6.0 // indirect gorm.io/driver/postgres v1.6.0 // indirect gorm.io/driver/sqlite v1.6.0 // indirect diff --git a/taco/cmd/statesman/go.sum b/taco/cmd/statesman/go.sum index c87563ed8..392e5832b 100644 --- a/taco/cmd/statesman/go.sum +++ b/taco/cmd/statesman/go.sum @@ -1,3 +1,7 @@ +ariga.io/atlas v0.36.1 h1:w0BGAHPkzxpx0n9QWUVbtu7vUUihs7cDCTPsnnw9nck= +ariga.io/atlas v0.36.1/go.mod h1:9ZAIr/V85596AVxmN8edyVHYKKpnNsDMdnHLsEliW7k= +ariga.io/atlas-go-sdk v0.7.2 h1:pvS8tKVeRQuqdETBqj5qAQtVbQE88Gya6bOfY8YF3vU= +ariga.io/atlas-go-sdk v0.7.2/go.mod h1:cFq7bnvHgKTWHCsU46mtkGxdl41rx2o7SjaLoh6cO8M= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= @@ -22,6 +26,12 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83 github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/aws/aws-sdk-go-v2 v1.38.1 h1:j7sc33amE74Rz0M/PoCpsZQ6OunLqys/m5antM0J+Z8= github.com/aws/aws-sdk-go-v2 v1.38.1/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.0 h1:6GMWV6CNpA/6fbFHnoAjrv4+LGfyTqZz2LtCHnspgDg= @@ -58,6 +68,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.38.0 h1:iV1Ko4Em/lkJIsoKyGfc0nQySi+v github.com/aws/aws-sdk-go-v2/service/sts v1.38.0/go.mod h1:bEPcjW7IbolPfK67G1nilqWyoxYMSPrDiIQ3RdIdKgo= github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw= github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= +github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -67,10 +79,14 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI= +github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo= +github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= +github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= @@ -94,6 +110,8 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+ github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= +github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= @@ -115,9 +133,11 @@ github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= @@ -130,10 +150,12 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= +github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/microsoft/go-mssqldb v1.8.2 h1:236sewazvC8FvG6Dr3bszrVhMkAl4KYImryLkRMCd0I= github.com/microsoft/go-mssqldb v1.8.2/go.mod h1:vp38dT33FGfVotRiTmDo3bFyaHq+p3LektQrjTULowo= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -147,6 +169,10 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI 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.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -166,6 +192,10 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= +github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= @@ -178,8 +208,8 @@ golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOM golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -203,10 +233,10 @@ golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -214,8 +244,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -236,8 +266,8 @@ golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -266,10 +296,10 @@ golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE= +golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -278,6 +308,7 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58 golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/taco/internal/atlas_loader.go b/taco/internal/atlas_loader.go new file mode 100644 index 000000000..fc2833433 --- /dev/null +++ b/taco/internal/atlas_loader.go @@ -0,0 +1,131 @@ +// +build ignore + +package main + +import ( + "fmt" + "log" + "os" + "strings" + + "github.com/diggerhq/digger/opentaco/internal/query/types" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "gorm.io/gorm/logger" +) + +func main() { + // Default to sqlite if no argument provided + dialect := "sqlite" + if len(os.Args) > 1 { + dialect = os.Args[1] + } + + var db *gorm.DB + var err error + + // Create an in-memory database for schema generation + switch dialect { + case "postgres": + // Use SQLite in postgres mode for schema generation since we just need the structure + db, err = gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Silent), + }) + case "mysql": + db, err = gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Silent), + }) + case "sqlite": + db, err = gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{ + Logger: logger.Default.LogMode(logger.Silent), + }) + default: + log.Fatalf("Unknown dialect: %s", dialect) + } + + if err != nil { + log.Fatalf("Failed to open in-memory database: %v", err) + } + + // Auto-migrate to generate schema + err = db.AutoMigrate(types.DefaultModels...) + if err != nil { + log.Fatalf("Failed to auto-migrate: %v", err) + } + + // Get raw SQL connection + sqlDB, err := db.DB() + if err != nil { + log.Fatalf("Failed to get sql.DB: %v", err) + } + + // Query sqlite_master to get CREATE statements in creation order (rootpage preserves order) + rows, err := sqlDB.Query("SELECT sql FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY rootpage") + if err != nil { + log.Fatalf("Failed to query schema: %v", err) + } + defer rows.Close() + + var statements []string + for rows.Next() { + var sql string + if err := rows.Scan(&sql); err != nil { + log.Fatalf("Failed to scan row: %v", err) + } + if sql != "" { + statements = append(statements, adaptSQL(sql, dialect)) + } + } + + // Also get indexes + rows, err = sqlDB.Query("SELECT sql FROM sqlite_master WHERE type='index' AND name NOT LIKE 'sqlite_%' ORDER BY rootpage") + if err != nil { + log.Fatalf("Failed to query indexes: %v", err) + } + defer rows.Close() + + for rows.Next() { + var sql string + if err := rows.Scan(&sql); err != nil { + log.Fatalf("Failed to scan row: %v", err) + } + if sql != "" { + statements = append(statements, adaptSQL(sql, dialect)) + } + } + + // Output all statements + fmt.Println(strings.Join(statements, ";\n") + ";") +} + +// adaptSQL adapts SQLite SQL to target dialect +func adaptSQL(sql, dialect string) string { + switch dialect { + case "postgres": + // PostgreSQL uses double quotes for identifiers, single quotes for strings + sql = strings.ReplaceAll(sql, "`", "\"") + sql = strings.ReplaceAll(sql, "AUTOINCREMENT", "") + sql = strings.ReplaceAll(sql, "datetime", "timestamptz") + sql = strings.ReplaceAll(sql, "numeric", "boolean") + sql = strings.ReplaceAll(sql, "integer", "int") + // Fix DEFAULT clause - PostgreSQL uses single quotes for string literals + sql = strings.ReplaceAll(sql, "DEFAULT \"allow\"", "DEFAULT 'allow'") + sql = strings.ReplaceAll(sql, "DEFAULT \"\"", "DEFAULT ''") + case "mysql": + // MySQL uses backticks (already correct from SQLite) + sql = strings.ReplaceAll(sql, "AUTOINCREMENT", "AUTO_INCREMENT") + sql = strings.ReplaceAll(sql, "timestamptz", "datetime") + sql = strings.ReplaceAll(sql, "numeric", "tinyint(1)") + // MySQL has limitations with TEXT (no DEFAULT, no index without key length) + // Convert most text fields to varchar(255), keep only truly large fields as text + sql = strings.ReplaceAll(sql, " text NOT NULL DEFAULT", " varchar(255) NOT NULL DEFAULT") + sql = strings.ReplaceAll(sql, " text DEFAULT", " varchar(255) DEFAULT") + sql = strings.ReplaceAll(sql, " text NOT NULL", " varchar(255) NOT NULL") + sql = strings.ReplaceAll(sql, " text,", " text,") // Keep text for description, resource_patterns + sql = strings.ReplaceAll(sql, "`action` varchar(255)", "`action` varchar(128)") // Smaller for indexed fields + sql = strings.ReplaceAll(sql, "`effect` varchar(255) NOT NULL DEFAULT", "`effect` varchar(8) NOT NULL DEFAULT") + case "sqlite": + // No adaptation needed + } + return sql +} diff --git a/taco/internal/go.mod b/taco/internal/go.mod index 6e788ec54..f42830e1b 100644 --- a/taco/internal/go.mod +++ b/taco/internal/go.mod @@ -1,8 +1,9 @@ module github.com/diggerhq/digger/opentaco/internal -go 1.24 +go 1.24.0 require ( + ariga.io/atlas-go-sdk v0.7.2 github.com/aws/aws-sdk-go-v2 v1.38.1 github.com/aws/aws-sdk-go-v2/config v1.31.2 github.com/aws/aws-sdk-go-v2/service/s3 v1.87.1 @@ -22,10 +23,13 @@ require ( ) require ( + ariga.io/atlas v0.36.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.0 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.18.6 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.4 // indirect @@ -40,12 +44,15 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.28.2 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.33.2 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.38.0 // indirect + github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/go-jose/go-jose/v4 v4.0.2 // indirect + github.com/go-jose/go-jose/v4 v4.1.2 // indirect + github.com/go-openapi/inflect v0.19.0 // indirect github.com/go-sql-driver/mysql v1.8.1 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/hashicorp/hcl/v2 v2.18.1 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/pgx/v5 v5.6.0 // indirect @@ -55,16 +62,20 @@ require ( github.com/labstack/gommon v0.4.2 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-sqlite3 v1.14.22 // indirect + github.com/mattn/go-sqlite3 v1.14.28 // indirect github.com/microsoft/go-mssqldb v1.8.2 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/oauth2 v0.24.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect + github.com/zclconf/go-cty v1.14.4 // indirect + github.com/zclconf/go-cty-yaml v1.1.0 // indirect + golang.org/x/crypto v0.41.0 // indirect + golang.org/x/net v0.43.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/taco/internal/go.sum b/taco/internal/go.sum index 427c9ad73..57da9aa89 100644 --- a/taco/internal/go.sum +++ b/taco/internal/go.sum @@ -1,10 +1,37 @@ +ariga.io/atlas v0.36.1 h1:w0BGAHPkzxpx0n9QWUVbtu7vUUihs7cDCTPsnnw9nck= +ariga.io/atlas v0.36.1/go.mod h1:9ZAIr/V85596AVxmN8edyVHYKKpnNsDMdnHLsEliW7k= +ariga.io/atlas-go-sdk v0.7.2 h1:pvS8tKVeRQuqdETBqj5qAQtVbQE88Gya6bOfY8YF3vU= +ariga.io/atlas-go-sdk v0.7.2/go.mod h1:cFq7bnvHgKTWHCsU46mtkGxdl41rx2o7SjaLoh6cO8M= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.1/go.mod h1:uE9zaUfEQT/nbQjVi2IblCG9iaLtZsuYZ8ne+PuQ02M= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1/go.mod h1:GpPjLhVR9dnUoJMyHWSPy71xY9/lcmpzIPZXmF0FCVY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occbWoio4EBLkbkevetNMAVX197GkzbUMtqjGWn80= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ= +github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/aws/aws-sdk-go-v2 v1.38.1 h1:j7sc33amE74Rz0M/PoCpsZQ6OunLqys/m5antM0J+Z8= github.com/aws/aws-sdk-go-v2 v1.38.1/go.mod h1:9Q0OoGQoboYIAJyslFyF1f5K1Ryddop8gqMhWx/n4Wg= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.0 h1:6GMWV6CNpA/6fbFHnoAjrv4+LGfyTqZz2LtCHnspgDg= @@ -41,29 +68,75 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.38.0 h1:iV1Ko4Em/lkJIsoKyGfc0nQySi+v github.com/aws/aws-sdk-go-v2/service/sts v1.38.0/go.mod h1:bEPcjW7IbolPfK67G1nilqWyoxYMSPrDiIQ3RdIdKgo= github.com/aws/smithy-go v1.22.5 h1:P9ATCXPMb2mPjYBgueqJNCA5S9UfktsW0tTxi+a7eqw= github.com/aws/smithy-go v1.22.5/go.mod h1:t1ufH5HMublsJYulve2RKmHDC15xu1f26kHCp/HgceI= +github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= +github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/coreos/go-oidc/v3 v3.11.0 h1:Ia3MxdwpSw702YW0xgfmP1GVCMA9aEFWu12XUZ3/OtI= github.com/coreos/go-oidc/v3 v3.11.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= -github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk= -github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/go-jose/go-jose/v4 v4.1.2 h1:TK/7NqRQZfgAh+Td8AlsrvtPoUyiHh0LqVvokh+1vHI= +github.com/go-jose/go-jose/v4 v4.1.2/go.mod h1:22cg9HWM1pOlnRiY+9cQYJ9XHmya1bYW8OeDM6Ku6Oo= +github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= +github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/jsonapi v1.0.0 h1:qIGgO5Smu3yJmSs+QlvhQnrscdZfFhiV6S8ryJAglqU= github.com/google/jsonapi v1.0.0/go.mod h1:YYHiRPJT8ARXGER8In9VuLv4qvLfDmA9ULQqptbLE4s= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= +github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgx/v5 v5.6.0 h1:SWJzexBzPL5jb0GEsrPMLIsi/3jOo7RHlzTjcAeDrPY= +github.com/jackc/pgx/v5 v5.6.0/go.mod h1:DNZ/vlrUnhWCoFGxHAG8U2ljioxukquj7utPDgtQdTw= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= +github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8= github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8= github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= @@ -73,32 +146,179 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A= +github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/microsoft/go-mssqldb v1.8.2 h1:236sewazvC8FvG6Dr3bszrVhMkAl4KYImryLkRMCd0I= +github.com/microsoft/go-mssqldb v1.8.2/go.mod h1:vp38dT33FGfVotRiTmDo3bFyaHq+p3LektQrjTULowo= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +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.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= +github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= +github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE= +golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.6.0 h1:eNbLmNTpPpTOVZi8MMxCi2aaIm0ZpInbORNXDwyLGvg= +gorm.io/driver/mysql v1.6.0/go.mod h1:D/oCC2GWK3M/dqoLxnOlaNKmXz8WNTfcS9y5ovaSqKo= gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= +gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo= gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= gorm.io/driver/sqlserver v1.6.1 h1:XWISFsu2I2pqd1KJhhTZNJMx1jNQ+zVL/Q8ovDcUjtY= +gorm.io/driver/sqlserver v1.6.1/go.mod h1:VZeNn7hqX1aXoN5TPAFGWvxWG90xtA8erGn2gQmpc6U= +gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= gorm.io/gorm v1.31.0 h1:0VlycGreVhK7RF/Bwt51Fk8v0xLiiiFdbGDPIZQ7mJY= +gorm.io/gorm v1.31.0/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs= diff --git a/taco/internal/query/common/sql_store.go b/taco/internal/query/common/sql_store.go index 255ae9fdd..ee906a587 100644 --- a/taco/internal/query/common/sql_store.go +++ b/taco/internal/query/common/sql_store.go @@ -18,26 +18,23 @@ const ( ) // SQLStore provides a generic, GORM-based implementation of the Store interface. -// It can be used with any GORM-compatible database dialect (SQLite, Postgres, etc.). type SQLStore struct { db *gorm.DB } -// NewSQLStore is a constructor for our common store. It takes a pre-configured -// GORM DB object and handles the common setup tasks like migration and view creation. +// NewSQLStore creates a new SQLStore. +// Note: Schema migrations are now handled by Atlas in queryfactory.NewQueryStore() func NewSQLStore(db *gorm.DB) (*SQLStore, error) { store := &SQLStore{db: db} - - if err := store.migrate(); err != nil { - return nil, fmt.Errorf("failed to migrate common sql schema: %w", err) - } + // Create org-scoped indexes (not handled by Atlas migrations) if err := CreateOrgScopedIndexes(db); err != nil { return nil, fmt.Errorf("failed to create org-scoped indexes: %w", err) } + // Create database views (not handled by Atlas migrations) if err := store.createViews(); err != nil { - return nil, fmt.Errorf("failed to create common sql views: %w", err) + return nil, fmt.Errorf("failed to create views: %w", err) } return store, nil @@ -49,10 +46,6 @@ func (s *SQLStore) GetDB() *gorm.DB { return s.db } -func (s *SQLStore) migrate() error { - return s.db.AutoMigrate(types.DefaultModels...) -} - // createViews now introspects the database dialect to use the correct SQL syntax. func (s *SQLStore) createViews() error { dialect := s.db.Dialector.Name() diff --git a/taco/internal/query/mssql/store.go b/taco/internal/query/mssql/store.go index 7009a8212..6941e017b 100644 --- a/taco/internal/query/mssql/store.go +++ b/taco/internal/query/mssql/store.go @@ -10,9 +10,8 @@ import ( "gorm.io/gorm/logger" ) -// NewMSSQLStore creates a new MS SQL-backed query store. -// Its only job is to establish the DB connection and pass it to the common SQLStore. -func NewMSSQLStore(cfg query.MSSQLConfig) (query.Store, error) { +// Connect establishes a MS SQL Server connection +func Connect(cfg query.MSSQLConfig) (*gorm.DB, error) { // DSN format: sqlserver://username:password@host:port?database=dbname dsn := fmt.Sprintf("sqlserver://%s:%s@%s:%d?database=%s", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.DBName) @@ -24,6 +23,11 @@ func NewMSSQLStore(cfg query.MSSQLConfig) (query.Store, error) { return nil, fmt.Errorf("failed to connect to mssql: %w", err) } - // Hand off to the common, dialect-aware SQLStore engine. + return db, nil +} + +// NewMSSQLStore creates a new MS SQL-backed query store. +// Assumes migrations have already been applied. +func NewMSSQLStore(db *gorm.DB) (query.Store, error) { return common.NewSQLStore(db) } diff --git a/taco/internal/query/mysql/store.go b/taco/internal/query/mysql/store.go index 3bedcdcfd..8d331a108 100644 --- a/taco/internal/query/mysql/store.go +++ b/taco/internal/query/mysql/store.go @@ -10,10 +10,8 @@ import ( "gorm.io/gorm/logger" ) -// NewMySQLStore creates a new MySQL-backed query store. -// Its only job is to establish the DB connection and pass it to the common SQLStore. -func NewMySQLStore(cfg query.MySQLConfig) (query.Store, error) { - // DSN format: user:pass@tcp(host:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local +// Connect establishes a MySQL connection +func Connect(cfg query.MySQLConfig) (*gorm.DB, error) { dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local", cfg.User, cfg.Password, cfg.Host, cfg.Port, cfg.DBName, cfg.Charset) @@ -24,6 +22,11 @@ func NewMySQLStore(cfg query.MySQLConfig) (query.Store, error) { return nil, fmt.Errorf("failed to connect to mysql: %w", err) } - // Hand off to the common, dialect-aware SQLStore engine. + return db, nil +} + +// NewMySQLStore creates a new MySQL-backed query store. +// Assumes migrations have already been applied. +func NewMySQLStore(db *gorm.DB) (query.Store, error) { return common.NewSQLStore(db) } diff --git a/taco/internal/query/postgres/store.go b/taco/internal/query/postgres/store.go index d9cd90134..9cd948884 100644 --- a/taco/internal/query/postgres/store.go +++ b/taco/internal/query/postgres/store.go @@ -10,9 +10,8 @@ import ( "gorm.io/gorm/logger" ) -// NewPostgresStore creates a new PostgreSQL-backed query store. -// Its only job is to establish the DB connection and pass it to the common SQLStore. -func NewPostgresStore(cfg query.PostgresConfig) (query.Store, error) { +// Connect establishes a PostgreSQL connection +func Connect(cfg query.PostgresConfig) (*gorm.DB, error) { dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s", cfg.Host, cfg.User, cfg.Password, cfg.DBName, cfg.Port, cfg.SSLMode) @@ -23,6 +22,11 @@ func NewPostgresStore(cfg query.PostgresConfig) (query.Store, error) { return nil, fmt.Errorf("failed to connect to postgres: %w", err) } - // Call the constructor from the 'common' package, breaking the cycle. + return db, nil +} + +// NewPostgresStore creates a new PostgreSQL-backed query store. +// Assumes migrations have already been applied. +func NewPostgresStore(db *gorm.DB) (query.Store, error) { return common.NewSQLStore(db) } \ No newline at end of file diff --git a/taco/internal/query/sqlite/store.go b/taco/internal/query/sqlite/store.go index 05a13d8d2..05ca9120c 100644 --- a/taco/internal/query/sqlite/store.go +++ b/taco/internal/query/sqlite/store.go @@ -13,8 +13,8 @@ import ( "gorm.io/gorm/logger" ) -// NewSQLiteQueryStore creates a new SQLite-backed query store. -func NewSQLiteQueryStore(cfg query.SQLiteConfig) (query.Store, error) { +// Connect establishes a SQLite connection +func Connect(cfg query.SQLiteConfig) (*gorm.DB, error) { if err := os.MkdirAll(filepath.Dir(cfg.Path), 0755); err != nil { return nil, fmt.Errorf("create db dir: %v", err) } @@ -46,7 +46,12 @@ func NewSQLiteQueryStore(cfg query.SQLiteConfig) (query.Store, error) { sqlDB.SetMaxOpenConns(cfg.MaxOpenConns) sqlDB.SetMaxIdleConns(cfg.MaxIdleConns) - // Create the common SQLStore with our configured DB object, breaking the cycle. + return db, nil +} + +// NewSQLiteQueryStore creates a new SQLite-backed query store. +// Assumes migrations have already been applied. +func NewSQLiteQueryStore(db *gorm.DB) (query.Store, error) { return common.NewSQLStore(db) } diff --git a/taco/internal/query/types/models.go b/taco/internal/query/types/models.go index b9d66d799..038318ff7 100644 --- a/taco/internal/query/types/models.go +++ b/taco/internal/query/types/models.go @@ -50,7 +50,7 @@ type Rule struct { Effect string `gorm:"size:8;not null;default:allow"` WildcardAction bool `gorm:"not null;default:false"` WildcardResource bool `gorm:"not null;default:false"` - ResourcePatterns string `gorm:"type:text;default:''"` + ResourcePatterns string `gorm:"type:text;"` Actions []RuleAction `gorm:"constraint:OnDelete:CASCADE"` UnitTargets []RuleUnit `gorm:"constraint:OnDelete:CASCADE"` TagTargets []RuleUnitTag `gorm:"constraint:OnDelete:CASCADE"` diff --git a/taco/internal/queryfactory/factory.go b/taco/internal/queryfactory/factory.go index b22fe2db4..5c68168e8 100644 --- a/taco/internal/queryfactory/factory.go +++ b/taco/internal/queryfactory/factory.go @@ -12,22 +12,59 @@ import ( "github.com/diggerhq/digger/opentaco/internal/query/mysql" "github.com/diggerhq/digger/opentaco/internal/query/postgres" "github.com/diggerhq/digger/opentaco/internal/query/sqlite" + "gorm.io/gorm" ) // NewQueryStore creates a new query.Store based on the provided configuration. +// NOTE: Migrations are NOT applied automatically. They must be applied via: +// - Docker/Production: entrypoint.sh runs "atlas migrate apply" before starting +// - Local Dev: Run "atlas migrate apply" manually before starting statesman func NewQueryStore(cfg query.Config) (query.Store, error) { backend := strings.ToLower(cfg.Backend) + // Step 1: Connect to database (get GORM DB instance) + db, _, err := connectDatabase(backend, cfg) + if err != nil { + return nil, err + } + + // Step 2: Create store (data access layer) + // NOTE: Migrations must be applied externally (see function comment above) + return createStore(db, backend) +} + +// connectDatabase establishes the database connection +func connectDatabase(backend string, cfg query.Config) (*gorm.DB, string, error) { + switch backend { + case "sqlite", "": + db, err := sqlite.Connect(cfg.SQLite) + return db, "sqlite", err + case "postgres": + db, err := postgres.Connect(cfg.Postgres) + return db, "postgres", err + case "mssql": + db, err := mssql.Connect(cfg.MSSQL) + return db, "sqlserver", err + case "mysql": + db, err := mysql.Connect(cfg.MySQL) + return db, "mysql", err + default: + return nil, "", fmt.Errorf("unsupported OPENTACO_QUERY_BACKEND value: %q (supported: sqlite, postgres, mssql, mysql)", backend) + } +} + +// createStore creates the actual store implementation +func createStore(db *gorm.DB, backend string) (query.Store, error) { switch backend { case "sqlite", "": - return sqlite.NewSQLiteQueryStore(cfg.SQLite) + return sqlite.NewSQLiteQueryStore(db) case "postgres": - return postgres.NewPostgresStore(cfg.Postgres) + return postgres.NewPostgresStore(db) case "mssql": - return mssql.NewMSSQLStore(cfg.MSSQL) + return mssql.NewMSSQLStore(db) case "mysql": - return mysql.NewMySQLStore(cfg.MySQL) + return mysql.NewMySQLStore(db) default: - return nil, fmt.Errorf("unsupported TACO_QUERY_BACKEND value: %q (supported: sqlite, postgres, mssql, mysql)", backend) + return nil, fmt.Errorf("unsupported backend: %q", backend) } } diff --git a/taco/internal/storage/memstore.go b/taco/internal/storage/memstore.go index bf7ce8561..5d5b69425 100644 --- a/taco/internal/storage/memstore.go +++ b/taco/internal/storage/memstore.go @@ -133,7 +133,18 @@ func (m *memStore) Upload(ctx context.Context, id string, data []byte, lockID st state, exists := m.units[id] if !exists { - return ErrNotFound + // Auto-create the unit if it doesn't exist (matches S3 behavior) + state = &unitData{ + metadata: &UnitMetadata{ + ID: id, + Size: 0, + Updated: time.Now(), + Locked: false, + }, + content: []byte{}, + versions: nil, + } + m.units[id] = state } // Check lock if provided diff --git a/taco/migrations/MIGRATIONS.md b/taco/migrations/MIGRATIONS.md new file mode 100644 index 000000000..4e95668d6 --- /dev/null +++ b/taco/migrations/MIGRATIONS.md @@ -0,0 +1,47 @@ +# Database Migrations + +Atlas-based schema migrations for PostgreSQL, MySQL, and SQLite. + +## Quick Reference + +```bash +# Preview changes (dry-run) +make atlas-plan name=my_change + +# Generate migrations +make atlas-diff-all name=my_change + +# Validate migrations +make atlas-lint-all + +# Apply migrations locally +atlas migrate apply --env postgres +atlas migrate apply --env mysql +atlas migrate apply --env sqlite +``` + +## Local Development + +### First-time setup +```bash +# Install Atlas CLI +make atlas-install + +# Ensure Docker is running (required for Postgres/MySQL dev databases) +docker info +``` + +### Modifying schema + +1. Edit GORM models in `internal/query/types/models.go` +2. Preview changes: `make atlas-plan name=add_user_field` +3. Generate migrations: `make atlas-diff-all name=add_user_field` +4. Review generated SQL in `migrations/{postgres,mysql,sqlite}/` +5. Apply locally: `atlas migrate apply --env [postgres|mysql|sqlite]` +6. Commit: `git add migrations/ && git commit -m "Add user field migration"` + +## Docker/Production + +Migrations are **automatically applied** via `scripts/entrypoint.sh` before the app starts. + + diff --git a/taco/migrations/mysql/20251025020916_20251024190908.sql b/taco/migrations/mysql/20251025020916_20251024190908.sql new file mode 100644 index 000000000..0647a28e9 --- /dev/null +++ b/taco/migrations/mysql/20251025020916_20251024190908.sql @@ -0,0 +1,141 @@ +-- Create "unit_tags" table +CREATE TABLE `unit_tags` ( + `unit_id` varchar(36) NOT NULL, + `tag_id` varchar(36) NOT NULL, + PRIMARY KEY (`unit_id`, `tag_id`), + INDEX `idx_unit_tags_tag_id` (`tag_id`), + INDEX `idx_unit_tags_unit_id` (`unit_id`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "permissions" table +CREATE TABLE `permissions` ( + `id` varchar(36) NOT NULL, + `org_id` varchar(36) NULL, + `name` varchar(255) NOT NULL, + `description` text NULL, + `created_by` text NULL, + `created_at` datetime NULL, + PRIMARY KEY (`id`), + INDEX `idx_permissions_name` (`name`), + INDEX `idx_permissions_org_id` (`org_id`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "role_permissions" table +CREATE TABLE `role_permissions` ( + `role_id` varchar(36) NOT NULL, + `permission_id` varchar(36) NOT NULL, + PRIMARY KEY (`role_id`, `permission_id`), + INDEX `idx_role_permissions_permission_id` (`permission_id`), + INDEX `idx_role_permissions_role_id` (`role_id`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "roles" table +CREATE TABLE `roles` ( + `id` varchar(36) NOT NULL, + `org_id` varchar(36) NULL, + `name` varchar(255) NOT NULL, + `description` text NULL, + `created_at` datetime NULL, + `created_by` text NULL, + PRIMARY KEY (`id`), + INDEX `idx_roles_name` (`name`), + INDEX `idx_roles_org_id` (`org_id`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "tags" table +CREATE TABLE `tags` ( + `id` varchar(36) NOT NULL, + `org_id` varchar(36) NULL, + `name` varchar(255) NOT NULL, + PRIMARY KEY (`id`), + INDEX `idx_tags_name` (`name`), + INDEX `idx_tags_org_id` (`org_id`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "organizations" table +CREATE TABLE `organizations` ( + `id` varchar(36) NOT NULL, + `name` varchar(255) NOT NULL, + `display_name` varchar(255) NOT NULL, + `external_org_id` varchar(500) NULL, + `created_by` varchar(255) NOT NULL, + `created_at` datetime NULL, + `updated_at` datetime NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `idx_organizations_external_org_id` (`external_org_id`), + UNIQUE INDEX `idx_organizations_name` (`name`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "units" table +CREATE TABLE `units` ( + `id` varchar(36) NOT NULL, + `org_id` varchar(36) NULL, + `name` varchar(255) NOT NULL, + `size` int NULL DEFAULT 0, + `updated_at` datetime NULL, + `locked` bool NULL DEFAULT 0, + `lock_id` varchar(255) NULL DEFAULT "", + `lock_who` varchar(255) NULL DEFAULT "", + `lock_created` datetime NULL, + PRIMARY KEY (`id`), + INDEX `idx_units_name` (`name`), + INDEX `idx_units_org_id` (`org_id`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "user_roles" table +CREATE TABLE `user_roles` ( + `user_id` varchar(36) NOT NULL, + `role_id` varchar(36) NOT NULL, + `org_id` varchar(36) NOT NULL, + PRIMARY KEY (`user_id`, `role_id`, `org_id`), + INDEX `idx_user_roles_org_id` (`org_id`), + INDEX `idx_user_roles_role_id` (`role_id`), + INDEX `idx_user_roles_user_id` (`user_id`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "users" table +CREATE TABLE `users` ( + `id` varchar(36) NOT NULL, + `subject` varchar(255) NOT NULL, + `email` varchar(255) NOT NULL, + `created_at` datetime NULL, + `updated_at` datetime NULL, + `version` int NULL, + PRIMARY KEY (`id`), + UNIQUE INDEX `idx_users_email` (`email`), + UNIQUE INDEX `idx_users_subject` (`subject`) +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "rules" table +CREATE TABLE `rules` ( + `id` varchar(36) NOT NULL, + `permission_id` varchar(36) NOT NULL, + `effect` varchar(8) NOT NULL DEFAULT "allow", + `wildcard_action` bool NOT NULL DEFAULT 0, + `wildcard_resource` bool NOT NULL DEFAULT 0, + `resource_patterns` text NULL, + PRIMARY KEY (`id`), + INDEX `idx_rules_permission_id` (`permission_id`), + CONSTRAINT `fk_permissions_rules` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "rule_actions" table +CREATE TABLE `rule_actions` ( + `id` varchar(36) NOT NULL, + `rule_id` varchar(36) NOT NULL, + `action` varchar(128) NOT NULL, + PRIMARY KEY (`id`), + INDEX `idx_rule_actions_action` (`action`), + INDEX `idx_rule_actions_rule_id` (`rule_id`), + CONSTRAINT `fk_rules_actions` FOREIGN KEY (`rule_id`) REFERENCES `rules` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "rule_unit_tags" table +CREATE TABLE `rule_unit_tags` ( + `id` varchar(36) NOT NULL, + `rule_id` varchar(36) NOT NULL, + `tag_id` varchar(36) NOT NULL, + PRIMARY KEY (`id`), + INDEX `idx_rule_unit_tags_rule_id` (`rule_id`), + INDEX `idx_rule_unit_tags_tag_id` (`tag_id`), + CONSTRAINT `fk_rules_tag_targets` FOREIGN KEY (`rule_id`) REFERENCES `rules` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; +-- Create "rule_units" table +CREATE TABLE `rule_units` ( + `id` varchar(36) NOT NULL, + `rule_id` varchar(36) NOT NULL, + `unit_id` varchar(36) NOT NULL, + PRIMARY KEY (`id`), + INDEX `idx_rule_units_rule_id` (`rule_id`), + INDEX `idx_rule_units_unit_id` (`unit_id`), + CONSTRAINT `fk_rules_unit_targets` FOREIGN KEY (`rule_id`) REFERENCES `rules` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE +) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci; diff --git a/taco/migrations/postgres/20251025020912_20251024190908.sql b/taco/migrations/postgres/20251025020912_20251024190908.sql new file mode 100644 index 000000000..8c697c967 --- /dev/null +++ b/taco/migrations/postgres/20251025020912_20251024190908.sql @@ -0,0 +1,167 @@ +-- Create "unit_tags" table +CREATE TABLE "public"."unit_tags" ( + "unit_id" character varying(36) NOT NULL, + "tag_id" character varying(36) NOT NULL, + PRIMARY KEY ("unit_id", "tag_id") +); +-- Create index "idx_unit_tags_tag_id" to table: "unit_tags" +CREATE INDEX "idx_unit_tags_tag_id" ON "public"."unit_tags" ("tag_id"); +-- Create index "idx_unit_tags_unit_id" to table: "unit_tags" +CREATE INDEX "idx_unit_tags_unit_id" ON "public"."unit_tags" ("unit_id"); +-- Create "permissions" table +CREATE TABLE "public"."permissions" ( + "id" character varying(36) NOT NULL, + "org_id" character varying(36) NULL, + "name" character varying(255) NOT NULL, + "description" text NULL, + "created_by" text NULL, + "created_at" timestamptz NULL, + PRIMARY KEY ("id") +); +-- Create index "idx_permissions_name" to table: "permissions" +CREATE INDEX "idx_permissions_name" ON "public"."permissions" ("name"); +-- Create index "idx_permissions_org_id" to table: "permissions" +CREATE INDEX "idx_permissions_org_id" ON "public"."permissions" ("org_id"); +-- Create "role_permissions" table +CREATE TABLE "public"."role_permissions" ( + "role_id" character varying(36) NOT NULL, + "permission_id" character varying(36) NOT NULL, + PRIMARY KEY ("role_id", "permission_id") +); +-- Create index "idx_role_permissions_permission_id" to table: "role_permissions" +CREATE INDEX "idx_role_permissions_permission_id" ON "public"."role_permissions" ("permission_id"); +-- Create index "idx_role_permissions_role_id" to table: "role_permissions" +CREATE INDEX "idx_role_permissions_role_id" ON "public"."role_permissions" ("role_id"); +-- Create "roles" table +CREATE TABLE "public"."roles" ( + "id" character varying(36) NOT NULL, + "org_id" character varying(36) NULL, + "name" character varying(255) NOT NULL, + "description" text NULL, + "created_at" timestamptz NULL, + "created_by" text NULL, + PRIMARY KEY ("id") +); +-- Create index "idx_roles_name" to table: "roles" +CREATE INDEX "idx_roles_name" ON "public"."roles" ("name"); +-- Create index "idx_roles_org_id" to table: "roles" +CREATE INDEX "idx_roles_org_id" ON "public"."roles" ("org_id"); +-- Create "tags" table +CREATE TABLE "public"."tags" ( + "id" character varying(36) NOT NULL, + "org_id" character varying(36) NULL, + "name" character varying(255) NOT NULL, + PRIMARY KEY ("id") +); +-- Create index "idx_tags_name" to table: "tags" +CREATE INDEX "idx_tags_name" ON "public"."tags" ("name"); +-- Create index "idx_tags_org_id" to table: "tags" +CREATE INDEX "idx_tags_org_id" ON "public"."tags" ("org_id"); +-- Create "organizations" table +CREATE TABLE "public"."organizations" ( + "id" character varying(36) NOT NULL, + "name" character varying(255) NOT NULL, + "display_name" character varying(255) NOT NULL, + "external_org_id" character varying(500) NULL, + "created_by" character varying(255) NOT NULL, + "created_at" timestamptz NULL, + "updated_at" timestamptz NULL, + PRIMARY KEY ("id") +); +-- Create index "idx_organizations_external_org_id" to table: "organizations" +CREATE UNIQUE INDEX "idx_organizations_external_org_id" ON "public"."organizations" ("external_org_id"); +-- Create index "idx_organizations_name" to table: "organizations" +CREATE UNIQUE INDEX "idx_organizations_name" ON "public"."organizations" ("name"); +-- Create "units" table +CREATE TABLE "public"."units" ( + "id" character varying(36) NOT NULL, + "org_id" character varying(36) NULL, + "name" character varying(255) NOT NULL, + "size" integer NULL DEFAULT 0, + "updated_at" timestamptz NULL, + "locked" boolean NULL DEFAULT false, + "lock_id" text NULL DEFAULT '', + "lock_who" text NULL DEFAULT '', + "lock_created" timestamptz NULL, + PRIMARY KEY ("id") +); +-- Create index "idx_units_name" to table: "units" +CREATE INDEX "idx_units_name" ON "public"."units" ("name"); +-- Create index "idx_units_org_id" to table: "units" +CREATE INDEX "idx_units_org_id" ON "public"."units" ("org_id"); +-- Create "user_roles" table +CREATE TABLE "public"."user_roles" ( + "user_id" character varying(36) NOT NULL, + "role_id" character varying(36) NOT NULL, + "org_id" character varying(36) NOT NULL, + PRIMARY KEY ("user_id", "role_id", "org_id") +); +-- Create index "idx_user_roles_org_id" to table: "user_roles" +CREATE INDEX "idx_user_roles_org_id" ON "public"."user_roles" ("org_id"); +-- Create index "idx_user_roles_role_id" to table: "user_roles" +CREATE INDEX "idx_user_roles_role_id" ON "public"."user_roles" ("role_id"); +-- Create index "idx_user_roles_user_id" to table: "user_roles" +CREATE INDEX "idx_user_roles_user_id" ON "public"."user_roles" ("user_id"); +-- Create "users" table +CREATE TABLE "public"."users" ( + "id" character varying(36) NOT NULL, + "subject" character varying(255) NOT NULL, + "email" character varying(255) NOT NULL, + "created_at" timestamptz NULL, + "updated_at" timestamptz NULL, + "version" integer NULL, + PRIMARY KEY ("id") +); +-- Create index "idx_users_email" to table: "users" +CREATE UNIQUE INDEX "idx_users_email" ON "public"."users" ("email"); +-- Create index "idx_users_subject" to table: "users" +CREATE UNIQUE INDEX "idx_users_subject" ON "public"."users" ("subject"); +-- Create "rules" table +CREATE TABLE "public"."rules" ( + "id" character varying(36) NOT NULL, + "permission_id" character varying(36) NOT NULL, + "effect" text NOT NULL DEFAULT 'allow', + "wildcard_action" boolean NOT NULL DEFAULT false, + "wildcard_resource" boolean NOT NULL DEFAULT false, + "resource_patterns" text NULL, + PRIMARY KEY ("id"), + CONSTRAINT "fk_permissions_rules" FOREIGN KEY ("permission_id") REFERENCES "public"."permissions" ("id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "idx_rules_permission_id" to table: "rules" +CREATE INDEX "idx_rules_permission_id" ON "public"."rules" ("permission_id"); +-- Create "rule_actions" table +CREATE TABLE "public"."rule_actions" ( + "id" character varying(36) NOT NULL, + "rule_id" character varying(36) NOT NULL, + "action" text NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "fk_rules_actions" FOREIGN KEY ("rule_id") REFERENCES "public"."rules" ("id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "idx_rule_actions_action" to table: "rule_actions" +CREATE INDEX "idx_rule_actions_action" ON "public"."rule_actions" ("action"); +-- Create index "idx_rule_actions_rule_id" to table: "rule_actions" +CREATE INDEX "idx_rule_actions_rule_id" ON "public"."rule_actions" ("rule_id"); +-- Create "rule_unit_tags" table +CREATE TABLE "public"."rule_unit_tags" ( + "id" character varying(36) NOT NULL, + "rule_id" character varying(36) NOT NULL, + "tag_id" character varying(36) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "fk_rules_tag_targets" FOREIGN KEY ("rule_id") REFERENCES "public"."rules" ("id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "idx_rule_unit_tags_rule_id" to table: "rule_unit_tags" +CREATE INDEX "idx_rule_unit_tags_rule_id" ON "public"."rule_unit_tags" ("rule_id"); +-- Create index "idx_rule_unit_tags_tag_id" to table: "rule_unit_tags" +CREATE INDEX "idx_rule_unit_tags_tag_id" ON "public"."rule_unit_tags" ("tag_id"); +-- Create "rule_units" table +CREATE TABLE "public"."rule_units" ( + "id" character varying(36) NOT NULL, + "rule_id" character varying(36) NOT NULL, + "unit_id" character varying(36) NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "fk_rules_unit_targets" FOREIGN KEY ("rule_id") REFERENCES "public"."rules" ("id") ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "idx_rule_units_rule_id" to table: "rule_units" +CREATE INDEX "idx_rule_units_rule_id" ON "public"."rule_units" ("rule_id"); +-- Create index "idx_rule_units_unit_id" to table: "rule_units" +CREATE INDEX "idx_rule_units_unit_id" ON "public"."rule_units" ("unit_id"); diff --git a/taco/migrations/sqlite/20251025020916_20251024190908.sql b/taco/migrations/sqlite/20251025020916_20251024190908.sql new file mode 100644 index 000000000..c09850f6f --- /dev/null +++ b/taco/migrations/sqlite/20251025020916_20251024190908.sql @@ -0,0 +1,167 @@ +-- Create "organizations" table +CREATE TABLE `organizations` ( + `id` varchar NULL, + `name` varchar NOT NULL, + `display_name` varchar NOT NULL, + `external_org_id` varchar NULL, + `created_by` varchar NOT NULL, + `created_at` datetime NULL, + `updated_at` datetime NULL, + PRIMARY KEY (`id`) +); +-- Create index "idx_organizations_external_org_id" to table: "organizations" +CREATE UNIQUE INDEX `idx_organizations_external_org_id` ON `organizations` (`external_org_id`); +-- Create index "idx_organizations_name" to table: "organizations" +CREATE UNIQUE INDEX `idx_organizations_name` ON `organizations` (`name`); +-- Create "users" table +CREATE TABLE `users` ( + `id` varchar NULL, + `subject` varchar NOT NULL, + `email` varchar NOT NULL, + `created_at` datetime NULL, + `updated_at` datetime NULL, + `version` integer NULL, + PRIMARY KEY (`id`) +); +-- Create index "idx_users_email" to table: "users" +CREATE UNIQUE INDEX `idx_users_email` ON `users` (`email`); +-- Create index "idx_users_subject" to table: "users" +CREATE UNIQUE INDEX `idx_users_subject` ON `users` (`subject`); +-- Create "user_roles" table +CREATE TABLE `user_roles` ( + `user_id` varchar NULL, + `role_id` varchar NULL, + `org_id` varchar NULL, + PRIMARY KEY (`user_id`, `role_id`, `org_id`) +); +-- Create index "idx_user_roles_org_id" to table: "user_roles" +CREATE INDEX `idx_user_roles_org_id` ON `user_roles` (`org_id`); +-- Create index "idx_user_roles_role_id" to table: "user_roles" +CREATE INDEX `idx_user_roles_role_id` ON `user_roles` (`role_id`); +-- Create index "idx_user_roles_user_id" to table: "user_roles" +CREATE INDEX `idx_user_roles_user_id` ON `user_roles` (`user_id`); +-- Create "roles" table +CREATE TABLE `roles` ( + `id` varchar NULL, + `org_id` varchar NULL, + `name` varchar NOT NULL, + `description` text NULL, + `created_at` datetime NULL, + `created_by` text NULL, + PRIMARY KEY (`id`) +); +-- Create index "idx_roles_name" to table: "roles" +CREATE INDEX `idx_roles_name` ON `roles` (`name`); +-- Create index "idx_roles_org_id" to table: "roles" +CREATE INDEX `idx_roles_org_id` ON `roles` (`org_id`); +-- Create "role_permissions" table +CREATE TABLE `role_permissions` ( + `role_id` varchar NULL, + `permission_id` varchar NULL, + PRIMARY KEY (`role_id`, `permission_id`) +); +-- Create index "idx_role_permissions_permission_id" to table: "role_permissions" +CREATE INDEX `idx_role_permissions_permission_id` ON `role_permissions` (`permission_id`); +-- Create index "idx_role_permissions_role_id" to table: "role_permissions" +CREATE INDEX `idx_role_permissions_role_id` ON `role_permissions` (`role_id`); +-- Create "permissions" table +CREATE TABLE `permissions` ( + `id` varchar NULL, + `org_id` varchar NULL, + `name` varchar NOT NULL, + `description` text NULL, + `created_by` text NULL, + `created_at` datetime NULL, + PRIMARY KEY (`id`) +); +-- Create index "idx_permissions_name" to table: "permissions" +CREATE INDEX `idx_permissions_name` ON `permissions` (`name`); +-- Create index "idx_permissions_org_id" to table: "permissions" +CREATE INDEX `idx_permissions_org_id` ON `permissions` (`org_id`); +-- Create "rules" table +CREATE TABLE `rules` ( + `id` varchar NULL, + `permission_id` varchar NOT NULL, + `effect` text NOT NULL DEFAULT 'allow', + `wildcard_action` numeric NOT NULL DEFAULT false, + `wildcard_resource` numeric NOT NULL DEFAULT false, + `resource_patterns` text NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_permissions_rules` FOREIGN KEY (`permission_id`) REFERENCES `permissions` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "idx_rules_permission_id" to table: "rules" +CREATE INDEX `idx_rules_permission_id` ON `rules` (`permission_id`); +-- Create "rule_actions" table +CREATE TABLE `rule_actions` ( + `id` varchar NULL, + `rule_id` varchar NOT NULL, + `action` text NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_rules_actions` FOREIGN KEY (`rule_id`) REFERENCES `rules` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "idx_rule_actions_action" to table: "rule_actions" +CREATE INDEX `idx_rule_actions_action` ON `rule_actions` (`action`); +-- Create index "idx_rule_actions_rule_id" to table: "rule_actions" +CREATE INDEX `idx_rule_actions_rule_id` ON `rule_actions` (`rule_id`); +-- Create "rule_units" table +CREATE TABLE `rule_units` ( + `id` varchar NULL, + `rule_id` varchar NOT NULL, + `unit_id` varchar NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_rules_unit_targets` FOREIGN KEY (`rule_id`) REFERENCES `rules` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "idx_rule_units_unit_id" to table: "rule_units" +CREATE INDEX `idx_rule_units_unit_id` ON `rule_units` (`unit_id`); +-- Create index "idx_rule_units_rule_id" to table: "rule_units" +CREATE INDEX `idx_rule_units_rule_id` ON `rule_units` (`rule_id`); +-- Create "rule_unit_tags" table +CREATE TABLE `rule_unit_tags` ( + `id` varchar NULL, + `rule_id` varchar NOT NULL, + `tag_id` varchar NOT NULL, + PRIMARY KEY (`id`), + CONSTRAINT `fk_rules_tag_targets` FOREIGN KEY (`rule_id`) REFERENCES `rules` (`id`) ON UPDATE NO ACTION ON DELETE CASCADE +); +-- Create index "idx_rule_unit_tags_tag_id" to table: "rule_unit_tags" +CREATE INDEX `idx_rule_unit_tags_tag_id` ON `rule_unit_tags` (`tag_id`); +-- Create index "idx_rule_unit_tags_rule_id" to table: "rule_unit_tags" +CREATE INDEX `idx_rule_unit_tags_rule_id` ON `rule_unit_tags` (`rule_id`); +-- Create "units" table +CREATE TABLE `units` ( + `id` varchar NULL, + `org_id` varchar NULL, + `name` varchar NOT NULL, + `size` integer NULL DEFAULT 0, + `updated_at` datetime NULL, + `locked` numeric NULL DEFAULT false, + `lock_id` text NULL DEFAULT '', + `lock_who` text NULL DEFAULT '', + `lock_created` datetime NULL, + PRIMARY KEY (`id`) +); +-- Create index "idx_units_name" to table: "units" +CREATE INDEX `idx_units_name` ON `units` (`name`); +-- Create index "idx_units_org_id" to table: "units" +CREATE INDEX `idx_units_org_id` ON `units` (`org_id`); +-- Create "unit_tags" table +CREATE TABLE `unit_tags` ( + `unit_id` varchar NULL, + `tag_id` varchar NULL, + PRIMARY KEY (`unit_id`, `tag_id`) +); +-- Create index "idx_unit_tags_tag_id" to table: "unit_tags" +CREATE INDEX `idx_unit_tags_tag_id` ON `unit_tags` (`tag_id`); +-- Create index "idx_unit_tags_unit_id" to table: "unit_tags" +CREATE INDEX `idx_unit_tags_unit_id` ON `unit_tags` (`unit_id`); +-- Create "tags" table +CREATE TABLE `tags` ( + `id` varchar NULL, + `org_id` varchar NULL, + `name` varchar NOT NULL, + PRIMARY KEY (`id`) +); +-- Create index "idx_tags_name" to table: "tags" +CREATE INDEX `idx_tags_name` ON `tags` (`name`); +-- Create index "idx_tags_org_id" to table: "tags" +CREATE INDEX `idx_tags_org_id` ON `tags` (`org_id`); diff --git a/taco/scripts/entrypoint.sh b/taco/scripts/entrypoint.sh new file mode 100644 index 000000000..ff2c8c935 --- /dev/null +++ b/taco/scripts/entrypoint.sh @@ -0,0 +1,45 @@ +#!/bin/bash +set -e + +# Determine which database backend is being used +BACKEND=${OPENTACO_QUERY_BACKEND:-sqlite} + +echo "Starting OpenTaco Statesman with backend: $BACKEND" + +# Generate checksums for migration directories (atlas.sum files are gitignored) +echo "Generating migration checksums..." +atlas migrate hash --dir "file:///app/migrations/postgres" 2>/dev/null || true +atlas migrate hash --dir "file:///app/migrations/mysql" 2>/dev/null || true +atlas migrate hash --dir "file:///app/migrations/sqlite" 2>/dev/null || true + +# Apply migrations based on backend type +case $BACKEND in + postgres) + echo "Applying PostgreSQL migrations..." + DB_URL="postgres://${OPENTACO_POSTGRES_USER}:${OPENTACO_POSTGRES_PASSWORD}@${OPENTACO_POSTGRES_HOST}:${OPENTACO_POSTGRES_PORT}/${OPENTACO_POSTGRES_DATABASE}?sslmode=${OPENTACO_POSTGRES_SSLMODE:-disable}" + atlas migrate apply --url "$DB_URL" --dir "file:///app/migrations/postgres" + ;; + mysql) + echo "Applying MySQL migrations..." + DB_URL="mysql://${OPENTACO_MYSQL_USER}:${OPENTACO_MYSQL_PASSWORD}@${OPENTACO_MYSQL_HOST}:${OPENTACO_MYSQL_PORT}/${OPENTACO_MYSQL_DATABASE}" + atlas migrate apply --url "$DB_URL" --dir "file:///app/migrations/mysql" + ;; + sqlite) + echo "Applying SQLite migrations..." + SQLITE_PATH=${OPENTACO_SQLITE_DB_PATH:-/app/data/taco.db} + # Ensure directory exists + mkdir -p "$(dirname "$SQLITE_PATH")" + DB_URL="sqlite://$SQLITE_PATH" + atlas migrate apply --url "$DB_URL" --dir "file:///app/migrations/sqlite" + ;; + *) + echo "Unknown backend: $BACKEND" + exit 1 + ;; +esac + +echo "Migrations applied successfully. Starting statesman..." + +# Start the statesman binary +exec /app/statesman "$@" +