Skip to content

Commit 77ea9af

Browse files
committed
fix deploy approval rack handling
1 parent c75a2e2 commit 77ea9af

28 files changed

Lines changed: 416 additions & 98 deletions

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- name: Setup Go
2020
uses: actions/setup-go@v5
2121
with:
22-
go-version: "1.26.1"
22+
go-version: "1.26.2"
2323

2424
- name: Install libfido2 dependencies
2525
run: |
@@ -63,7 +63,7 @@ jobs:
6363
- name: Setup Go
6464
uses: actions/setup-go@v5
6565
with:
66-
go-version: "1.26.1"
66+
go-version: "1.26.2"
6767

6868
- name: Cache golangci-lint cache
6969
uses: actions/cache@v4

.github/workflows/e2e.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ jobs:
157157
- name: Setup Go
158158
uses: actions/setup-go@v5
159159
with:
160-
go-version: "1.26.1"
160+
go-version: "1.26.2"
161161

162162
- name: Download gateway image
163163
uses: actions/download-artifact@v4

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
- name: Setup Go
7878
uses: actions/setup-go@v5
7979
with:
80-
go-version: "1.26.1"
80+
go-version: "1.26.2"
8181
- name: Build binary
8282
env:
8383
CGO_ENABLED: 0

Dockerfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,15 @@ RUN bun install --frozen-lockfile
1515
COPY web/ ./
1616
RUN bun run build
1717

18-
FROM golang:1.26.1-alpine AS builder
18+
FROM golang:1.26.2-alpine AS builder
1919

2020
RUN apk add --no-cache git ca-certificates make gcc musl-dev nodejs npm
2121

2222
WORKDIR /app
2323

2424
# Cache go mod download
2525
COPY go.mod go.sum ./
26+
COPY internal/shims ./internal/shims
2627
RUN go mod download
2728

2829
# Copy version source (package.json for version number)

Dockerfile.gateway-dev

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
FROM golang:1.26.1-alpine AS builder
1+
FROM golang:1.26.2-alpine AS builder
22

33
RUN apk add --no-cache git ca-certificates make gcc musl-dev
44

55
WORKDIR /app
66

77
# Cache go mod download
88
COPY go.mod go.sum ./
9+
COPY internal/shims ./internal/shims
910
RUN --mount=type=cache,target=/go/pkg/mod,sharing=locked \
1011
--mount=type=cache,target=/root/.cache/go-build,sharing=locked \
1112
go mod download

Dockerfile.mock-convox

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
# Build stage
22
# syntax=docker/dockerfile:1.5
33

4-
FROM golang:1.26.1-alpine AS builder
4+
FROM golang:1.26.2-alpine AS builder
55

66
RUN apk add --no-cache git make
77

88
WORKDIR /app
99

1010
# Cache go dependencies with BuildKit caches
1111
COPY go.mod go.sum ./
12+
COPY internal/shims ./internal/shims
1213
RUN --mount=type=cache,target=/go/pkg/mod,sharing=locked \
1314
--mount=type=cache,target=/root/.cache/go-build,sharing=locked \
1415
go mod download

go.mod

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module github.com/DocSpring/rack-gateway
22

3-
go 1.26.1
3+
go 1.26.2
44

