diff --git a/go.mod b/go.mod index f509963b..4885a05e 100644 --- a/go.mod +++ b/go.mod @@ -3,19 +3,9 @@ module github.com/brevdev/brev-cli go 1.22.6 require ( - github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 github.com/alessio/shellescape v1.4.1 - github.com/aws/aws-sdk-go-v2 v1.16.16 - github.com/aws/aws-sdk-go-v2/config v1.17.8 - github.com/aws/aws-sdk-go-v2/service/costexplorer v1.21.0 - github.com/aws/aws-sdk-go-v2/service/dlm v1.13.0 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.63.1 - github.com/aws/aws-sdk-go-v2/service/iam v1.18.20 - github.com/aws/aws-sdk-go-v2/service/pricing v1.17.1 - github.com/aws/aws-sdk-go-v2/service/servicequotas v1.13.18 github.com/brevdev/parse v0.0.11 github.com/briandowns/spinner v1.16.0 - github.com/cenkalti/backoff/v4 v4.3.0 github.com/docker/docker v20.10.23+incompatible github.com/fatih/color v1.13.0 github.com/getsentry/sentry-go v0.14.0 @@ -33,14 +23,12 @@ require ( github.com/jinzhu/copier v0.4.0 github.com/kevinburke/ssh_config v1.2.0 github.com/manifoldco/promptui v0.9.0 - github.com/mitchellh/mapstructure v1.5.0 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 github.com/pkg/errors v0.9.1 github.com/robfig/cron/v3 v3.0.1 github.com/samber/lo v1.33.0 github.com/samber/mo v1.5.1 github.com/schollz/progressbar/v3 v3.9.0 - github.com/segmentio/ksuid v1.0.4 github.com/sevlyar/go-daemon v0.1.5 github.com/sirupsen/logrus v1.9.0 github.com/spf13/afero v1.9.2 @@ -51,9 +39,7 @@ require ( github.com/tweekmonster/luser v0.0.0-20161003172636-3fa38070dbd7 github.com/wk8/go-ordered-map/v2 v2.0.0 github.com/writeas/go-strip-markdown v2.0.1+incompatible - go.opentelemetry.io/otel v1.10.0 golang.org/x/crypto v0.24.0 - golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 golang.org/x/text v0.16.0 k8s.io/cli-runtime v0.31.1 k8s.io/client-go v0.31.1 @@ -64,16 +50,6 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.12.21 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.11.23 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.6 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.16.19 // indirect - github.com/aws/smithy-go v1.13.3 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bytedance/sonic v1.11.6 // indirect @@ -93,7 +69,6 @@ require ( github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.5.0 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.20.0 // indirect @@ -102,14 +77,13 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/term v0.5.0 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect github.com/pelletier/go-toml v1.9.5 // indirect @@ -126,8 +100,8 @@ require ( github.com/ugorji/go/codec v1.2.12 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect - go.opentelemetry.io/otel/trace v1.10.0 // indirect golang.org/x/arch v0.8.0 // indirect + golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 // indirect golang.org/x/mod v0.17.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect @@ -166,7 +140,6 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect - github.com/moby/spdystream v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect diff --git a/go.sum b/go.sum index 9259af94..68814edf 100644 --- a/go.sum +++ b/go.sum @@ -47,50 +47,12 @@ github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migc github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aws/aws-sdk-go-v2 v1.16.16 h1:M1fj4FE2lB4NzRb9Y0xdWsn2P0+2UHVxwKyOa4YJNjk= -github.com/aws/aws-sdk-go-v2 v1.16.16/go.mod h1:SwiyXi/1zTUZ6KIAmLK5V5ll8SiURNUYOqTerZPaF9k= -github.com/aws/aws-sdk-go-v2/config v1.17.8 h1:b9LGqNnOdg9vR4Q43tBTVWk4J6F+W774MSchvKJsqnE= -github.com/aws/aws-sdk-go-v2/config v1.17.8/go.mod h1:UkCI3kb0sCdvtjiXYiU4Zx5h07BOpgBTtkPu/49r+kA= -github.com/aws/aws-sdk-go-v2/credentials v1.12.21 h1:4tjlyCD0hRGNQivh5dN8hbP30qQhMLBE/FgQR1vHHWM= -github.com/aws/aws-sdk-go-v2/credentials v1.12.21/go.mod h1:O+4XyAt4e+oBAoIwNUYkRg3CVMscaIJdmZBOcPgJ8D8= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17 h1:r08j4sbZu/RVi+BNxkBJwPMUYY3P8mgSDuKkZ/ZN1lE= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.17/go.mod h1:yIkQcCDYNsZfXpd5UX2Cy+sWA1jPgIhGTw9cOBzfVnQ= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23 h1:s4g/wnzMf+qepSNgTvaQQHNxyMLKSawNhKCPNy++2xY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.23/go.mod h1:2DFxAQ9pfIRy0imBCJv+vZ2X6RKxves6fbnEuSry6b4= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17 h1:/K482T5A3623WJgWT8w1yRAFK4RzGzEl7y39yhtn9eA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.17/go.mod h1:pRwaTYCJemADaqCbUAxltMoHKata7hmB5PjEXeu0kfg= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24 h1:wj5Rwc05hvUSvKuOF29IYb9QrCLjU+rHAy/x/o0DK2c= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.24/go.mod h1:jULHjqqjDlbyTa7pfM7WICATnOv+iOhjletM3N0Xbu8= -github.com/aws/aws-sdk-go-v2/service/costexplorer v1.21.0 h1:K0ukobM374TprgOdsweMF57xR31UOoOnc7kXGkULLL0= -github.com/aws/aws-sdk-go-v2/service/costexplorer v1.21.0/go.mod h1:+rgkhuF0gVpzTfGbfcyPpkaU7z+IcErFUghZHPDwYGA= -github.com/aws/aws-sdk-go-v2/service/dlm v1.13.0 h1:44gXZl9oRKRb7s1n3cZkh1AIhmGam4dla9Fbn2EAfTQ= -github.com/aws/aws-sdk-go-v2/service/dlm v1.13.0/go.mod h1:yfYybgdz0MGljkiQl8FPmr0+n+601DdIw+XE22d0pVQ= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.63.1 h1:jSS5gynKz4XaGcs6m25idCTN+tvPkRJ2WedSWCcZEjI= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.63.1/go.mod h1:0+6fPoY0SglgzQUs2yml7X/fup12cMlVumJufh5npRQ= -github.com/aws/aws-sdk-go-v2/service/iam v1.18.20 h1:Kv+0rsPs7+Q7b2t9UAVUZONv2qdfSInySmBC9kaCyd8= -github.com/aws/aws-sdk-go-v2/service/iam v1.18.20/go.mod h1:pDBRPE4AibneAh4P6fZuU3eUkAgYirM88o2M2MxIXlg= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17 h1:Jrd/oMh0PKQc6+BowB+pLEwLIgaQF29eYbe7E1Av9Ug= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.17/go.mod h1:4nYOrY41Lrbk2170/BGkcJKBhws9Pfn8MG3aGqjjeFI= -github.com/aws/aws-sdk-go-v2/service/pricing v1.17.1 h1:Wg/TwzCrw0tbnVYmdhJ+2+xNV71QqCl/e6lHA7qR3u0= -github.com/aws/aws-sdk-go-v2/service/pricing v1.17.1/go.mod h1:xTZR/7BgDBEFthXYHhx2V98T288w0UE8fnYEUDaEWk4= -github.com/aws/aws-sdk-go-v2/service/servicequotas v1.13.18 h1:YnU5FAULDk4oSKNqxpi472lDHM5/uhiCHs+IYnd6UME= -github.com/aws/aws-sdk-go-v2/service/servicequotas v1.13.18/go.mod h1:37P6g8ocxIq0FwK3iN6ptBp6DdyxLxNHOSopUkirnxQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.23 h1:pwvCchFUEnlceKIgPUouBJwK81aCkQ8UDMORfeFtW10= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.23/go.mod h1:/w0eg9IhFGjGyyncHIQrXtU8wvNsTJOP0R6PPj0wf80= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.6 h1:OwhhKc1P9ElfWbMKPIbMMZBV6hzJlL2JKD76wNNVzgQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.13.6/go.mod h1:csZuQY65DAdFBt1oIjO5hhBR49kQqop4+lcuCjf2arA= -github.com/aws/aws-sdk-go-v2/service/sts v1.16.19 h1:9pPi0PsFNAGILFfPCk8Y0iyEBGc6lu6OQ97U7hmdesg= -github.com/aws/aws-sdk-go-v2/service/sts v1.16.19/go.mod h1:h4J3oPZQbxLhzGnk+j9dfYHi5qIOVJ5kczZd658/ydM= -github.com/aws/smithy-go v1.13.3 h1:l7LYxGuzK6/K+NzJ2mC+VvLUbae0sL3bXU//04MkmnA= -github.com/aws/smithy-go v1.13.3/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -104,8 +66,6 @@ github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -186,11 +146,8 @@ github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lK github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= @@ -261,7 +218,6 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -325,10 +281,6 @@ github.com/jedib0t/go-pretty/v6 v6.3.1 h1:aOXiD9oqiuLH8btPQW6SfgtQN5zwhyfzZls8a6 github.com/jedib0t/go-pretty/v6 v6.3.1/go.mod h1:FMkOpgGD3EZ91cW8g/96RfxoV7bdeJyzXPYgz1L1ln0= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -381,8 +333,6 @@ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2Em github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= -github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -396,8 +346,6 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= @@ -440,8 +388,6 @@ github.com/samber/mo v1.5.1 h1:5dRSevAB33Q/OrYwTmtksHHxquuf2urnRSUTsdTFysY= github.com/samber/mo v1.5.1/go.mod h1:pDuQgWscOVGGoEz+NAeth/Xq+MPAcXxCeph1XIAm/DU= github.com/schollz/progressbar/v3 v3.9.0 h1:k9SRNQ8KZyibz1UZOaKxnkUE3iGtmGSDt1YY9KlCYQk= github.com/schollz/progressbar/v3 v3.9.0/go.mod h1:W5IEwbJecncFGBvuEh4A7HT1nZZ6WNIL2i3qbnI0WKY= -github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= -github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sevlyar/go-daemon v0.1.5 h1:Zy/6jLbM8CfqJ4x4RPr7MJlSKt90f00kNM1D401C+Qk= @@ -517,10 +463,6 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= -go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= -go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= -go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca h1:VdD38733bfYv5tUZwEIskMM93VanwNIi5bIKnDrJdEY= go.starlark.net v0.0.0-20230525235612-a134d8f9ddca/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= diff --git a/pkg/auth/auth.go b/pkg/auth/auth.go index c5843e6d..d0f9cad9 100644 --- a/pkg/auth/auth.go +++ b/pkg/auth/auth.go @@ -64,6 +64,36 @@ type AuthStore interface { type OAuth interface { DoDeviceAuthFlow(onStateRetrieved func(url string, code string)) (*LoginTokens, error) GetNewAuthTokensWithRefresh(refreshToken string) (*entity.AuthTokens, error) + GetCredentialProvider() entity.CredentialProvider + IsTokenValid(token string) bool +} + +type OAuthRetriever struct { + oauths []OAuth +} + +func NewOAuthRetriever(oauths []OAuth) *OAuthRetriever { + return &OAuthRetriever{ + oauths: oauths, + } +} + +func (o *OAuthRetriever) GetByProvider(provider entity.CredentialProvider) (OAuth, error) { + for _, oauth := range o.oauths { + if oauth.GetCredentialProvider() == provider { + return oauth, nil + } + } + return nil, fmt.Errorf("no oauth found for provider %s", provider) +} + +func (o *OAuthRetriever) GetByToken(token string) (OAuth, error) { + for _, oauth := range o.oauths { + if oauth.IsTokenValid(token) { + return oauth, nil + } + } + return nil, fmt.Errorf("no oauth found for token") } type Auth struct { @@ -263,7 +293,6 @@ type LoginTokens struct { func (t Auth) getSavedTokensOrNil() (*entity.AuthTokens, error) { tokens, err := t.authStore.GetAuthTokens() - fmt.Fprintf(os.Stderr, "AuthTokens: %+v\n", tokens) if err != nil { switch err.(type) { //nolint:gocritic // like the ability to extend case *breverrors.CredentialsFileNotFound: @@ -327,3 +356,31 @@ func isAccessTokenValid(token string) (bool, error) { } return true, nil } + +func IssuerCheck(token string, issuer string) bool { + parser := jwt.Parser{} + claims := jwt.MapClaims{} + _, _, err := parser.ParseUnverified(token, &claims) + if err != nil { + return false + } + iss, ok := claims["iss"].(string) + if !ok { + return false + } + return iss == issuer +} + +func GetEmailFromToken(token string) string { + parser := jwt.Parser{} + claims := jwt.MapClaims{} + _, _, err := parser.ParseUnverified(token, &claims) + if err != nil { + return "" + } + email, ok := claims["email"].(string) + if !ok { + return "" + } + return email +} diff --git a/pkg/auth/auth0.go b/pkg/auth/auth0.go index eedb65eb..2296397a 100644 --- a/pkg/auth/auth0.go +++ b/pkg/auth/auth0.go @@ -43,13 +43,20 @@ var requiredScopes = []string{ "create:organizations", "delete:organizations", "read:organizations", "update:organizations", } +const CredentialProviderAuth0 entity.CredentialProvider = "auth0" + type Auth0Authenticator struct { + Issuer string Audience string ClientID string DeviceCodeEndpoint string OauthTokenEndpoint string } +func (a Auth0Authenticator) GetCredentialProvider() entity.CredentialProvider { + return CredentialProviderAuth0 +} + var _ OAuth = Auth0Authenticator{} type Auth0Result struct { @@ -94,14 +101,17 @@ func (a Auth0Authenticator) DoDeviceAuthFlow(onStateRetrieved func(url string, c return &LoginTokens{ AuthTokens: entity.AuthTokens{ - AccessToken: res.AccessToken, - RefreshToken: res.RefreshToken, - CredentialProvider: entity.CredentialProviderAuth0, + AccessToken: res.AccessToken, + RefreshToken: res.RefreshToken, }, IDToken: res.IDToken, }, nil } +func (a Auth0Authenticator) IsTokenValid(token string) bool { + return IssuerCheck(token, a.Issuer) +} + // Start kicks-off the device authentication flow // by requesting a device code from Auth0, // The returned state contains the URI for the next step of the flow. diff --git a/pkg/auth/auth_test.go b/pkg/auth/auth_test.go index 8f595116..992f1bdb 100644 --- a/pkg/auth/auth_test.go +++ b/pkg/auth/auth_test.go @@ -60,6 +60,14 @@ type MockOauth struct { flowDone bool } +func (m *MockOauth) GetCredentialProvider() entity.CredentialProvider { + return "mock" +} + +func (m *MockOauth) IsTokenValid(token string) bool { + return true +} + func (m *MockOauth) DoDeviceAuthFlow(_ func(string, string)) (*LoginTokens, error) { m.flowDone = true return m.loginTokens, nil diff --git a/pkg/auth/kas.go b/pkg/auth/kas.go index e6da7900..e77f702e 100644 --- a/pkg/auth/kas.go +++ b/pkg/auth/kas.go @@ -16,17 +16,31 @@ import ( var _ OAuth = KasAuthenticator{} +const CredentialProviderKAS entity.CredentialProvider = "kas" + type KasAuthenticator struct { - Email string - BaseURL string - PollTimeout time.Duration + Email string + ShouldPromptEmail bool + BaseURL string + PollTimeout time.Duration + Issuer string +} + +func (a KasAuthenticator) GetCredentialProvider() entity.CredentialProvider { + return CredentialProviderKAS +} + +func (a KasAuthenticator) IsTokenValid(token string) bool { + return IssuerCheck(token, a.Issuer) } -func NewKasAuthenticator(email, baseURL string) KasAuthenticator { +func NewKasAuthenticator(email, baseURL, issuer string, shouldPromptEmail bool) KasAuthenticator { return KasAuthenticator{ - Email: email, - BaseURL: baseURL, - PollTimeout: 5 * time.Minute, + Email: email, + ShouldPromptEmail: shouldPromptEmail, + Issuer: issuer, + BaseURL: baseURL, + PollTimeout: 5 * time.Minute, } } @@ -41,9 +55,8 @@ func (a KasAuthenticator) GetNewAuthTokensWithRefresh(refreshToken string) (*ent return nil, breverrors.WrapAndTrace(err) } return &entity.AuthTokens{ - AccessToken: token, - RefreshToken: refreshToken, - CredentialProvider: entity.CredentialProviderKAS, + AccessToken: token, + RefreshToken: refreshToken, }, nil } @@ -98,14 +111,10 @@ func (a KasAuthenticator) MakeLoginCall(id, email string) (LoginCallResponse, er func (a KasAuthenticator) DoDeviceAuthFlow(userLoginFlow func(url string, code string)) (*LoginTokens, error) { id := uuid.New().String() - email := a.Email - if a.Email == "" { - fmt.Print("Enter your email: ") - _, err := fmt.Scanln(&email) - if err != nil { - return nil, breverrors.WrapAndTrace(err) - } + email, err := a.maybePromptForEmail() + if err != nil { + return nil, breverrors.WrapAndTrace(err) } loginResp, err := a.MakeLoginCall(id, email) @@ -118,6 +127,32 @@ func (a KasAuthenticator) DoDeviceAuthFlow(userLoginFlow func(url string, code s return a.pollForTokens(loginResp.SessionKey, id) } +func (a KasAuthenticator) maybePromptForEmail() (string, error) { + var email string + if a.Email != "" && a.ShouldPromptEmail { //nolint:gocritic // fine + fmt.Printf("Logging in with email %s\nPress enter to continue or type a different email: ", a.Email) + var response string + _, err := fmt.Scanln(&response) + if err != nil && err.Error() != "unexpected newline" { + return "", breverrors.WrapAndTrace(err) + } + if response == "" { + email = a.Email + } else { + email = response + } + } else if a.Email != "" { + return a.Email, nil + } else { + fmt.Print("Enter your email: ") + _, err := fmt.Scanln(&email) + if err != nil { + return "", breverrors.WrapAndTrace(err) + } + } + return email, nil +} + func (a KasAuthenticator) pollForTokens(sessionKey, id string) (*LoginTokens, error) { // Try to retrieve tokens for up to 5 minutes timeout := time.After(a.PollTimeout) @@ -130,7 +165,6 @@ func (a KasAuthenticator) pollForTokens(sessionKey, id string) (*LoginTokens, er case <-ticker.C: idToken, err := a.retrieveIDToken(sessionKey, id) if err == nil { - fmt.Println(idToken) return &LoginTokens{ AuthTokens: entity.AuthTokens{ AccessToken: idToken, diff --git a/pkg/cmd/cmd.go b/pkg/cmd/cmd.go index ca671bdd..43e5a01d 100644 --- a/pkg/cmd/cmd.go +++ b/pkg/cmd/cmd.go @@ -61,22 +61,22 @@ import ( ) var ( - user string - email string - authProvider string + userFlag string + emailFlag string + authProviderFlag string ) func init() { - flag.StringVar(&email, "email", "", "email to use for authentication") - flag.StringVar(&authProvider, "auth", "", "authentication provider to use (auth0 or kas, default is auth0)") + flag.StringVar(&emailFlag, "email", "", "email to use for authentication") + flag.StringVar(&authProviderFlag, "auth", "", "authentication provider to use (auth0 or kas, default is auth0)") flag.Parse() } func NewDefaultBrevCommand() *cobra.Command { cmd := NewBrevCommand() - cmd.PersistentFlags().StringVar(&user, "user", "", "non root user to use for per user configuration of commands run as root") - cmd.PersistentFlags().StringVar(&email, "email", "", "email to use for authentication") - cmd.PersistentFlags().StringVar(&authProvider, "auth", "", "authentication provider to use (auth0 or kas, default is auth0)") + cmd.PersistentFlags().StringVar(&userFlag, "user", "", "non root user to use for per user configuration of commands run as root") + cmd.PersistentFlags().StringVar(&emailFlag, "email", "", "email to use for authentication") + cmd.PersistentFlags().StringVar(&authProviderFlag, "auth", "", "authentication provider to use (auth0 or kas, default is auth0)") return cmd } @@ -97,25 +97,54 @@ func NewBrevCommand() *cobra.Command { //nolint:funlen,gocognit,gocyclo // defin fmt.Printf("%v\n", err) } - authP := tokens.GetCredentialProvider() - if authProvider != "" { - authP = entity.CredentialProvider(authProvider) + // the default authenticator + var authenticator auth.OAuth = auth.Auth0Authenticator{ + Issuer: "https://brevdev.us.auth0.com/", + Audience: "https://brevdev.us.auth0.com/api/v2/", + ClientID: "JaqJRLEsdat5w7Tb0WqmTxzIeqwqepmk", + DeviceCodeEndpoint: "https://brevdev.us.auth0.com/oauth/device/code", + OauthTokenEndpoint: "https://brevdev.us.auth0.com/oauth/token", } - var authenticator auth.OAuth - switch authP { - case entity.CredentialProviderKAS: - config.ConsoleBaseURL = "https://brev.nvidia.com" - authenticator = auth.NewKasAuthenticator(email, "https://api.ngc.nvidia.com") - default: - authenticator = auth.Auth0Authenticator{ - Audience: "https://brevdev.us.auth0.com/api/v2/", - ClientID: "JaqJRLEsdat5w7Tb0WqmTxzIeqwqepmk", - DeviceCodeEndpoint: "https://brevdev.us.auth0.com/oauth/device/code", - OauthTokenEndpoint: "https://brevdev.us.auth0.com/oauth/token", + email := auth.GetEmailFromToken(tokens.AccessToken) + shouldPromptEmail := true + if emailFlag != "" { + email = emailFlag + shouldPromptEmail = false + } + + authRetriever := auth.NewOAuthRetriever([]auth.OAuth{ + authenticator, + auth.NewKasAuthenticator( + email, + "https://api.ngc.nvidia.com", + "https://login.nvidia.com", + shouldPromptEmail, + ), + }) + + if tokens != nil && tokens.AccessToken != "" { + authenticatorFromToken, errr := authRetriever.GetByToken(tokens.AccessToken) + if errr != nil { + fmt.Printf("%v\n", errr) + } else { + authenticator = authenticatorFromToken } } + if authProviderFlag != "" { + authenticatorByProviderFlag, errr := authRetriever.GetByProvider(entity.CredentialProvider(authProviderFlag)) + if errr != nil { + fmt.Printf("%v\n", errr) + } else { + authenticator = authenticatorByProviderFlag + } + } + + if authenticator.GetCredentialProvider() == auth.CredentialProviderKAS { + config.ConsoleBaseURL = "https://brev.nvidia.com" + } + // super annoying. this is needed to make the import stay _ = color.New(color.FgYellow, color.Bold).SprintFunc() @@ -189,16 +218,16 @@ func NewBrevCommand() *cobra.Command { //nolint:funlen,gocognit,gocyclo // defin fmt.Println(v) } } - if user != "" { - _, err := noLoginCmdStore.WithUserID(user) + if userFlag != "" { + _, err := noLoginCmdStore.WithUserID(userFlag) if err != nil { return breverrors.WrapAndTrace(err) } - _, err = loginCmdStore.WithUserID(user) + _, err = loginCmdStore.WithUserID(userFlag) if err != nil { return breverrors.WrapAndTrace(err) } - _, err = fsStore.WithUserID(user) + _, err = fsStore.WithUserID(userFlag) if err != nil { return breverrors.WrapAndTrace(err) } diff --git a/pkg/entity/entity.go b/pkg/entity/entity.go index fda8d57c..1ca2e09a 100644 --- a/pkg/entity/entity.go +++ b/pkg/entity/entity.go @@ -16,9 +16,6 @@ type CredentialProvider string const ( CredientialProviderUnspecified CredentialProvider = "" - CredentialProviderAuth0 CredentialProvider = "auth0" - CredentialProviderKAS CredentialProvider = "kas" - // CredentialProviderStarfleet CredentialProvider = "starfleet" ) const WorkspaceGroupDevPlane = "devplane-brev-1" @@ -31,15 +28,6 @@ var LegacyWorkspaceGroups = map[string]bool{ type AuthTokens struct { AccessToken string `json:"access_token"` RefreshToken string `json:"refresh_token"` - - CredentialProvider CredentialProvider `json:"credential_provider"` -} - -func (a AuthTokens) GetCredentialProvider() CredentialProvider { - if a.CredentialProvider == CredientialProviderUnspecified { - return CredentialProviderAuth0 - } - return a.CredentialProvider } type IDEConfig struct {