55
require (
66
github.com/GeertJohan/yubigo v0.0.0-20190917122436-175bc097e60e
@@ -45,7 +45,6 @@ require (
4545
cloud.google.com/go/compute/metadata v0.3.0 // indirect
4646
cloud.google.com/go/iam v1.1.1 // indirect
4747
cloud.google.com/go/storage v1.30.1 // indirect
48-
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8 // indirect
4948
github.com/Azure/azure-pipeline-go v0.2.2 // indirect
5049
github.com/Azure/azure-sdk-for-go v66.0.0+incompatible // indirect
5150
github.com/Azure/azure-storage-file-go v0.6.0 // indirect
@@ -106,7 +105,7 @@ require (
106105
github.com/creack/pty v1.1.18 // indirect
107106
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
108107
github.com/dimchansky/utfbom v1.1.1 // indirect
109-
github.com/docker/docker v28.0.0+incompatible // indirect
108+
github.com/docker/docker/pkg/archive v0.0.0-00010101000000-000000000000 // indirect
110109
github.com/docker/engine v1.4.2-0.20190717161051-705d9623b7c1 // indirect
111110
github.com/dustin/go-humanize v1.0.0 // indirect
112111
github.com/elastic/go-elasticsearch/v6 v6.8.2 // indirect
@@ -156,7 +155,7 @@ require (
156155
github.com/josharian/intern v1.0.0 // indirect
157156
github.com/json-iterator/go v1.1.12 // indirect
158157
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
159-
github.com/klauspost/compress v1.17.7 // indirect
158+
github.com/klauspost/compress v1.18.2 // indirect
160159
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
161160
github.com/leodido/go-urn v1.4.0 // indirect
162161
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
@@ -167,11 +166,12 @@ require (
167166
github.com/mitchellh/go-homedir v1.1.0 // indirect
168167
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
169168
github.com/mitchellh/mapstructure v1.5.0 // indirect
170-
github.com/moby/buildkit v0.10.6 // indirect
169+
github.com/moby/buildkit/frontend/dockerfile/dockerignore v0.0.0 // indirect
170+
github.com/moby/go-archive v0.2.0 // indirect
171171
github.com/moby/patternmatcher v0.6.0 // indirect
172172
github.com/moby/spdystream v0.5.0 // indirect
173173
github.com/moby/sys/sequential v0.6.0 // indirect
174-
github.com/moby/sys/user v0.1.0 // indirect
174+
github.com/moby/sys/user v0.4.0 // indirect
175175
github.com/moby/sys/userns v0.1.0 // indirect
176176
github.com/moby/term v0.5.0 // indirect
177177
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -229,7 +229,6 @@ require (
229229
gopkg.in/inf.v0 v0.9.1 // indirect
230230
gopkg.in/yaml.v2 v2.4.0 // indirect
231231
gotest.tools v2.2.0+incompatible // indirect
232-
gotest.tools/v3 v3.0.3 // indirect
233232
k8s.io/api v0.32.7 // indirect
234233
k8s.io/apiextensions-apiserver v0.25.2 // indirect
235234
k8s.io/apimachinery v0.32.7 // indirect
@@ -250,3 +249,11 @@ require (
250249
sigs.k8s.io/structured-merge-diff/v4 v4.7.0 // indirect
251250
sigs.k8s.io/yaml v1.4.0 // indirect
252251
)
252+
253+
replace github.com/docker/docker => ./internal/shims/docker-root
254+
255+
replace github.com/docker/docker/pkg/archive => ./internal/shims/docker-archive
256+
257+
replace github.com/moby/buildkit => ./internal/shims/buildkit-root
258+
259+
replace github.com/moby/buildkit/frontend/dockerfile/dockerignore => ./internal/shims/buildkit-dockerignore

go.sum

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
88
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
99
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
1010
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
11-
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8 h1:V8krnnfGj4pV65YLUm3C0/8bl7V5Nry2Pwvy3ru/wLc=
12-
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg=
11+
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
12+
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
1313
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
1414
github.com/Azure/azure-pipeline-go v0.2.2 h1:6oiIS9yaG6XCCzhgAgKFfIWyo4LLCiDhZot6ltoThhY=
1515
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
@@ -186,8 +186,6 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
186186
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
187187
github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U=
188188
github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE=
189-
github.com/docker/docker v28.0.0+incompatible h1:Olh0KS820sJ7nPsBKChVhk5pzqcwDR15fumfAd/p9hM=
190-
github.com/docker/docker v28.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
191189
github.com/docker/engine v1.4.2-0.20190717161051-705d9623b7c1 h1:HjO0YFIGk26fADKDJYuAoGneX9nrVVotZJ1Ctn15Vv4=
192190
github.com/docker/engine v1.4.2-0.20190717161051-705d9623b7c1/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY=
193191
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
@@ -378,8 +376,8 @@ github.com/keys-pub/go-libfido2 v1.5.4-0.20250104233141-2534349bd685 h1:zSJ+Njvd
378376
github.com/keys-pub/go-libfido2 v1.5.4-0.20250104233141-2534349bd685/go.mod h1:92J9LtSBl0UyUWljElJpTbMMNhC6VeY8dshsu40qjjo=
379377
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
380378
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
381-
github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg=
382-
github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
379+
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
380+
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
383381
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
384382
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
385383
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -420,16 +418,16 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ
420418
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
421419
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
422420
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
423-
github.com/moby/buildkit v0.10.6 h1:DJlEuLIgnu34HQKF4n9Eg6q2YqQVC0eOpMb4p2eRS2w=
424-
github.com/moby/buildkit v0.10.6/go.mod h1:tQuuyTWtOb9D+RE425cwOCUkX0/oZ+5iBZ+uWpWQ9bU=
421+
github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
422+
github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU=
425423
github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk=
426424
github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
427425
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
428426
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
429427
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
430428
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
431-
github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg=
432-
github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU=
429+
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
430+
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
433431
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
434432
github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28=
435433
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
@@ -513,7 +511,6 @@ github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
513511
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
514512
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
515513
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
516-
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
517514
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
518515
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
519516
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
@@ -684,7 +681,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3
684681
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
685682
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
686683
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
687-
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
688684
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
689685
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
690686
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
@@ -757,8 +753,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
757753
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
758754
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
759755
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
760-
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
761-
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
756+
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
757+
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
762758
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
763759
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
764760
k8s.io/api v0.32.7 h1:CBhHkoi3YJW8QQI6VL/Hu9f1HHVImmuIh513d4H4VfQ=

internal/cli/CLAUDE.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Structure:
6464
- `mfa_preference` - Default MFA method: `"default"`, `"webauthn"`, or `"totp"`
6565
- `notification_sound` - Default notification sound: `"default"`, `"disabled"`, or path to MP3 file
6666
- `sound_volume` - Default sound volume: 0.0 to 1.0 (default: 0.6 = 60%)
67-
- `all_racks_exclude` - Array of rack names to exclude when using `--racks all`
67+
- `all_racks_exclude` - Array of rack names to exclude when using `--rack all`
6868

6969
**Per-Rack Settings (GatewayConfig):**
7070
- `url` - Gateway API URL
@@ -80,19 +80,19 @@ Structure:
8080
- `notification_sound` - Per-rack notification sound override
8181
- `sound_volume` - Per-rack sound volume override (0.0 to 1.0)
8282

83-
**Using --racks all:**
83+
**Using --rack all:**
8484

85-
Deploy approval commands support `--racks all` to operate on all configured racks:
85+
Deploy approval commands support `--rack all` to operate on all configured racks:
8686

8787
```bash
8888
# Wait for deploy approval on all production racks (excluding dev)
89-
cx deploy-approval wait --racks all --commit abc123
89+
cx deploy-approval wait --rack all --commit abc123
9090

9191
# Approve deploy on all racks
92-
cx deploy-approval approve --racks all --commit abc123
92+
cx deploy-approval approve --rack all --commit abc123
9393

9494
# List deploy approval requests from all racks
95-
cx deploy-approval list --racks all
95+
cx deploy-approval list --rack all
9696
```
9797

9898
The `all` value expands to all configured racks in `gateways`, excluding any racks listed in `all_racks_exclude`. This is useful for avoiding local development racks when operating on production infrastructure.

internal/cli/cli_login.go

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"os"
7+
"strings"
78
"time"
89

910
"github.com/spf13/cobra"
@@ -20,7 +21,8 @@ func LoginCommand() *cobra.Command {
2021
Long: `Login to a Convox rack via OAuth.
2122
2223
If no arguments are provided, re-authenticates with the current rack.
23-
Otherwise, provide both rack name and gateway URL to login to a new rack.`,
24+
Provide a rack name to re-authenticate against a configured rack URL.
25+
Provide both rack name and gateway URL to login to a new rack.`,
2426
Args: cobra.RangeArgs(0, 2),
2527
RunE: func(_ *cobra.Command, args []string) error {
2628
return loginCommandWithFlags(args, noOpen, authFile)
@@ -68,13 +70,14 @@ func loginCommandWithFlags(args []string, noOpen bool, authFile string) error {
6870
}
6971

7072
func resolveLoginTarget(args []string) (string, string, error) {
73+
rackArg, gatewayArg := normalizeLoginArgs(args)
7174
switch len(args) {
7275
case 0:
7376
rack, err := SelectedRack()
7477
if err != nil {
7578
return "", "", fmt.Errorf("no current rack selected: %w. Run: rack-gateway login <rack> <gateway-url>", err)
7679
}
77-
gatewayURL, _, err := LoadRackAuth(rack)
80+
gatewayURL, err := resolveLoginGatewayURL(rack)
7881
if err != nil {
7982
return "", "", fmt.Errorf(
8083
"rack %s not configured: %w. Run: rack-gateway login <rack> <gateway-url>",
@@ -84,9 +87,24 @@ func resolveLoginTarget(args []string) (string, string, error) {
8487
}
8588
return rack, gatewayURL, nil
8689
case 1:
87-
return "", "", fmt.Errorf("both rack name and gateway URL are required")
90+
rack := rackArg
91+
if rack == "" {
92+
return "", "", fmt.Errorf("rack name cannot be empty")
93+
}
94+
gatewayURL, err := resolveLoginGatewayURL(rack)
95+
if err != nil {
96+
return "", "", fmt.Errorf("gateway URL required for rack %s: %w", rack, err)
97+
}
98+
return rack, gatewayURL, nil
8899
case 2:
89-
rack, gatewayURL := args[0], args[1]
100+
rack := rackArg
101+
gatewayURL := gatewayArg
102+
if rack == "" {
103+
return "", "", fmt.Errorf("rack name cannot be empty")
104+
}
105+
if gatewayURL == "" {
106+
return "", "", fmt.Errorf("gateway URL cannot be empty")
107+
}
90108
if err := SaveGatewayConfig(rack, gatewayURL); err != nil {
91109
return "", "", fmt.Errorf("failed to save gateway config: %w", err)
92110
}
@@ -96,6 +114,30 @@ func resolveLoginTarget(args []string) (string, string, error) {
96114
}
97115
}
98116

117+
func normalizeLoginArgs(args []string) (string, string) {
118+
var rack string
119+
var gatewayURL string
120+
for i, arg := range args {
121+
switch i {
122+
case 0:
123+
rack = strings.TrimSpace(arg)
124+
case 1:
125+
gatewayURL = strings.TrimSpace(arg)
126+
}
127+
}
128+
return rack, gatewayURL
129+
}
130+
131+
func resolveLoginGatewayURL(rack string) (string, error) {
132+
if gatewayURL := strings.TrimSpace(os.Getenv("RACK_GATEWAY_URL")); gatewayURL != "" {
133+
if err := SaveGatewayConfig(rack, gatewayURL); err != nil {
134+
return "", fmt.Errorf("failed to save gateway config: %w", err)
135+
}
136+
return gatewayURL, nil
137+
}
138+
return LoadGatewayURL(rack)
139+
}
140+
99141
func writeAuthFile(path string, startResp *LoginStartResponse) error {
100142
if path == "" {
101143
return nil

0 commit comments

Comments
 (0)