Compare commits

..

552 Commits
v1.23.3 ... seq

Author SHA1 Message Date
Hidetake Iwata
e392645593 Fix 2025-01-19 17:55:12 +09:00
Hidetake Iwata
1c2ca4f248 Rewrite with mermaid 2025-01-19 17:24:52 +09:00
Hidetake Iwata
21c50a5a0e Merge branch 'master' into seq 2025-01-19 16:59:01 +09:00
Hidetake Iwata
a2a6ea229d Improve docs (#1250)
* Refactor docs

* Update --exec-api-version

* Add device authorization grant

* Fix
2025-01-19 15:02:02 +09:00
Rahul Somasundaram
e7819f15eb Added windows arm64 release (#1244)
Co-authored-by: Hidetake Iwata <int128@gmail.com>
2025-01-19 11:12:57 +09:00
renovate[bot]
6099a60aad chore(deps): update dependency go to v1.23.5 (#1249)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-18 15:06:31 +00:00
Hidetake Iwata
e31ad59e63 Add clean command (#1248)
* Add clean command

* Refactor

* Refactor
2025-01-18 22:24:23 +09:00
renovate[bot]
355d9cf224 fix(deps): update kubernetes packages to v0.32.1 (#1246)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-16 15:08:01 +00:00
renovate[bot]
fb5cfcf18f chore(deps): update docker/build-push-action action to v6.12.0 (#1247)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-16 13:14:40 +00:00
renovate[bot]
31fadd2569 chore(deps): update int128/update-generated-files-action action to v2.57.0 (#1245)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-15 12:14:48 +00:00
renovate[bot]
9f55437307 fix(deps): update module github.com/vektra/mockery/v2 to v2.51.0 (#1243)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.51.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12764870470

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-01-14 12:14:38 +00:00
Hidetake Iwata
aa1f445672 Rename flag to --oidc-pkce-method and improve docs (#1240)
* Add --oidc-pkce-method and improve docs

* Fix lint

* Refactor

* Refactor
2025-01-14 09:57:19 +09:00
Hidetake Iwata
0c160f9db2 Refactor integration-test (#1242)
* Refactor integration-test

* Refactor
2025-01-13 16:29:27 +09:00
Hidetake Iwata
8c7903b2db Test PKCE by default (integration-test) (#1241) 2025-01-13 15:50:48 +09:00
Hidetake Iwata
898e8a12de Refactor PKCE implementation (#1239) 2025-01-12 21:41:20 +09:00
Hidetake Iwata
606f1cd0b6 Remove unused struct field (#1238) 2025-01-12 15:55:26 +09:00
Hidetake Iwata
562b998ca7 Add [SECURITY RISK] to insecure flag description (#1237) 2025-01-12 15:17:47 +09:00
Hidetake Iwata
6c9d198ef5 Add --token-cache-storage flag (#1236) 2025-01-12 14:55:46 +09:00
Hidetake Iwata
5ebecc534e Format markdown (#1235) 2025-01-12 14:00:03 +09:00
Hidetake Iwata
ca273c358d Refactor getDefaultTokenCacheDir() (#1234) 2025-01-12 13:36:28 +09:00
Hidetake Iwata
ccc6b772db Extract tokenCacheOptions (#1232)
* Extract tokenCacheOptions

* Refactor
2025-01-12 13:21:03 +09:00
Hidetake Iwata
1681d84fae Push container image on push event only (#1233) 2025-01-12 13:15:09 +09:00
Hidetake Iwata
6f62b25c40 Extract struct tokencache.Config (#1226) 2025-01-11 16:44:56 +09:00
renovate[bot]
71a7467e64 chore(deps): update docker/build-push-action action to v6.11.0 (#1228)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 18:11:18 +00:00
renovate[bot]
5c78b7823b chore(deps): update docker/setup-qemu-action action to v3.3.0 (#1229)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-08 16:09:57 +00:00
Hidetake Iwata
361c376c95 Enable keyring in system-test (#1225)
* Enable keyring in system-test

* Add dbus-run-session and gnome-keyring-daemon

* Fix

* Fix

* Refactor
2025-01-08 16:53:59 +09:00
Hidetake Iwata
c66570c030 Remove unused struct member (#1224) 2025-01-08 12:50:15 +09:00
kalle (jag)
afb25f511c Added key cache via OS keyring (#973)
* Added key cache via OS keyring

* Fix lint issue

* Disable keyring in integration tests

* Disable keyring in system test

---------

Co-authored-by: Hidetake Iwata <int128@gmail.com>
2025-01-08 12:32:26 +09:00
Hidetake Iwata
a836ef0e92 Do not push container image on fork (#1223) 2025-01-08 12:17:50 +09:00
Hidetake Iwata
fb00b17088 Configure automatically generated release notes (#1222) 2025-01-08 09:17:45 +09:00
renovate[bot]
c836641412 fix(deps): update module golang.org/x/term to v0.28.0 (#1220)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-05 05:07:45 +00:00
renovate[bot]
d471ea7152 fix(deps): update module golang.org/x/oauth2 to v0.25.0 (#1219)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-04 17:06:05 +00:00
renovate[bot]
33d94678d6 fix(deps): update module github.com/coreos/go-oidc/v3 to v3.12.0 (#1218)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-04 08:09:46 +00:00
renovate[bot]
9f9ec16196 fix(deps): update module github.com/golangci/golangci-lint to v1.63.4 (#1217)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-04 00:39:06 +00:00
renovate[bot]
10e957702d fix(deps): update module github.com/vektra/mockery/v2 to v2.50.4 (#1216)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.50.4

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12603054218

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-01-03 22:07:25 +00:00
renovate[bot]
b7a90a5a5c fix(deps): update module github.com/golangci/golangci-lint to v1.63.3 (#1215)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-03 00:40:06 +00:00
renovate[bot]
f852891af3 fix(deps): update module github.com/golangci/golangci-lint to v1.63.2 (#1214)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-02 17:07:10 +00:00
renovate[bot]
994a063566 fix(deps): update module github.com/vektra/mockery/v2 to v2.50.3 (#1213)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.50.3

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12577746109

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2025-01-02 06:11:54 +00:00
renovate[bot]
7aa20d770c fix(deps): update module github.com/golangci/golangci-lint to v1.63.1 (#1212)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-02 00:18:32 +00:00
renovate[bot]
9806833dfe fix(deps): update module github.com/golangci/golangci-lint to v1.63.0 (#1211)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-01 17:07:04 +00:00
renovate[bot]
a6ce0d461e fix(deps): update module github.com/vektra/mockery/v2 to v2.50.2 (#1209)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.50.2

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12554219550

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-12-31 03:12:19 +00:00
Hidetake Iwata
97b0a20b0b Remove deprecated --listen-port flag (#1207) 2024-12-27 15:22:53 +09:00
renovate[bot]
97fc59829b fix(deps): update module github.com/vektra/mockery/v2 to v2.50.1 (#1206)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.50.1

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12478246181

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-12-24 08:11:17 +00:00
renovate[bot]
d5df561b9d chore(deps): update docker/setup-buildx-action action to v3.8.0 (#1205)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-16 14:08:50 +00:00
renovate[bot]
750675fd8f fix(deps): update kubernetes packages to v0.32.0 (#1204)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-12 02:21:14 +00:00
renovate[bot]
2d9b849a1f chore(deps): update actions/setup-go action to v5.2.0 (#1203)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-11 09:09:31 +00:00
renovate[bot]
4f584cd504 fix(deps): update kubernetes packages to v0.31.4 (#1202)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-11 03:26:40 +00:00
renovate[bot]
ec2be992e9 chore(deps): update int128/docker-build-cache-config-action action to v1.37.0 (#1201)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-08 12:14:46 +00:00
renovate[bot]
8c62d95679 fix(deps): update module github.com/vektra/mockery/v2 to v2.50.0 (#1199)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.50.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12164768589

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-12-04 20:10:07 +00:00
renovate[bot]
b643d5fcaf fix(deps): update module golang.org/x/term to v0.27.0 (#1200)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-04 18:12:11 +00:00
renovate[bot]
6c064ccd87 chore(deps): update dependency go to v1.23.4 (#1197)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-04 17:07:57 +00:00
renovate[bot]
d0f250d13d fix(deps): update module golang.org/x/sync to v0.10.0 (#1198)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-04 15:30:27 +00:00
renovate[bot]
fd1ed4c971 fix(deps): update module github.com/vektra/mockery/v2 to v2.49.2 (#1196)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.49.2

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12145201435

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-12-03 20:10:09 +00:00
renovate[bot]
7fc9dfddd4 fix(deps): update module github.com/vektra/mockery/v2 to v2.49.1 (#1194)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.49.1

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/12042258621

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-11-27 03:25:18 +00:00
renovate[bot]
54d5a58a00 chore(deps): update docker/build-push-action action to v6.10.0 (#1193)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-26 17:08:01 +00:00
renovate[bot]
9af4c6af05 fix(deps): update module github.com/golangci/golangci-lint to v1.62.2 (#1192)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-25 16:10:26 +00:00
renovate[bot]
e3a7e80907 fix(deps): update module github.com/stretchr/testify to v1.10.0 (#1191)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-23 14:07:09 +00:00
renovate[bot]
7f2bcb653e fix(deps): update kubernetes packages to v0.31.3 (#1190)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-21 09:09:10 +00:00
renovate[bot]
0164b3ef69 fix(deps): update module github.com/vektra/mockery/v2 to v2.49.0 (#1189)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.49.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/11945541249

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-11-21 05:08:48 +00:00
renovate[bot]
3d31e81128 chore(deps): update docker/metadata-action action to v5.6.1 (#1188)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 20:09:39 +00:00
renovate[bot]
fc1767f1d0 chore(deps): update docker/metadata-action action to v5.6.0 (#1187)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-19 18:11:34 +00:00
renovate[bot]
4ae812342e fix(deps): update module github.com/vektra/mockery/v2 to v2.48.0 (#1186)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.48.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/11910966209

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-11-19 12:15:53 +00:00
renovate[bot]
f1367689a8 chore(deps): update int128/update-generated-files-action action to v2.56.0 (#1185)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-15 17:07:37 +00:00
renovate[bot]
ea88241e34 chore(deps): update int128/docker-build-cache-config-action action to v1.36.0 (#1184)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-15 12:15:38 +00:00
renovate[bot]
ebda978f02 fix(deps): update module github.com/vektra/mockery/v2 to v2.47.0 (#1183)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.47.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/11844880778

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-11-14 22:07:46 +00:00
renovate[bot]
d03f57bdbd fix(deps): update module github.com/chromedp/chromedp to v0.11.2 (#1181)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-11 12:15:16 +00:00
renovate[bot]
cc0318db18 fix(deps): update module github.com/golangci/golangci-lint to v1.62.0 (#1180)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-10 21:31:21 +00:00
renovate[bot]
f8fabda051 chore(deps): update rajatjindal/krew-release-bot action to v0.0.47 (#1179)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-10 20:08:11 +00:00
Hidetake Iwata
43922b3b43 Use BUILDPLATFORM for multi-architecture build (#1178)
* Refactor docker build workflows

* Refactor
2024-11-10 16:49:05 +09:00
renovate[bot]
ada466d3a7 chore(deps): update dependency int128/go-renovate-config to v1.7.2 (#1165)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-10 10:49:14 +09:00
Hidetake Iwata
df0eae3497 Refactor go workflows (#1176)
* Refactor go workflows

* Fix
2024-11-10 10:46:47 +09:00
renovate[bot]
239b93925c fix(deps): update module github.com/int128/oauth2cli to v1.14.1 (#1175)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-09 15:08:24 +00:00
renovate[bot]
17ac028bd7 fix(deps): update module golang.org/x/oauth2 to v0.24.0 (#1167)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 06:11:37 +00:00
renovate[bot]
946fde9567 fix(deps): update module golang.org/x/term to v0.26.0 (#1169)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 05:08:09 +00:00
Hidetake Iwata
ad727ee576 Add links to OIDC spec or RFC (#1172) 2024-11-08 11:28:19 +09:00
Hidetake Iwata
a87beb33b6 Use Go 1.22 router (integration_test) (#1171) 2024-11-08 10:47:27 +09:00
Hidetake Iwata
5d657ed981 Extract service package (integration_test) (#1170)
* Extract service package (integration_test)

* Refactor

* make generate

* Rename

* Comment

* Refactor
2024-11-08 10:20:20 +09:00
renovate[bot]
b69f00f380 chore(deps): update dependency go to v1.23.3 (#1166)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 00:46:40 +00:00
renovate[bot]
fdbd391a92 fix(deps): update module golang.org/x/sync to v0.9.0 (#1168)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-11-08 00:38:55 +00:00
Hidetake Iwata
1895099836 Fix flaky system test (#1164) 2024-11-03 18:08:46 +09:00
Hidetake Iwata
0e9a39a571 Infer apiVersion from KUBERNETES_EXEC_INFO environment variable (#1162)
* Infer apiVersion from KUBERNETES_EXEC_INFO

* Test client.authentication.k8s.io/v1

* Set --exec-interactive-mode

* Set --exec-interactive-mode=Never

* Fix comments
2024-11-03 17:21:25 +09:00
Hidetake Iwata
f1f2a37adc Include essential options to token cache key (#1161) 2024-10-26 21:42:23 +09:00
Hidetake Iwata
438068e9de refactor: Move useAccessToken to oidc.Provider (#1160)
* refactor: Move useAccessToken to oidc.Provider

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/11530911738

---------

Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
2024-10-26 21:07:44 +09:00
renovate[bot]
aaf9a6a58f chore(deps): update dependency int128/go-renovate-config to v1.6.1 (#1149)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-26 18:26:49 +09:00
renovate[bot]
9567ab157b fix(deps): update kubernetes packages to v0.31.2 (#1159)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-23 18:08:57 +00:00
renovate[bot]
f49d73087a fix(deps): update module github.com/chromedp/chromedp to v0.11.1 (#1158)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-23 05:08:53 +00:00
renovate[bot]
1c84d270a9 fix(deps): update module github.com/chromedp/chromedp to v0.11.0 (#1157)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-14 21:45:14 +00:00
renovate[bot]
1b245f9947 fix(deps): update module github.com/vektra/mockery/v2 to v2.46.3 (#1156)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.46.3

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/11320535114

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-10-14 06:12:32 +00:00
renovate[bot]
963942afad fix(deps): update module golang.org/x/term to v0.25.0 (#1155)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-04 18:10:39 +00:00
renovate[bot]
24357b6ea7 chore(deps): update dependency go to v1.23.2 (#1153)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-10-02 20:09:23 +00:00
renovate[bot]
4e7a44cdbe fix(deps): update module github.com/vektra/mockery/v2 to v2.46.2 (#1154)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.46.2

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/11147159678

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-10-02 18:11:24 +00:00
renovate[bot]
3f7513754c fix(deps): update module github.com/vektra/mockery/v2 to v2.46.1 (#1152)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.46.1

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/11081139611

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-09-28 06:10:30 +00:00
renovate[bot]
61555d8ee2 chore(deps): update dependency go to v1.23.1 (#1148)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-24 15:19:54 +09:00
Hidetake Iwata
f22f6ee483 Update go directive in go.mod (#1147) 2024-09-24 15:11:20 +09:00
Hidetake Iwata
c2cbc47438 Lock dedicated file instead of token cache file (#1146)
* Run test on Windows

* Run integration_test on Windows and macOS

* Lock dedicated file instead of token cache file

* Add comment
2024-09-24 14:39:53 +09:00
Hidetake Iwata
765d97542c Use go-version-file (#1142) 2024-09-23 18:06:11 +09:00
Hidetake Iwata
3d114bfeba Lock token cache file before authentication (#1126)
* Lock token cache file in authentication

* Fix tests

* make generate

* Lock before FindByKey

* Fix test
2024-09-21 14:54:32 +09:00
renovate[bot]
f0c3628f2a fix(deps): update module github.com/vektra/mockery/v2 to v2.46.0 (#1141)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.46.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/10896389638

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-09-17 06:11:39 +00:00
renovate[bot]
57f5409402 fix(deps): update kubernetes packages to v0.31.1 (#1140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-12 09:08:10 +00:00
renovate[bot]
1601ba1ef1 chore(deps): update dependency golangci/golangci-lint to v1.61.0 (#1139)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-09 21:37:37 +00:00
renovate[bot]
7c733fe841 fix(deps): update module github.com/vektra/mockery/v2 to v2.45.1 (#1138)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.45.1

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/10779024006

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-09-09 20:08:32 +00:00
renovate[bot]
244c32b5d7 fix(deps): update module golang.org/x/oauth2 to v0.23.0 (#1134)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-05 23:08:15 +00:00
renovate[bot]
2bbff2c363 chore(deps): update dependency golang-version to v1.23.1 (#1137)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-05 21:07:02 +00:00
renovate[bot]
3c5c326a2a fix(deps): update module golang.org/x/term to v0.24.0 (#1135)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-09-04 17:06:53 +00:00
renovate[bot]
cabd0e7c2f fix(deps): update module github.com/vektra/mockery/v2 to v2.45.0 (#1131)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.45.0

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/10554564162

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-08-26 08:11:25 +00:00
renovate[bot]
cf9f86b386 fix(deps): update module github.com/vektra/mockery/v2 to v2.44.2 (#1125)
* fix(deps): update module github.com/vektra/mockery/v2 to v2.44.2

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/10437019943

* Empty commit to trigger GitHub Actions

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: int128-renovate-merge-bot[bot] <132176788+int128-renovate-merge-bot[bot]@users.noreply.github.com>
2024-08-26 06:11:21 +00:00
renovate[bot]
e3a43015c3 chore(deps): update dependency golangci/golangci-lint to v1.60.3 (#1130)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-23 03:24:12 +00:00
renovate[bot]
17b1ef093f chore(deps): update dependency golangci/golangci-lint to v1.60.2 (#1128)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-21 01:24:56 +00:00
Hidetake Iwata
b1c8a18c76 Add wire to make generate (#1127) 2024-08-18 11:10:49 +09:00
Hidetake Iwata
66127ff3fc Migrate to mockery packages feature (#1124)
* Migrate to mockery packages feature

* Fix workflow
2024-08-17 12:27:13 +09:00
Hidetake Iwata
1b267eb7af Update flags in usage.md (#1123) 2024-08-16 17:07:48 +09:00
renovate[bot]
a49bd30178 fix(deps): update module gopkg.in/yaml.v2 to v3 (#845)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-16 17:01:57 +09:00
Adam Kafka
905238ce07 Add new --oidc-use-access-token flag to get-token (#1084)
* Add new `--oidc-use-access-token` flag to `get-token`

Implements https://github.com/int128/kubelogin/issues/1083. See
description there for context.

In its current form, this PR is bare bones functionality. I have not yet
added any tests to confirm this behavior. Additionally, we could
consider updtating some of the naming. It is confusing to return a
`TokenSet` where `IDToken` actually has an `accessToken`. I'm open to
feedback on how best to improve this.

However, this PR is functional. I have validated it locally. Without
adding `--oidc-use-access-token`, and `id_token` is successfully
returned. Adding `--oidc-use-access-token` results in an `access_token`
being successfully returned.

* Fix failing tests

Needed to plumb through our new parameter `UseAccessToken` to the mocks
as well.

* Add a test to make sure new flag is plumbed through

* Support Access Tokens whose audience differ from the client_id

As noted in the PR, there are some cases where the access token `aud`
field will not be the `client_id`. To allow for these, we use a
different token verifier that will not verify that claim.

---------

Co-authored-by: Adam kafka <akafka@tesla.com>
2024-08-16 16:57:05 +09:00
renovate[bot]
70ce255a8d fix(deps): update kubernetes packages to v0.31.0 (#1120)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-14 17:27:51 +00:00
renovate[bot]
0e4865fbec chore(deps): update golang docker tag to v1.23 (#1121)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-14 14:48:00 +00:00
renovate[bot]
1e44ca40f8 chore(deps): update dependency golang-version to v1.23.0 (#1119)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-14 11:04:47 +00:00
renovate[bot]
394175ef87 chore(deps): update dependency golangci/golangci-lint to v1.60.1 (#1122)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-14 08:14:03 +00:00
renovate[bot]
20e4e62ee9 fix(deps): update module golang.org/x/term to v0.23.0 (#1117)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-07 01:54:08 +00:00
renovate[bot]
fae1341887 chore(deps): update dependency golang-version to v1.22.6 (#1116)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-06 22:29:33 +00:00
renovate[bot]
878a3e5d18 fix(deps): update module golang.org/x/sync to v0.8.0 (#1115)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-05 02:18:53 +00:00
renovate[bot]
192daaa938 fix(deps): update module golang.org/x/oauth2 to v0.22.0 (#1114)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-04 21:44:19 +00:00
Hidetake Iwata
a2f4e935dc Remove golang.org/x/net/context (#1112) 2024-08-03 11:42:54 +09:00
renovate[bot]
98531a75c3 fix(deps): update module github.com/chromedp/chromedp to v0.10.0 (#1111)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-08-02 01:03:00 +00:00
renovate[bot]
fef0f2d73b fix(deps): update kubernetes packages to v0.30.3 (#1108)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-18 04:51:42 +00:00
renovate[bot]
8c9aea0662 fix(deps): update module github.com/coreos/go-oidc/v3 to v3.11.0 (#1107)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-08 22:50:06 +00:00
renovate[bot]
d878ace92c fix(deps): update module golang.org/x/net to v0.27.0 (#1106)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-05 18:57:17 +00:00
renovate[bot]
7424e8c09e chore(deps): update dependency golang-version to v1.22.5 (#1104)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-05 01:02:42 +00:00
renovate[bot]
1989395c30 fix(deps): update module golang.org/x/term to v0.22.0 (#1105)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-07-04 22:29:50 +00:00
renovate[bot]
51c45683ce fix(deps): update module k8s.io/klog/v2 to v2.130.1 (#1102)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-30 14:12:54 +00:00
renovate[bot]
0edac231c7 fix(deps): update module github.com/spf13/cobra to v1.8.1 (#1101)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-30 09:02:24 +00:00
renovate[bot]
646449cdd5 fix(deps): update kubernetes packages to v0.30.2 (#1100)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-30 07:29:24 +00:00
Hidetake Iwata
38e1dec3df Update dexidp/dex to v2.39.0 (#1103) 2024-06-30 13:53:12 +09:00
renovate[bot]
717f1a668b chore(deps): update dependency golangci/golangci-lint to v1.59.1 (#1099)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-09 21:02:29 +00:00
renovate[bot]
baf1b6419c fix(deps): update module golang.org/x/net to v0.26.0 (#1098)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-05 04:38:22 +00:00
renovate[bot]
9b86200fca chore(deps): update dependency golang-version to v1.22.4 (#1097)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-05 01:56:14 +00:00
renovate[bot]
380ab4090c fix(deps): update module golang.org/x/term to v0.21.0 (#1096)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-04 22:11:20 +00:00
renovate[bot]
fcbb25dd1b fix(deps): update module golang.org/x/oauth2 to v0.21.0 (#1095)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-04 18:08:42 +00:00
renovate[bot]
852a040607 chore(deps): update dependency golangci/golangci-lint to v1.59.0 (#1094)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-26 21:17:06 +00:00
renovate[bot]
173192da4d chore(deps): update dependency golangci/golangci-lint to v1.58.2 (#1093)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-19 23:29:53 +00:00
renovate[bot]
72912ff126 fix(deps): update kubernetes packages to v0.30.1 (#1092)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-16 05:37:16 +00:00
renovate[bot]
94ca6bc8d2 chore(deps): update dependency golang-version to v1.22.3 (#1090)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-09 03:24:29 +00:00
renovate[bot]
ad39239e7f chore(deps): update dependency golangci/golangci-lint to v1.58.1 (#1091)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-09 02:07:09 +00:00
renovate[bot]
88a134e5b1 fix(deps): update module golang.org/x/net to v0.25.0 (#1089)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-06 22:23:03 +00:00
renovate[bot]
95bfdedf3f fix(deps): update module golang.org/x/term to v0.20.0 (#1087)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-05 19:49:40 +00:00
renovate[bot]
48cd10d595 fix(deps): update module golang.org/x/oauth2 to v0.20.0 (#1086)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-04 18:45:52 +00:00
renovate[bot]
ae54330f2c chore(deps): update dependency golangci/golangci-lint to v1.58.0 (#1085)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-05-04 00:03:15 +00:00
renovate[bot]
fdcdcc3a60 chore(deps): update dependency go to v1.22.2 (#1080)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-18 08:41:07 +00:00
renovate[bot]
3d9ce981ce fix(deps): update kubernetes packages to v0.30.0 (#1079)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-18 05:06:40 +00:00
renovate[bot]
5185211e70 fix(deps): update kubernetes packages to v0.29.4 (#1078)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-17 06:33:38 +00:00
renovate[bot]
e4caacf78c fix(deps): update module golang.org/x/sync to v0.7.0 (#1075)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-04 21:53:00 +00:00
renovate[bot]
15482ee981 fix(deps): update module golang.org/x/net to v0.24.0 (#1076)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-04 19:53:26 +00:00
renovate[bot]
596791e365 fix(deps): update module golang.org/x/oauth2 to v0.19.0 (#1074)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-04 19:52:54 +00:00
renovate[bot]
c088abbf7e fix(deps): update module golang.org/x/net to v0.23.0 (#1072)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-03 22:56:36 +00:00
renovate[bot]
1c38f8cd1d chore(deps): update dependency golang-version to v1.22.2 (#1071)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-04-03 20:03:24 +00:00
renovate[bot]
885adc8562 chore(deps): update dependency golangci/golangci-lint to v1.57.2 (#1070)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-29 01:30:13 +00:00
renovate[bot]
a4714fe2f8 chore(deps): update dependency golangci/golangci-lint to v1.57.1 (#1068)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-20 23:50:12 +00:00
renovate[bot]
8f9e7a7f0f chore(deps): update dependency golangci/golangci-lint to v1.57.0 (#1067)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-20 03:35:20 +00:00
renovate[bot]
7ddb6d0277 fix(deps): update module github.com/coreos/go-oidc/v3 to v3.10.0 (#1066)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-19 21:55:17 +00:00
renovate[bot]
c52239678e fix(deps): update kubernetes packages to v0.29.3 (#1065)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-16 03:04:03 +00:00
renovate[bot]
c23d373d80 chore(deps): update dependency golang-version to v1.22.1 (#1061)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 21:01:34 +00:00
renovate[bot]
ce15cb284c fix(deps): update module golang.org/x/oauth2 to v0.18.0 (#1059)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 09:32:23 +00:00
renovate[bot]
526bd85947 fix(deps): update module github.com/golang-jwt/jwt/v5 to v5.2.1 (#1060)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 07:00:18 +00:00
renovate[bot]
ba5f2e36e7 fix(deps): update module golang.org/x/net to v0.22.0 (#1058)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-05 01:09:47 +00:00
renovate[bot]
eee5cd92db fix(deps): update module golang.org/x/term to v0.18.0 (#1057)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-04 22:18:07 +00:00
renovate[bot]
1dbfff621f fix(deps): update module github.com/stretchr/testify to v1.9.0 (#1056)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-03-02 22:37:38 +00:00
renovate[bot]
53718139f2 chore(deps): update dependency golangci/golangci-lint to v1.56.2 (#1051)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 22:13:02 +00:00
renovate[bot]
e8e7f6b4d4 fix(deps): update kubernetes packages to v0.29.2 (#1050)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-15 03:50:40 +00:00
renovate[bot]
7832d45c27 chore(deps): update dependency golangci/golangci-lint to v1.56.1 (#1047)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-08 22:00:56 +00:00
renovate[bot]
6e166357c3 fix(deps): update module golang.org/x/oauth2 to v0.17.0 (#1046)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-08 18:21:06 +00:00
renovate[bot]
35bb3a6297 fix(deps): update module golang.org/x/net to v0.21.0 (#1045)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-08 04:03:02 +00:00
renovate[bot]
45bad277b6 fix(deps): update module github.com/google/wire to v0.6.0 (#1043)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-08 00:28:17 +00:00
renovate[bot]
9878c2a7e9 chore(deps): update golang docker tag to v1.22 (#1041)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-07 22:37:43 +00:00
renovate[bot]
d34faa478c chore(deps): update dependency golangci/golangci-lint to v1.56.0 (#1042)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-07 18:10:07 +00:00
renovate[bot]
a6f22d9acc fix(deps): update module github.com/chromedp/chromedp to v0.9.5 (#1038)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-07 06:53:25 +00:00
renovate[bot]
d1a6bea6a9 chore(deps): update dependency golang-version to v1.22.0 (#1040)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-07 03:08:32 +00:00
renovate[bot]
c68df0f232 fix(deps): update module github.com/chromedp/chromedp to v0.9.4 (#1036)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-02-02 01:36:43 +00:00
renovate[bot]
cf6ebe8da2 fix(deps): update module k8s.io/klog/v2 to v2.120.1 (#1035)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 20:26:34 +00:00
renovate[bot]
2cb45ad66a fix(deps): update kubernetes packages to v0.29.1 (#1034)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-18 03:51:52 +00:00
renovate[bot]
72062a6ff1 chore(deps): update int128/go-workflows action to v0.3.0 (#1033)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-15 10:15:04 +00:00
renovate[bot]
79a6f85967 fix(deps): update module github.com/alexflint/go-filemutex to v1.3.0 (#1032)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-11 20:10:41 +00:00
renovate[bot]
7f651e7b3d fix(deps): update module k8s.io/klog/v2 to v2.120.0 (#1031)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-10 22:48:35 +00:00
renovate[bot]
4519d1b320 chore(deps): update dependency golang-version to v1.21.6 (#1029)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-10 00:36:10 +00:00
renovate[bot]
1ae6b219c7 fix(deps): update module golang.org/x/oauth2 to v0.16.0 (#1027)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-09 00:15:57 +00:00
renovate[bot]
44d388a9e1 fix(deps): update module golang.org/x/net to v0.20.0 (#1026)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-08 23:26:03 +00:00
renovate[bot]
87c8086fc7 fix(deps): update module golang.org/x/term to v0.16.0 (#1025)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-04 22:13:37 +00:00
renovate[bot]
18c8f85530 fix(deps): update module golang.org/x/sync to v0.6.0 (#1024)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-04 19:13:49 +00:00
renovate[bot]
8a17c34be1 fix(deps): update github.com/pkg/browser digest to 5ac0b6a (#1023)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-02 14:21:14 +00:00
Hidetake Iwata
967cdaac59 Parallel build of multi-architectures image (#1021)
* Parallel build of multi-architectures image

* Test image
2023-12-17 14:53:41 +09:00
renovate[bot]
e0155675b1 chore(deps): update int128/go-workflows action to v0.2.1 (#1022)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-17 05:46:26 +00:00
Hidetake Iwata
e0ee661cab Bump int128/go-release-action@v2 (#1020) 2023-12-17 13:45:56 +09:00
Hidetake Iwata
7b22915e28 Build multi-architectures image in single job (#1019) 2023-12-17 10:25:46 +09:00
github-actions[bot]
5dd50923c2 Generated by GitHub Actions (go / fmt) (#1018)
https://github.com/int128/kubelogin/actions/runs/7229804014

Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
2023-12-16 13:35:36 +09:00
Tobias Wolter
9da00c5e21 Respect KUBECACHEDIR environment variable (#975)
This adds a check for the existence of a (non-empty) `KUBECACHEDIR`
environment variable that will be used to construct the cache directory
path if present.
2023-12-16 13:32:42 +09:00
Mike Williams
e41b425ef4 fix(docker): Bump to distroless debian12 for golang:1.21 binaries (#980)
golang:1.21 binaries are compiled to require at least GLIBC 2.36, debian 10 is only 2.31.
2023-12-16 13:24:27 +09:00
renovate[bot]
0aae8ad815 fix(deps): update kubernetes packages to v0.29.0 (#1017)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-14 19:46:46 +00:00
renovate[bot]
da85dfa303 fix(deps): update module github.com/coreos/go-oidc/v3 to v3.9.0 (#1016)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-09 21:11:00 +00:00
renovate[bot]
788b3258a1 chore(deps): update actions/setup-go action to v5 (#1015) 2023-12-09 21:12:06 +09:00
renovate[bot]
c5847ea24f chore(deps): update dependency golang-version to v1.21.5 (#1014)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-05 22:12:15 +00:00
renovate[bot]
2cf9fcd390 fix(deps): update module github.com/golang-jwt/jwt/v5 to v5.2.0 (#1013)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-02 05:26:38 +00:00
renovate[bot]
ca5cf85b29 fix(deps): update module github.com/coreos/go-oidc/v3 to v3.8.0 (#1012)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-28 12:28:53 +00:00
renovate[bot]
a24c5752f3 fix(deps): update module golang.org/x/oauth2 to v0.15.0 (#1011)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-28 00:58:01 +00:00
renovate[bot]
36b9709c05 fix(deps): update module golang.org/x/net to v0.19.0 (#1010)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-27 22:48:59 +00:00
renovate[bot]
4503cfacb9 fix(deps): update module golang.org/x/term to v0.15.0 (#1009)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-27 19:51:53 +00:00
renovate[bot]
94f4145193 fix(deps): update kubernetes packages to v0.28.4 (#1008)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-16 06:14:40 +00:00
renovate[bot]
b1575d2878 fix(deps): update module golang.org/x/oauth2 to v0.14.0 (#1007)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-09 04:02:25 +00:00
renovate[bot]
649e394358 fix(deps): update module golang.org/x/net to v0.18.0 (#1006)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-09 01:45:18 +00:00
renovate[bot]
78c44eb0cc fix(deps): update module golang.org/x/term to v0.14.0 (#1005)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-08 09:45:16 +00:00
renovate[bot]
e60821fb70 fix(deps): update module github.com/golang-jwt/jwt/v5 to v5.1.0 (#1004)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-08 07:48:41 +00:00
renovate[bot]
5b0e22e090 chore(deps): update dependency golang-version to v1.21.4 (#1003)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-07 23:57:39 +00:00
renovate[bot]
2daa1dac45 fix(deps): update module github.com/spf13/cobra to v1.8.0 (#1002)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-05 00:33:12 +00:00
renovate[bot]
6d43cf81d9 fix(deps): update module golang.org/x/sync to v0.5.0 (#1001)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-04 19:21:41 +00:00
renovate[bot]
b7a98f41d0 chore(deps): update dependency golangci/golangci-lint to v1.55.2 (#1000)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-11-03 18:28:46 +00:00
renovate[bot]
6370cab657 fix(deps): update module k8s.io/klog/v2 to v2.110.1 (#999)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-31 16:14:26 +00:00
renovate[bot]
bb41bb5726 chore(deps): update int128/go-workflows action to v0.2.0 (#998)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-28 03:45:48 +00:00
renovate[bot]
8d3cb4682e chore(deps): update dependency golangci/golangci-lint to v1.55.1 (#997)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-25 15:34:45 +00:00
renovate[bot]
8005dfe948 chore(deps): update dependency golangci/golangci-lint to v1.55.0 (#996)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 17:13:14 +00:00
renovate[bot]
0a749a7d07 fix(deps): update module github.com/coreos/go-oidc/v3 to v3.7.0 (#995)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-20 09:28:50 +00:00
renovate[bot]
518ce6da18 fix(deps): update kubernetes packages to v0.28.3 (#994)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-18 18:32:10 +00:00
renovate[bot]
4ec4812b35 fix(deps): update module github.com/chromedp/chromedp to v0.9.3 (#993)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-11 09:52:49 +00:00
renovate[bot]
b7004d4312 fix(deps): update module golang.org/x/net to v0.17.0 (#992)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-11 04:50:47 +00:00
renovate[bot]
2f432bf3ea fix(deps): update module github.com/google/go-cmp to v0.6.0 (#991)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-11 01:47:44 +00:00
renovate[bot]
ac0725ae46 chore(deps): update dependency golang-version to v1.21.3 (#990)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-10 21:21:34 +00:00
renovate[bot]
20a024b3c4 fix(deps): update module golang.org/x/oauth2 to v0.13.0 (#988)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-06 13:48:26 +00:00
renovate[bot]
7a36e88579 fix(deps): update module golang.org/x/net to v0.16.0 (#987)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-06 03:58:28 +00:00
renovate[bot]
a514ed807c chore(deps): update dependency golang-version to v1.21.2 (#986)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-06 00:23:37 +00:00
renovate[bot]
9c3fe1c247 fix(deps): update module golang.org/x/term to v0.13.0 (#985)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-05 18:59:24 +00:00
renovate[bot]
e7a2ea0da1 fix(deps): update module golang.org/x/sync to v0.4.0 (#984)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-10-05 16:09:04 +00:00
renovate[bot]
e35ee4ca61 fix(deps): update kubernetes packages to v0.28.2 (#983)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-14 00:47:03 +00:00
renovate[bot]
fc630b21f6 chore(deps): update actions/checkout action to v4 (#977)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-10 13:22:38 +00:00
renovate[bot]
6d6e084ebe fix(deps): update module github.com/int128/oauth2dev to v1.0.1 (#982)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-10 09:02:31 +00:00
renovate[bot]
37ad2fddd6 chore(deps): update dependency golang-version to v1.21.1 (#981)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-06 23:17:32 +00:00
renovate[bot]
8d8d9e3e4c fix(deps): update module golang.org/x/oauth2 to v0.12.0 (#979)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-06 01:03:45 +00:00
renovate[bot]
6737cae622 fix(deps): update module golang.org/x/net to v0.15.0 (#978)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-05 21:41:14 +00:00
renovate[bot]
c256bb9b0b fix(deps): update module golang.org/x/term to v0.12.0 (#976)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-09-03 19:08:26 +00:00
renovate[bot]
9151f23e71 fix(deps): update kubernetes packages to v0.28.1 (#974)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-24 19:37:23 +00:00
renovate[bot]
17d32369ce chore(deps): update dependency golangci/golangci-lint to v1.54.2 (#972)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-21 19:45:22 +00:00
renovate[bot]
8ff9fe5d0d fix(deps): update kubernetes packages to v0.28.0 (#971)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-16 03:06:01 +00:00
renovate[bot]
3ce908b35c chore(deps): update dependency golangci/golangci-lint to v1.54.1 (#970)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-11 18:09:47 +00:00
renovate[bot]
434be51543 chore(deps): update golang docker tag to v1.21 (#968)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 20:25:22 +00:00
renovate[bot]
2b68e5d59d chore(deps): update dependency golangci/golangci-lint to v1.54.0 (#969)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-09 17:33:48 +00:00
renovate[bot]
241d4cc2a9 chore(deps): update dependency golang-version to v1.21.0 (#967)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-08 19:07:47 +00:00
renovate[bot]
c3e4632fea fix(deps): update module github.com/chromedp/chromedp to v0.9.2 (#966)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-05 09:44:56 +00:00
renovate[bot]
d2ca6e68c0 fix(deps): update module golang.org/x/oauth2 to v0.11.0 (#965)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-05 07:48:45 +00:00
renovate[bot]
d1c871d1ff fix(deps): update module golang.org/x/net to v0.14.0 (#964)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-05 04:33:45 +00:00
renovate[bot]
68a121b949 fix(deps): update module golang.org/x/term to v0.11.0 (#963)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-04 18:17:00 +00:00
renovate[bot]
8497e548fc fix(deps): update module golang.org/x/net to v0.13.0 (#962)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 03:43:31 +00:00
renovate[bot]
87a98eb866 chore(deps): update dependency golang-version to v1.20.7 (#961)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-02 01:51:46 +00:00
renovate[bot]
9c63db7ba0 fix(deps): update kubernetes packages to v0.27.4 (#959)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-20 07:29:09 +00:00
renovate[bot]
243cfff790 chore(deps): update dependency golang-version to v1.20.6 (#957)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-11 18:57:51 +00:00
renovate[bot]
54faf5f306 fix(deps): update module golang.org/x/oauth2 to v0.10.0 (#955)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-06 01:30:16 +00:00
renovate[bot]
8549d219b0 fix(deps): update module golang.org/x/net to v0.12.0 (#953)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-07-05 19:41:43 +00:00
Hidetake Iwata
622dc5ba0b Refactor #944 (#951) 2023-06-24 15:26:39 +09:00
Reza Nikoopour
069ff68d99 Added flag to let user set redirect uri for authcode-keyboard (#944) 2023-06-23 16:53:55 +09:00
renovate[bot]
3d6784a336 chore(deps): update dependency golangci/golangci-lint to v1.53.3 (#949)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-15 14:49:40 +00:00
renovate[bot]
67dc859f0e fix(deps): update kubernetes packages to v0.27.3 (#948)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-15 07:37:34 +00:00
renovate[bot]
d8686babb0 fix(deps): update module golang.org/x/sync to v0.3.0 (#947)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-14 23:17:04 +00:00
renovate[bot]
7804f7240c fix(deps): update module golang.org/x/oauth2 to v0.9.0 (#946)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-14 18:42:06 +00:00
renovate[bot]
a99cad7890 fix(deps): update module golang.org/x/net to v0.11.0 (#945)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-14 16:57:50 +00:00
renovate[bot]
e1be9b5c7e chore(deps): update dependency golang-version to v1.20.5 (#940)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-06 22:22:57 +00:00
renovate[bot]
d9b10a46e3 chore(deps): update dependency golangci/golangci-lint to v1.53.2 (#939)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-03 18:38:33 +00:00
renovate[bot]
845dcd3f79 chore(deps): update dependency golangci/golangci-lint to v1.53.1 (#938)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-06-02 13:34:11 +00:00
renovate[bot]
fc496932e1 fix(deps): update module github.com/stretchr/testify to v1.8.4 (#937)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-30 13:09:48 +00:00
renovate[bot]
54372086fb fix(deps): update module github.com/stretchr/testify to v1.8.3 (#936)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-19 04:46:33 +00:00
renovate[bot]
d954d971a0 fix(deps): update kubernetes packages to v0.27.2 (#935)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-18 10:50:23 +00:00
renovate[bot]
9f1136cabc fix(deps): update module github.com/coreos/go-oidc/v3 to v3.6.0 (#934)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-17 00:05:07 +00:00
renovate[bot]
9e2fcd8cdb fix(deps): update module github.com/golang-jwt/jwt/v4 to v5 (#925)
* fix(deps): update module github.com/golang-jwt/jwt/v4 to v5

* Replace with `jwt.RegisteredClaims`

* Replace with `jwt.NewNumericDate`

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Hidetake Iwata <int128@gmail.com>
2023-05-14 21:38:48 +09:00
renovate[bot]
974369fe6f fix(deps): update module golang.org/x/oauth2 to v0.8.0 (#922) 2023-05-14 19:19:18 +09:00
Hidetake Iwata
8dc9f70407 Use setup-go@v4 and int128/go-workflows (#933) 2023-05-14 18:32:24 +09:00
Hidetake Iwata
10412effa2 Run go fmt (#866)
* Run go fmt

* Generated by GitHub Actions (go / generate)

https://github.com/int128/kubelogin/actions/runs/4971610724

---------

Co-authored-by: update-generated-files-action <41898282+github-actions[bot]@users.noreply.github.com>
2023-05-14 18:21:55 +09:00
renovate[bot]
269d8a48d4 fix(deps): update module golang.org/x/net to v0.10.0 (#932)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-08 22:07:55 +00:00
renovate[bot]
4ef50e884a fix(deps): update module golang.org/x/term to v0.8.0 (#930)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-05 01:28:43 +00:00
renovate[bot]
424cc24d15 fix(deps): update module golang.org/x/sync to v0.2.0 (#929)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-04 20:13:07 +00:00
renovate[bot]
18d06de10c fix(deps): update module k8s.io/klog/v2 to v2.100.1 (#927)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-03 02:03:28 +00:00
renovate[bot]
191b1ec7a3 chore(deps): update dependency golang-version to v1.20.4 (#928)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-02 23:30:46 +00:00
renovate[bot]
9b4ecec896 fix(deps): update kubernetes packages to v0.27.1 (#924)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-15 03:30:07 +00:00
renovate[bot]
004d7ca3f5 fix(deps): update kubernetes packages to v0.27.0 (#923)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-12 06:52:31 +00:00
renovate[bot]
dda70d881a fix(deps): update module golang.org/x/net to v0.9.0 (#921)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-07 01:25:02 +00:00
renovate[bot]
75e139b248 chore(deps): update dependency golang-version to v1.20.3 (#918)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-05 06:08:03 +00:00
renovate[bot]
66e05bbddf fix(deps): update module github.com/spf13/cobra to v1.7.0 (#919)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-05 00:51:46 +00:00
renovate[bot]
a5ec2e1252 chore(deps): update rajatjindal/krew-release-bot action to v0.0.46 (#915)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-26 15:38:20 +00:00
renovate[bot]
97e7a5c7c4 chore(deps): update rajatjindal/krew-release-bot action to v0.0.44 (#914)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-26 06:45:34 +00:00
renovate[bot]
727eeb8f7c chore(deps): update dependency golangci/golangci-lint to v1.52.2 (#913)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-25 23:33:00 +00:00
renovate[bot]
c96c931b83 chore(deps): update dependency golangci/golangci-lint to v1.52.1 (#912)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-22 02:57:24 +00:00
renovate[bot]
9a242e44d3 chore(deps): update dependency golangci/golangci-lint to v1.52.0 (#911)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-18 13:32:17 +00:00
renovate[bot]
124c558a6f fix(deps): update kubernetes packages to v0.26.3 (#910)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-18 07:04:14 +00:00
renovate[bot]
4df4f4132d fix(deps): update module github.com/chromedp/chromedp to v0.9.1 (#906)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-11 14:33:04 +00:00
renovate[bot]
a3d502e5d4 chore(deps): update dependency golang-version to v1.20.2 (#902)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-07 19:25:44 +00:00
renovate[bot]
5b7bf4b199 fix(deps): update module github.com/chromedp/chromedp to v0.8.8 (#901)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-05 15:27:50 +00:00
renovate[bot]
d1438615ac fix(deps): update module golang.org/x/oauth2 to v0.6.0 (#900)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-05 07:32:42 +00:00
renovate[bot]
435fe39c89 fix(deps): update module k8s.io/klog/v2 to v2.90.1 (#897)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-01 20:43:27 +00:00
renovate[bot]
b09e50d08d fix(deps): update kubernetes packages to v0.26.2 (#895)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-01 09:05:36 +00:00
renovate[bot]
e7f3b2c997 fix(deps): update module github.com/int128/oauth2dev to v1 (#896)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-01 15:08:29 +09:00
renovate[bot]
79cd9c53f8 fix(deps): update module github.com/stretchr/testify to v1.8.2 (#893)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-25 19:08:29 +00:00
renovate[bot]
ca2977a7e0 fix(deps): update github.com/int128/oauth2dev digest to 3709c53 (#890)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-20 12:12:23 +00:00
renovate[bot]
4c3a9f82f7 chore(deps): update dependency golangci/golangci-lint to v1.51.2 (#889)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-20 00:55:34 +00:00
renovate[bot]
d233ca1c20 fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.5.0 (#888)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-19 16:41:06 +00:00
renovate[bot]
6377df181e fix(deps): update github.com/int128/oauth2dev digest to fd475b2 (#887)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-17 14:07:14 +00:00
Martin Linkhorst
f03d4fe821 get-token: add --force-refresh flag to refresh ID token (#879) 2023-02-17 15:25:11 +09:00
Hidetake Iwata
a049f321f1 Update renovate.json5 (#886) 2023-02-17 13:54:32 +09:00
renovate[bot]
1e650f52c9 fix(deps): update module golang.org/x/net to v0.7.0 (#884)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-15 14:26:45 +00:00
renovate[bot]
08f80581f2 fix(deps): update github.com/int128/oauth2dev digest to fe60e7d (#885)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-15 09:55:42 +00:00
renovate[bot]
a7b10d5a04 chore(deps): update dependency golang-version to v1.20.1 (#883)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-15 04:26:46 +00:00
renovate[bot]
0772812f03 fix(deps): update github.com/int128/oauth2dev digest to eaff031 (#882)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-13 02:07:25 +00:00
renovate[bot]
e32cdbf46b chore(deps): update dependency golang-version to v1.20.0 (#869)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-12 21:30:49 +00:00
renovate[bot]
9e6b8da46b chore(deps): update golang docker tag to v1.20 (#870)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-12 17:23:14 +00:00
Hidetake Iwata
f9a72bca0c Update renovate.json5 (#881) 2023-02-12 16:58:49 +09:00
renovate[bot]
792e737bc6 fix(deps): update github.com/int128/oauth2dev digest to efb5770 (#878)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-09 09:32:39 +00:00
renovate[bot]
6cdf48071a fix(deps): update module golang.org/x/net to v0.6.0 (#876)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-09 04:58:23 +00:00
renovate[bot]
5e12c3ee48 fix(deps): update module golang.org/x/term to v0.5.0 (#875)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-08 04:03:15 +00:00
renovate[bot]
c4219d6efd fix(deps): update github.com/int128/oauth2dev digest to 574d1a1 (#874)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-06 03:13:46 +00:00
renovate[bot]
8e23a2089c chore(deps): update dependency golangci/golangci-lint to v1.51.1 (#873)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-05 18:12:22 +00:00
renovate[bot]
965a7bb199 fix(deps): update github.com/int128/oauth2dev digest to abccf6b (#872)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-02 18:23:56 +00:00
renovate[bot]
9bb31d04b4 chore(deps): update dependency golangci/golangci-lint to v1.51.0 (#871)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-02-02 13:54:15 +00:00
renovate[bot]
8c755aa792 fix(deps): update module k8s.io/klog/v2 to v2.90.0 (#867)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-23 21:33:52 +00:00
renovate[bot]
5d7819cd7c fix(deps): update kubernetes packages to v0.26.1 (#864)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-19 09:58:57 +00:00
renovate[bot]
1b8e3750a4 fix(deps): update github.com/int128/oauth2dev digest to b478dfb (#861)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-11 05:04:36 +00:00
renovate[bot]
d87be5ec93 chore(deps): update dependency golang-version to v1.19.5 (#860)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-10 22:08:15 +00:00
renovate[bot]
145e6f907f fix(deps): update module github.com/chromedp/chromedp to v0.8.7 (#859)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-10 11:28:15 +00:00
renovate[bot]
c275178afe fix(deps): update github.com/int128/oauth2dev digest to c3e3a0f (#856)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-05 04:59:56 +00:00
renovate[bot]
d17fe6965f fix(deps): update module golang.org/x/oauth2 to v0.4.0 (#855)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-05 01:10:57 +00:00
renovate[bot]
b8a0317548 fix(deps): update module golang.org/x/net to v0.5.0 (#854)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-04 21:30:28 +00:00
Hidetake Iwata
5b3a605f10 Refactor with github.ref_name and github.ref_type (#853) 2023-01-04 09:34:00 +09:00
renovate[bot]
642195e7dd fix(deps): update module github.com/coreos/go-oidc/v3 to v3.5.0 (#852)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-03 22:52:11 +00:00
Hidetake Iwata
26733f68df Use actions/setup-go (#850) 2023-01-03 16:14:53 +09:00
renovate[bot]
7ee5296398 fix(deps): update module golang.org/x/net to v0.4.0 (#840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-01 08:54:16 +00:00
renovate[bot]
fe267ef2ec fix(deps): update kubernetes packages to v0.26.0 (#843)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-01 06:27:30 +00:00
renovate[bot]
a925330117 fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.4.3 (#836)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-01-01 04:05:34 +00:00
Hidetake Iwata
0976a226d3 Use int128/docker-build-workflow (#849) 2023-01-01 09:38:59 +09:00
Hidetake Iwata
adfbc48b24 Handle verification_url field in device flow (#846) 2022-12-24 19:10:21 +09:00
Hidetake Iwata
345465a5d3 Refactor test (#847) 2022-12-24 17:00:59 +09:00
Bastian
cda2eccaac feat(authentication): add oauth2 device grant (#837) 2022-12-22 08:03:10 +09:00
renovate[bot]
3aab0a575d chore(deps): update dependency golang-version to v1.19.4 (#842)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-12-07 21:31:58 +00:00
Hidetake Iwata
0dffdd7988 Use setup-go (#835) 2022-11-29 14:39:07 +09:00
Hidetake Iwata
bc6a86d002 Use setup-go cache (#834) 2022-11-29 11:49:31 +09:00
Hidetake Iwata
8b336ee2d5 Build multi-architecture image in parallel (#833)
* Build multi platforms in parallel

* Fix suffix

* docker pull

* Push [DO NOT MERGE]

* Add linux prefix

* Use int128/docker-manifest-create-action

* Fix latest

* Remove push
2022-11-20 21:30:28 +09:00
renovate[bot]
b640aa17df chore(deps): update module go to 1.19 (#751)
* chore(deps): update module go to 1.19

* Fix deprecations

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Hidetake Iwata <int128@gmail.com>
2022-11-19 21:45:08 +09:00
renovate[bot]
60f11875b1 chore(deps): update golang docker tag to v1.19 (#771)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-19 19:31:47 +09:00
renovate[bot]
b2303dde05 chore(deps): update dependency golang-version to v1.19.3 (#769)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-19 19:11:51 +09:00
Hidetake Iwata
1169cb534b refactor: replace io/ioutil with os, io package (#832) 2022-11-19 19:06:22 +09:00
renovate[bot]
9dfbe81b28 fix(deps): update module k8s.io/klog/v2 to v2.80.1 (#791)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-11 12:27:00 +00:00
renovate[bot]
0bdc92c218 fix(deps): update module golang.org/x/sync to v0.1.0 (#825)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-11 09:40:08 +00:00
renovate[bot]
d68ef508ac fix(deps): update module golang.org/x/oauth2 to v0.2.0 (#829)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-11 06:41:46 +00:00
renovate[bot]
e19d0404fd fix(deps): update module golang.org/x/net to v0.2.0 (#828)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-11 04:50:24 +00:00
renovate[bot]
dbd830b64f fix(deps): update module github.com/spf13/cobra to v1.6.1 (#818)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-11 03:02:12 +00:00
renovate[bot]
f722b2a40c fix(deps): update module github.com/coreos/go-oidc/v3 to v3.4.0 (#790)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-11 00:56:05 +00:00
renovate[bot]
7514789ace fix(deps): update kubernetes packages to v0.25.4 (#786)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-10 22:07:13 +00:00
renovate[bot]
3119e466c9 fix(deps): update module github.com/stretchr/testify to v1.8.1 (#827)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-10 20:02:21 +00:00
renovate[bot]
8d1d4d1c4b chore(deps): update dependency golangci/golangci-lint to v1.50.1 (#787)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-11-10 16:08:52 +00:00
renovate[bot]
1943ee0399 fix(deps): update golang.org/x/term digest to 8365914 (#824)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-17 23:59:30 +00:00
renovate[bot]
0a5671c135 fix(deps): update golang.org/x/net digest to f25eb7e (#823)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-17 20:52:28 +00:00
Huang Huang
3602948645 Correct the --listen-address flag at stage 2 instructions (#815) 2022-10-16 14:26:54 +09:00
renovate[bot]
bd2e7123ad fix(deps): update golang.org/x/oauth2 digest to 6fdb5e3 (#822)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-14 20:42:30 +00:00
renovate[bot]
934e27dd91 fix(deps): update golang.org/x/net digest to f15817d (#820)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-14 11:51:28 +00:00
renovate[bot]
24cf76feeb fix(deps): update golang.org/x/net digest to 0b7e1fb (#819)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-12 17:55:23 +00:00
renovate[bot]
051e5a8d52 fix(deps): update golang.org/x/oauth2 digest to b44042a (#816)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-06 19:58:04 +00:00
renovate[bot]
690ee40af0 fix(deps): update golang.org/x/net digest to 8021a29 (#814)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-04 21:20:37 +00:00
renovate[bot]
f742440099 fix(deps): update golang.org/x/net digest to bcab684 (#813)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-02 09:05:28 +00:00
renovate[bot]
7f37251846 fix(deps): update golang.org/x/net digest to 107f3e3 (#812)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-01 04:08:43 +00:00
renovate[bot]
e47ce9bd8c fix(deps): update module github.com/chromedp/chromedp to v0.8.6 (#811)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-10-01 00:36:46 +00:00
renovate[bot]
7a18b9c80d fix(deps): update golang.org/x/sync digest to 8fcdb60 (#810)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-30 01:06:33 +00:00
renovate[bot]
1b46377c31 fix(deps): update golang.org/x/net digest to f486391 (#809)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-27 23:56:09 +00:00
renovate[bot]
2f2f46382c fix(deps): update golang.org/x/net digest to 02166a9 (#806)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-27 01:08:20 +00:00
renovate[bot]
28c5da0b08 fix(deps): update golang.org/x/sync digest to 7f9b162 (#805)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-24 05:38:52 +00:00
renovate[bot]
fffb76284d fix(deps): update golang.org/x/net digest to 8be6392 (#804)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-24 02:55:33 +00:00
renovate[bot]
fe2ed1d7f1 fix(deps): update golang.org/x/net digest to d300de1 (#803)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-22 01:20:28 +00:00
renovate[bot]
0ee202bc50 fix(deps): update golang.org/x/net digest to d0c6ba3 (#802)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-21 01:05:17 +00:00
renovate[bot]
9d9b4f22c9 fix(deps): update golang.org/x/term digest to 7a66f97 (#801)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-20 11:38:41 +00:00
renovate[bot]
c9f1a9be18 fix(deps): update golang.org/x/net digest to f2f64eb (#800)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-20 06:04:35 +00:00
Mayur Waghmode
b43161531d Added ppc64le support (#799)
Signed-off-by: mayurwaghmode <waghmodemayur17@gmail.com>

Signed-off-by: mayurwaghmode <waghmodemayur17@gmail.com>
2022-09-12 18:49:03 +09:00
renovate[bot]
43c5283b3b fix(deps): update golang.org/x/net digest to bea034e (#797)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-09 20:37:10 +00:00
renovate[bot]
0a9a6a81f3 fix(deps): update module github.com/google/go-cmp to v0.5.9 (#795)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-09 08:38:06 +00:00
renovate[bot]
ec070a46f3 fix(deps): update golang.org/x/oauth2 digest to f213421 (#796)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-09 05:51:00 +00:00
renovate[bot]
0632078b7d fix(deps): update golang.org/x/sync digest to f12130a (#794)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-08 01:56:15 +00:00
renovate[bot]
44d0740937 fix(deps): update golang.org/x/net digest to 1e95f45 (#793)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-07 21:48:21 +00:00
renovate[bot]
523d07e83b fix(deps): update golang.org/x/net digest to f3363e0 (#792)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-09-06 21:30:45 +00:00
renovate[bot]
ffcb64ba74 fix(deps): update module github.com/chromedp/chromedp to v0.8.5 (#789)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-27 12:48:37 +00:00
renovate[bot]
a684112dd5 fix(deps): update golang.org/x/net digest to 83b083e (#788)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-26 19:52:41 +00:00
renovate[bot]
017b1b9fba fix(deps): update golang.org/x/oauth2 digest to 0ebed06 (#784)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-23 11:00:44 +00:00
renovate[bot]
5290ca9474 fix(deps): update golang.org/x/net digest to b0a4917 (#785)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-23 05:01:06 +00:00
renovate[bot]
542b454d1c fix(deps): update golang.org/x/sync digest to 7fc1605 (#783)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-19 06:06:49 +00:00
renovate[bot]
ba1beb0b10 fix(deps): update kubernetes packages to v0.24.4 (#782)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-18 09:31:51 +00:00
renovate[bot]
8a2837d0ff fix(deps): update module github.com/chromedp/chromedp to v0.8.4 (#779)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-14 10:38:20 +00:00
renovate[bot]
a04131280e fix(deps): update golang.org/x/net digest to 3211cb9 (#778)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-12 21:57:19 +00:00
renovate[bot]
ccaf76f370 fix(deps): update golang.org/x/net digest to 13a9a73 (#777)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-11 21:54:48 +00:00
renovate[bot]
7537256308 fix(deps): update golang.org/x/net digest to 07c6da5 (#776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-09 22:44:49 +00:00
renovate[bot]
cd68981c75 fix(deps): update golang.org/x/net digest to f428fae (#775)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-09 05:54:24 +00:00
renovate[bot]
e3934f5e3b fix(deps): update golang.org/x/oauth2 digest to 8227340 (#774)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-08 22:08:06 +00:00
renovate[bot]
1bd1fc9079 chore(deps): update dependency golangci/golangci-lint to v1.48.0 (#772) 2022-08-06 11:23:20 +09:00
renovate[bot]
63c9018faa fix(deps): update golang.org/x/net digest to a33c5aa (#773)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-05 04:48:31 +00:00
renovate[bot]
d6f30063bd fix(deps): update golang.org/x/net digest to 0bcc04d (#770)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-03 02:29:18 +00:00
renovate[bot]
572eaed609 chore(deps): update dependency golangci/golangci-lint to v1.47.3 (#768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-02 01:57:48 +00:00
renovate[bot]
2757feda35 chore(deps): update dependency golang-version to v1.18.5 (#767)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-08-01 21:35:30 +00:00
Marko Mikulicic
7bcc15827a Use cgo when cross-compiling macos arm64 (#763) 2022-07-29 12:56:36 +09:00
renovate[bot]
0b53136d12 fix(deps): update golang.org/x/net digest to c7608f3 (#766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-29 01:05:14 +00:00
renovate[bot]
4642e559d4 fix(deps): update golang.org/x/net digest to 1f511ac (#765)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-28 17:38:34 +00:00
renovate[bot]
de66e882b3 fix(deps): update golang.org/x/net digest to 41545e8 (#764)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-28 05:53:33 +00:00
renovate[bot]
4055aeaaa4 fix(deps): update golang.org/x/net digest to 0699458 (#761)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-27 04:04:47 +00:00
renovate[bot]
51d38d6937 fix(deps): update module github.com/chromedp/chromedp to v0.8.3 (#760)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-26 03:00:46 +00:00
renovate[bot]
88729027f1 fix(deps): update golang.org/x/net digest to 46097bf (#759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-26 00:51:33 +00:00
renovate[bot]
96354ebfb9 fix(deps): update golang.org/x/term digest to a9ba230 (#758)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-23 02:08:15 +00:00
renovate[bot]
c01bbe3110 fix(deps): update golang.org/x/sync digest to 886fb93 (#730)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-22 23:52:26 +00:00
renovate[bot]
75c24e8a25 fix(deps): update golang.org/x/oauth2 digest to 128564f (#756)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-22 21:33:03 +00:00
renovate[bot]
7b824e6e20 fix(deps): update golang.org/x/net digest to a158d28 (#755)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-22 19:40:46 +00:00
renovate[bot]
fda2fe3775 chore(deps): update dependency golangci/golangci-lint to v1.47.2 (#752)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-21 16:12:08 +00:00
renovate[bot]
a13e6ecf5d chore(deps): update dependency golangci/golangci-lint to v1.47.1 (#750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-19 17:09:16 +00:00
renovate[bot]
cbc4a5a4c6 fix(deps): update golang.org/x/oauth2 digest to c8730f7 (#749)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 22:44:53 +00:00
renovate[bot]
696b630950 fix(deps): update kubernetes packages to v0.24.3 (#675)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 21:09:11 +00:00
renovate[bot]
55af8ab1d1 chore(deps): update dependency golangci/golangci-lint to v1.47.0 (#748)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 18:41:37 +00:00
renovate[bot]
7b1597de54 fix(deps): update golang.org/x/term digest to 065cf7b (#721)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 15:53:33 +00:00
renovate[bot]
6510482278 fix(deps): update golang.org/x/net digest to 1185a90 (#670)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 12:22:08 +00:00
renovate[bot]
da6d8f9467 chore(deps): update docker/setup-buildx-action action to v2 (#746) 2022-07-18 16:11:53 +09:00
renovate[bot]
37c602fc73 chore(deps): update docker/setup-qemu-action action to v2 (#747) 2022-07-18 16:06:21 +09:00
renovate[bot]
78808eed97 chore(deps): update docker/metadata-action action to v4 (#745) 2022-07-18 15:57:23 +09:00
renovate[bot]
66592b5831 fix(deps): update module github.com/alexflint/go-filemutex to v1.2.0 (#712)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 14:17:34 +09:00
renovate[bot]
cc323d2fae chore(deps): update docker/build-push-action action to v3 (#743)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 14:17:16 +09:00
renovate[bot]
1829e2caaa chore(deps): update docker/login-action action to v2 (#744)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 14:17:06 +09:00
renovate[bot]
cc30f40e58 fix(deps): update module k8s.io/klog/v2 to v2.70.1 (#742)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 13:58:12 +09:00
renovate[bot]
6037d5706a fix(deps): update golang.org/x/oauth2 digest to 2104d58 (#693)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 13:57:41 +09:00
renovate[bot]
d67e2663c9 fix(deps): update module github.com/spf13/cobra to v1.5.0 (#741)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 13:57:19 +09:00
renovate[bot]
1fe770939a fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.4.2 (#715)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-18 13:05:24 +09:00
Hidetake Iwata
5ba7f551cf Refactor tests (#740)
* refactor: use t.Setenv()

* refactor: use t.TempDir()

* refactor: use t.Cleanup()
2022-07-16 22:08:55 +09:00
renovate[bot]
5ea4d3648a chore(deps): update dependency golang-version to v1.18.4 (#720)
* chore(deps): update dependency golang-version to v1.18.4

* Bump github.com/json-iterator/go to v1.1.12

https://github.com/json-iterator/go/releases/tag/v1.1.12

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Hidetake Iwata <int128@gmail.com>
2022-07-16 21:05:23 +09:00
renovate[bot]
41f31cd056 fix(deps): update module github.com/coreos/go-oidc/v3 to v3.2.0 (#738)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-16 20:41:08 +09:00
Hidetake Iwata
7152bccd21 refactor: migrate to Testify Mock (#739) 2022-07-16 16:55:51 +09:00
renovate[bot]
e27b5723da fix(deps): update module github.com/chromedp/chromedp to v0.8.2 (#726)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-07-16 13:10:42 +09:00
renovate[bot]
5499a35916 chore(deps): update dependency golangci/golangci-lint to v1.46.2 (#735)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2022-07-16 13:10:02 +09:00
Hidetake Iwata
86341c82fb Use int128/go-actions/setup (#731) 2022-05-21 16:40:56 +09:00
renovate[bot]
a028255661 fix(deps): update module github.com/google/go-cmp to v0.5.8 (#724) 2022-05-21 16:27:07 +09:00
Hidetake Iwata
3679e5e436 Update runner of system-test to ubuntu-latest (#509) 2022-05-21 14:28:30 +09:00
Hidetake Iwata
ed723fed2a Fix authentication error in system-test (#729)
* Show log of kube-apiserver

* Fix kubeadmConfigPatches
2022-05-21 13:57:06 +09:00
renovate[bot]
98b1fb92f1 chore(deps): update actions/cache action to v3 (#710)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-05-07 17:28:16 +09:00
Hidetake Iwata
d28cecd756 Use int128/renovate-base (#725) 2022-05-07 17:27:04 +09:00
renovate[bot]
4ba848019a chore(deps): update rajatjindal/krew-release-bot action to v0.0.43 (#723)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-04-17 05:18:25 +00:00
renovate[bot]
03a1b10c3c chore(deps): update rajatjindal/krew-release-bot action to v0.0.42 (#716)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-29 11:03:58 +00:00
renovate[bot]
03322d0cad chore(deps): update dependency golangci/golangci-lint to v1.45.2 (#714)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-24 16:18:40 +00:00
renovate[bot]
58ee2725e9 chore(deps): update dependency golangci/golangci-lint to v1.45.1 (#713)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-24 11:23:43 +00:00
renovate[bot]
8572c8db95 fix(deps): update module github.com/chromedp/chromedp to v0.8.0 (#709)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-21 12:15:04 +00:00
renovate[bot]
ff6e770818 fix(deps): update module k8s.io/klog/v2 to v2.60.1 (#708)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-20 18:27:45 +00:00
renovate[bot]
1a58259fc0 chore(deps): update dependency golangci/golangci-lint to v1.45.0 (#707)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-18 19:59:14 +00:00
renovate[bot]
1c37d7a8b7 fix(deps): update module k8s.io/klog/v2 to v2.60.0 (#705)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-17 17:27:21 +00:00
renovate[bot]
4be2ac025a fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.4.0 (#704)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-17 05:22:31 +00:00
renovate[bot]
adb57bdb36 fix(deps): update module k8s.io/klog/v2 to v2.50.2 (#703)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-17 02:35:59 +00:00
renovate[bot]
1166672b92 fix(deps): update module k8s.io/klog/v2 to v2.50.1 (#702)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-16 17:29:05 +00:00
renovate[bot]
c08bedfcbd chore(deps): update dependency golang to v1.18 (#700)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-16 03:50:28 +00:00
renovate[bot]
72237142c8 fix(deps): update module k8s.io/klog/v2 to v2.50.0 (#699)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-16 01:32:13 +00:00
renovate[bot]
aa727c424a chore(deps): update golangci/golangci-lint-action action to v3 (#695)
* chore(deps): update golangci/golangci-lint-action action to v3

* Update go.yaml

Co-authored-by: Renovate Bot <bot@renovateapp.com>
Co-authored-by: Hidetake Iwata <int128@gmail.com>
2022-03-12 16:36:09 +09:00
renovate[bot]
92cb984154 chore(deps): update actions/setup-go action to v3 (#696)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-12 16:29:56 +09:00
renovate[bot]
86fc4df483 fix(deps): update module github.com/spf13/cobra to v1.4.0 (#698)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-11 17:42:17 +00:00
renovate[bot]
c931677964 chore(deps): update actions/checkout action to v3 (#697)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-03-04 19:12:00 +09:00
renovate[bot]
8b0a087e14 fix(deps): update module github.com/chromedp/chromedp to v0.7.8 (#691)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-02-19 05:01:48 +00:00
renovate[bot]
713696ce12 chore(deps): update dependency golangci/golangci-lint to v1.44.2 (#690)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-02-18 00:42:56 +00:00
renovate[bot]
0f281e8bb6 chore(deps): update dependency golangci/golangci-lint to v1.44.1 (#689)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-02-17 15:00:53 +00:00
renovate[bot]
64c0f56480 fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.3.0 (#687)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-02-10 08:28:01 +00:00
renovate[bot]
71076214ce fix(deps): update module github.com/chromedp/chromedp to v0.7.7 (#686)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-02-04 11:39:14 +00:00
renovate[bot]
46b5961742 chore(deps): update dependency golangci/golangci-lint to v1.44.0 (#684)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-01-25 13:16:01 +00:00
renovate[bot]
2675df15d4 fix(deps): update module github.com/google/go-cmp to v0.5.7 (#682)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2022-01-22 15:25:59 +00:00
Hidetake Iwata
b17843ce7b Update README.md 2022-01-22 22:03:43 +09:00
Hidetake Iwata
775841a72b Remove deprecation of standalone mode (#680)
* Remove deprecation of standalone mode

* Update standalone-mode.md
2022-01-08 17:48:00 +09:00
renovate[bot]
564177cd18 fix(deps): update module k8s.io/klog/v2 to v2.40.1 (#679)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-12-19 04:11:07 +00:00
renovate[bot]
3f5514573d fix(deps): update module k8s.io/klog/v2 to v2.40.0 (#678)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-12-17 16:41:23 +00:00
renovate[bot]
a70c0e21b9 fix(deps): update module github.com/spf13/cobra to v1.3.0 (#677)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-12-14 23:53:29 +00:00
renovate[bot]
6a8dd65a1a fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.2.0 (#672)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-12-03 20:38:18 +00:00
renovate[bot]
6b5947b174 chore(deps): update dependency golangci/golangci-lint to v1.43.0 (#669)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-28 07:10:52 +00:00
Hidetake Iwata
6ff75291d7 Use Renovate config in int128/go-actions 2021-11-28 15:44:45 +09:00
Hidetake Iwata
3cb6988b8b Refactor workflows (#668)
* Refactor workflows

* Fix runs-on

* Fix Dockerfile
2021-11-28 15:10:23 +09:00
renovate[bot]
2a14902541 fix(deps): update module github.com/chromedp/chromedp to v0.7.6 (#667)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-27 04:25:47 +00:00
renovate[bot]
78d9d1f913 fix(deps): update golang.org/x/net commit hash to d83791d (#666)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-23 23:03:26 +00:00
renovate[bot]
9f39c00cc8 fix(deps): update module k8s.io/client-go to v0.22.4 (#663)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-18 21:14:24 +00:00
renovate[bot]
6c767e8545 fix(deps): update golang.org/x/net commit hash to 6a13c67 (#664)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-18 18:27:01 +00:00
renovate[bot]
ccb00b7b58 fix(deps): update module k8s.io/apimachinery to v0.22.4 (#662)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-18 04:48:38 +00:00
renovate[bot]
cf8b89d6ae fix(deps): update golang.org/x/oauth2 commit hash to d3ed0bb (#661)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-17 03:58:13 +00:00
renovate[bot]
86a8721cac fix(deps): update golang.org/x/net commit hash to 47ca1ff (#660)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-11-17 01:37:59 +00:00
renovate[bot]
5f2ae5497f Merge pull request #657 from int128/renovate/k8s.io-client-go-0.x
fix(deps): update module k8s.io/client-go to v0.22.3
2021-10-28 10:29:01 +00:00
Renovate Bot
e89de7de0f fix(deps): update module k8s.io/client-go to v0.22.3 2021-10-28 10:28:26 +00:00
renovate[bot]
fd5580861f Merge pull request #656 from int128/renovate/k8s.io-apimachinery-0.x
fix(deps): update module k8s.io/apimachinery to v0.22.3
2021-10-28 10:26:21 +00:00
Renovate Bot
4382333ac9 fix(deps): update module k8s.io/apimachinery to v0.22.3 2021-10-28 10:26:17 +00:00
renovate[bot]
821265c912 fix(deps): update module k8s.io/klog/v2 to v2.30.0 (#654)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-22 15:17:05 +00:00
renovate[bot]
f5f0c7eadd fix(deps): update golang.org/x/net commit hash to d418f37 (#653)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-20 09:47:35 +00:00
Hidetake Iwata
b1af578679 Fix docker push error 2021-10-20 12:20:53 +09:00
renovate[bot]
5737f96665 fix(deps): update golang.org/x/net commit hash to c6ed85c (#652)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-20 02:08:53 +00:00
renovate[bot]
07129f8c77 fix(deps): update golang.org/x/net commit hash to 4f30a5c (#651)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-15 22:57:15 +00:00
renovate[bot]
931d4f3a89 fix(deps): update golang.org/x/net commit hash to fd004c5 (#650)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-15 01:31:08 +00:00
renovate[bot]
f76e186d72 fix(deps): update golang.org/x/net commit hash to 2b766c0 (#649)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-14 20:01:03 +00:00
renovate[bot]
3e44d7655f fix(deps): update golang.org/x/net commit hash to e13a265 (#648)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-13 20:13:11 +00:00
renovate[bot]
14f57e7232 fix(deps): update golang.org/x/net commit hash to ee2e9a0 (#647)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-13 16:48:16 +00:00
renovate[bot]
af8ae6f2f6 fix(deps): update module github.com/int128/oauth2cli to v1.14.0 (#646)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-12 02:40:53 +00:00
renovate[bot]
83a4524487 fix(deps): update golang.org/x/net commit hash to caeb26a (#645)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-11 18:40:20 +00:00
renovate[bot]
aeda430a1f fix(deps): update golang.org/x/net commit hash to 3b03d30 (#644)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-08 21:53:21 +00:00
renovate[bot]
10fdb63be3 fix(deps): update golang.org/x/net commit hash to 59d4e92 (#643)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-07 17:24:54 +00:00
renovate[bot]
fb439187d3 fix(deps): update golang.org/x/net commit hash to 62292e8 (#642)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-06 21:05:48 +00:00
renovate[bot]
73359e62db fix(deps): update golang.org/x/net commit hash to d2e5035 (#641)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-06 00:05:56 +00:00
renovate[bot]
c38b41cf85 fix(deps): update golang.org/x/oauth2 commit hash to 6b3c2da (#640)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-05 19:59:18 +00:00
renovate[bot]
e149f6443f fix(deps): update module github.com/golang-jwt/jwt/v4 to v4.1.0 (#636)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-05 13:35:11 +00:00
renovate[bot]
3c0bca7dee fix(deps): update golang.org/x/term commit hash to 03fcf44 (#637)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-05 11:33:50 +00:00
renovate[bot]
43497466f9 fix(deps): update golang.org/x/net commit hash to d4b1ae0 (#635)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-10-05 09:25:27 +00:00
Hidetake Iwata
0075043866 Use int128/docker-build-cache-config-action (#639) 2021-10-05 16:33:30 +09:00
renovate[bot]
b160aea35e fix(deps): update golang.org/x/net commit hash to 3c21e5b (#634)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-17 19:13:50 +00:00
renovate[bot]
52311525fe fix(deps): update module k8s.io/client-go to v0.22.2 (#632)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-17 17:31:25 +00:00
renovate[bot]
ab923d0d49 fix(deps): update module k8s.io/apimachinery to v0.22.2 (#631)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-17 16:05:50 +00:00
renovate[bot]
97908c775f fix(deps): update module github.com/coreos/go-oidc/v3 to v3.1.0 (#630)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-17 10:16:07 +00:00
renovate[bot]
c6662f32fb fix(deps): update golang.org/x/term commit hash to 140adaa (#629)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-17 00:08:20 +00:00
renovate[bot]
a07a1eb7e8 fix(deps): update golang.org/x/net commit hash to 12bc252 (#626)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-16 04:35:33 +00:00
renovate[bot]
f5f73df697 fix(deps): update github.com/pkg/browser commit hash to 681adbf (#625)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-11 10:11:49 +00:00
renovate[bot]
ae3a001dd2 fix(deps): update golang.org/x/net commit hash to a5e0955 (#624)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-08 21:19:10 +00:00
renovate[bot]
eb8f211e67 fix(deps): update golang.org/x/net commit hash to ff17edf (#623)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-08 00:40:24 +00:00
Hidetake Iwata
237e53313d Add flag to set custom browser command (#622)
* Add flag to set custom browser command

* Use --browser-command in system_test

* Add --browser-command= to setup message
2021-09-05 11:35:03 +09:00
renovate[bot]
8cce70c302 fix(deps): update github.com/pkg/browser commit hash to 6d279e1 (#621)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-04 02:44:53 +00:00
renovate[bot]
751b62b418 fix(deps): update golang.org/x/net commit hash to ad29c8a (#620)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-03 19:31:19 +00:00
renovate[bot]
1aeb6b0c0d fix(deps): update golang.org/x/net commit hash to 8d99171 (#619)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-02 19:08:13 +00:00
renovate[bot]
58d354f6bc fix(deps): update module k8s.io/klog/v2 to v2.20.0 (#618)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-09-02 07:32:31 +00:00
Hidetake Iwata
077d9ab90c Use docker/metadata-action@v3 (#616) 2021-08-28 22:10:41 +09:00
Joel Kaasinen
50bc986085 update README.md (#615) 2021-08-28 08:03:20 +09:00
renovate[bot]
75698aee0c fix(deps): update golang.org/x/net commit hash to e898025 (#613)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-25 19:59:14 +00:00
renovate[bot]
a17137b4e9 fix(deps): update module k8s.io/client-go to v0.22.1 (#612)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-20 00:16:31 +00:00
renovate[bot]
395a36eb53 fix(deps): update module k8s.io/apimachinery to v0.22.1 (#611)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-19 22:44:00 +00:00
renovate[bot]
b86118034f fix(deps): update golang.org/x/oauth2 commit hash to 2bc19b1 (#610)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-19 21:04:49 +00:00
renovate[bot]
a4b63da790 fix(deps): update golang.org/x/oauth2 commit hash to 7df4dd6 (#609)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-18 02:05:49 +00:00
renovate[bot]
b0d9ff907b chore(deps): update golang docker tag to v1.17 (#608)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-17 04:36:40 +00:00
renovate[bot]
c8d7fa5009 fix(deps): update golang.org/x/oauth2 commit hash to faf39c7 (#606)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-13 20:13:09 +00:00
renovate[bot]
99fc66e205 fix(deps): update golang.org/x/net commit hash to 60bc85c (#607)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-13 18:16:01 +00:00
Hidetake Iwata
33275b0a30 Export BuildKit cache to GHCR (#605) 2021-08-09 22:53:48 +09:00
Hidetake Iwata
9a850d7072 Migrate to github.com/golang-jwt/jwt/v4 (#604) 2021-08-08 11:39:45 +09:00
renovate[bot]
e5981c49c8 chore(deps): update codecov/codecov-action action to v2 (#595) 2021-08-08 10:51:03 +09:00
renovate[bot]
226683c051 fix(deps): update golang.org/x/oauth2 commit hash to 6f1e639 (#602)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-05 20:23:53 +00:00
renovate[bot]
3d6cfe5054 fix(deps): update golang.org/x/net commit hash to aaa1db6 (#603)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-05 19:35:51 +00:00
renovate[bot]
8cba4b4647 fix(deps): update module k8s.io/client-go to v0.22.0 (#601)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-04 23:32:41 +00:00
renovate[bot]
f1b17d2fc1 fix(deps): update module k8s.io/apimachinery to v0.22.0 (#600)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-08-04 22:57:35 +00:00
Pedro Kiefer
a0cfde7198 refactor: add --oidc-use-pkce flag to force PKCE authorization flow (#599) 2021-08-04 06:38:26 +09:00
renovate[bot]
680dfeea68 fix(deps): update golang.org/x/net commit hash to c6fcb2d (#598)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-26 23:54:50 +00:00
renovate[bot]
103451e68d fix(deps): update golang.org/x/net commit hash to 853a461 (#594)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-16 21:48:03 +00:00
renovate[bot]
480c8305b1 fix(deps): update module k8s.io/client-go to v0.21.3 (#593)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-16 09:00:36 +00:00
renovate[bot]
e472a4b261 fix(deps): update module k8s.io/apimachinery to v0.21.3 (#592)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-16 07:51:53 +00:00
renovate[bot]
849bf27c09 fix(deps): update module k8s.io/klog/v2 to v2.10.0 (#591)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-15 11:13:45 +00:00
renovate[bot]
b5462d49ad fix(deps): update module github.com/chromedp/chromedp to v0.7.4 (#589)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-13 08:52:17 +00:00
renovate[bot]
08fdfa8a61 fix(deps): update github.com/pkg/browser commit hash to 7d21f8c (#588)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-06 15:47:15 +00:00
renovate[bot]
d10adc61cf fix(deps): update module github.com/spf13/cobra to v1.2.1 (#587)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-02 16:36:21 +00:00
renovate[bot]
9ecf09d7bc fix(deps): update module github.com/spf13/cobra to v1.2.0 (#586)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-07-01 19:22:49 +00:00
renovate[bot]
d92802565d chore(deps): update rajatjindal/krew-release-bot action to v0.0.40 (#583)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-28 21:25:12 +00:00
renovate[bot]
14c55a1312 fix(deps): update golang.org/x/oauth2 commit hash to a41e5a7 (#585)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-28 20:09:04 +00:00
renovate[bot]
aa912cf6d0 fix(deps): update golang.org/x/oauth2 commit hash to a8dc77f (#582)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-22 22:26:23 +00:00
renovate[bot]
7e15541455 fix(deps): update golang.org/x/oauth2 commit hash to bce0382 (#581)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-22 20:21:24 +00:00
renovate[bot]
eb205ebbe8 fix(deps): update golang.org/x/oauth2 commit hash to 14747e6 (#580)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-22 18:49:24 +00:00
renovate[bot]
dc5cc7e7ad fix(deps): update github.com/pkg/browser commit hash to c198bc9 (#579)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-21 11:06:17 +00:00
renovate[bot]
06fa24bcee fix(deps): update module k8s.io/client-go to v0.21.2 (#578)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-18 02:31:09 +00:00
renovate[bot]
e5469925f5 fix(deps): update module k8s.io/apimachinery to v0.21.2 (#577)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-18 01:14:34 +00:00
renovate[bot]
6dbd197e8c fix(deps): update golang.org/x/oauth2 commit hash to d040287 (#576)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-15 20:28:06 +00:00
renovate[bot]
0e10951907 fix(deps): update golang.org/x/term commit hash to 6886f2d (#575)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-15 18:15:51 +00:00
renovate[bot]
b23f036445 fix(deps): update golang.org/x/net commit hash to 04defd4 (#573)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-14 20:00:31 +00:00
renovate[bot]
63f08f2f7a fix(deps): update module github.com/golang/mock to v1.6.0 (#572)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-11 23:01:45 +00:00
renovate[bot]
2006d13375 fix(deps): update golang.org/x/net commit hash to 84b48f8 (#571)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-10 15:28:35 +00:00
renovate[bot]
fb4d9663d5 fix(deps): update golang.org/x/net commit hash to 52da8fb (#570)
Co-authored-by: Renovate Bot <bot@renovateapp.com>
2021-06-10 13:26:15 +00:00
Hidetake Iwata
b3f2e2d9ec Add sequence diagram of credential plugin 2019-09-01 10:13:05 +09:00
135 changed files with 8177 additions and 3324 deletions

16
.github/release.yml vendored Normal file
View File

@@ -0,0 +1,16 @@
# https://docs.github.com/en/repositories/releasing-projects-on-github/automatically-generated-release-notes
changelog:
categories:
- title: Features
labels:
- '*'
exclude:
labels:
- renovate
- refactoring
- title: Refactoring
labels:
- refactoring
- title: Dependencies
labels:
- renovate

14
.github/renovate.json vendored
View File

@@ -1,14 +0,0 @@
{
"extends": [
"config:base"
],
"packageRules": [
{
"updateTypes": ["minor", "patch", "digest"],
"automerge": true
}
],
"postUpdateOptions": [
"gomodTidy"
]
}

12
.github/renovate.json5 vendored Normal file
View File

@@ -0,0 +1,12 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"github>int128/renovate-base",
"github>int128/go-renovate-config#v1.7.2",
"github>int128/go-renovate-config:go-directive#v1.7.2",
"github>int128/go-renovate-config:github-actions#v1.7.2",
"github>int128/go-renovate-config:kubernetes#v1.7.2",
"github>int128/go-renovate-config:kustomization-github-releases#v1.7.2",
"helpers:pinGitHubActionDigests",
],
}

View File

@@ -9,7 +9,6 @@ on:
- pkg/**
- go.*
- Dockerfile
- Makefile
push:
branches:
- master
@@ -18,28 +17,54 @@ on:
- pkg/**
- go.*
- Dockerfile
- Makefile
tags:
- v*
jobs:
build-and-push:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: read
packages: write
outputs:
image-uri: ghcr.io/${{ github.repository }}@${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v2
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- uses: actions/cache@v2
with:
path: /tmp/buildx
key: buildx-${{ runner.os }}-${{ github.sha }}
restore-keys: |
buildx-${{ runner.os }}-
- uses: docker/login-action@v1
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: int128/buildx-push-action@v1
- uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1
id: metadata
with:
extra-args: --platform=linux/amd64,linux/arm64
images: ghcr.io/${{ github.repository }}
- uses: int128/docker-build-cache-config-action@622932dfa73db7d3a65e40d5fcc094f2101e659a # v1.37.0
id: cache
with:
image: ghcr.io/${{ github.repository }}/cache
- uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0
- uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0
- uses: docker/build-push-action@67a2d409c0a876cbe6b11854e3e25193efe4e62d # v6.12.0
id: build
with:
push: ${{ github.event_name == 'push' }}
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}
cache-from: ${{ steps.cache.outputs.cache-from }}
cache-to: ${{ steps.cache.outputs.cache-to }}
platforms: |
linux/amd64
linux/arm64
linux/ppc64le
test:
if: github.event_name == 'push'
needs: build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- run: docker run --rm "$IMAGE_URI" --help
env:
IMAGE_URI: ${{ needs.build.outputs.image-uri }}

View File

@@ -7,8 +7,10 @@ on:
paths:
- .github/workflows/go.yaml
- pkg/**
- go.*
- Makefile
- integration_test/**
- mocks/**
- tools/**
- '**/go.*'
tags:
- v*
pull_request:
@@ -17,115 +19,61 @@ on:
paths:
- .github/workflows/go.yaml
- pkg/**
- go.*
- Makefile
- integration_test/**
- mocks/**
- tools/**
- '**/go.*'
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: 1.16
- uses: golangci/golangci-lint-action@v2
with:
version: v1.38.0
test:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: 1.16
- uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: go-linux-amd64-${{ hashFiles('**/go.sum') }}
restore-keys: |
go-linux-amd64-
- run: go test -v -race -cover -coverprofile=coverage.out ./...
- uses: codecov/codecov-action@v1
go-version-file: go.mod
cache-dependency-path: go.sum
- run: make test
test-platform-dependent:
integration-test:
strategy:
fail-fast: false
matrix:
platform:
- os: windows-latest
GOOS: windows
GOARCH: amd64
- os: macos-latest
GOOS: darwin
GOARCH: amd64
runs-on: ${{ matrix.platform.os }}
env:
GOOS: ${{ matrix.platform.GOOS }}
GOARCH: ${{ matrix.platform.GOARCH }}
os:
- ubuntu-latest
- macos-latest
- windows-latest
runs-on: ${{ matrix.os }}
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: 1.16
- uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: go-${{ matrix.platform.GOOS }}-${{ matrix.platform.GOARCH }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
go-${{ matrix.platform.GOOS }}-${{ matrix.platform.GOARCH }}-
- run: go test -race ./...
go-version-file: go.mod
cache-dependency-path: go.sum
- run: make integration-test
release:
strategy:
matrix:
platform:
- os: ubuntu-latest
GOOS: linux
GOARCH: amd64
CGO_ENABLED: 0 # https://github.com/int128/kubelogin/issues/567
- os: ubuntu-latest
GOOS: linux
GOARCH: arm64
- os: ubuntu-latest
GOOS: linux
GOARCH: arm
- os: macos-latest
GOOS: darwin
GOARCH: amd64
CGO_ENABLED: 1 # https://github.com/int128/kubelogin/issues/249
- os: macos-latest
GOOS: darwin
GOARCH: arm64
- os: windows-latest
GOOS: windows
GOARCH: amd64
runs-on: ${{ matrix.platform.os }}
env:
GOOS: ${{ matrix.platform.GOOS }}
GOARCH: ${{ matrix.platform.GOARCH }}
CGO_ENABLED: ${{ matrix.platform.CGO_ENABLED }}
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v2
with:
go-version: 1.16
- uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: go-${{ matrix.platform.GOOS }}-${{ matrix.platform.GOARCH }}-${{ hashFiles('**/go.sum') }}
restore-keys: |
go-${{ matrix.platform.GOOS }}-${{ matrix.platform.GOARCH }}-
- run: make dist
- run: make dist-release
if: startswith(github.ref, 'refs/tags/')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
publish:
if: startswith(github.ref, 'refs/tags/')
needs:
- release
lint:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v2
- uses: rajatjindal/krew-release-bot@v0.0.39
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version-file: tools/go.mod
cache-dependency-path: tools/go.sum
- run: make lint
generate:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version-file: tools/go.mod
cache-dependency-path: tools/go.sum
- run: go mod tidy
- run: make generate
- uses: int128/update-generated-files-action@65b9a7ae3ededc5679d78343f58fbebcf1ebd785 # v2.57.0

78
.github/workflows/release.yaml vendored Normal file
View File

@@ -0,0 +1,78 @@
name: release
on:
push:
branches:
- master
paths:
- .github/workflows/release.yaml
- pkg/**
- go.*
tags:
- v*
pull_request:
branches:
- master
paths:
- .github/workflows/release.yaml
- pkg/**
- go.*
jobs:
build:
strategy:
matrix:
platform:
- runs-on: ubuntu-latest
GOOS: linux
GOARCH: amd64
CGO_ENABLED: 0 # https://github.com/int128/kubelogin/issues/567
- runs-on: ubuntu-latest
GOOS: linux
GOARCH: arm64
- runs-on: ubuntu-latest
GOOS: linux
GOARCH: arm
- runs-on: ubuntu-latest
GOOS: linux
GOARCH: ppc64le
- runs-on: macos-latest
GOOS: darwin
GOARCH: amd64
CGO_ENABLED: 1 # https://github.com/int128/kubelogin/issues/249
- runs-on: macos-latest
GOOS: darwin
GOARCH: arm64
CGO_ENABLED: 1 # https://github.com/int128/kubelogin/issues/762
- runs-on: windows-latest
GOOS: windows
GOARCH: amd64
- runs-on: windows-latest
GOOS: windows
GOARCH: arm64
runs-on: ${{ matrix.platform.runs-on }}
env:
GOOS: ${{ matrix.platform.GOOS }}
GOARCH: ${{ matrix.platform.GOARCH }}
CGO_ENABLED: ${{ matrix.platform.CGO_ENABLED }}
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version-file: go.mod
cache-dependency-path: go.sum
- run: go build -ldflags '-X main.version=${{ github.ref_name }}'
- uses: int128/go-release-action@2979cc5b15ceb7ae458e95b0a9467afc7ae25259 # v2.0.0
with:
binary: kubelogin
publish:
if: github.ref_type == 'tag'
needs:
- build
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: rajatjindal/krew-release-bot@3d9faef30a82761d610544f62afddca00993eef9 # v0.0.47

View File

@@ -20,23 +20,24 @@ on:
jobs:
system-test:
# https://help.github.com/en/actions/automating-your-workflow-with-github-actions/software-installed-on-github-hosted-runners#ubuntu-1804-lts
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- uses: actions/setup-go@v2
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-go@3041bf56c941b39c61721a86cd11f3bb1338122a # v5.2.0
with:
go-version: 1.16
id: go
- uses: actions/checkout@v2
- uses: actions/cache@v2
with:
path: ~/go/pkg/mod
key: go-${{ hashFiles('**/go.sum') }}
restore-keys: |
go-
go-version-file: go.mod
cache-dependency-path: go.sum
- run: sudo apt-get update
# Install certutil.
# https://packages.ubuntu.com/xenial/libnss3-tools
- run: sudo apt update
- run: sudo apt install -y libnss3-tools
- run: mkdir -p ~/.pki/nssdb
# Install keyring related packages.
# https://github.com/zalando/go-keyring/issues/45
- run: sudo apt-get install --no-install-recommends -y libnss3-tools dbus-x11 gnome-keyring
- run: echo '127.0.0.1 dex-server' | sudo tee -a /etc/hosts
- run: make -C system_test -j3
- run: make -C system_test logs
if: always()

2
.gitignore vendored
View File

@@ -1,5 +1,7 @@
/.idea
/tools/bin
/acceptance_test/output/
/coverage.out

View File

@@ -60,3 +60,9 @@ spec:
matchLabels:
os: windows
arch: amd64
- bin: kubelogin.exe
{{ addURIAndSha "https://github.com/int128/kubelogin/releases/download/{{ .TagName }}/kubelogin_windows_arm64.zip" .TagName }}
selector:
matchLabels:
os: windows
arch: arm64

11
.mockery.yaml Normal file
View File

@@ -0,0 +1,11 @@
outpkg: "{{.PackageName}}_mock"
dir: "mocks/{{.PackagePath}}_mock"
packages:
github.com/int128/kubelogin:
config:
all: true
recursive: true
io:
interfaces:
Closer:

View File

@@ -1,13 +1,20 @@
FROM golang:1.16 as builder
FROM --platform=$BUILDPLATFORM golang:1.23 AS builder
WORKDIR /builder
COPY go.* .
# Copy the Go Modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
RUN go mod download
COPY Makefile .
# Copy the go source
COPY main.go .
COPY pkg pkg
RUN make
FROM gcr.io/distroless/base-debian10
ARG TARGETOS
ARG TARGETARCH
RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} go build
FROM gcr.io/distroless/base-debian12
COPY --from=builder /builder/kubelogin /
ENTRYPOINT ["/kubelogin"]

View File

@@ -1,49 +1,22 @@
PRODUCT := kubelogin
TARGET_ARCHIVE := $(PRODUCT)_$(GOOS)_$(GOARCH).zip
TARGET_DIGEST := $(PRODUCT)_$(GOOS)_$(GOARCH).zip.sha256
.PHONY: all
all:
ifeq ($(GOOS), windows)
TARGET := $(PRODUCT).exe
else
TARGET := $(PRODUCT)
endif
.PHONY: test
test:
go test -v -race ./pkg/...
# determine the version from ref
ifeq ($(GITHUB_REF), refs/heads/master)
VERSION := latest
else
VERSION ?= $(notdir $(GITHUB_REF))
endif
.PHONY: integration-test
integration-test:
go test -v -race ./integration_test/...
LDFLAGS := -X main.version=$(VERSION)
.PHONY: generate
generate:
$(MAKE) -C tools
./tools/bin/wire ./pkg/di
rm -fr mocks/
./tools/bin/mockery
all: $(TARGET)
$(TARGET):
go build -o $@ -ldflags "$(LDFLAGS)"
.PHONY: dist
dist: $(TARGET_ARCHIVE) $(TARGET_DIGEST)
$(TARGET_ARCHIVE): $(TARGET)
ifeq ($(GOOS), windows)
powershell Compress-Archive -Path $(TARGET),LICENSE,README.md -DestinationPath $@
else
zip $@ $(TARGET) LICENSE README.md
endif
$(TARGET_DIGEST): $(TARGET_ARCHIVE)
ifeq ($(GOOS), darwin)
shasum -a 256 -b $(TARGET_ARCHIVE) > $@
else
sha256sum -b $(TARGET_ARCHIVE) > $@
endif
.PHONY: dist-release
dist-release: dist
gh release upload $(VERSION) $(TARGET_ARCHIVE) $(TARGET_DIGEST) --clobber
.PHONY: clean
clean:
-rm $(TARGET)
-rm -r dist/output/
-rm coverage.out gotest.log
.PHONY: lint
lint:
$(MAKE) -C tools
./tools/bin/golangci-lint run

123
README.md
View File

@@ -13,7 +13,6 @@ Take a look at the diagram:
![Diagram of the credential plugin](docs/credential-plugin-diagram.svg)
## Getting Started
### Setup
@@ -31,26 +30,28 @@ kubectl krew install oidc-login
choco install kubelogin
```
If you install via GitHub releases, save the binary as the name `kubectl-oidc_login` on your path.
When you invoke `kubectl oidc-login`, kubectl finds it by the [naming convention of kubectl plugins](https://kubernetes.io/docs/tasks/extend-kubectl/kubectl-plugins/).
The other install methods do this for you.
You need to set up the OIDC provider, cluster role binding, Kubernetes API server and kubeconfig.
The kubeconfig looks like:
Your kubeconfig looks like this:
```yaml
users:
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- --oidc-issuer-url=ISSUER_URL
- --oidc-client-id=YOUR_CLIENT_ID
- --oidc-client-secret=YOUR_CLIENT_SECRET
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: kubectl
args:
- oidc-login
- get-token
- --oidc-issuer-url=ISSUER_URL
- --oidc-client-id=YOUR_CLIENT_ID
```
See [setup guide](docs/setup.md) for more.
See the [setup guide](docs/setup.md) for more.
### Run
@@ -63,33 +64,46 @@ kubectl get pods
Kubectl executes kubelogin before calling the Kubernetes APIs.
Kubelogin automatically opens the browser, and you can log in to the provider.
<img src="docs/keycloak-login.png" alt="keycloak-login" width="455" height="329">
After the authentication, kubelogin returns the credentials to kubectl.
Kubectl then calls the Kubernetes APIs with the credentials.
After authentication, kubelogin returns the credentials to kubectl and kubectl then calls the Kubernetes APIs with these credentials.
```
```console
% kubectl get pods
Open http://localhost:8000 for authentication
NAME READY STATUS RESTARTS AGE
echoserver-86c78fdccd-nzmd5 1/1 Running 0 26d
```
Kubelogin writes the ID token and refresh token to the token cache file.
Kubelogin stores the ID token and refresh token to the cache.
If the ID token is valid, it just returns it.
If the ID token has expired, it will refresh the token using the refresh token.
If the refresh token has expired, it will perform re-authentication.
If the cached ID token is valid, kubelogin just returns it.
If the cached ID token has expired, kubelogin will refresh the token using the refresh token.
If the refresh token has expired, kubelogin will perform re-authentication (you will have to login via browser again).
## Troubleshooting
### Token cache
### Troubleshoot
If the OS keyring is available, kubelogin stores the token cache to the OS keyring.
Otherwise, kubelogin stores the token cache to the file system.
See the [token cache](docs/usage.md#token-cache) for details.
You can log out by removing the token cache directory (default `~/.kube/cache/oidc-login`).
Kubelogin will ask you to login via browser again if the token cache file does not exist i.e., it starts with a clean slate
You can dump claims of an ID token by `setup` command.
You can log out by deleting the token cache.
```console
% kubectl oidc-login setup --oidc-issuer-url https://accounts.google.com --oidc-client-id REDACTED --oidc-client-secret REDACTED
% kubectl oidc-login clean
Deleted the token cache at /home/user/.kube/cache/oidc-login
Deleted the token cache in the keyring
```
Kubelogin will ask you to log in via the browser again.
If the browser has a cookie for the provider, you need to log out from the provider or clear the cookie.
### ID token claims
You can run `setup` command to dump the claims of an ID token from the provider.
```console
% kubectl oidc-login setup --oidc-issuer-url=ISSUER_URL --oidc-client-id=REDACTED
...
You got a token with the following claims:
@@ -101,55 +115,32 @@ You got a token with the following claims:
}
```
You can increase the log level by `-v1` option.
You can set `-v1` option to increase the log level.
```yaml
users:
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: kubectl
args:
- oidc-login
- get-token
- -v1
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: kubectl
args:
- oidc-login
- get-token
- -v1
```
You can verify kubelogin works with your provider using [acceptance test](acceptance_test).
You can run the [acceptance test](acceptance_test) to verify if kubelogin works with your provider.
## Docs
- [Setup guide](docs/setup.md)
- [Usage and options](docs/usage.md)
- [Standalone mode](docs/standalone-mode.md) (deprecated)
## Related works
### Kubernetes Dashboard
You can access the Kubernetes Dashboard using kubelogin and [kauthproxy](https://github.com/int128/kauthproxy).
- [Standalone mode](docs/standalone-mode.md)
- [System test](system_test)
- [Acceptance_test for identity providers](acceptance_test)
## Contributions
This is an open source software licensed under Apache License 2.0.
Feel free to open issues and pull requests for improving code and documents.
Your pull request will be merged into master with squash.
### Development
Go 1.16+ is required.
```sh
make
./kubelogin
```
See also:
- [system test](system_test)
- [acceptance_test](acceptance_test)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 KiB

View File

@@ -10,9 +10,16 @@ Let's see the following steps:
1. Set up the kubeconfig
1. Verify cluster access
## 1. Set up the OIDC provider
Kubelogin supports the following authentication flows:
- Authorization code flow
- Device authorization grant
- Resource owner password credentials grant
See the [usage](usage.md) for the details.
### Google Identity Platform
You can log in with a Google account.
@@ -24,11 +31,10 @@ Open [Google APIs Console](https://console.developers.google.com/apis/credential
Check the client ID and secret.
Replace the following variables in the later sections.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://accounts.google.com`
`YOUR_CLIENT_ID` | `xxx.apps.googleusercontent.com`
`YOUR_CLIENT_SECRET` | random string
| Variable | Value |
| ---------------- | -------------------------------- |
| `ISSUER_URL` | `https://accounts.google.com` |
| `YOUR_CLIENT_ID` | `xxx.apps.googleusercontent.com` |
### Keycloak
@@ -39,8 +45,8 @@ Open Keycloak and create an OIDC client as follows:
- Client ID: `YOUR_CLIENT_ID`
- Valid Redirect URLs:
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- Issuer URL: `https://keycloak.example.com/auth/realms/YOUR_REALM`
You can associate client roles by adding the following mapper:
@@ -56,11 +62,10 @@ For example, if you have `admin` role of the client, you will get a JWT with the
Replace the following variables in the later sections.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://keycloak.example.com/auth/realms/YOUR_REALM`
`YOUR_CLIENT_ID` | `YOUR_CLIENT_ID`
`YOUR_CLIENT_SECRET` | random string
| Variable | Value |
| ---------------- | ----------------------------------------------------- |
| `ISSUER_URL` | `https://keycloak.example.com/auth/realms/YOUR_REALM` |
| `YOUR_CLIENT_ID` | `YOUR_CLIENT_ID` |
### Dex with GitHub
@@ -77,29 +82,29 @@ Deploy [Dex](https://github.com/dexidp/dex) with the following config:
```yaml
issuer: https://dex.example.com
connectors:
- type: github
id: github
name: GitHub
config:
clientID: YOUR_GITHUB_CLIENT_ID
clientSecret: YOUR_GITHUB_CLIENT_SECRET
redirectURI: https://dex.example.com/callback
- type: github
id: github
name: GitHub
config:
clientID: YOUR_GITHUB_CLIENT_ID
clientSecret: YOUR_GITHUB_CLIENT_SECRET
redirectURI: https://dex.example.com/callback
staticClients:
- id: YOUR_CLIENT_ID
name: Kubernetes
redirectURIs:
- http://localhost:8000
- http://localhost:18000
secret: YOUR_DEX_CLIENT_SECRET
- id: YOUR_CLIENT_ID
name: Kubernetes
redirectURIs:
- http://localhost:8000
- http://localhost:18000
secret: YOUR_DEX_CLIENT_SECRET
```
Replace the following variables in the later sections.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://dex.example.com`
`YOUR_CLIENT_ID` | `YOUR_CLIENT_ID`
`YOUR_CLIENT_SECRET` | `YOUR_DEX_CLIENT_SECRET`
| Variable | Value |
| -------------------- | ------------------------- |
| `ISSUER_URL` | `https://dex.example.com` |
| `YOUR_CLIENT_ID` | `YOUR_CLIENT_ID` |
| `YOUR_CLIENT_SECRET` | `YOUR_DEX_CLIENT_SECRET` |
### Okta
@@ -112,17 +117,17 @@ Open your Okta organization and create an application with the following options
- Application type: Native
- Initiate login URI: `http://localhost:8000`
- Login redirect URIs:
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- Allowed grant types: Authorization Code
- Client authentication: Use PKCE (for public clients)
Replace the following variables in the later sections.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://YOUR_ORGANIZATION.okta.com`
`YOUR_CLIENT_ID` | random string
| Variable | Value |
| ---------------- | ------------------------------------ |
| `ISSUER_URL` | `https://YOUR_ORGANIZATION.okta.com` |
| `YOUR_CLIENT_ID` | random string |
You do not need to set `YOUR_CLIENT_SECRET`.
@@ -135,17 +140,17 @@ Login with an account that has permissions to create applications.
Create an OIDC application with the following configuration:
- Redirect URIs:
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- `http://localhost:8000`
- `http://localhost:18000` (used if the port 8000 is already in use)
- Grant type: Authorization Code
- PKCE Enforcement: Required
Leverage the following variables in the next steps.
Variable | Value
------------------------|------
`ISSUER_URL` | `https://auth.pingone.com/<PingOne Tenant Id>/as`
`YOUR_CLIENT_ID` | random string
| Variable | Value |
| ---------------- | ------------------------------------------------- |
| `ISSUER_URL` | `https://auth.pingone.com/<PingOne Tenant Id>/as` |
| `YOUR_CLIENT_ID` | random string |
`YOUR_CLIENT_SECRET` is not required for this configuration.
@@ -156,8 +161,7 @@ Run the following command:
```sh
kubectl oidc-login setup \
--oidc-issuer-url=ISSUER_URL \
--oidc-client-id=YOUR_CLIENT_ID \
--oidc-client-secret=YOUR_CLIENT_SECRET
--oidc-client-id=YOUR_CLIENT_ID
```
It launches the browser and navigates to `http://localhost:8000`.
@@ -170,7 +174,6 @@ See also the full options.
kubectl oidc-login setup --help
```
## 3. Bind a cluster role
Here bind `cluster-admin` role to you.
@@ -181,7 +184,6 @@ kubectl create clusterrolebinding oidc-cluster-admin --clusterrole=cluster-admin
As well as you can create a custom cluster role and bind it.
## 4. Set up the Kubernetes API server
Add the following flags to kube-apiserver:
@@ -193,41 +195,20 @@ Add the following flags to kube-apiserver:
See [Kubernetes Authenticating: OpenID Connect Tokens](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#openid-connect-tokens) for the all flags.
If you are using [kops](https://github.com/kubernetes/kops), run `kops edit cluster` and append the following settings:
```yaml
spec:
kubeAPIServer:
oidcIssuerURL: ISSUER_URL
oidcClientID: YOUR_CLIENT_ID
```
If you are using [kube-aws](https://github.com/kubernetes-incubator/kube-aws), append the following settings to the `cluster.yaml`:
```yaml
oidc:
enabled: true
issuerUrl: ISSUER_URL
clientId: YOUR_CLIENT_ID
```
## 5. Set up the kubeconfig
Add `oidc` user to the kubeconfig.
```sh
kubectl config set-credentials oidc \
--exec-api-version=client.authentication.k8s.io/v1beta1 \
--exec-api-version=client.authentication.k8s.io/v1 \
--exec-command=kubectl \
--exec-arg=oidc-login \
--exec-arg=get-token \
--exec-arg=--oidc-issuer-url=ISSUER_URL \
--exec-arg=--oidc-client-id=YOUR_CLIENT_ID \
--exec-arg=--oidc-client-secret=YOUR_CLIENT_SECRET
--exec-arg=--oidc-client-id=YOUR_CLIENT_ID
```
## 6. Verify cluster access
Make sure you can access the Kubernetes cluster.

View File

@@ -1,9 +1,11 @@
# Standalone mode
You can run kubelogin as a standalone command.
In this mode, you need to manually run the command before running kubectl.
Kubelogin supports the standalone mode as well.
It writes the token to the kubeconfig (typically `~/.kube/config`) after authentication.
Configure the kubeconfig like:
## Getting started
Configure your kubeconfig like:
```yaml
- name: keycloak
@@ -31,7 +33,7 @@ It automatically opens the browser and you can log in to the provider.
After authentication, kubelogin writes the ID token and refresh token to the kubeconfig.
```
```console
% kubelogin
Open http://localhost:8000 for authentication
You got a valid token until 2019-05-18 10:28:51 +0900 JST
@@ -40,7 +42,7 @@ Updated ~/.kubeconfig
Now you can access the cluster.
```
```console
% kubectl get pods
NAME READY STATUS RESTARTS AGE
echoserver-86c78fdccd-nzmd5 1/1 Running 0 26d
@@ -50,21 +52,21 @@ Your kubeconfig looks like:
```yaml
users:
- name: keycloak
user:
auth-provider:
config:
client-id: YOUR_CLIENT_ID
client-secret: YOUR_CLIENT_SECRET
idp-issuer-url: https://issuer.example.com
id-token: ey... # kubelogin will add or update the ID token here
refresh-token: ey... # kubelogin will add or update the refresh token here
name: oidc
- name: keycloak
user:
auth-provider:
config:
client-id: YOUR_CLIENT_ID
client-secret: YOUR_CLIENT_SECRET
idp-issuer-url: https://issuer.example.com
id-token: ey... # kubelogin will add or update the ID token here
refresh-token: ey... # kubelogin will add or update the refresh token here
name: oidc
```
If the ID token is valid, kubelogin does nothing.
```
```console
% kubelogin
You already have a valid token until 2019-05-18 10:28:51 +0900 JST
```
@@ -72,11 +74,8 @@ You already have a valid token until 2019-05-18 10:28:51 +0900 JST
If the ID token has expired, kubelogin will refresh the token using the refresh token in the kubeconfig.
If the refresh token has expired, kubelogin will proceed the authentication.
## Usage
### Kubeconfig
You can set path to the kubeconfig file by the option or the environment variable just like kubectl.
It defaults to `~/.kube/config`.
@@ -93,37 +92,15 @@ If you set multiple files, kubelogin will find the file which has the current au
Kubelogin supports the following keys of `auth-provider` in a kubeconfig.
See [kubectl authentication](https://kubernetes.io/docs/reference/access-authn-authz/authentication/#using-kubectl) for more.
Key | Direction | Value
----|-----------|------
`idp-issuer-url` | Read (Mandatory) | Issuer URL of the provider.
`client-id` | Read (Mandatory) | Client ID of the provider.
`client-secret` | Read (Mandatory) | Client Secret of the provider.
`idp-certificate-authority` | Read | CA certificate path of the provider.
`idp-certificate-authority-data` | Read | Base64 encoded CA certificate of the provider.
`extra-scopes` | Read | Scopes to request to the provider (comma separated).
`id-token` | Write | ID token got from the provider.
`refresh-token` | Write | Refresh token got from the provider.
| Key | Direction | Value |
| -------------------------------- | ---------------- | ---------------------------------------------------- |
| `idp-issuer-url` | Read (Mandatory) | Issuer URL of the provider. |
| `client-id` | Read (Mandatory) | Client ID of the provider. |
| `client-secret` | Read (Mandatory) | Client Secret of the provider. |
| `idp-certificate-authority` | Read | CA certificate path of the provider. |
| `idp-certificate-authority-data` | Read | Base64 encoded CA certificate of the provider. |
| `extra-scopes` | Read | Scopes to request to the provider (comma separated). |
| `id-token` | Write | ID token got from the provider. |
| `refresh-token` | Write | Refresh token got from the provider. |
### Extra scopes
You can set the extra scopes to request to the provider by `extra-scopes` in the kubeconfig.
```sh
kubectl config set-credentials keycloak --auth-provider-arg extra-scopes=email
```
Currently kubectl does not accept multiple scopes, so you need to edit the kubeconfig as like:
```sh
kubectl config set-credentials keycloak --auth-provider-arg extra-scopes=SCOPES
sed -i '' -e s/SCOPES/email,profile/ $KUBECONFIG
```
### CA Certificates
You can use your self-signed certificates for the provider.
```sh
kubectl config set-credentials keycloak \
--auth-provider-arg idp-certificate-authority=$HOME/.kube/keycloak-ca.pem
```
See also [usage.md](usage.md).

View File

@@ -11,20 +11,26 @@ Flags:
--oidc-client-id string Client ID of the provider (mandatory)
--oidc-client-secret string Client secret of the provider
--oidc-extra-scope strings Scopes to request to the provider
--token-cache-dir string Path to a directory for token cache (default "~/.kube/cache/oidc-login")
--oidc-use-access-token Instead of using the id_token, use the access_token to authenticate to Kubernetes
--force-refresh If set, refresh the ID token regardless of its expiration time
--token-cache-dir string Path to a directory of the token cache (default "~/.kube/cache/oidc-login")
--token-cache-storage string Storage for the token cache. One of (auto|keyring|disk) (default "auto")
--certificate-authority stringArray Path to a cert file for the certificate authority
--certificate-authority-data stringArray Base64 encoded cert for the certificate authority
--insecure-skip-tls-verify If set, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure
--insecure-skip-tls-verify [SECURITY RISK] If set, the server's certificate will not be checked for validity
--tls-renegotiation-once If set, allow a remote server to request renegotiation once per connection
--tls-renegotiation-freely If set, allow a remote server to repeatedly request renegotiation
--grant-type string Authorization grant type to use. One of (auto|authcode|authcode-keyboard|password) (default "auto")
--oidc-pkce-method string PKCE code challenge method. Automatically determined by default. One of (auto|no|S256) (default "auto")
--grant-type string Authorization grant type to use. One of (auto|authcode|authcode-keyboard|password|device-code) (default "auto")
--listen-address strings [authcode] Address to bind to the local server. If multiple addresses are set, it will try binding in order (default [127.0.0.1:8000,127.0.0.1:18000])
--skip-open-browser [authcode] Do not open the browser automatically
--browser-command string [authcode] Command to open the browser
--authentication-timeout-sec int [authcode] Timeout of authentication in seconds (default 180)
--local-server-cert string [authcode] Certificate path for the local server
--local-server-key string [authcode] Certificate key path for the local server
--open-url-after-authentication string [authcode] If set, open the URL in the browser after authentication
--oidc-redirect-url-hostname string [authcode] Hostname of the redirect URL (default "localhost")
--oidc-redirect-url-authcode-keyboard string [authcode-keyboard] Redirect URL (default "urn:ietf:wg:oauth:2.0:oob")
--oidc-auth-request-extra-params stringToString [authcode, authcode-keyboard] Extra query parameters to send with an authentication request (default [])
--username string [password] Username for resource owner password credentials grant
--password string [password] Password for resource owner password credentials grant
@@ -32,20 +38,37 @@ Flags:
Global Flags:
--add_dir_header If true, adds the file directory to the header of the log messages
--alsologtostderr log to standard error as well as files
--alsologtostderr log to standard error as well as files (no effect when -logtostderr=true)
--log_backtrace_at traceLocation when logging hits line file:N, emit a stack trace (default :0)
--log_dir string If non-empty, write log files in this directory
--log_file string If non-empty, use this log file
--log_file_max_size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--log_dir string If non-empty, write log files in this directory (no effect when -logtostderr=true)
--log_file string If non-empty, use this log file (no effect when -logtostderr=true)
--log_file_max_size uint Defines the maximum size a log file can grow to (no effect when -logtostderr=true). Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--logtostderr log to standard error instead of files (default true)
--one_output If true, only write logs to their native severity level (vs also writing to each lower severity level)
--one_output If true, only write logs to their native severity level (vs also writing to each lower severity level; no effect when -logtostderr=true)
--skip_headers If true, avoid header prefixes in the log messages
--skip_log_headers If true, avoid headers when opening log files
--stderrthreshold severity logs at or above this threshold go to stderr (default 2)
--skip_log_headers If true, avoid headers when opening log files (no effect when -logtostderr=true)
--stderrthreshold severity logs at or above this threshold go to stderr when writing to files and stderr (no effect when -logtostderr=true or -alsologtostderr=true) (default 2)
-v, --v Level number for the log level verbosity
--vmodule moduleSpec comma-separated list of pattern=N settings for file-filtered logging
```
Here is the sequence diagram of the credential plugin.
```mermaid
sequenceDiagram
actor User
User ->>+ kubectl: Run
kubectl ->>+ kubelogin: Run the plugin
kubelogin ->>+ Provider: Authentication request
Note over User, Provider: Browser interaction
Provider -->>- kubelogin: Authentication response
kubelogin ->>+ Provider: Token request
Provider -->>- kubelogin: Token response
kubelogin -->>- kubectl: Credential
kubectl ->>+ kube-apiserver: Request with the credential
kube-apiserver -->>- kubectl: Response
kubectl -->>- User: Response
```
## Options
@@ -56,7 +79,7 @@ This prevents a process from remaining forever.
You can change the timeout by the following flag:
```yaml
- --authentication-timeout-sec=60
- --authentication-timeout-sec=60
```
For now this timeout works only for the authorization code flow.
@@ -66,17 +89,31 @@ For now this timeout works only for the authorization code flow.
You can set the extra scopes to request to the provider by `--oidc-extra-scope`.
```yaml
- --oidc-extra-scope=email
- --oidc-extra-scope=profile
- --oidc-extra-scope=email
- --oidc-extra-scope=profile
```
### PKCE
Kubelogin automatically uses the PKCE if the provider supports it.
It determines the code challenge method by the `code_challenge_methods_supported` claim of the OpenID Connect Discovery document.
If your provider does not return a valid `code_challenge_methods_supported` claim,
you can enforce the code challenge method by `--oidc-pkce-method`.
```yaml
- --oidc-pkce-method=S256
```
For the most providers, you don't need to set this option explicitly.
### CA certificate
You can use your self-signed certificate for the provider.
```yaml
- --certificate-authority=/home/user/.kube/keycloak-ca.pem
- --certificate-authority-data=LS0t...
- --certificate-authority=/home/user/.kube/keycloak-ca.pem
- --certificate-authority-data=LS0t...
```
### HTTP proxy
@@ -84,6 +121,20 @@ You can use your self-signed certificate for the provider.
You can set the following environment variables if you are behind a proxy: `HTTP_PROXY`, `HTTPS_PROXY` and `NO_PROXY`.
See also [net/http#ProxyFromEnvironment](https://golang.org/pkg/net/http/#ProxyFromEnvironment).
### Token cache
Kubelogin stores the token cache to the OS keyring if available.
It depends on [zalando/go-keyring](https://github.com/zalando/go-keyring) for the keyring storage.
If you encounter a problem, try `--token-cache-storage` to set the storage.
```yaml
# Force to use the OS keyring
- --token-cache-storage=keyring
# Force to use the file system
- --token-cache-storage=disk
```
### Home directory expansion
If a value in the following options begins with a tilde character `~`, it is expanded to the home directory.
@@ -93,18 +144,18 @@ If a value in the following options begins with a tilde character `~`, it is exp
- `--local-server-key`
- `--token-cache-dir`
## Authentication flows
Kubelogin support the following flows:
- Authorization code flow
- Authorization code flow with a keyboard
- Resource owner password credentials grant flow
- [Authorization code flow](#authorization-code-flow)
- [Authorization code flow with a keyboard](#authorization-code-flow-with-a-keyboard)
- [Device authorization grant](#device-authorization-grant)
- [Resource owner password credentials grant](#resource-owner-password-credentials-grant)
### Authorization code flow
Kubelogin performs the authorization code flow by default.
Kubelogin performs the [authorization code flow](https://openid.net/specs/openid-connect-core-1_0.html#CodeFlowAuth) by default.
It starts the local server at port 8000 or 18000 by default.
You need to register the following redirect URIs to the provider:
@@ -115,50 +166,51 @@ You need to register the following redirect URIs to the provider:
You can change the listening address.
```yaml
- --listen-address=127.0.0.1:12345
- --listen-address=127.0.0.1:23456
- --listen-address=127.0.0.1:12345
- --listen-address=127.0.0.1:23456
```
You can specify a certificate for the local webserver if HTTPS is required by your identity provider.
```yaml
- --local-server-cert=localhost.crt
- --local-server-key=localhost.key
- --local-server-cert=localhost.crt
- --local-server-key=localhost.key
```
You can change the hostname of redirect URI from the default value `localhost`.
```yaml
- --oidc-redirect-url-hostname=127.0.0.1
- --oidc-redirect-url-hostname=127.0.0.1
```
You can add extra parameters to the authentication request.
```yaml
- --oidc-auth-request-extra-params=ttl=86400
- --oidc-auth-request-extra-params=ttl=86400
```
When authentication completed, kubelogin shows a message to close the browser.
You can change the URL to show after authentication.
```yaml
- --open-url-after-authentication=https://example.com/success.html
- --open-url-after-authentication=https://example.com/success.html
```
You can skip opening the browser if you encounter some environment problem.
If you encounter a problem with the browser, you can change the browser command or skip opening the browser.
```yaml
- --skip-open-browser
# Change the browser command
- --browser-command=google-chrome
# Do not open the browser
- --skip-open-browser
```
For Linux users, you change the default browser by `BROWSER` environment variable.
### Authorization code flow with a keyboard
If you cannot access the browser, instead use the authorization code flow with a keyboard.
```yaml
- --grant-type=authcode-keyboard
- --grant-type=authcode-keyboard
```
Kubelogin will show the URL and prompt.
@@ -170,33 +222,59 @@ Open https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&client_id=
Enter code: YOUR_CODE
```
Note that this flow uses the redirect URI `urn:ietf:wg:oauth:2.0:oob` and some OIDC providers do not support it.
The default of redirect URI is `urn:ietf:wg:oauth:2.0:oob`.
You can overwrite it.
```yaml
- oidc-redirect-url-authcode-keyboard=http://localhost
```
You can add extra parameters to the authentication request.
```yaml
- --oidc-auth-request-extra-params=ttl=86400
- --oidc-auth-request-extra-params=ttl=86400
```
### Resource owner password credentials grant flow
### Device authorization grant
Kubelogin performs the resource owner password credentials grant flow
Kubelogin performs the [device authorization grant](https://tools.ietf.org/html/rfc8628) when `--grant-type=device-code` is set.
```yaml
- --grant-type=device-code
```
It automatically opens the browser.
If the provider returns the `verification_uri_complete` parameter, you don't need to enter the code.
Otherwise, you need to enter the code shown.
If you encounter a problem with the browser, you can change the browser command or skip opening the browser.
```yaml
# Change the browser command
- --browser-command=google-chrome
# Do not open the browser
- --skip-open-browser
```
### Resource owner password credentials grant
Kubelogin performs the resource owner password credentials grant
when `--grant-type=password` or `--username` is set.
Note that most OIDC providers do not support this flow.
Keycloak supports this flow but you need to explicitly enable the "Direct Access Grants" feature in the client settings.
Note that most OIDC providers do not support this grant.
Keycloak supports this grant but you need to explicitly enable the "Direct Access Grants" feature in the client settings.
You can set the username and password.
```yaml
- --username=USERNAME
- --password=PASSWORD
- --username=USERNAME
- --password=PASSWORD
```
If the password is not set, kubelogin will show the prompt for the password.
```yaml
- --username=USERNAME
- --username=USERNAME
```
```
@@ -207,7 +285,7 @@ Password:
If the username is not set, kubelogin will show the prompt for the username and password.
```yaml
- --grant-type=password
- --grant-type=password
```
```
@@ -223,25 +301,25 @@ The kubeconfig looks like:
```yaml
users:
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1beta1
command: docker
args:
- run
- --rm
- -v
- /tmp/.token-cache:/.token-cache
- -p
- 8000:8000
- ghcr.io/int128/kubelogin
- get-token
- --token-cache-dir=/.token-cache
- --listen-address=0.0.0.0:8000
- --oidc-issuer-url=ISSUER_URL
- --oidc-client-id=YOUR_CLIENT_ID
- --oidc-client-secret=YOUR_CLIENT_SECRET
- name: oidc
user:
exec:
apiVersion: client.authentication.k8s.io/v1
command: docker
args:
- run
- --rm
- -v
- /tmp/.token-cache:/.token-cache
- -p
- 8000:8000
- ghcr.io/int128/kubelogin
- get-token
- --token-cache-dir=/.token-cache
- --listen-address=0.0.0.0:8000
- --oidc-issuer-url=ISSUER_URL
- --oidc-client-id=YOUR_CLIENT_ID
- --oidc-client-secret=YOUR_CLIENT_SECRET
```
Known limitations:

79
go.mod
View File

@@ -1,25 +1,66 @@
module github.com/int128/kubelogin
go 1.16
go 1.23.5
require (
github.com/alexflint/go-filemutex v1.1.0
github.com/chromedp/chromedp v0.7.3
github.com/coreos/go-oidc/v3 v3.0.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/golang/mock v1.5.0
github.com/google/go-cmp v0.5.6
github.com/google/wire v0.5.0
github.com/int128/oauth2cli v1.13.0
github.com/pkg/browser v0.0.0-20210606212950-a7b7a6107d32
github.com/spf13/cobra v1.1.3
github.com/chromedp/chromedp v0.11.2
github.com/coreos/go-oidc/v3 v3.12.0
github.com/gofrs/flock v0.12.1
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/google/go-cmp v0.6.0
github.com/google/wire v0.6.0
github.com/int128/oauth2cli v1.14.1
github.com/int128/oauth2dev v1.0.1
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
golang.org/x/net v0.0.0-20210525063256-abc453219eb5
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/term v0.0.0-20210503060354-a79de5458b56
gopkg.in/yaml.v2 v2.4.0
k8s.io/apimachinery v0.21.1
k8s.io/client-go v0.21.1
k8s.io/klog/v2 v2.9.0
github.com/stretchr/testify v1.10.0
github.com/zalando/go-keyring v0.2.6
golang.org/x/oauth2 v0.25.0
golang.org/x/sync v0.10.0
golang.org/x/term v0.28.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/apimachinery v0.32.1
k8s.io/client-go v0.32.1
k8s.io/klog/v2 v2.130.1
)
require (
al.essio.dev/pkg/shellescape v1.5.1 // indirect
github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb // indirect
github.com/chromedp/sysutil v1.1.0 // indirect
github.com/danieljoos/wincred v1.2.2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.4.0 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/int128/listener v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/rogpeppe/go-internal v1.13.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/crypto v0.28.0 // indirect
golang.org/x/net v0.30.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/text v0.19.0 // indirect
golang.org/x/time v0.7.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

799
go.sum
View File

@@ -1,686 +1,237 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alexflint/go-filemutex v1.1.0 h1:IAWuUuRYL2hETx5b8vCgwnD+xSdlsTQY6s2JjBsqLdg=
github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/chromedp/cdproto v0.0.0-20210526005521-9e51b9051fd0 h1:aIcgRshD5I1MfJfB92KBDKpaXrYqj3fkqI8bHdtP3zA=
github.com/chromedp/cdproto v0.0.0-20210526005521-9e51b9051fd0/go.mod h1:At5TxYYdxkbQL0TSefRjhLE3Q0lgvqKKMSFUglJ7i1U=
github.com/chromedp/chromedp v0.7.3 h1:FvgJICfjvXtDX+miuMUY0NHuY8zQvjS/TcEQEG6Ldzs=
github.com/chromedp/chromedp v0.7.3/go.mod h1:9gC521Yzgrk078Ulv6KIgG7hJ2x9aWrxMBBobTFk30A=
github.com/chromedp/sysutil v1.0.0 h1:+ZxhTpfpZlmchB58ih/LBHX52ky7w2VhQVKQMucy3Ic=
github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moAV0xufSww=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-oidc/v3 v3.0.0 h1:/mAA0XMgYJw2Uqm7WKGCsKnjitE/+A0FFbOmiRJm7LQ=
github.com/coreos/go-oidc/v3 v3.0.0/go.mod h1:rEJ/idjfUyfkBit1eI1fvyr+64/g9dcKpAm8MJMesvo=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
al.essio.dev/pkg/shellescape v1.5.1 h1:86HrALUujYS/h+GtqoB26SBEdkWfmMI6FubjXlsXyho=
al.essio.dev/pkg/shellescape v1.5.1/go.mod h1:6sIqp7X2P6mThCQ7twERpZTuigpr6KbZWtls1U8I890=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb h1:noKVm2SsG4v0Yd0lHNtFYc9EUxIVvrr4kJ6hM8wvIYU=
github.com/chromedp/cdproto v0.0.0-20241022234722-4d5d5faf59fb/go.mod h1:4XqMl3iIW08jtieURWL6Tt5924w21pxirC6th662XUM=
github.com/chromedp/chromedp v0.11.2 h1:ZRHTh7DjbNTlfIv3NFTbB7eVeu5XCNkgrpcGSpn2oX0=
github.com/chromedp/chromedp v0.11.2/go.mod h1:lr8dFRLKsdTTWb75C/Ttol2vnBKOSnt0BW8R9Xaupi8=
github.com/chromedp/sysutil v1.1.0 h1:PUFNv5EcprjqXZD9nJb9b/c9ibAbxiYo4exNWZyipwM=
github.com/chromedp/sysutil v1.1.0/go.mod h1:WiThHUdltqCNKGc4gaU50XgYjwjYIhKWoHGPTUfWTJ8=
github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=
github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0=
github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
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-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g=
github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
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-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE=
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1 h1:xfeeEhW7pwmX8nuLVlqbzVc7udMDrwetjEv+TZIz1og=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.1.0-rc.5 h1:QOAag7FoBaBYYHRqzqkhhd8fq5RTubvI4v3Ft/gDVVQ=
github.com/gobwas/ws v1.1.0-rc.5/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gobwas/ws v1.4.0 h1:CTaoG1tojrh4ucGPcoJFiAQUAsEWekEWvLy7GsVNqGs=
github.com/gobwas/ws v1.4.0/go.mod h1:G3gNqMNtPppf5XUz7O4shetPpcZ1VJ7zt18dlUeakrc=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E=
github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0 h1:jlYHihg//f7RRwuPfptm04yp4s7O6Kw8EZiVYIGcH0g=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
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=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8=
github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
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/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI=
github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/int128/listener v1.1.0 h1:2Jb41DWLpkQ3I9bIdBzO8H/tNwMvyl/OBZWtCV5Pjuw=
github.com/int128/listener v1.1.0/go.mod h1:68WkmTN8PQtLzc9DucIaagAKeGVyMnyyKIkW4Xn47UA=
github.com/int128/oauth2cli v1.13.0 h1:3wR48gSHdOPFgHmtnXzs4wEFA6p24prPqLXu6QUOujw=
github.com/int128/oauth2cli v1.13.0/go.mod h1:EUpEzcUumoVjLPHD7y2KGxwfXYqxDVqwDfqQ+u7qAwM=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/int128/oauth2cli v1.14.1 h1:MxkiSSMT1RcsVKxyzaJYGgmMXvGWPXTMduhG4a1OqTs=
github.com/int128/oauth2cli v1.14.1/go.mod h1:ha/eC3cUAixVzJ0V+voMRNQejLWGvk49AWDWN4Gawsk=
github.com/int128/oauth2dev v1.0.1 h1:TWokv4obxKuRZXvcXFMOYcaAcdZ/rcZYcbjkJNu+6Ek=
github.com/int128/oauth2dev v1.0.1/go.mod h1:caoxoXz7nlt2nc7/o3GKgGCyuruOAmsViPSRmrUmV9o=
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.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
github.com/pkg/browser v0.0.0-20210606212950-a7b7a6107d32 h1:K3WnH8Ka32vWygzmjKEhz1zAVqckNoWDqX3azMxuiSA=
github.com/pkg/browser v0.0.0-20210606212950-a7b7a6107d32/go.mod h1:yvwcBfzEX4m+eTgxPBbNYytaWFv4PSQzBaeYjxp8Iik=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
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/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhAVbbWWBzr41ElhJx5tXPWkIHA2HWPRuw=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
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/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
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.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
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/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
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.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zalando/go-keyring v0.2.6 h1:r7Yc3+H+Ux0+M72zacZoItR3UDxeWfKTcabvkI8ua9s=
github.com/zalando/go-keyring v0.2.6/go.mod h1:2TCrxYrbUNYfNS/Kgy/LSrkSQzZ5UPVH85RwfczwvcI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
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.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw=
golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
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.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/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-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200505041828-1ed23360d12c/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
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.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
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.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
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.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/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201207223542-d4d67f95c62d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea h1:+WiDlPBBaO+h9vPNZi8uJ3k4BkKQB7Iow3aqwHVA5hI=
golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/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.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.8.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.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56 h1:b8jxX3zqjpqb2LklXPzKSGJhzyxCOZSz8ncv8Nv+y7w=
golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
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.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
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.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
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.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM=
golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
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.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA=
google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
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/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
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.4/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 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c=
k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s=
k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs=
k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4=
k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM=
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 h1:CbnUZsM497iRC5QMVkHwyl8s2tB3g7yaSHkYPkpgelw=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8=
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc=
k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k=
k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs=
k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU=
k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg=
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y=
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro=
k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8=
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA=
sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=

View File

@@ -0,0 +1,28 @@
package integration_test
import (
"context"
"os"
"testing"
"time"
"github.com/int128/kubelogin/integration_test/httpdriver"
"github.com/int128/kubelogin/pkg/di"
"github.com/int128/kubelogin/pkg/testing/clock"
"github.com/int128/kubelogin/pkg/testing/logger"
)
func TestClean(t *testing.T) {
tokenCacheDir := t.TempDir()
cmd := di.NewCmdForHeadless(clock.Fake(time.Now()), os.Stdin, os.Stdout, logger.New(t), httpdriver.Zero(t))
exitCode := cmd.Run(context.TODO(), []string{
"kubelogin",
"clean",
"--token-cache-dir", tokenCacheDir,
"--token-cache-storage", "disk",
}, "HEAD")
if exitCode != 0 {
t.Errorf("exit status wants 0 but %d", exitCode)
}
}

View File

@@ -13,6 +13,7 @@ import (
"github.com/int128/kubelogin/integration_test/httpdriver"
"github.com/int128/kubelogin/integration_test/keypair"
"github.com/int128/kubelogin/integration_test/oidcserver"
"github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
"github.com/int128/kubelogin/pkg/di"
"github.com/int128/kubelogin/pkg/infrastructure/browser"
"github.com/int128/kubelogin/pkg/testing/clock"
@@ -27,7 +28,6 @@ import (
// 2. Run the Cmd.
// 3. Open a request for the local server.
// 4. Verify the output.
//
func TestCredentialPlugin(t *testing.T) {
timeout := 10 * time.Second
now := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
@@ -43,7 +43,7 @@ func TestCredentialPlugin(t *testing.T) {
args: []string{"--certificate-authority", keypair.Server.CACertPath},
},
} {
httpDriverOption := httpdriver.Option{
httpDriverConfig := httpdriver.Config{
TLSConfig: tc.keyPair.TLSConfig,
BodyContains: "Authenticated",
}
@@ -53,48 +53,49 @@ func TestCredentialPlugin(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, oidcserver.Config{
Want: oidcserver.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
svc := oidcserver.New(t, tc.keyPair, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverOption),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverConfig),
now: now,
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("ROPC", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, oidcserver.Config{
Want: oidcserver.Want{
svc := oidcserver.New(t, tc.keyPair, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
Username: "USER1",
Password: "PASS1",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.Zero(t),
now: now,
stdout: &stdout,
@@ -103,172 +104,205 @@ func TestCredentialPlugin(t *testing.T) {
"--password", "PASS1",
}, tc.args...),
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("TokenCacheLifecycle", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, oidcserver.Config{})
defer sv.Shutdown(t, ctx)
svc := oidcserver.New(t, tc.keyPair, testconfig.Config{})
t.Run("NoCache", func(t *testing.T) {
sv.SetConfig(oidcserver.Config{
Want: oidcserver.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
svc.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
RefreshToken: "REFRESH_TOKEN_1",
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
RefreshToken: "REFRESH_TOKEN_1",
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverOption),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverConfig),
now: now,
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("Valid", func(t *testing.T) {
sv.SetConfig(oidcserver.Config{})
svc.SetConfig(testconfig.Config{})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.Zero(t),
now: now,
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("Refresh", func(t *testing.T) {
sv.SetConfig(oidcserver.Config{
Want: oidcserver.Want{
svc.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
RefreshToken: "REFRESH_TOKEN_1",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(3 * time.Hour),
RefreshToken: "REFRESH_TOKEN_2",
Response: testconfig.Response{
IDTokenExpiry: now.Add(3 * time.Hour),
RefreshToken: "REFRESH_TOKEN_2",
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverOption),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverConfig),
now: now.Add(2 * time.Hour),
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(3*time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(3*time.Hour))
})
t.Run("RefreshAgain", func(t *testing.T) {
sv.SetConfig(oidcserver.Config{
Want: oidcserver.Want{
svc.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
RefreshToken: "REFRESH_TOKEN_2",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(5 * time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(5 * time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverOption),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpDriverConfig),
now: now.Add(4 * time.Hour),
stdout: &stdout,
args: tc.args,
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(5*time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(5*time.Hour))
})
})
})
}
t.Run("PKCE", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, oidcserver.Config{
Want: oidcserver.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
t.Run("Not supported by provider", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: nil,
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
})
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
t.Run("Enforce", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: nil,
},
})
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{"--oidc-use-pkce"},
})
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("TLSData", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.Server, oidcserver.Config{
Want: oidcserver.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
svc := oidcserver.New(t, keypair.Server, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{TLSConfig: keypair.Server.TLSConfig, BodyContains: "Authenticated"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{TLSConfig: keypair.Server.TLSConfig, BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{"--certificate-authority-data", keypair.Server.CACertBase64},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("ExtraScopes", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, oidcserver.Config{
Want: oidcserver.Want{
Scope: "email profile openid",
RedirectURIPrefix: "http://localhost:",
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "email profile openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "Authenticated"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{
@@ -276,80 +310,83 @@ func TestCredentialPlugin(t *testing.T) {
"--oidc-extra-scope", "profile",
},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("OpenURLAfterAuthentication", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, oidcserver.Config{
Want: oidcserver.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "URL=https://example.com/success"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "URL=https://example.com/success"}),
now: now,
stdout: &stdout,
args: []string{"--open-url-after-authentication", "https://example.com/success"},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("RedirectURLHostname", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, oidcserver.Config{
Want: oidcserver.Want{
Scope: "openid",
RedirectURIPrefix: "http://127.0.0.1:",
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://127.0.0.1:",
CodeChallengeMethod: "S256",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "Authenticated"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{"--oidc-redirect-url-hostname", "127.0.0.1"},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("RedirectURLHTTPS", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, oidcserver.Config{
Want: oidcserver.Want{
Scope: "openid",
RedirectURIPrefix: "https://localhost:",
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "https://localhost:",
CodeChallengeMethod: "S256",
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{
TLSConfig: keypair.Server.TLSConfig,
BodyContains: "Authenticated",
}),
@@ -360,32 +397,33 @@ func TestCredentialPlugin(t *testing.T) {
"--local-server-key", keypair.Server.KeyPath,
},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
t.Run("ExtraParams", func(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, oidcserver.Config{
Want: oidcserver.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
svc := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
CodeChallengeMethod: "S256",
ExtraParams: map[string]string{
"ttl": "86400",
"reauth": "false",
},
},
Response: oidcserver.Response{
IDTokenExpiry: now.Add(time.Hour),
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
CodeChallengeMethodsSupported: []string{"plain", "S256"},
},
})
defer sv.Shutdown(t, ctx)
var stdout bytes.Buffer
runGetToken(t, ctx, getTokenConfig{
tokenCacheDir: tokenCacheDir,
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{BodyContains: "Authenticated"}),
issuerURL: svc.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{BodyContains: "Authenticated"}),
now: now,
stdout: &stdout,
args: []string{
@@ -393,7 +431,7 @@ func TestCredentialPlugin(t *testing.T) {
"--oidc-auth-request-extra-params", "reauth=false",
},
})
assertCredentialPluginStdout(t, &stdout, sv.LastTokenResponse().IDToken, now.Add(time.Hour))
assertCredentialPluginStdout(t, &stdout, svc.LastTokenResponse().IDToken, now.Add(time.Hour))
})
}
@@ -412,6 +450,7 @@ func runGetToken(t *testing.T, ctx context.Context, cfg getTokenConfig) {
"kubelogin",
"get-token",
"--token-cache-dir", cfg.tokenCacheDir,
"--token-cache-storage", "disk",
"--oidc-issuer-url", cfg.issuerURL,
"--oidc-client-id", "kubernetes",
"--listen-address", "127.0.0.1:0",

View File

@@ -4,20 +4,20 @@ package httpdriver
import (
"context"
"crypto/tls"
"io/ioutil"
"io"
"net/http"
"strings"
"testing"
)
type Option struct {
type Config struct {
TLSConfig *tls.Config
BodyContains string
}
// New returns a client to simulate browser access.
func New(ctx context.Context, t *testing.T, o Option) *client {
return &client{ctx, t, o}
func New(ctx context.Context, t *testing.T, config Config) *client {
return &client{ctx, t, config}
}
// Zero returns a client which call is not expected.
@@ -26,13 +26,13 @@ func Zero(t *testing.T) *zeroClient {
}
type client struct {
ctx context.Context
t *testing.T
o Option
ctx context.Context
t *testing.T
config Config
}
func (c *client) Open(url string) error {
client := http.Client{Transport: &http.Transport{TLSClientConfig: c.o.TLSConfig}}
client := http.Client{Transport: &http.Transport{TLSClientConfig: c.config.TLSConfig}}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
c.t.Errorf("could not create a request: %s", err)
@@ -48,18 +48,22 @@ func (c *client) Open(url string) error {
if resp.StatusCode != 200 {
c.t.Errorf("StatusCode wants 200 but %d", resp.StatusCode)
}
b, err := ioutil.ReadAll(resp.Body)
b, err := io.ReadAll(resp.Body)
if err != nil {
c.t.Errorf("could not read body: %s", err)
return nil
}
body := string(b)
if !strings.Contains(body, c.o.BodyContains) {
c.t.Errorf("body should contain %s but was %s", c.o.BodyContains, body)
if !strings.Contains(body, c.config.BodyContains) {
c.t.Errorf("body should contain %s but was %s", c.config.BodyContains, body)
}
return nil
}
func (c *client) OpenCommand(_ context.Context, url, _ string) error {
return c.Open(url)
}
type zeroClient struct {
t *testing.T
}
@@ -68,3 +72,7 @@ func (c *zeroClient) Open(url string) error {
c.t.Errorf("unexpected function call Open(%s)", url)
return nil
}
func (c *zeroClient) OpenCommand(_ context.Context, url, _ string) error {
return c.Open(url)
}

View File

@@ -5,7 +5,6 @@ import (
"crypto/x509"
"encoding/base64"
"io"
"io/ioutil"
"os"
"strings"
)
@@ -50,7 +49,7 @@ func readAsBase64(name string) string {
}
func newTLSConfig(name string) *tls.Config {
b, err := ioutil.ReadFile(name)
b, err := os.ReadFile(name)
if err != nil {
panic(err)
}

View File

@@ -6,7 +6,7 @@ import (
"path/filepath"
"testing"
"gopkg.in/yaml.v2"
"gopkg.in/yaml.v3"
)
// Values represents values in .kubeconfig template.
@@ -22,7 +22,8 @@ type Values struct {
// Create creates a kubeconfig file and returns path to it.
func Create(t *testing.T, v *Values) string {
t.Helper()
f, err := os.Create(filepath.Join(t.TempDir(), "kubeconfig"))
name := filepath.Join(t.TempDir(), "kubeconfig")
f, err := os.Create(name)
if err != nil {
t.Fatal(err)
}
@@ -34,7 +35,7 @@ func Create(t *testing.T, v *Values) string {
if err := tpl.Execute(f, v); err != nil {
t.Fatal(err)
}
return f.Name()
return name
}
type AuthProviderConfig struct {

View File

@@ -1,4 +1,4 @@
// Package handler provides a HTTP handler for the OpenID Connect Provider.
// Package handler provides HTTP handlers for the OpenID Connect Provider.
package handler
import (
@@ -6,29 +6,34 @@ import (
"errors"
"fmt"
"net/http"
"net/url"
"testing"
"github.com/int128/kubelogin/integration_test/oidcserver/service"
)
func New(t *testing.T, provider Provider) *Handler {
return &Handler{t, provider}
func Register(t *testing.T, mux *http.ServeMux, provider service.Provider) {
h := &Handlers{t, provider}
mux.HandleFunc("GET /.well-known/openid-configuration", h.Discovery)
mux.HandleFunc("GET /certs", h.GetCertificates)
mux.HandleFunc("GET /auth", h.AuthenticateCode)
mux.HandleFunc("POST /token", h.Exchange)
}
// Handler provides a HTTP handler for the OpenID Connect Provider.
// Handlers provides HTTP handlers for the OpenID Connect Provider.
// You need to implement the Provider interface.
// Note that this skips some security checks and is only for testing.
type Handler struct {
type Handlers struct {
t *testing.T
provider Provider
provider service.Provider
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
wr := &responseWriterRecorder{w, 200}
err := h.serveHTTP(wr, r)
func (h *Handlers) handleError(w http.ResponseWriter, r *http.Request, f func() error) {
err := f()
if err == nil {
h.t.Logf("%d %s %s", wr.statusCode, r.Method, r.RequestURI)
return
}
if errResp := new(ErrorResponse); errors.As(err, &errResp) {
if errResp := new(service.ErrorResponse); errors.As(err, &errResp) {
h.t.Logf("400 %s %s: %s", r.Method, r.RequestURI, err)
w.Header().Add("Content-Type", "application/json")
w.WriteHeader(400)
@@ -42,38 +47,35 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
http.Error(w, err.Error(), 500)
}
type responseWriterRecorder struct {
http.ResponseWriter
statusCode int
}
func (w *responseWriterRecorder) WriteHeader(statusCode int) {
w.ResponseWriter.WriteHeader(statusCode)
w.statusCode = statusCode
}
func (h *Handler) serveHTTP(w http.ResponseWriter, r *http.Request) error {
m := r.Method
p := r.URL.Path
switch {
case m == "GET" && p == "/.well-known/openid-configuration":
func (h *Handlers) Discovery(w http.ResponseWriter, r *http.Request) {
h.handleError(w, r, func() error {
discoveryResponse := h.provider.Discovery()
w.Header().Add("Content-Type", "application/json")
e := json.NewEncoder(w)
if err := e.Encode(discoveryResponse); err != nil {
return fmt.Errorf("could not render json: %w", err)
}
case m == "GET" && p == "/certs":
return nil
})
}
func (h *Handlers) GetCertificates(w http.ResponseWriter, r *http.Request) {
h.handleError(w, r, func() error {
certificatesResponse := h.provider.GetCertificates()
w.Header().Add("Content-Type", "application/json")
e := json.NewEncoder(w)
if err := e.Encode(certificatesResponse); err != nil {
return fmt.Errorf("could not render json: %w", err)
}
case m == "GET" && p == "/auth":
return nil
})
}
func (h *Handlers) AuthenticateCode(w http.ResponseWriter, r *http.Request) {
h.handleError(w, r, func() error {
q := r.URL.Query()
redirectURI, state := q.Get("redirect_uri"), q.Get("state")
code, err := h.provider.AuthenticateCode(AuthenticationRequest{
code, err := h.provider.AuthenticateCode(service.AuthenticationRequest{
RedirectURI: redirectURI,
State: state,
Scope: q.Get("scope"),
@@ -85,16 +87,25 @@ func (h *Handler) serveHTTP(w http.ResponseWriter, r *http.Request) error {
if err != nil {
return fmt.Errorf("authentication error: %w", err)
}
to := fmt.Sprintf("%s?state=%s&code=%s", redirectURI, state, code)
http.Redirect(w, r, to, 302)
case m == "POST" && p == "/token":
redirectTo, err := url.Parse(redirectURI)
if err != nil {
return fmt.Errorf("invalid redirect_uri: %w", err)
}
redirectTo.RawQuery = url.Values{"state": {state}, "code": {code}}.Encode()
http.Redirect(w, r, redirectTo.String(), http.StatusFound)
return nil
})
}
func (h *Handlers) Exchange(w http.ResponseWriter, r *http.Request) {
h.handleError(w, r, func() error {
if err := r.ParseForm(); err != nil {
return fmt.Errorf("could not parse the form: %w", err)
}
grantType := r.Form.Get("grant_type")
switch grantType {
case "authorization_code":
tokenResponse, err := h.provider.Exchange(TokenRequest{
tokenResponse, err := h.provider.Exchange(service.TokenRequest{
Code: r.Form.Get("code"),
CodeVerifier: r.Form.Get("code_verifier"),
})
@@ -135,13 +146,11 @@ func (h *Handler) serveHTTP(w http.ResponseWriter, r *http.Request) error {
default:
// 5.2. Error Response
// https://tools.ietf.org/html/rfc6749#section-5.2
return &ErrorResponse{
return &service.ErrorResponse{
Code: "invalid_grant",
Description: fmt.Sprintf("unknown grant_type %s", grantType),
}
}
default:
http.NotFound(w, r)
}
return nil
return nil
})
}

View File

@@ -1,78 +0,0 @@
// Package http provides a http server running on localhost for testing.
package http
import (
"context"
"net"
"net/http"
"testing"
"github.com/int128/kubelogin/integration_test/keypair"
)
type Shutdowner interface {
Shutdown(t *testing.T, ctx context.Context)
}
type shutdowner struct {
s *http.Server
}
func (s *shutdowner) Shutdown(t *testing.T, ctx context.Context) {
if err := s.s.Shutdown(ctx); err != nil {
t.Errorf("could not shutdown the server: %s", err)
}
}
func Start(t *testing.T, h http.Handler, k keypair.KeyPair) (string, Shutdowner) {
if k == keypair.None {
return startNoTLS(t, h)
}
return startTLS(t, h, k)
}
func startNoTLS(t *testing.T, h http.Handler) (string, *shutdowner) {
t.Helper()
l, port := newLocalhostListener(t)
url := "http://localhost:" + port
s := &http.Server{
Handler: h,
}
go func() {
err := s.Serve(l)
if err != nil && err != http.ErrServerClosed {
t.Error(err)
}
}()
return url, &shutdowner{s}
}
func startTLS(t *testing.T, h http.Handler, k keypair.KeyPair) (string, *shutdowner) {
t.Helper()
l, port := newLocalhostListener(t)
url := "https://localhost:" + port
s := &http.Server{
Handler: h,
}
go func() {
err := s.ServeTLS(l, k.CertPath, k.KeyPath)
if err != nil && err != http.ErrServerClosed {
t.Error(err)
}
}()
return url, &shutdowner{s}
}
func newLocalhostListener(t *testing.T) (net.Listener, string) {
t.Helper()
l, err := net.Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("Could not create a listener: %s", err)
}
addr := l.Addr().String()
_, port, err := net.SplitHostPort(addr)
if err != nil {
t.Fatalf("Could not parse the address %s: %s", addr, err)
}
return l, port
}

View File

@@ -0,0 +1,54 @@
// Package oidcserver provides a stub of OpenID Connect provider.
package oidcserver
import (
"context"
"errors"
"fmt"
"net"
"net/http"
"net/http/httptest"
"testing"
"github.com/int128/kubelogin/integration_test/keypair"
"github.com/int128/kubelogin/integration_test/oidcserver/handler"
"github.com/int128/kubelogin/integration_test/oidcserver/service"
"github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
)
// New starts a server for the OpenID Connect provider.
func New(t *testing.T, kp keypair.KeyPair, config testconfig.Config) service.Service {
mux := http.NewServeMux()
serverURL := startServer(t, mux, kp)
svc := service.New(t, serverURL, config)
handler.Register(t, mux, svc)
return svc
}
func startServer(t *testing.T, h http.Handler, kp keypair.KeyPair) string {
if kp == keypair.None {
srv := httptest.NewServer(h)
t.Cleanup(srv.Close)
return srv.URL
}
// Unfortunately, httptest package did not work with keypair.KeyPair.
// We use httptest package only for allocating a new port.
portAllocator := httptest.NewUnstartedServer(h)
t.Cleanup(portAllocator.Close)
serverURL := fmt.Sprintf("https://localhost:%d", portAllocator.Listener.Addr().(*net.TCPAddr).Port)
srv := &http.Server{Handler: h}
go func() {
err := srv.ServeTLS(portAllocator.Listener, kp.CertPath, kp.KeyPath)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
t.Error(err)
}
}()
t.Cleanup(func() {
if err := srv.Shutdown(context.TODO()); err != nil {
t.Errorf("could not shutdown the server: %s", err)
}
})
return serverURL
}

View File

@@ -1,217 +0,0 @@
// Package oidcserver provides a stub of OpenID Connect provider.
package oidcserver
import (
"crypto/sha256"
"encoding/base64"
"fmt"
"math/big"
"strings"
"testing"
"time"
"github.com/int128/kubelogin/integration_test/keypair"
"github.com/int128/kubelogin/integration_test/oidcserver/handler"
"github.com/int128/kubelogin/integration_test/oidcserver/http"
"github.com/int128/kubelogin/pkg/testing/jwt"
)
type Server interface {
http.Shutdowner
IssuerURL() string
SetConfig(Config)
LastTokenResponse() *handler.TokenResponse
}
// Want represents a set of expected values.
type Want struct {
Scope string
RedirectURIPrefix string
CodeChallengeMethod string // optional
ExtraParams map[string]string // optional
Username string // optional
Password string // optional
RefreshToken string // optional
}
// Response represents a set of response values.
type Response struct {
IDTokenExpiry time.Time
RefreshToken string
RefreshError string // if set, Refresh() will return the error
CodeChallengeMethodsSupported []string // optional
}
// Config represents a configuration of the OpenID Connect provider.
type Config struct {
Want Want
Response Response
}
// New starts a HTTP server for the OpenID Connect provider.
func New(t *testing.T, k keypair.KeyPair, c Config) Server {
sv := server{Config: c, t: t}
sv.issuerURL, sv.Shutdowner = http.Start(t, handler.New(t, &sv), k)
return &sv
}
type server struct {
Config
http.Shutdowner
t *testing.T
issuerURL string
lastAuthenticationRequest *handler.AuthenticationRequest
lastTokenResponse *handler.TokenResponse
}
func (sv *server) IssuerURL() string {
return sv.issuerURL
}
func (sv *server) SetConfig(cfg Config) {
sv.Config = cfg
}
func (sv *server) LastTokenResponse() *handler.TokenResponse {
return sv.lastTokenResponse
}
func (sv *server) Discovery() *handler.DiscoveryResponse {
// based on https://accounts.google.com/.well-known/openid-configuration
return &handler.DiscoveryResponse{
Issuer: sv.issuerURL,
AuthorizationEndpoint: sv.issuerURL + "/auth",
TokenEndpoint: sv.issuerURL + "/token",
JwksURI: sv.issuerURL + "/certs",
UserinfoEndpoint: sv.issuerURL + "/userinfo",
RevocationEndpoint: sv.issuerURL + "/revoke",
ResponseTypesSupported: []string{"code id_token"},
SubjectTypesSupported: []string{"public"},
IDTokenSigningAlgValuesSupported: []string{"RS256"},
ScopesSupported: []string{"openid", "email", "profile"},
TokenEndpointAuthMethodsSupported: []string{"client_secret_post", "client_secret_basic"},
CodeChallengeMethodsSupported: sv.Config.Response.CodeChallengeMethodsSupported,
ClaimsSupported: []string{"aud", "email", "exp", "iat", "iss", "name", "sub"},
}
}
func (sv *server) GetCertificates() *handler.CertificatesResponse {
idTokenKeyPair := jwt.PrivateKey
return &handler.CertificatesResponse{
Keys: []*handler.CertificatesResponseKey{
{
Kty: "RSA",
Alg: "RS256",
Use: "sig",
Kid: "dummy",
E: base64.RawURLEncoding.EncodeToString(big.NewInt(int64(idTokenKeyPair.E)).Bytes()),
N: base64.RawURLEncoding.EncodeToString(idTokenKeyPair.N.Bytes()),
},
},
}
}
func (sv *server) AuthenticateCode(req handler.AuthenticationRequest) (code string, err error) {
if req.Scope != sv.Want.Scope {
sv.t.Errorf("scope wants `%s` but was `%s`", sv.Want.Scope, req.Scope)
}
if !strings.HasPrefix(req.RedirectURI, sv.Want.RedirectURIPrefix) {
sv.t.Errorf("redirectURI wants prefix `%s` but was `%s`", sv.Want.RedirectURIPrefix, req.RedirectURI)
}
if req.CodeChallengeMethod != sv.Want.CodeChallengeMethod {
sv.t.Errorf("code_challenge_method wants `%s` but was `%s`", sv.Want.CodeChallengeMethod, req.CodeChallengeMethod)
}
for k, v := range sv.Want.ExtraParams {
got := req.RawQuery.Get(k)
if got != v {
sv.t.Errorf("parameter %s wants `%s` but was `%s`", k, v, got)
}
}
sv.lastAuthenticationRequest = &req
return "YOUR_AUTH_CODE", nil
}
func (sv *server) Exchange(req handler.TokenRequest) (*handler.TokenResponse, error) {
if req.Code != "YOUR_AUTH_CODE" {
return nil, fmt.Errorf("code wants %s but was %s", "YOUR_AUTH_CODE", req.Code)
}
if sv.lastAuthenticationRequest.CodeChallengeMethod == "S256" {
// https://tools.ietf.org/html/rfc7636#section-4.6
challenge := computeS256Challenge(req.CodeVerifier)
if challenge != sv.lastAuthenticationRequest.CodeChallenge {
sv.t.Errorf("pkce S256 challenge did not match (want %s but was %s)", sv.lastAuthenticationRequest.CodeChallenge, challenge)
}
}
resp := &handler.TokenResponse{
TokenType: "Bearer",
ExpiresIn: 3600,
AccessToken: "YOUR_ACCESS_TOKEN",
RefreshToken: sv.Response.RefreshToken,
IDToken: jwt.EncodeF(sv.t, func(claims *jwt.Claims) {
claims.Issuer = sv.issuerURL
claims.Subject = "SUBJECT"
claims.IssuedAt = sv.Response.IDTokenExpiry.Add(-time.Hour).Unix()
claims.ExpiresAt = sv.Response.IDTokenExpiry.Unix()
claims.Audience = []string{"kubernetes"}
claims.Nonce = sv.lastAuthenticationRequest.Nonce
}),
}
sv.lastTokenResponse = resp
return resp, nil
}
func computeS256Challenge(verifier string) string {
c := sha256.Sum256([]byte(verifier))
return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(c[:])
}
func (sv *server) AuthenticatePassword(username, password, scope string) (*handler.TokenResponse, error) {
if scope != sv.Want.Scope {
sv.t.Errorf("scope wants `%s` but was `%s`", sv.Want.Scope, scope)
}
if username != sv.Want.Username {
sv.t.Errorf("username wants `%s` but was `%s`", sv.Want.Username, username)
}
if password != sv.Want.Password {
sv.t.Errorf("password wants `%s` but was `%s`", sv.Want.Password, password)
}
resp := &handler.TokenResponse{
TokenType: "Bearer",
ExpiresIn: 3600,
AccessToken: "YOUR_ACCESS_TOKEN",
RefreshToken: sv.Response.RefreshToken,
IDToken: jwt.EncodeF(sv.t, func(claims *jwt.Claims) {
claims.Issuer = sv.issuerURL
claims.Subject = "SUBJECT"
claims.IssuedAt = sv.Response.IDTokenExpiry.Add(-time.Hour).Unix()
claims.ExpiresAt = sv.Response.IDTokenExpiry.Unix()
claims.Audience = []string{"kubernetes"}
}),
}
sv.lastTokenResponse = resp
return resp, nil
}
func (sv *server) Refresh(refreshToken string) (*handler.TokenResponse, error) {
if refreshToken != sv.Want.RefreshToken {
sv.t.Errorf("refreshToken wants %s but was %s", sv.Want.RefreshToken, refreshToken)
}
if sv.Response.RefreshError != "" {
return nil, &handler.ErrorResponse{Code: "invalid_request", Description: sv.Response.RefreshError}
}
resp := &handler.TokenResponse{
TokenType: "Bearer",
ExpiresIn: 3600,
AccessToken: "YOUR_ACCESS_TOKEN",
RefreshToken: sv.Response.RefreshToken,
IDToken: jwt.EncodeF(sv.t, func(claims *jwt.Claims) {
claims.Issuer = sv.issuerURL
claims.Subject = "SUBJECT"
claims.IssuedAt = sv.Response.IDTokenExpiry.Add(-time.Hour).Unix()
claims.ExpiresAt = sv.Response.IDTokenExpiry.Unix()
claims.Audience = []string{"kubernetes"}
}),
}
sv.lastTokenResponse = resp
return resp, nil
}

View File

@@ -0,0 +1,184 @@
package service
import (
"crypto/sha256"
"encoding/base64"
"fmt"
"math/big"
"strings"
"testing"
"time"
"github.com/golang-jwt/jwt/v5"
"github.com/google/go-cmp/cmp"
"github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
testingJWT "github.com/int128/kubelogin/pkg/testing/jwt"
)
func New(t *testing.T, issuerURL string, config testconfig.Config) Service {
return &service{
config: config,
t: t,
issuerURL: issuerURL,
}
}
type service struct {
config testconfig.Config
t *testing.T
issuerURL string
lastAuthenticationRequest *AuthenticationRequest
lastTokenResponse *TokenResponse
}
func (svc *service) IssuerURL() string {
return svc.issuerURL
}
func (svc *service) SetConfig(cfg testconfig.Config) {
svc.config = cfg
}
func (svc *service) LastTokenResponse() *TokenResponse {
return svc.lastTokenResponse
}
func (svc *service) Discovery() *DiscoveryResponse {
// based on https://accounts.google.com/.well-known/openid-configuration
return &DiscoveryResponse{
Issuer: svc.issuerURL,
AuthorizationEndpoint: svc.issuerURL + "/auth",
TokenEndpoint: svc.issuerURL + "/token",
JwksURI: svc.issuerURL + "/certs",
UserinfoEndpoint: svc.issuerURL + "/userinfo",
RevocationEndpoint: svc.issuerURL + "/revoke",
ResponseTypesSupported: []string{"code id_token"},
SubjectTypesSupported: []string{"public"},
IDTokenSigningAlgValuesSupported: []string{"RS256"},
ScopesSupported: []string{"openid", "email", "profile"},
TokenEndpointAuthMethodsSupported: []string{"client_secret_post", "client_secret_basic"},
CodeChallengeMethodsSupported: svc.config.Response.CodeChallengeMethodsSupported,
ClaimsSupported: []string{"aud", "email", "exp", "iat", "iss", "name", "sub"},
}
}
func (svc *service) GetCertificates() *CertificatesResponse {
idTokenKeyPair := testingJWT.PrivateKey
return &CertificatesResponse{
Keys: []*CertificatesResponseKey{
{
Kty: "RSA",
Alg: "RS256",
Use: "sig",
Kid: "dummy",
E: base64.RawURLEncoding.EncodeToString(big.NewInt(int64(idTokenKeyPair.E)).Bytes()),
N: base64.RawURLEncoding.EncodeToString(idTokenKeyPair.N.Bytes()),
},
},
}
}
func (svc *service) AuthenticateCode(req AuthenticationRequest) (code string, err error) {
if req.Scope != svc.config.Want.Scope {
svc.t.Errorf("scope wants `%s` but was `%s`", svc.config.Want.Scope, req.Scope)
}
if !strings.HasPrefix(req.RedirectURI, svc.config.Want.RedirectURIPrefix) {
svc.t.Errorf("redirectURI wants prefix `%s` but was `%s`", svc.config.Want.RedirectURIPrefix, req.RedirectURI)
}
if diff := cmp.Diff(svc.config.Want.CodeChallengeMethod, req.CodeChallengeMethod); diff != "" {
svc.t.Errorf("code_challenge_method mismatch (-want +got):\n%s", diff)
}
for k, v := range svc.config.Want.ExtraParams {
got := req.RawQuery.Get(k)
if got != v {
svc.t.Errorf("parameter %s wants `%s` but was `%s`", k, v, got)
}
}
svc.lastAuthenticationRequest = &req
return "YOUR_AUTH_CODE", nil
}
func (svc *service) Exchange(req TokenRequest) (*TokenResponse, error) {
if req.Code != "YOUR_AUTH_CODE" {
return nil, fmt.Errorf("code wants %s but was %s", "YOUR_AUTH_CODE", req.Code)
}
if svc.lastAuthenticationRequest.CodeChallengeMethod == "S256" {
// https://tools.ietf.org/html/rfc7636#section-4.6
challenge := computeS256Challenge(req.CodeVerifier)
if challenge != svc.lastAuthenticationRequest.CodeChallenge {
svc.t.Errorf("pkce S256 challenge did not match (want %s but was %s)", svc.lastAuthenticationRequest.CodeChallenge, challenge)
}
}
resp := &TokenResponse{
TokenType: "Bearer",
ExpiresIn: 3600,
AccessToken: "YOUR_ACCESS_TOKEN",
RefreshToken: svc.config.Response.RefreshToken,
IDToken: testingJWT.EncodeF(svc.t, func(claims *testingJWT.Claims) {
claims.Issuer = svc.issuerURL
claims.Subject = "SUBJECT"
claims.IssuedAt = jwt.NewNumericDate(svc.config.Response.IDTokenExpiry.Add(-time.Hour))
claims.ExpiresAt = jwt.NewNumericDate(svc.config.Response.IDTokenExpiry)
claims.Audience = []string{"kubernetes"}
claims.Nonce = svc.lastAuthenticationRequest.Nonce
}),
}
svc.lastTokenResponse = resp
return resp, nil
}
func computeS256Challenge(verifier string) string {
c := sha256.Sum256([]byte(verifier))
return base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(c[:])
}
func (svc *service) AuthenticatePassword(username, password, scope string) (*TokenResponse, error) {
if scope != svc.config.Want.Scope {
svc.t.Errorf("scope wants `%s` but was `%s`", svc.config.Want.Scope, scope)
}
if username != svc.config.Want.Username {
svc.t.Errorf("username wants `%s` but was `%s`", svc.config.Want.Username, username)
}
if password != svc.config.Want.Password {
svc.t.Errorf("password wants `%s` but was `%s`", svc.config.Want.Password, password)
}
resp := &TokenResponse{
TokenType: "Bearer",
ExpiresIn: 3600,
AccessToken: "YOUR_ACCESS_TOKEN",
RefreshToken: svc.config.Response.RefreshToken,
IDToken: testingJWT.EncodeF(svc.t, func(claims *testingJWT.Claims) {
claims.Issuer = svc.issuerURL
claims.Subject = "SUBJECT"
claims.IssuedAt = jwt.NewNumericDate(svc.config.Response.IDTokenExpiry.Add(-time.Hour))
claims.ExpiresAt = jwt.NewNumericDate(svc.config.Response.IDTokenExpiry)
claims.Audience = []string{"kubernetes"}
}),
}
svc.lastTokenResponse = resp
return resp, nil
}
func (svc *service) Refresh(refreshToken string) (*TokenResponse, error) {
if refreshToken != svc.config.Want.RefreshToken {
svc.t.Errorf("refreshToken wants %s but was %s", svc.config.Want.RefreshToken, refreshToken)
}
if svc.config.Response.RefreshError != "" {
return nil, &ErrorResponse{Code: "invalid_request", Description: svc.config.Response.RefreshError}
}
resp := &TokenResponse{
TokenType: "Bearer",
ExpiresIn: 3600,
AccessToken: "YOUR_ACCESS_TOKEN",
RefreshToken: svc.config.Response.RefreshToken,
IDToken: testingJWT.EncodeF(svc.t, func(claims *testingJWT.Claims) {
claims.Issuer = svc.issuerURL
claims.Subject = "SUBJECT"
claims.IssuedAt = jwt.NewNumericDate(svc.config.Response.IDTokenExpiry.Add(-time.Hour))
claims.ExpiresAt = jwt.NewNumericDate(svc.config.Response.IDTokenExpiry)
claims.Audience = []string{"kubernetes"}
}),
}
svc.lastTokenResponse = resp
return resp, nil
}

View File

@@ -1,11 +1,24 @@
package handler
package service
import (
"fmt"
"net/url"
"github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
)
// Provider provides discovery and authentication methods.
// Service represents the test service of OpenID Connect Provider.
// It provides the feature of Provider and additional methods for testing.
type Service interface {
Provider
IssuerURL() string
SetConfig(config testconfig.Config)
LastTokenResponse() *TokenResponse
}
// Provider represents an OpenID Connect Provider.
//
// If an implemented method returns an ErrorResponse,
// the handler will respond 400 and corresponding json of the ErrorResponse.
// Otherwise, the handler will respond 500 and fail the current test.
@@ -18,6 +31,8 @@ type Provider interface {
Refresh(refreshToken string) (*TokenResponse, error)
}
// DiscoveryResponse represents the type of:
// https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationResponse
type DiscoveryResponse struct {
Issuer string `json:"issuer"`
AuthorizationEndpoint string `json:"authorization_endpoint"`
@@ -34,10 +49,14 @@ type DiscoveryResponse struct {
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
}
// CertificatesResponse represents the type of:
// https://datatracker.ietf.org/doc/html/rfc7517#section-5
type CertificatesResponse struct {
Keys []*CertificatesResponseKey `json:"keys"`
}
// CertificatesResponseKey represents the type of:
// https://datatracker.ietf.org/doc/html/rfc7517#section-4
type CertificatesResponseKey struct {
Kty string `json:"kty"`
Alg string `json:"alg"`
@@ -47,7 +66,7 @@ type CertificatesResponseKey struct {
E string `json:"e"`
}
// AuthenticationRequest represents a type of:
// AuthenticationRequest represents the type of:
// https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
type AuthenticationRequest struct {
RedirectURI string
@@ -59,13 +78,15 @@ type AuthenticationRequest struct {
RawQuery url.Values
}
// TokenRequest represents a type of:
// TokenRequest represents the type of:
// https://openid.net/specs/openid-connect-core-1_0.html#TokenRequest
type TokenRequest struct {
Code string
CodeVerifier string
}
// TokenResponse represents the type of:
// https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse
type TokenResponse struct {
AccessToken string `json:"access_token"`
TokenType string `json:"token_type"`
@@ -74,7 +95,7 @@ type TokenResponse struct {
IDToken string `json:"id_token"`
}
// ErrorResponse represents an error response described in the following section:
// ErrorResponse represents the error response described in the following section:
// 5.2 Error Response
// https://tools.ietf.org/html/rfc6749#section-5.2
type ErrorResponse struct {

View File

@@ -0,0 +1,28 @@
package testconfig
import "time"
// Want represents a set of expected values.
type Want struct {
Scope string
RedirectURIPrefix string
CodeChallengeMethod string
ExtraParams map[string]string // optional
Username string // optional
Password string // optional
RefreshToken string // optional
}
// Response represents a set of response values.
type Response struct {
IDTokenExpiry time.Time
RefreshToken string
RefreshError string // if set, Refresh() will return the error
CodeChallengeMethodsSupported []string
}
// Config represents a configuration of the OpenID Connect provider.
type Config struct {
Want Want
Response Response
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/int128/kubelogin/integration_test/keypair"
"github.com/int128/kubelogin/integration_test/kubeconfig"
"github.com/int128/kubelogin/integration_test/oidcserver"
"github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
"github.com/int128/kubelogin/pkg/di"
"github.com/int128/kubelogin/pkg/infrastructure/browser"
"github.com/int128/kubelogin/pkg/testing/clock"
@@ -22,7 +23,6 @@ import (
// 2. Run the Cmd.
// 3. Open a request for the local server.
// 4. Verify the kubeconfig.
//
func TestStandalone(t *testing.T) {
timeout := 3 * time.Second
now := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)
@@ -36,7 +36,7 @@ func TestStandalone(t *testing.T) {
keyPair: keypair.Server,
},
} {
httpDriverOption := httpdriver.Option{
httpDriverOption := httpdriver.Config{
TLSConfig: tc.keyPair.TLSConfig,
BodyContains: "Authenticated",
}
@@ -46,21 +46,19 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, oidcserver.Config{
Want: oidcserver.Want{
sv := oidcserver.New(t, tc.keyPair, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
},
Response: oidcserver.Response{
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
},
})
defer sv.Shutdown(t, ctx)
kubeConfigFilename := kubeconfig.Create(t, &kubeconfig.Values{
Issuer: sv.IssuerURL(),
IDPCertificateAuthority: tc.keyPair.CACertPath,
})
defer os.Remove(kubeConfigFilename)
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
kubeConfigFilename: kubeConfigFilename,
@@ -77,23 +75,21 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, oidcserver.Config{
Want: oidcserver.Want{
sv := oidcserver.New(t, tc.keyPair, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
Username: "USER1",
Password: "PASS1",
},
Response: oidcserver.Response{
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
},
})
defer sv.Shutdown(t, ctx)
kubeConfigFilename := kubeconfig.Create(t, &kubeconfig.Values{
Issuer: sv.IssuerURL(),
IDPCertificateAuthority: tc.keyPair.CACertPath,
})
defer os.Remove(kubeConfigFilename)
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
kubeConfigFilename: kubeConfigFilename,
@@ -114,21 +110,19 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, tc.keyPair, oidcserver.Config{})
defer sv.Shutdown(t, ctx)
sv := oidcserver.New(t, tc.keyPair, testconfig.Config{})
kubeConfigFilename := kubeconfig.Create(t, &kubeconfig.Values{
Issuer: sv.IssuerURL(),
IDPCertificateAuthority: tc.keyPair.CACertPath,
})
defer os.Remove(kubeConfigFilename)
t.Run("NoToken", func(t *testing.T) {
sv.SetConfig(oidcserver.Config{
Want: oidcserver.Want{
sv.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
},
Response: oidcserver.Response{
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
RefreshToken: "REFRESH_TOKEN_1",
},
@@ -145,7 +139,7 @@ func TestStandalone(t *testing.T) {
})
})
t.Run("Valid", func(t *testing.T) {
sv.SetConfig(oidcserver.Config{})
sv.SetConfig(testconfig.Config{})
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
kubeConfigFilename: kubeConfigFilename,
@@ -158,13 +152,13 @@ func TestStandalone(t *testing.T) {
})
})
t.Run("Refresh", func(t *testing.T) {
sv.SetConfig(oidcserver.Config{
Want: oidcserver.Want{
sv.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
RefreshToken: "REFRESH_TOKEN_1",
},
Response: oidcserver.Response{
Response: testconfig.Response{
IDTokenExpiry: now.Add(3 * time.Hour),
RefreshToken: "REFRESH_TOKEN_2",
},
@@ -181,13 +175,13 @@ func TestStandalone(t *testing.T) {
})
})
t.Run("RefreshAgain", func(t *testing.T) {
sv.SetConfig(oidcserver.Config{
Want: oidcserver.Want{
sv.SetConfig(testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
RefreshToken: "REFRESH_TOKEN_2",
},
Response: oidcserver.Response{
Response: testconfig.Response{
IDTokenExpiry: now.Add(5 * time.Hour),
},
})
@@ -210,25 +204,23 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.Server, oidcserver.Config{
Want: oidcserver.Want{
sv := oidcserver.New(t, keypair.Server, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
},
Response: oidcserver.Response{
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
},
})
defer sv.Shutdown(t, ctx)
kubeConfigFilename := kubeconfig.Create(t, &kubeconfig.Values{
Issuer: sv.IssuerURL(),
IDPCertificateAuthorityData: keypair.Server.CACertBase64,
})
defer os.Remove(kubeConfigFilename)
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
kubeConfigFilename: kubeConfigFilename,
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{TLSConfig: keypair.Server.TLSConfig}),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{TLSConfig: keypair.Server.TLSConfig}),
now: now,
})
kubeconfig.Verify(t, kubeConfigFilename, kubeconfig.AuthProviderConfig{
@@ -240,25 +232,22 @@ func TestStandalone(t *testing.T) {
t.Run("env_KUBECONFIG", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, oidcserver.Config{
Want: oidcserver.Want{
sv := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "openid",
RedirectURIPrefix: "http://localhost:",
},
Response: oidcserver.Response{
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
},
})
defer sv.Shutdown(t, ctx)
kubeConfigFilename := kubeconfig.Create(t, &kubeconfig.Values{
Issuer: sv.IssuerURL(),
})
defer os.Remove(kubeConfigFilename)
setenv(t, "KUBECONFIG", kubeConfigFilename+string(os.PathListSeparator)+"kubeconfig/testdata/dummy.yaml")
defer unsetenv(t, "KUBECONFIG")
t.Setenv("KUBECONFIG", kubeConfigFilename+string(os.PathListSeparator)+"kubeconfig/testdata/dummy.yaml")
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{}),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{}),
now: now,
})
kubeconfig.Verify(t, kubeConfigFilename, kubeconfig.AuthProviderConfig{
@@ -271,25 +260,23 @@ func TestStandalone(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.TODO(), timeout)
defer cancel()
sv := oidcserver.New(t, keypair.None, oidcserver.Config{
Want: oidcserver.Want{
sv := oidcserver.New(t, keypair.None, testconfig.Config{
Want: testconfig.Want{
Scope: "profile groups openid",
RedirectURIPrefix: "http://localhost:",
},
Response: oidcserver.Response{
Response: testconfig.Response{
IDTokenExpiry: now.Add(time.Hour),
},
})
defer sv.Shutdown(t, ctx)
kubeConfigFilename := kubeconfig.Create(t, &kubeconfig.Values{
Issuer: sv.IssuerURL(),
ExtraScopes: "profile,groups",
})
defer os.Remove(kubeConfigFilename)
runStandalone(t, ctx, standaloneConfig{
issuerURL: sv.IssuerURL(),
kubeConfigFilename: kubeConfigFilename,
httpDriver: httpdriver.New(ctx, t, httpdriver.Option{}),
httpDriver: httpdriver.New(ctx, t, httpdriver.Config{}),
now: now,
})
kubeconfig.Verify(t, kubeConfigFilename, kubeconfig.AuthProviderConfig{
@@ -318,17 +305,3 @@ func runStandalone(t *testing.T, ctx context.Context, cfg standaloneConfig) {
t.Errorf("exit status wants 0 but %d", exitCode)
}
}
func setenv(t *testing.T, key, value string) {
t.Helper()
if err := os.Setenv(key, value); err != nil {
t.Fatalf("Could not set the env var %s=%s: %s", key, value, err)
}
}
func unsetenv(t *testing.T, key string) {
t.Helper()
if err := os.Unsetenv(key); err != nil {
t.Fatalf("Could not unset the env var %s: %s", key, err)
}
}

View File

@@ -3,6 +3,8 @@ package main
import (
"context"
"os"
"os/signal"
"syscall"
"github.com/int128/kubelogin/pkg/di"
)
@@ -10,5 +12,8 @@ import (
var version = "HEAD"
func main() {
os.Exit(di.NewCmd().Run(context.Background(), os.Args, version))
ctx := context.Background()
ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)
defer stop()
os.Exit(di.NewCmd().Run(ctx, os.Args, version))
}

View File

@@ -0,0 +1,361 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package service_mock
import (
service "github.com/int128/kubelogin/integration_test/oidcserver/service"
mock "github.com/stretchr/testify/mock"
)
// MockProvider is an autogenerated mock type for the Provider type
type MockProvider struct {
mock.Mock
}
type MockProvider_Expecter struct {
mock *mock.Mock
}
func (_m *MockProvider) EXPECT() *MockProvider_Expecter {
return &MockProvider_Expecter{mock: &_m.Mock}
}
// AuthenticateCode provides a mock function with given fields: req
func (_m *MockProvider) AuthenticateCode(req service.AuthenticationRequest) (string, error) {
ret := _m.Called(req)
if len(ret) == 0 {
panic("no return value specified for AuthenticateCode")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(service.AuthenticationRequest) (string, error)); ok {
return rf(req)
}
if rf, ok := ret.Get(0).(func(service.AuthenticationRequest) string); ok {
r0 = rf(req)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(service.AuthenticationRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_AuthenticateCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticateCode'
type MockProvider_AuthenticateCode_Call struct {
*mock.Call
}
// AuthenticateCode is a helper method to define mock.On call
// - req service.AuthenticationRequest
func (_e *MockProvider_Expecter) AuthenticateCode(req interface{}) *MockProvider_AuthenticateCode_Call {
return &MockProvider_AuthenticateCode_Call{Call: _e.mock.On("AuthenticateCode", req)}
}
func (_c *MockProvider_AuthenticateCode_Call) Run(run func(req service.AuthenticationRequest)) *MockProvider_AuthenticateCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(service.AuthenticationRequest))
})
return _c
}
func (_c *MockProvider_AuthenticateCode_Call) Return(code string, err error) *MockProvider_AuthenticateCode_Call {
_c.Call.Return(code, err)
return _c
}
func (_c *MockProvider_AuthenticateCode_Call) RunAndReturn(run func(service.AuthenticationRequest) (string, error)) *MockProvider_AuthenticateCode_Call {
_c.Call.Return(run)
return _c
}
// AuthenticatePassword provides a mock function with given fields: username, password, scope
func (_m *MockProvider) AuthenticatePassword(username string, password string, scope string) (*service.TokenResponse, error) {
ret := _m.Called(username, password, scope)
if len(ret) == 0 {
panic("no return value specified for AuthenticatePassword")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(string, string, string) (*service.TokenResponse, error)); ok {
return rf(username, password, scope)
}
if rf, ok := ret.Get(0).(func(string, string, string) *service.TokenResponse); ok {
r0 = rf(username, password, scope)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(username, password, scope)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_AuthenticatePassword_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticatePassword'
type MockProvider_AuthenticatePassword_Call struct {
*mock.Call
}
// AuthenticatePassword is a helper method to define mock.On call
// - username string
// - password string
// - scope string
func (_e *MockProvider_Expecter) AuthenticatePassword(username interface{}, password interface{}, scope interface{}) *MockProvider_AuthenticatePassword_Call {
return &MockProvider_AuthenticatePassword_Call{Call: _e.mock.On("AuthenticatePassword", username, password, scope)}
}
func (_c *MockProvider_AuthenticatePassword_Call) Run(run func(username string, password string, scope string)) *MockProvider_AuthenticatePassword_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockProvider_AuthenticatePassword_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockProvider_AuthenticatePassword_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockProvider_AuthenticatePassword_Call) RunAndReturn(run func(string, string, string) (*service.TokenResponse, error)) *MockProvider_AuthenticatePassword_Call {
_c.Call.Return(run)
return _c
}
// Discovery provides a mock function with no fields
func (_m *MockProvider) Discovery() *service.DiscoveryResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Discovery")
}
var r0 *service.DiscoveryResponse
if rf, ok := ret.Get(0).(func() *service.DiscoveryResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.DiscoveryResponse)
}
}
return r0
}
// MockProvider_Discovery_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Discovery'
type MockProvider_Discovery_Call struct {
*mock.Call
}
// Discovery is a helper method to define mock.On call
func (_e *MockProvider_Expecter) Discovery() *MockProvider_Discovery_Call {
return &MockProvider_Discovery_Call{Call: _e.mock.On("Discovery")}
}
func (_c *MockProvider_Discovery_Call) Run(run func()) *MockProvider_Discovery_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockProvider_Discovery_Call) Return(_a0 *service.DiscoveryResponse) *MockProvider_Discovery_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockProvider_Discovery_Call) RunAndReturn(run func() *service.DiscoveryResponse) *MockProvider_Discovery_Call {
_c.Call.Return(run)
return _c
}
// Exchange provides a mock function with given fields: req
func (_m *MockProvider) Exchange(req service.TokenRequest) (*service.TokenResponse, error) {
ret := _m.Called(req)
if len(ret) == 0 {
panic("no return value specified for Exchange")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(service.TokenRequest) (*service.TokenResponse, error)); ok {
return rf(req)
}
if rf, ok := ret.Get(0).(func(service.TokenRequest) *service.TokenResponse); ok {
r0 = rf(req)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(service.TokenRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_Exchange_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Exchange'
type MockProvider_Exchange_Call struct {
*mock.Call
}
// Exchange is a helper method to define mock.On call
// - req service.TokenRequest
func (_e *MockProvider_Expecter) Exchange(req interface{}) *MockProvider_Exchange_Call {
return &MockProvider_Exchange_Call{Call: _e.mock.On("Exchange", req)}
}
func (_c *MockProvider_Exchange_Call) Run(run func(req service.TokenRequest)) *MockProvider_Exchange_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(service.TokenRequest))
})
return _c
}
func (_c *MockProvider_Exchange_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockProvider_Exchange_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockProvider_Exchange_Call) RunAndReturn(run func(service.TokenRequest) (*service.TokenResponse, error)) *MockProvider_Exchange_Call {
_c.Call.Return(run)
return _c
}
// GetCertificates provides a mock function with no fields
func (_m *MockProvider) GetCertificates() *service.CertificatesResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for GetCertificates")
}
var r0 *service.CertificatesResponse
if rf, ok := ret.Get(0).(func() *service.CertificatesResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.CertificatesResponse)
}
}
return r0
}
// MockProvider_GetCertificates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCertificates'
type MockProvider_GetCertificates_Call struct {
*mock.Call
}
// GetCertificates is a helper method to define mock.On call
func (_e *MockProvider_Expecter) GetCertificates() *MockProvider_GetCertificates_Call {
return &MockProvider_GetCertificates_Call{Call: _e.mock.On("GetCertificates")}
}
func (_c *MockProvider_GetCertificates_Call) Run(run func()) *MockProvider_GetCertificates_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockProvider_GetCertificates_Call) Return(_a0 *service.CertificatesResponse) *MockProvider_GetCertificates_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockProvider_GetCertificates_Call) RunAndReturn(run func() *service.CertificatesResponse) *MockProvider_GetCertificates_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function with given fields: refreshToken
func (_m *MockProvider) Refresh(refreshToken string) (*service.TokenResponse, error) {
ret := _m.Called(refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(string) (*service.TokenResponse, error)); ok {
return rf(refreshToken)
}
if rf, ok := ret.Get(0).(func(string) *service.TokenResponse); ok {
r0 = rf(refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockProvider_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockProvider_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - refreshToken string
func (_e *MockProvider_Expecter) Refresh(refreshToken interface{}) *MockProvider_Refresh_Call {
return &MockProvider_Refresh_Call{Call: _e.mock.On("Refresh", refreshToken)}
}
func (_c *MockProvider_Refresh_Call) Run(run func(refreshToken string)) *MockProvider_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockProvider_Refresh_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockProvider_Refresh_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockProvider_Refresh_Call) RunAndReturn(run func(string) (*service.TokenResponse, error)) *MockProvider_Refresh_Call {
_c.Call.Return(run)
return _c
}
// NewMockProvider creates a new instance of MockProvider. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockProvider(t interface {
mock.TestingT
Cleanup(func())
}) *MockProvider {
mock := &MockProvider{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,487 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package service_mock
import (
service "github.com/int128/kubelogin/integration_test/oidcserver/service"
testconfig "github.com/int128/kubelogin/integration_test/oidcserver/testconfig"
mock "github.com/stretchr/testify/mock"
)
// MockService is an autogenerated mock type for the Service type
type MockService struct {
mock.Mock
}
type MockService_Expecter struct {
mock *mock.Mock
}
func (_m *MockService) EXPECT() *MockService_Expecter {
return &MockService_Expecter{mock: &_m.Mock}
}
// AuthenticateCode provides a mock function with given fields: req
func (_m *MockService) AuthenticateCode(req service.AuthenticationRequest) (string, error) {
ret := _m.Called(req)
if len(ret) == 0 {
panic("no return value specified for AuthenticateCode")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(service.AuthenticationRequest) (string, error)); ok {
return rf(req)
}
if rf, ok := ret.Get(0).(func(service.AuthenticationRequest) string); ok {
r0 = rf(req)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(service.AuthenticationRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_AuthenticateCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticateCode'
type MockService_AuthenticateCode_Call struct {
*mock.Call
}
// AuthenticateCode is a helper method to define mock.On call
// - req service.AuthenticationRequest
func (_e *MockService_Expecter) AuthenticateCode(req interface{}) *MockService_AuthenticateCode_Call {
return &MockService_AuthenticateCode_Call{Call: _e.mock.On("AuthenticateCode", req)}
}
func (_c *MockService_AuthenticateCode_Call) Run(run func(req service.AuthenticationRequest)) *MockService_AuthenticateCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(service.AuthenticationRequest))
})
return _c
}
func (_c *MockService_AuthenticateCode_Call) Return(code string, err error) *MockService_AuthenticateCode_Call {
_c.Call.Return(code, err)
return _c
}
func (_c *MockService_AuthenticateCode_Call) RunAndReturn(run func(service.AuthenticationRequest) (string, error)) *MockService_AuthenticateCode_Call {
_c.Call.Return(run)
return _c
}
// AuthenticatePassword provides a mock function with given fields: username, password, scope
func (_m *MockService) AuthenticatePassword(username string, password string, scope string) (*service.TokenResponse, error) {
ret := _m.Called(username, password, scope)
if len(ret) == 0 {
panic("no return value specified for AuthenticatePassword")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(string, string, string) (*service.TokenResponse, error)); ok {
return rf(username, password, scope)
}
if rf, ok := ret.Get(0).(func(string, string, string) *service.TokenResponse); ok {
r0 = rf(username, password, scope)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(string, string, string) error); ok {
r1 = rf(username, password, scope)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_AuthenticatePassword_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AuthenticatePassword'
type MockService_AuthenticatePassword_Call struct {
*mock.Call
}
// AuthenticatePassword is a helper method to define mock.On call
// - username string
// - password string
// - scope string
func (_e *MockService_Expecter) AuthenticatePassword(username interface{}, password interface{}, scope interface{}) *MockService_AuthenticatePassword_Call {
return &MockService_AuthenticatePassword_Call{Call: _e.mock.On("AuthenticatePassword", username, password, scope)}
}
func (_c *MockService_AuthenticatePassword_Call) Run(run func(username string, password string, scope string)) *MockService_AuthenticatePassword_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockService_AuthenticatePassword_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockService_AuthenticatePassword_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_AuthenticatePassword_Call) RunAndReturn(run func(string, string, string) (*service.TokenResponse, error)) *MockService_AuthenticatePassword_Call {
_c.Call.Return(run)
return _c
}
// Discovery provides a mock function with no fields
func (_m *MockService) Discovery() *service.DiscoveryResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Discovery")
}
var r0 *service.DiscoveryResponse
if rf, ok := ret.Get(0).(func() *service.DiscoveryResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.DiscoveryResponse)
}
}
return r0
}
// MockService_Discovery_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Discovery'
type MockService_Discovery_Call struct {
*mock.Call
}
// Discovery is a helper method to define mock.On call
func (_e *MockService_Expecter) Discovery() *MockService_Discovery_Call {
return &MockService_Discovery_Call{Call: _e.mock.On("Discovery")}
}
func (_c *MockService_Discovery_Call) Run(run func()) *MockService_Discovery_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_Discovery_Call) Return(_a0 *service.DiscoveryResponse) *MockService_Discovery_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_Discovery_Call) RunAndReturn(run func() *service.DiscoveryResponse) *MockService_Discovery_Call {
_c.Call.Return(run)
return _c
}
// Exchange provides a mock function with given fields: req
func (_m *MockService) Exchange(req service.TokenRequest) (*service.TokenResponse, error) {
ret := _m.Called(req)
if len(ret) == 0 {
panic("no return value specified for Exchange")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(service.TokenRequest) (*service.TokenResponse, error)); ok {
return rf(req)
}
if rf, ok := ret.Get(0).(func(service.TokenRequest) *service.TokenResponse); ok {
r0 = rf(req)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(service.TokenRequest) error); ok {
r1 = rf(req)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_Exchange_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Exchange'
type MockService_Exchange_Call struct {
*mock.Call
}
// Exchange is a helper method to define mock.On call
// - req service.TokenRequest
func (_e *MockService_Expecter) Exchange(req interface{}) *MockService_Exchange_Call {
return &MockService_Exchange_Call{Call: _e.mock.On("Exchange", req)}
}
func (_c *MockService_Exchange_Call) Run(run func(req service.TokenRequest)) *MockService_Exchange_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(service.TokenRequest))
})
return _c
}
func (_c *MockService_Exchange_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockService_Exchange_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_Exchange_Call) RunAndReturn(run func(service.TokenRequest) (*service.TokenResponse, error)) *MockService_Exchange_Call {
_c.Call.Return(run)
return _c
}
// GetCertificates provides a mock function with no fields
func (_m *MockService) GetCertificates() *service.CertificatesResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for GetCertificates")
}
var r0 *service.CertificatesResponse
if rf, ok := ret.Get(0).(func() *service.CertificatesResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.CertificatesResponse)
}
}
return r0
}
// MockService_GetCertificates_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCertificates'
type MockService_GetCertificates_Call struct {
*mock.Call
}
// GetCertificates is a helper method to define mock.On call
func (_e *MockService_Expecter) GetCertificates() *MockService_GetCertificates_Call {
return &MockService_GetCertificates_Call{Call: _e.mock.On("GetCertificates")}
}
func (_c *MockService_GetCertificates_Call) Run(run func()) *MockService_GetCertificates_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_GetCertificates_Call) Return(_a0 *service.CertificatesResponse) *MockService_GetCertificates_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_GetCertificates_Call) RunAndReturn(run func() *service.CertificatesResponse) *MockService_GetCertificates_Call {
_c.Call.Return(run)
return _c
}
// IssuerURL provides a mock function with no fields
func (_m *MockService) IssuerURL() string {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for IssuerURL")
}
var r0 string
if rf, ok := ret.Get(0).(func() string); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// MockService_IssuerURL_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IssuerURL'
type MockService_IssuerURL_Call struct {
*mock.Call
}
// IssuerURL is a helper method to define mock.On call
func (_e *MockService_Expecter) IssuerURL() *MockService_IssuerURL_Call {
return &MockService_IssuerURL_Call{Call: _e.mock.On("IssuerURL")}
}
func (_c *MockService_IssuerURL_Call) Run(run func()) *MockService_IssuerURL_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_IssuerURL_Call) Return(_a0 string) *MockService_IssuerURL_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_IssuerURL_Call) RunAndReturn(run func() string) *MockService_IssuerURL_Call {
_c.Call.Return(run)
return _c
}
// LastTokenResponse provides a mock function with no fields
func (_m *MockService) LastTokenResponse() *service.TokenResponse {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for LastTokenResponse")
}
var r0 *service.TokenResponse
if rf, ok := ret.Get(0).(func() *service.TokenResponse); ok {
r0 = rf()
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
return r0
}
// MockService_LastTokenResponse_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'LastTokenResponse'
type MockService_LastTokenResponse_Call struct {
*mock.Call
}
// LastTokenResponse is a helper method to define mock.On call
func (_e *MockService_Expecter) LastTokenResponse() *MockService_LastTokenResponse_Call {
return &MockService_LastTokenResponse_Call{Call: _e.mock.On("LastTokenResponse")}
}
func (_c *MockService_LastTokenResponse_Call) Run(run func()) *MockService_LastTokenResponse_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockService_LastTokenResponse_Call) Return(_a0 *service.TokenResponse) *MockService_LastTokenResponse_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockService_LastTokenResponse_Call) RunAndReturn(run func() *service.TokenResponse) *MockService_LastTokenResponse_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function with given fields: refreshToken
func (_m *MockService) Refresh(refreshToken string) (*service.TokenResponse, error) {
ret := _m.Called(refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *service.TokenResponse
var r1 error
if rf, ok := ret.Get(0).(func(string) (*service.TokenResponse, error)); ok {
return rf(refreshToken)
}
if rf, ok := ret.Get(0).(func(string) *service.TokenResponse); ok {
r0 = rf(refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*service.TokenResponse)
}
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockService_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockService_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - refreshToken string
func (_e *MockService_Expecter) Refresh(refreshToken interface{}) *MockService_Refresh_Call {
return &MockService_Refresh_Call{Call: _e.mock.On("Refresh", refreshToken)}
}
func (_c *MockService_Refresh_Call) Run(run func(refreshToken string)) *MockService_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockService_Refresh_Call) Return(_a0 *service.TokenResponse, _a1 error) *MockService_Refresh_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockService_Refresh_Call) RunAndReturn(run func(string) (*service.TokenResponse, error)) *MockService_Refresh_Call {
_c.Call.Return(run)
return _c
}
// SetConfig provides a mock function with given fields: config
func (_m *MockService) SetConfig(config testconfig.Config) {
_m.Called(config)
}
// MockService_SetConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'SetConfig'
type MockService_SetConfig_Call struct {
*mock.Call
}
// SetConfig is a helper method to define mock.On call
// - config testconfig.Config
func (_e *MockService_Expecter) SetConfig(config interface{}) *MockService_SetConfig_Call {
return &MockService_SetConfig_Call{Call: _e.mock.On("SetConfig", config)}
}
func (_c *MockService_SetConfig_Call) Run(run func(config testconfig.Config)) *MockService_SetConfig_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(testconfig.Config))
})
return _c
}
func (_c *MockService_SetConfig_Call) Return() *MockService_SetConfig_Call {
_c.Call.Return()
return _c
}
func (_c *MockService_SetConfig_Call) RunAndReturn(run func(testconfig.Config)) *MockService_SetConfig_Call {
_c.Run(run)
return _c
}
// NewMockService creates a new instance of MockService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockService(t interface {
mock.TestingT
Cleanup(func())
}) *MockService {
mock := &MockService{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,84 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package cmd_mock
import (
context "context"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Run provides a mock function with given fields: ctx, args, version
func (_m *MockInterface) Run(ctx context.Context, args []string, version string) int {
ret := _m.Called(ctx, args, version)
if len(ret) == 0 {
panic("no return value specified for Run")
}
var r0 int
if rf, ok := ret.Get(0).(func(context.Context, []string, string) int); ok {
r0 = rf(ctx, args, version)
} else {
r0 = ret.Get(0).(int)
}
return r0
}
// MockInterface_Run_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Run'
type MockInterface_Run_Call struct {
*mock.Call
}
// Run is a helper method to define mock.On call
// - ctx context.Context
// - args []string
// - version string
func (_e *MockInterface_Expecter) Run(ctx interface{}, args interface{}, version interface{}) *MockInterface_Run_Call {
return &MockInterface_Run_Call{Call: _e.mock.On("Run", ctx, args, version)}
}
func (_c *MockInterface_Run_Call) Run(run func(ctx context.Context, args []string, version string)) *MockInterface_Run_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].([]string), args[2].(string))
})
return _c
}
func (_c *MockInterface_Run_Call) Return(_a0 int) *MockInterface_Run_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Run_Call) RunAndReturn(run func(context.Context, []string, string) int) *MockInterface_Run_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,90 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package reader_mock
import (
credentialplugin "github.com/int128/kubelogin/pkg/credentialplugin"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Read provides a mock function with no fields
func (_m *MockInterface) Read() (credentialplugin.Input, error) {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Read")
}
var r0 credentialplugin.Input
var r1 error
if rf, ok := ret.Get(0).(func() (credentialplugin.Input, error)); ok {
return rf()
}
if rf, ok := ret.Get(0).(func() credentialplugin.Input); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(credentialplugin.Input)
}
if rf, ok := ret.Get(1).(func() error); ok {
r1 = rf()
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Read_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Read'
type MockInterface_Read_Call struct {
*mock.Call
}
// Read is a helper method to define mock.On call
func (_e *MockInterface_Expecter) Read() *MockInterface_Read_Call {
return &MockInterface_Read_Call{Call: _e.mock.On("Read")}
}
func (_c *MockInterface_Read_Call) Run(run func()) *MockInterface_Read_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockInterface_Read_Call) Return(_a0 credentialplugin.Input, _a1 error) *MockInterface_Read_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_Read_Call) RunAndReturn(run func() (credentialplugin.Input, error)) *MockInterface_Read_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,81 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package writer_mock
import (
credentialplugin "github.com/int128/kubelogin/pkg/credentialplugin"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Write provides a mock function with given fields: out
func (_m *MockInterface) Write(out credentialplugin.Output) error {
ret := _m.Called(out)
if len(ret) == 0 {
panic("no return value specified for Write")
}
var r0 error
if rf, ok := ret.Get(0).(func(credentialplugin.Output) error); ok {
r0 = rf(out)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write'
type MockInterface_Write_Call struct {
*mock.Call
}
// Write is a helper method to define mock.On call
// - out credentialplugin.Output
func (_e *MockInterface_Expecter) Write(out interface{}) *MockInterface_Write_Call {
return &MockInterface_Write_Call{Call: _e.mock.On("Write", out)}
}
func (_c *MockInterface_Write_Call) Run(run func(out credentialplugin.Output)) *MockInterface_Write_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(credentialplugin.Output))
})
return _c
}
func (_c *MockInterface_Write_Call) Return(_a0 error) *MockInterface_Write_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Write_Call) RunAndReturn(run func(credentialplugin.Output) error) *MockInterface_Write_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,130 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package browser_mock
import (
context "context"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Open provides a mock function with given fields: url
func (_m *MockInterface) Open(url string) error {
ret := _m.Called(url)
if len(ret) == 0 {
panic("no return value specified for Open")
}
var r0 error
if rf, ok := ret.Get(0).(func(string) error); ok {
r0 = rf(url)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Open_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Open'
type MockInterface_Open_Call struct {
*mock.Call
}
// Open is a helper method to define mock.On call
// - url string
func (_e *MockInterface_Expecter) Open(url interface{}) *MockInterface_Open_Call {
return &MockInterface_Open_Call{Call: _e.mock.On("Open", url)}
}
func (_c *MockInterface_Open_Call) Run(run func(url string)) *MockInterface_Open_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockInterface_Open_Call) Return(_a0 error) *MockInterface_Open_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Open_Call) RunAndReturn(run func(string) error) *MockInterface_Open_Call {
_c.Call.Return(run)
return _c
}
// OpenCommand provides a mock function with given fields: ctx, url, command
func (_m *MockInterface) OpenCommand(ctx context.Context, url string, command string) error {
ret := _m.Called(ctx, url, command)
if len(ret) == 0 {
panic("no return value specified for OpenCommand")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) error); ok {
r0 = rf(ctx, url, command)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_OpenCommand_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'OpenCommand'
type MockInterface_OpenCommand_Call struct {
*mock.Call
}
// OpenCommand is a helper method to define mock.On call
// - ctx context.Context
// - url string
// - command string
func (_e *MockInterface_Expecter) OpenCommand(ctx interface{}, url interface{}, command interface{}) *MockInterface_OpenCommand_Call {
return &MockInterface_OpenCommand_Call{Call: _e.mock.On("OpenCommand", ctx, url, command)}
}
func (_c *MockInterface_OpenCommand_Call) Run(run func(ctx context.Context, url string, command string)) *MockInterface_OpenCommand_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockInterface_OpenCommand_Call) Return(_a0 error) *MockInterface_OpenCommand_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_OpenCommand_Call) RunAndReturn(run func(context.Context, string, string) error) *MockInterface_OpenCommand_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,81 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package clock_mock
import (
time "time"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Now provides a mock function with no fields
func (_m *MockInterface) Now() time.Time {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Now")
}
var r0 time.Time
if rf, ok := ret.Get(0).(func() time.Time); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(time.Time)
}
return r0
}
// MockInterface_Now_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Now'
type MockInterface_Now_Call struct {
*mock.Call
}
// Now is a helper method to define mock.On call
func (_e *MockInterface_Expecter) Now() *MockInterface_Now_Call {
return &MockInterface_Now_Call{Call: _e.mock.On("Now")}
}
func (_c *MockInterface_Now_Call) Run(run func()) *MockInterface_Now_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockInterface_Now_Call) Return(_a0 time.Time) *MockInterface_Now_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Now_Call) RunAndReturn(run func() time.Time) *MockInterface_Now_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,208 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package logger_mock
import (
logger "github.com/int128/kubelogin/pkg/infrastructure/logger"
mock "github.com/stretchr/testify/mock"
pflag "github.com/spf13/pflag"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// AddFlags provides a mock function with given fields: f
func (_m *MockInterface) AddFlags(f *pflag.FlagSet) {
_m.Called(f)
}
// MockInterface_AddFlags_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AddFlags'
type MockInterface_AddFlags_Call struct {
*mock.Call
}
// AddFlags is a helper method to define mock.On call
// - f *pflag.FlagSet
func (_e *MockInterface_Expecter) AddFlags(f interface{}) *MockInterface_AddFlags_Call {
return &MockInterface_AddFlags_Call{Call: _e.mock.On("AddFlags", f)}
}
func (_c *MockInterface_AddFlags_Call) Run(run func(f *pflag.FlagSet)) *MockInterface_AddFlags_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(*pflag.FlagSet))
})
return _c
}
func (_c *MockInterface_AddFlags_Call) Return() *MockInterface_AddFlags_Call {
_c.Call.Return()
return _c
}
func (_c *MockInterface_AddFlags_Call) RunAndReturn(run func(*pflag.FlagSet)) *MockInterface_AddFlags_Call {
_c.Run(run)
return _c
}
// IsEnabled provides a mock function with given fields: level
func (_m *MockInterface) IsEnabled(level int) bool {
ret := _m.Called(level)
if len(ret) == 0 {
panic("no return value specified for IsEnabled")
}
var r0 bool
if rf, ok := ret.Get(0).(func(int) bool); ok {
r0 = rf(level)
} else {
r0 = ret.Get(0).(bool)
}
return r0
}
// MockInterface_IsEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsEnabled'
type MockInterface_IsEnabled_Call struct {
*mock.Call
}
// IsEnabled is a helper method to define mock.On call
// - level int
func (_e *MockInterface_Expecter) IsEnabled(level interface{}) *MockInterface_IsEnabled_Call {
return &MockInterface_IsEnabled_Call{Call: _e.mock.On("IsEnabled", level)}
}
func (_c *MockInterface_IsEnabled_Call) Run(run func(level int)) *MockInterface_IsEnabled_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(int))
})
return _c
}
func (_c *MockInterface_IsEnabled_Call) Return(_a0 bool) *MockInterface_IsEnabled_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_IsEnabled_Call) RunAndReturn(run func(int) bool) *MockInterface_IsEnabled_Call {
_c.Call.Return(run)
return _c
}
// Printf provides a mock function with given fields: format, args
func (_m *MockInterface) Printf(format string, args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, format)
_ca = append(_ca, args...)
_m.Called(_ca...)
}
// MockInterface_Printf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Printf'
type MockInterface_Printf_Call struct {
*mock.Call
}
// Printf is a helper method to define mock.On call
// - format string
// - args ...interface{}
func (_e *MockInterface_Expecter) Printf(format interface{}, args ...interface{}) *MockInterface_Printf_Call {
return &MockInterface_Printf_Call{Call: _e.mock.On("Printf",
append([]interface{}{format}, args...)...)}
}
func (_c *MockInterface_Printf_Call) Run(run func(format string, args ...interface{})) *MockInterface_Printf_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]interface{}, len(args)-1)
for i, a := range args[1:] {
if a != nil {
variadicArgs[i] = a.(interface{})
}
}
run(args[0].(string), variadicArgs...)
})
return _c
}
func (_c *MockInterface_Printf_Call) Return() *MockInterface_Printf_Call {
_c.Call.Return()
return _c
}
func (_c *MockInterface_Printf_Call) RunAndReturn(run func(string, ...interface{})) *MockInterface_Printf_Call {
_c.Run(run)
return _c
}
// V provides a mock function with given fields: level
func (_m *MockInterface) V(level int) logger.Verbose {
ret := _m.Called(level)
if len(ret) == 0 {
panic("no return value specified for V")
}
var r0 logger.Verbose
if rf, ok := ret.Get(0).(func(int) logger.Verbose); ok {
r0 = rf(level)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(logger.Verbose)
}
}
return r0
}
// MockInterface_V_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'V'
type MockInterface_V_Call struct {
*mock.Call
}
// V is a helper method to define mock.On call
// - level int
func (_e *MockInterface_Expecter) V(level interface{}) *MockInterface_V_Call {
return &MockInterface_V_Call{Call: _e.mock.On("V", level)}
}
func (_c *MockInterface_V_Call) Run(run func(level int)) *MockInterface_V_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(int))
})
return _c
}
func (_c *MockInterface_V_Call) Return(_a0 logger.Verbose) *MockInterface_V_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_V_Call) RunAndReturn(run func(int) logger.Verbose) *MockInterface_V_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,76 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package logger_mock
import mock "github.com/stretchr/testify/mock"
// MockVerbose is an autogenerated mock type for the Verbose type
type MockVerbose struct {
mock.Mock
}
type MockVerbose_Expecter struct {
mock *mock.Mock
}
func (_m *MockVerbose) EXPECT() *MockVerbose_Expecter {
return &MockVerbose_Expecter{mock: &_m.Mock}
}
// Infof provides a mock function with given fields: format, args
func (_m *MockVerbose) Infof(format string, args ...interface{}) {
var _ca []interface{}
_ca = append(_ca, format)
_ca = append(_ca, args...)
_m.Called(_ca...)
}
// MockVerbose_Infof_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Infof'
type MockVerbose_Infof_Call struct {
*mock.Call
}
// Infof is a helper method to define mock.On call
// - format string
// - args ...interface{}
func (_e *MockVerbose_Expecter) Infof(format interface{}, args ...interface{}) *MockVerbose_Infof_Call {
return &MockVerbose_Infof_Call{Call: _e.mock.On("Infof",
append([]interface{}{format}, args...)...)}
}
func (_c *MockVerbose_Infof_Call) Run(run func(format string, args ...interface{})) *MockVerbose_Infof_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]interface{}, len(args)-1)
for i, a := range args[1:] {
if a != nil {
variadicArgs[i] = a.(interface{})
}
}
run(args[0].(string), variadicArgs...)
})
return _c
}
func (_c *MockVerbose_Infof_Call) Return() *MockVerbose_Infof_Call {
_c.Call.Return()
return _c
}
func (_c *MockVerbose_Infof_Call) RunAndReturn(run func(string, ...interface{})) *MockVerbose_Infof_Call {
_c.Run(run)
return _c
}
// NewMockVerbose creates a new instance of MockVerbose. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockVerbose(t interface {
mock.TestingT
Cleanup(func())
}) *MockVerbose {
mock := &MockVerbose{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,76 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package logger_mock
import mock "github.com/stretchr/testify/mock"
// MockgoLogger is an autogenerated mock type for the goLogger type
type MockgoLogger struct {
mock.Mock
}
type MockgoLogger_Expecter struct {
mock *mock.Mock
}
func (_m *MockgoLogger) EXPECT() *MockgoLogger_Expecter {
return &MockgoLogger_Expecter{mock: &_m.Mock}
}
// Printf provides a mock function with given fields: format, v
func (_m *MockgoLogger) Printf(format string, v ...interface{}) {
var _ca []interface{}
_ca = append(_ca, format)
_ca = append(_ca, v...)
_m.Called(_ca...)
}
// MockgoLogger_Printf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Printf'
type MockgoLogger_Printf_Call struct {
*mock.Call
}
// Printf is a helper method to define mock.On call
// - format string
// - v ...interface{}
func (_e *MockgoLogger_Expecter) Printf(format interface{}, v ...interface{}) *MockgoLogger_Printf_Call {
return &MockgoLogger_Printf_Call{Call: _e.mock.On("Printf",
append([]interface{}{format}, v...)...)}
}
func (_c *MockgoLogger_Printf_Call) Run(run func(format string, v ...interface{})) *MockgoLogger_Printf_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]interface{}, len(args)-1)
for i, a := range args[1:] {
if a != nil {
variadicArgs[i] = a.(interface{})
}
}
run(args[0].(string), variadicArgs...)
})
return _c
}
func (_c *MockgoLogger_Printf_Call) Return() *MockgoLogger_Printf_Call {
_c.Call.Return()
return _c
}
func (_c *MockgoLogger_Printf_Call) RunAndReturn(run func(string, ...interface{})) *MockgoLogger_Printf_Call {
_c.Run(run)
return _c
}
// NewMockgoLogger creates a new instance of MockgoLogger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockgoLogger(t interface {
mock.TestingT
Cleanup(func())
}) *MockgoLogger {
mock := &MockgoLogger{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,144 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package reader_mock
import mock "github.com/stretchr/testify/mock"
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// ReadPassword provides a mock function with given fields: prompt
func (_m *MockInterface) ReadPassword(prompt string) (string, error) {
ret := _m.Called(prompt)
if len(ret) == 0 {
panic("no return value specified for ReadPassword")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
return rf(prompt)
}
if rf, ok := ret.Get(0).(func(string) string); ok {
r0 = rf(prompt)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(prompt)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_ReadPassword_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadPassword'
type MockInterface_ReadPassword_Call struct {
*mock.Call
}
// ReadPassword is a helper method to define mock.On call
// - prompt string
func (_e *MockInterface_Expecter) ReadPassword(prompt interface{}) *MockInterface_ReadPassword_Call {
return &MockInterface_ReadPassword_Call{Call: _e.mock.On("ReadPassword", prompt)}
}
func (_c *MockInterface_ReadPassword_Call) Run(run func(prompt string)) *MockInterface_ReadPassword_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockInterface_ReadPassword_Call) Return(_a0 string, _a1 error) *MockInterface_ReadPassword_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_ReadPassword_Call) RunAndReturn(run func(string) (string, error)) *MockInterface_ReadPassword_Call {
_c.Call.Return(run)
return _c
}
// ReadString provides a mock function with given fields: prompt
func (_m *MockInterface) ReadString(prompt string) (string, error) {
ret := _m.Called(prompt)
if len(ret) == 0 {
panic("no return value specified for ReadString")
}
var r0 string
var r1 error
if rf, ok := ret.Get(0).(func(string) (string, error)); ok {
return rf(prompt)
}
if rf, ok := ret.Get(0).(func(string) string); ok {
r0 = rf(prompt)
} else {
r0 = ret.Get(0).(string)
}
if rf, ok := ret.Get(1).(func(string) error); ok {
r1 = rf(prompt)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_ReadString_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ReadString'
type MockInterface_ReadString_Call struct {
*mock.Call
}
// ReadString is a helper method to define mock.On call
// - prompt string
func (_e *MockInterface_Expecter) ReadString(prompt interface{}) *MockInterface_ReadString_Call {
return &MockInterface_ReadString_Call{Call: _e.mock.On("ReadString", prompt)}
}
func (_c *MockInterface_ReadString_Call) Run(run func(prompt string)) *MockInterface_ReadString_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string))
})
return _c
}
func (_c *MockInterface_ReadString_Call) Return(_a0 string, _a1 error) *MockInterface_ReadString_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_ReadString_Call) RunAndReturn(run func(string) (string, error)) *MockInterface_ReadString_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,88 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package stdio_mock
import mock "github.com/stretchr/testify/mock"
// MockStdin is an autogenerated mock type for the Stdin type
type MockStdin struct {
mock.Mock
}
type MockStdin_Expecter struct {
mock *mock.Mock
}
func (_m *MockStdin) EXPECT() *MockStdin_Expecter {
return &MockStdin_Expecter{mock: &_m.Mock}
}
// Read provides a mock function with given fields: p
func (_m *MockStdin) Read(p []byte) (int, error) {
ret := _m.Called(p)
if len(ret) == 0 {
panic("no return value specified for Read")
}
var r0 int
var r1 error
if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok {
return rf(p)
}
if rf, ok := ret.Get(0).(func([]byte) int); ok {
r0 = rf(p)
} else {
r0 = ret.Get(0).(int)
}
if rf, ok := ret.Get(1).(func([]byte) error); ok {
r1 = rf(p)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockStdin_Read_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Read'
type MockStdin_Read_Call struct {
*mock.Call
}
// Read is a helper method to define mock.On call
// - p []byte
func (_e *MockStdin_Expecter) Read(p interface{}) *MockStdin_Read_Call {
return &MockStdin_Read_Call{Call: _e.mock.On("Read", p)}
}
func (_c *MockStdin_Read_Call) Run(run func(p []byte)) *MockStdin_Read_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].([]byte))
})
return _c
}
func (_c *MockStdin_Read_Call) Return(n int, err error) *MockStdin_Read_Call {
_c.Call.Return(n, err)
return _c
}
func (_c *MockStdin_Read_Call) RunAndReturn(run func([]byte) (int, error)) *MockStdin_Read_Call {
_c.Call.Return(run)
return _c
}
// NewMockStdin creates a new instance of MockStdin. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockStdin(t interface {
mock.TestingT
Cleanup(func())
}) *MockStdin {
mock := &MockStdin{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,88 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package stdio_mock
import mock "github.com/stretchr/testify/mock"
// MockStdout is an autogenerated mock type for the Stdout type
type MockStdout struct {
mock.Mock
}
type MockStdout_Expecter struct {
mock *mock.Mock
}
func (_m *MockStdout) EXPECT() *MockStdout_Expecter {
return &MockStdout_Expecter{mock: &_m.Mock}
}
// Write provides a mock function with given fields: p
func (_m *MockStdout) Write(p []byte) (int, error) {
ret := _m.Called(p)
if len(ret) == 0 {
panic("no return value specified for Write")
}
var r0 int
var r1 error
if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok {
return rf(p)
}
if rf, ok := ret.Get(0).(func([]byte) int); ok {
r0 = rf(p)
} else {
r0 = ret.Get(0).(int)
}
if rf, ok := ret.Get(1).(func([]byte) error); ok {
r1 = rf(p)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockStdout_Write_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Write'
type MockStdout_Write_Call struct {
*mock.Call
}
// Write is a helper method to define mock.On call
// - p []byte
func (_e *MockStdout_Expecter) Write(p interface{}) *MockStdout_Write_Call {
return &MockStdout_Write_Call{Call: _e.mock.On("Write", p)}
}
func (_c *MockStdout_Write_Call) Run(run func(p []byte)) *MockStdout_Write_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].([]byte))
})
return _c
}
func (_c *MockStdout_Write_Call) Return(n int, err error) *MockStdout_Write_Call {
_c.Call.Return(n, err)
return _c
}
func (_c *MockStdout_Write_Call) RunAndReturn(run func([]byte) (int, error)) *MockStdout_Write_Call {
_c.Call.Return(run)
return _c
}
// NewMockStdout creates a new instance of MockStdout. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockStdout(t interface {
mock.TestingT
Cleanup(func())
}) *MockStdout {
mock := &MockStdout{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,81 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package jwt_mock
import (
time "time"
mock "github.com/stretchr/testify/mock"
)
// MockClock is an autogenerated mock type for the Clock type
type MockClock struct {
mock.Mock
}
type MockClock_Expecter struct {
mock *mock.Mock
}
func (_m *MockClock) EXPECT() *MockClock_Expecter {
return &MockClock_Expecter{mock: &_m.Mock}
}
// Now provides a mock function with no fields
func (_m *MockClock) Now() time.Time {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Now")
}
var r0 time.Time
if rf, ok := ret.Get(0).(func() time.Time); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(time.Time)
}
return r0
}
// MockClock_Now_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Now'
type MockClock_Now_Call struct {
*mock.Call
}
// Now is a helper method to define mock.On call
func (_e *MockClock_Expecter) Now() *MockClock_Now_Call {
return &MockClock_Now_Call{Call: _e.mock.On("Now")}
}
func (_c *MockClock_Now_Call) Run(run func()) *MockClock_Now_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockClock_Now_Call) Return(_a0 time.Time) *MockClock_Now_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockClock_Now_Call) RunAndReturn(run func() time.Time) *MockClock_Now_Call {
_c.Call.Return(run)
return _c
}
// NewMockClock creates a new instance of MockClock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockClock(t interface {
mock.TestingT
Cleanup(func())
}) *MockClock {
mock := &MockClock{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,96 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package loader_mock
import (
kubeconfig "github.com/int128/kubelogin/pkg/kubeconfig"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// GetCurrentAuthProvider provides a mock function with given fields: explicitFilename, contextName, userName
func (_m *MockInterface) GetCurrentAuthProvider(explicitFilename string, contextName kubeconfig.ContextName, userName kubeconfig.UserName) (*kubeconfig.AuthProvider, error) {
ret := _m.Called(explicitFilename, contextName, userName)
if len(ret) == 0 {
panic("no return value specified for GetCurrentAuthProvider")
}
var r0 *kubeconfig.AuthProvider
var r1 error
if rf, ok := ret.Get(0).(func(string, kubeconfig.ContextName, kubeconfig.UserName) (*kubeconfig.AuthProvider, error)); ok {
return rf(explicitFilename, contextName, userName)
}
if rf, ok := ret.Get(0).(func(string, kubeconfig.ContextName, kubeconfig.UserName) *kubeconfig.AuthProvider); ok {
r0 = rf(explicitFilename, contextName, userName)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*kubeconfig.AuthProvider)
}
}
if rf, ok := ret.Get(1).(func(string, kubeconfig.ContextName, kubeconfig.UserName) error); ok {
r1 = rf(explicitFilename, contextName, userName)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetCurrentAuthProvider_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetCurrentAuthProvider'
type MockInterface_GetCurrentAuthProvider_Call struct {
*mock.Call
}
// GetCurrentAuthProvider is a helper method to define mock.On call
// - explicitFilename string
// - contextName kubeconfig.ContextName
// - userName kubeconfig.UserName
func (_e *MockInterface_Expecter) GetCurrentAuthProvider(explicitFilename interface{}, contextName interface{}, userName interface{}) *MockInterface_GetCurrentAuthProvider_Call {
return &MockInterface_GetCurrentAuthProvider_Call{Call: _e.mock.On("GetCurrentAuthProvider", explicitFilename, contextName, userName)}
}
func (_c *MockInterface_GetCurrentAuthProvider_Call) Run(run func(explicitFilename string, contextName kubeconfig.ContextName, userName kubeconfig.UserName)) *MockInterface_GetCurrentAuthProvider_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(string), args[1].(kubeconfig.ContextName), args[2].(kubeconfig.UserName))
})
return _c
}
func (_c *MockInterface_GetCurrentAuthProvider_Call) Return(_a0 *kubeconfig.AuthProvider, _a1 error) *MockInterface_GetCurrentAuthProvider_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_GetCurrentAuthProvider_Call) RunAndReturn(run func(string, kubeconfig.ContextName, kubeconfig.UserName) (*kubeconfig.AuthProvider, error)) *MockInterface_GetCurrentAuthProvider_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,81 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package writer_mock
import (
kubeconfig "github.com/int128/kubelogin/pkg/kubeconfig"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// UpdateAuthProvider provides a mock function with given fields: p
func (_m *MockInterface) UpdateAuthProvider(p kubeconfig.AuthProvider) error {
ret := _m.Called(p)
if len(ret) == 0 {
panic("no return value specified for UpdateAuthProvider")
}
var r0 error
if rf, ok := ret.Get(0).(func(kubeconfig.AuthProvider) error); ok {
r0 = rf(p)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_UpdateAuthProvider_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'UpdateAuthProvider'
type MockInterface_UpdateAuthProvider_Call struct {
*mock.Call
}
// UpdateAuthProvider is a helper method to define mock.On call
// - p kubeconfig.AuthProvider
func (_e *MockInterface_Expecter) UpdateAuthProvider(p interface{}) *MockInterface_UpdateAuthProvider_Call {
return &MockInterface_UpdateAuthProvider_Call{Call: _e.mock.On("UpdateAuthProvider", p)}
}
func (_c *MockInterface_UpdateAuthProvider_Call) Run(run func(p kubeconfig.AuthProvider)) *MockInterface_UpdateAuthProvider_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(kubeconfig.AuthProvider))
})
return _c
}
func (_c *MockInterface_UpdateAuthProvider_Call) Return(_a0 error) *MockInterface_UpdateAuthProvider_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_UpdateAuthProvider_Call) RunAndReturn(run func(kubeconfig.AuthProvider) error) *MockInterface_UpdateAuthProvider_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,102 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package client_mock
import (
context "context"
client "github.com/int128/kubelogin/pkg/oidc/client"
mock "github.com/stretchr/testify/mock"
oidc "github.com/int128/kubelogin/pkg/oidc"
tlsclientconfig "github.com/int128/kubelogin/pkg/tlsclientconfig"
)
// MockFactoryInterface is an autogenerated mock type for the FactoryInterface type
type MockFactoryInterface struct {
mock.Mock
}
type MockFactoryInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockFactoryInterface) EXPECT() *MockFactoryInterface_Expecter {
return &MockFactoryInterface_Expecter{mock: &_m.Mock}
}
// New provides a mock function with given fields: ctx, prov, tlsClientConfig
func (_m *MockFactoryInterface) New(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config) (client.Interface, error) {
ret := _m.Called(ctx, prov, tlsClientConfig)
if len(ret) == 0 {
panic("no return value specified for New")
}
var r0 client.Interface
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, oidc.Provider, tlsclientconfig.Config) (client.Interface, error)); ok {
return rf(ctx, prov, tlsClientConfig)
}
if rf, ok := ret.Get(0).(func(context.Context, oidc.Provider, tlsclientconfig.Config) client.Interface); ok {
r0 = rf(ctx, prov, tlsClientConfig)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(client.Interface)
}
}
if rf, ok := ret.Get(1).(func(context.Context, oidc.Provider, tlsclientconfig.Config) error); ok {
r1 = rf(ctx, prov, tlsClientConfig)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockFactoryInterface_New_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'New'
type MockFactoryInterface_New_Call struct {
*mock.Call
}
// New is a helper method to define mock.On call
// - ctx context.Context
// - prov oidc.Provider
// - tlsClientConfig tlsclientconfig.Config
func (_e *MockFactoryInterface_Expecter) New(ctx interface{}, prov interface{}, tlsClientConfig interface{}) *MockFactoryInterface_New_Call {
return &MockFactoryInterface_New_Call{Call: _e.mock.On("New", ctx, prov, tlsClientConfig)}
}
func (_c *MockFactoryInterface_New_Call) Run(run func(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config)) *MockFactoryInterface_New_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(oidc.Provider), args[2].(tlsclientconfig.Config))
})
return _c
}
func (_c *MockFactoryInterface_New_Call) Return(_a0 client.Interface, _a1 error) *MockFactoryInterface_New_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockFactoryInterface_New_Call) RunAndReturn(run func(context.Context, oidc.Provider, tlsclientconfig.Config) (client.Interface, error)) *MockFactoryInterface_New_Call {
_c.Call.Return(run)
return _c
}
// NewMockFactoryInterface creates a new instance of MockFactoryInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockFactoryInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockFactoryInterface {
mock := &MockFactoryInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,490 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package client_mock
import (
context "context"
client "github.com/int128/kubelogin/pkg/oidc/client"
mock "github.com/stretchr/testify/mock"
oauth2dev "github.com/int128/oauth2dev"
oidc "github.com/int128/kubelogin/pkg/oidc"
pkce "github.com/int128/kubelogin/pkg/pkce"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// ExchangeAuthCode provides a mock function with given fields: ctx, in
func (_m *MockInterface) ExchangeAuthCode(ctx context.Context, in client.ExchangeAuthCodeInput) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for ExchangeAuthCode")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, client.ExchangeAuthCodeInput) (*oidc.TokenSet, error)); ok {
return rf(ctx, in)
}
if rf, ok := ret.Get(0).(func(context.Context, client.ExchangeAuthCodeInput) *oidc.TokenSet); ok {
r0 = rf(ctx, in)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, client.ExchangeAuthCodeInput) error); ok {
r1 = rf(ctx, in)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_ExchangeAuthCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExchangeAuthCode'
type MockInterface_ExchangeAuthCode_Call struct {
*mock.Call
}
// ExchangeAuthCode is a helper method to define mock.On call
// - ctx context.Context
// - in client.ExchangeAuthCodeInput
func (_e *MockInterface_Expecter) ExchangeAuthCode(ctx interface{}, in interface{}) *MockInterface_ExchangeAuthCode_Call {
return &MockInterface_ExchangeAuthCode_Call{Call: _e.mock.On("ExchangeAuthCode", ctx, in)}
}
func (_c *MockInterface_ExchangeAuthCode_Call) Run(run func(ctx context.Context, in client.ExchangeAuthCodeInput)) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(client.ExchangeAuthCodeInput))
})
return _c
}
func (_c *MockInterface_ExchangeAuthCode_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_ExchangeAuthCode_Call) RunAndReturn(run func(context.Context, client.ExchangeAuthCodeInput) (*oidc.TokenSet, error)) *MockInterface_ExchangeAuthCode_Call {
_c.Call.Return(run)
return _c
}
// ExchangeDeviceCode provides a mock function with given fields: ctx, authResponse
func (_m *MockInterface) ExchangeDeviceCode(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, authResponse)
if len(ret) == 0 {
panic("no return value specified for ExchangeDeviceCode")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error)); ok {
return rf(ctx, authResponse)
}
if rf, ok := ret.Get(0).(func(context.Context, *oauth2dev.AuthorizationResponse) *oidc.TokenSet); ok {
r0 = rf(ctx, authResponse)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, *oauth2dev.AuthorizationResponse) error); ok {
r1 = rf(ctx, authResponse)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_ExchangeDeviceCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ExchangeDeviceCode'
type MockInterface_ExchangeDeviceCode_Call struct {
*mock.Call
}
// ExchangeDeviceCode is a helper method to define mock.On call
// - ctx context.Context
// - authResponse *oauth2dev.AuthorizationResponse
func (_e *MockInterface_Expecter) ExchangeDeviceCode(ctx interface{}, authResponse interface{}) *MockInterface_ExchangeDeviceCode_Call {
return &MockInterface_ExchangeDeviceCode_Call{Call: _e.mock.On("ExchangeDeviceCode", ctx, authResponse)}
}
func (_c *MockInterface_ExchangeDeviceCode_Call) Run(run func(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse)) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(*oauth2dev.AuthorizationResponse))
})
return _c
}
func (_c *MockInterface_ExchangeDeviceCode_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_ExchangeDeviceCode_Call) RunAndReturn(run func(context.Context, *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error)) *MockInterface_ExchangeDeviceCode_Call {
_c.Call.Return(run)
return _c
}
// GetAuthCodeURL provides a mock function with given fields: in
func (_m *MockInterface) GetAuthCodeURL(in client.AuthCodeURLInput) string {
ret := _m.Called(in)
if len(ret) == 0 {
panic("no return value specified for GetAuthCodeURL")
}
var r0 string
if rf, ok := ret.Get(0).(func(client.AuthCodeURLInput) string); ok {
r0 = rf(in)
} else {
r0 = ret.Get(0).(string)
}
return r0
}
// MockInterface_GetAuthCodeURL_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAuthCodeURL'
type MockInterface_GetAuthCodeURL_Call struct {
*mock.Call
}
// GetAuthCodeURL is a helper method to define mock.On call
// - in client.AuthCodeURLInput
func (_e *MockInterface_Expecter) GetAuthCodeURL(in interface{}) *MockInterface_GetAuthCodeURL_Call {
return &MockInterface_GetAuthCodeURL_Call{Call: _e.mock.On("GetAuthCodeURL", in)}
}
func (_c *MockInterface_GetAuthCodeURL_Call) Run(run func(in client.AuthCodeURLInput)) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(client.AuthCodeURLInput))
})
return _c
}
func (_c *MockInterface_GetAuthCodeURL_Call) Return(_a0 string) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_GetAuthCodeURL_Call) RunAndReturn(run func(client.AuthCodeURLInput) string) *MockInterface_GetAuthCodeURL_Call {
_c.Call.Return(run)
return _c
}
// GetDeviceAuthorization provides a mock function with given fields: ctx
func (_m *MockInterface) GetDeviceAuthorization(ctx context.Context) (*oauth2dev.AuthorizationResponse, error) {
ret := _m.Called(ctx)
if len(ret) == 0 {
panic("no return value specified for GetDeviceAuthorization")
}
var r0 *oauth2dev.AuthorizationResponse
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (*oauth2dev.AuthorizationResponse, error)); ok {
return rf(ctx)
}
if rf, ok := ret.Get(0).(func(context.Context) *oauth2dev.AuthorizationResponse); ok {
r0 = rf(ctx)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oauth2dev.AuthorizationResponse)
}
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(ctx)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetDeviceAuthorization_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetDeviceAuthorization'
type MockInterface_GetDeviceAuthorization_Call struct {
*mock.Call
}
// GetDeviceAuthorization is a helper method to define mock.On call
// - ctx context.Context
func (_e *MockInterface_Expecter) GetDeviceAuthorization(ctx interface{}) *MockInterface_GetDeviceAuthorization_Call {
return &MockInterface_GetDeviceAuthorization_Call{Call: _e.mock.On("GetDeviceAuthorization", ctx)}
}
func (_c *MockInterface_GetDeviceAuthorization_Call) Run(run func(ctx context.Context)) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context))
})
return _c
}
func (_c *MockInterface_GetDeviceAuthorization_Call) Return(_a0 *oauth2dev.AuthorizationResponse, _a1 error) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_GetDeviceAuthorization_Call) RunAndReturn(run func(context.Context) (*oauth2dev.AuthorizationResponse, error)) *MockInterface_GetDeviceAuthorization_Call {
_c.Call.Return(run)
return _c
}
// GetTokenByAuthCode provides a mock function with given fields: ctx, in, localServerReadyChan
func (_m *MockInterface) GetTokenByAuthCode(ctx context.Context, in client.GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, in, localServerReadyChan)
if len(ret) == 0 {
panic("no return value specified for GetTokenByAuthCode")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) (*oidc.TokenSet, error)); ok {
return rf(ctx, in, localServerReadyChan)
}
if rf, ok := ret.Get(0).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) *oidc.TokenSet); ok {
r0 = rf(ctx, in, localServerReadyChan)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) error); ok {
r1 = rf(ctx, in, localServerReadyChan)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetTokenByAuthCode_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenByAuthCode'
type MockInterface_GetTokenByAuthCode_Call struct {
*mock.Call
}
// GetTokenByAuthCode is a helper method to define mock.On call
// - ctx context.Context
// - in client.GetTokenByAuthCodeInput
// - localServerReadyChan chan<- string
func (_e *MockInterface_Expecter) GetTokenByAuthCode(ctx interface{}, in interface{}, localServerReadyChan interface{}) *MockInterface_GetTokenByAuthCode_Call {
return &MockInterface_GetTokenByAuthCode_Call{Call: _e.mock.On("GetTokenByAuthCode", ctx, in, localServerReadyChan)}
}
func (_c *MockInterface_GetTokenByAuthCode_Call) Run(run func(ctx context.Context, in client.GetTokenByAuthCodeInput, localServerReadyChan chan<- string)) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(client.GetTokenByAuthCodeInput), args[2].(chan<- string))
})
return _c
}
func (_c *MockInterface_GetTokenByAuthCode_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_GetTokenByAuthCode_Call) RunAndReturn(run func(context.Context, client.GetTokenByAuthCodeInput, chan<- string) (*oidc.TokenSet, error)) *MockInterface_GetTokenByAuthCode_Call {
_c.Call.Return(run)
return _c
}
// GetTokenByROPC provides a mock function with given fields: ctx, username, password
func (_m *MockInterface) GetTokenByROPC(ctx context.Context, username string, password string) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, username, password)
if len(ret) == 0 {
panic("no return value specified for GetTokenByROPC")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string) (*oidc.TokenSet, error)); ok {
return rf(ctx, username, password)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string) *oidc.TokenSet); ok {
r0 = rf(ctx, username, password)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string) error); ok {
r1 = rf(ctx, username, password)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_GetTokenByROPC_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetTokenByROPC'
type MockInterface_GetTokenByROPC_Call struct {
*mock.Call
}
// GetTokenByROPC is a helper method to define mock.On call
// - ctx context.Context
// - username string
// - password string
func (_e *MockInterface_Expecter) GetTokenByROPC(ctx interface{}, username interface{}, password interface{}) *MockInterface_GetTokenByROPC_Call {
return &MockInterface_GetTokenByROPC_Call{Call: _e.mock.On("GetTokenByROPC", ctx, username, password)}
}
func (_c *MockInterface_GetTokenByROPC_Call) Run(run func(ctx context.Context, username string, password string)) *MockInterface_GetTokenByROPC_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string), args[2].(string))
})
return _c
}
func (_c *MockInterface_GetTokenByROPC_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_GetTokenByROPC_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_GetTokenByROPC_Call) RunAndReturn(run func(context.Context, string, string) (*oidc.TokenSet, error)) *MockInterface_GetTokenByROPC_Call {
_c.Call.Return(run)
return _c
}
// NegotiatedPKCEMethod provides a mock function with no fields
func (_m *MockInterface) NegotiatedPKCEMethod() pkce.Method {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for NegotiatedPKCEMethod")
}
var r0 pkce.Method
if rf, ok := ret.Get(0).(func() pkce.Method); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(pkce.Method)
}
return r0
}
// MockInterface_NegotiatedPKCEMethod_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'NegotiatedPKCEMethod'
type MockInterface_NegotiatedPKCEMethod_Call struct {
*mock.Call
}
// NegotiatedPKCEMethod is a helper method to define mock.On call
func (_e *MockInterface_Expecter) NegotiatedPKCEMethod() *MockInterface_NegotiatedPKCEMethod_Call {
return &MockInterface_NegotiatedPKCEMethod_Call{Call: _e.mock.On("NegotiatedPKCEMethod")}
}
func (_c *MockInterface_NegotiatedPKCEMethod_Call) Run(run func()) *MockInterface_NegotiatedPKCEMethod_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockInterface_NegotiatedPKCEMethod_Call) Return(_a0 pkce.Method) *MockInterface_NegotiatedPKCEMethod_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_NegotiatedPKCEMethod_Call) RunAndReturn(run func() pkce.Method) *MockInterface_NegotiatedPKCEMethod_Call {
_c.Call.Return(run)
return _c
}
// Refresh provides a mock function with given fields: ctx, refreshToken
func (_m *MockInterface) Refresh(ctx context.Context, refreshToken string) (*oidc.TokenSet, error) {
ret := _m.Called(ctx, refreshToken)
if len(ret) == 0 {
panic("no return value specified for Refresh")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string) (*oidc.TokenSet, error)); ok {
return rf(ctx, refreshToken)
}
if rf, ok := ret.Get(0).(func(context.Context, string) *oidc.TokenSet); ok {
r0 = rf(ctx, refreshToken)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string) error); ok {
r1 = rf(ctx, refreshToken)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Refresh_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Refresh'
type MockInterface_Refresh_Call struct {
*mock.Call
}
// Refresh is a helper method to define mock.On call
// - ctx context.Context
// - refreshToken string
func (_e *MockInterface_Expecter) Refresh(ctx interface{}, refreshToken interface{}) *MockInterface_Refresh_Call {
return &MockInterface_Refresh_Call{Call: _e.mock.On("Refresh", ctx, refreshToken)}
}
func (_c *MockInterface_Refresh_Call) Run(run func(ctx context.Context, refreshToken string)) *MockInterface_Refresh_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(string))
})
return _c
}
func (_c *MockInterface_Refresh_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_Refresh_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_Refresh_Call) RunAndReturn(run func(context.Context, string) (*oidc.TokenSet, error)) *MockInterface_Refresh_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,76 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package logger_mock
import mock "github.com/stretchr/testify/mock"
// MocktestingLogger is an autogenerated mock type for the testingLogger type
type MocktestingLogger struct {
mock.Mock
}
type MocktestingLogger_Expecter struct {
mock *mock.Mock
}
func (_m *MocktestingLogger) EXPECT() *MocktestingLogger_Expecter {
return &MocktestingLogger_Expecter{mock: &_m.Mock}
}
// Logf provides a mock function with given fields: format, v
func (_m *MocktestingLogger) Logf(format string, v ...interface{}) {
var _ca []interface{}
_ca = append(_ca, format)
_ca = append(_ca, v...)
_m.Called(_ca...)
}
// MocktestingLogger_Logf_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Logf'
type MocktestingLogger_Logf_Call struct {
*mock.Call
}
// Logf is a helper method to define mock.On call
// - format string
// - v ...interface{}
func (_e *MocktestingLogger_Expecter) Logf(format interface{}, v ...interface{}) *MocktestingLogger_Logf_Call {
return &MocktestingLogger_Logf_Call{Call: _e.mock.On("Logf",
append([]interface{}{format}, v...)...)}
}
func (_c *MocktestingLogger_Logf_Call) Run(run func(format string, v ...interface{})) *MocktestingLogger_Logf_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]interface{}, len(args)-1)
for i, a := range args[1:] {
if a != nil {
variadicArgs[i] = a.(interface{})
}
}
run(args[0].(string), variadicArgs...)
})
return _c
}
func (_c *MocktestingLogger_Logf_Call) Return() *MocktestingLogger_Logf_Call {
_c.Call.Return()
return _c
}
func (_c *MocktestingLogger_Logf_Call) RunAndReturn(run func(string, ...interface{})) *MocktestingLogger_Logf_Call {
_c.Run(run)
return _c
}
// NewMocktestingLogger creates a new instance of MocktestingLogger. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMocktestingLogger(t interface {
mock.TestingT
Cleanup(func())
}) *MocktestingLogger {
mock := &MocktestingLogger{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,96 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package loader_mock
import (
tls "crypto/tls"
mock "github.com/stretchr/testify/mock"
tlsclientconfig "github.com/int128/kubelogin/pkg/tlsclientconfig"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Load provides a mock function with given fields: config
func (_m *MockInterface) Load(config tlsclientconfig.Config) (*tls.Config, error) {
ret := _m.Called(config)
if len(ret) == 0 {
panic("no return value specified for Load")
}
var r0 *tls.Config
var r1 error
if rf, ok := ret.Get(0).(func(tlsclientconfig.Config) (*tls.Config, error)); ok {
return rf(config)
}
if rf, ok := ret.Get(0).(func(tlsclientconfig.Config) *tls.Config); ok {
r0 = rf(config)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*tls.Config)
}
}
if rf, ok := ret.Get(1).(func(tlsclientconfig.Config) error); ok {
r1 = rf(config)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Load_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Load'
type MockInterface_Load_Call struct {
*mock.Call
}
// Load is a helper method to define mock.On call
// - config tlsclientconfig.Config
func (_e *MockInterface_Expecter) Load(config interface{}) *MockInterface_Load_Call {
return &MockInterface_Load_Call{Call: _e.mock.On("Load", config)}
}
func (_c *MockInterface_Load_Call) Run(run func(config tlsclientconfig.Config)) *MockInterface_Load_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(tlsclientconfig.Config))
})
return _c
}
func (_c *MockInterface_Load_Call) Return(_a0 *tls.Config, _a1 error) *MockInterface_Load_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_Load_Call) RunAndReturn(run func(tlsclientconfig.Config) (*tls.Config, error)) *MockInterface_Load_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,251 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package repository_mock
import (
io "io"
oidc "github.com/int128/kubelogin/pkg/oidc"
mock "github.com/stretchr/testify/mock"
tokencache "github.com/int128/kubelogin/pkg/tokencache"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// DeleteAll provides a mock function with given fields: config
func (_m *MockInterface) DeleteAll(config tokencache.Config) error {
ret := _m.Called(config)
if len(ret) == 0 {
panic("no return value specified for DeleteAll")
}
var r0 error
if rf, ok := ret.Get(0).(func(tokencache.Config) error); ok {
r0 = rf(config)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_DeleteAll_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DeleteAll'
type MockInterface_DeleteAll_Call struct {
*mock.Call
}
// DeleteAll is a helper method to define mock.On call
// - config tokencache.Config
func (_e *MockInterface_Expecter) DeleteAll(config interface{}) *MockInterface_DeleteAll_Call {
return &MockInterface_DeleteAll_Call{Call: _e.mock.On("DeleteAll", config)}
}
func (_c *MockInterface_DeleteAll_Call) Run(run func(config tokencache.Config)) *MockInterface_DeleteAll_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(tokencache.Config))
})
return _c
}
func (_c *MockInterface_DeleteAll_Call) Return(_a0 error) *MockInterface_DeleteAll_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_DeleteAll_Call) RunAndReturn(run func(tokencache.Config) error) *MockInterface_DeleteAll_Call {
_c.Call.Return(run)
return _c
}
// FindByKey provides a mock function with given fields: config, key
func (_m *MockInterface) FindByKey(config tokencache.Config, key tokencache.Key) (*oidc.TokenSet, error) {
ret := _m.Called(config, key)
if len(ret) == 0 {
panic("no return value specified for FindByKey")
}
var r0 *oidc.TokenSet
var r1 error
if rf, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key) (*oidc.TokenSet, error)); ok {
return rf(config, key)
}
if rf, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key) *oidc.TokenSet); ok {
r0 = rf(config, key)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*oidc.TokenSet)
}
}
if rf, ok := ret.Get(1).(func(tokencache.Config, tokencache.Key) error); ok {
r1 = rf(config, key)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_FindByKey_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'FindByKey'
type MockInterface_FindByKey_Call struct {
*mock.Call
}
// FindByKey is a helper method to define mock.On call
// - config tokencache.Config
// - key tokencache.Key
func (_e *MockInterface_Expecter) FindByKey(config interface{}, key interface{}) *MockInterface_FindByKey_Call {
return &MockInterface_FindByKey_Call{Call: _e.mock.On("FindByKey", config, key)}
}
func (_c *MockInterface_FindByKey_Call) Run(run func(config tokencache.Config, key tokencache.Key)) *MockInterface_FindByKey_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(tokencache.Config), args[1].(tokencache.Key))
})
return _c
}
func (_c *MockInterface_FindByKey_Call) Return(_a0 *oidc.TokenSet, _a1 error) *MockInterface_FindByKey_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_FindByKey_Call) RunAndReturn(run func(tokencache.Config, tokencache.Key) (*oidc.TokenSet, error)) *MockInterface_FindByKey_Call {
_c.Call.Return(run)
return _c
}
// Lock provides a mock function with given fields: config, key
func (_m *MockInterface) Lock(config tokencache.Config, key tokencache.Key) (io.Closer, error) {
ret := _m.Called(config, key)
if len(ret) == 0 {
panic("no return value specified for Lock")
}
var r0 io.Closer
var r1 error
if rf, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key) (io.Closer, error)); ok {
return rf(config, key)
}
if rf, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key) io.Closer); ok {
r0 = rf(config, key)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(io.Closer)
}
}
if rf, ok := ret.Get(1).(func(tokencache.Config, tokencache.Key) error); ok {
r1 = rf(config, key)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Lock_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Lock'
type MockInterface_Lock_Call struct {
*mock.Call
}
// Lock is a helper method to define mock.On call
// - config tokencache.Config
// - key tokencache.Key
func (_e *MockInterface_Expecter) Lock(config interface{}, key interface{}) *MockInterface_Lock_Call {
return &MockInterface_Lock_Call{Call: _e.mock.On("Lock", config, key)}
}
func (_c *MockInterface_Lock_Call) Run(run func(config tokencache.Config, key tokencache.Key)) *MockInterface_Lock_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(tokencache.Config), args[1].(tokencache.Key))
})
return _c
}
func (_c *MockInterface_Lock_Call) Return(_a0 io.Closer, _a1 error) *MockInterface_Lock_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_Lock_Call) RunAndReturn(run func(tokencache.Config, tokencache.Key) (io.Closer, error)) *MockInterface_Lock_Call {
_c.Call.Return(run)
return _c
}
// Save provides a mock function with given fields: config, key, tokenSet
func (_m *MockInterface) Save(config tokencache.Config, key tokencache.Key, tokenSet oidc.TokenSet) error {
ret := _m.Called(config, key, tokenSet)
if len(ret) == 0 {
panic("no return value specified for Save")
}
var r0 error
if rf, ok := ret.Get(0).(func(tokencache.Config, tokencache.Key, oidc.TokenSet) error); ok {
r0 = rf(config, key, tokenSet)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Save_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Save'
type MockInterface_Save_Call struct {
*mock.Call
}
// Save is a helper method to define mock.On call
// - config tokencache.Config
// - key tokencache.Key
// - tokenSet oidc.TokenSet
func (_e *MockInterface_Expecter) Save(config interface{}, key interface{}, tokenSet interface{}) *MockInterface_Save_Call {
return &MockInterface_Save_Call{Call: _e.mock.On("Save", config, key, tokenSet)}
}
func (_c *MockInterface_Save_Call) Run(run func(config tokencache.Config, key tokencache.Key, tokenSet oidc.TokenSet)) *MockInterface_Save_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(tokencache.Config), args[1].(tokencache.Key), args[2].(oidc.TokenSet))
})
return _c
}
func (_c *MockInterface_Save_Call) Return(_a0 error) *MockInterface_Save_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Save_Call) RunAndReturn(run func(tokencache.Config, tokencache.Key, oidc.TokenSet) error) *MockInterface_Save_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,97 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package authentication_mock
import (
context "context"
authentication "github.com/int128/kubelogin/pkg/usecases/authentication"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function with given fields: ctx, in
func (_m *MockInterface) Do(ctx context.Context, in authentication.Input) (*authentication.Output, error) {
ret := _m.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
}
var r0 *authentication.Output
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, authentication.Input) (*authentication.Output, error)); ok {
return rf(ctx, in)
}
if rf, ok := ret.Get(0).(func(context.Context, authentication.Input) *authentication.Output); ok {
r0 = rf(ctx, in)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*authentication.Output)
}
}
if rf, ok := ret.Get(1).(func(context.Context, authentication.Input) error); ok {
r1 = rf(ctx, in)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockInterface_Do_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Do'
type MockInterface_Do_Call struct {
*mock.Call
}
// Do is a helper method to define mock.On call
// - ctx context.Context
// - in authentication.Input
func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInterface_Do_Call {
return &MockInterface_Do_Call{Call: _e.mock.On("Do", ctx, in)}
}
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in authentication.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(authentication.Input))
})
return _c
}
func (_c *MockInterface_Do_Call) Return(_a0 *authentication.Output, _a1 error) *MockInterface_Do_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(context.Context, authentication.Input) (*authentication.Output, error)) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,85 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package clean_mock
import (
context "context"
clean "github.com/int128/kubelogin/pkg/usecases/clean"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function with given fields: ctx, in
func (_m *MockInterface) Do(ctx context.Context, in clean.Input) error {
ret := _m.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, clean.Input) error); ok {
r0 = rf(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Do_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Do'
type MockInterface_Do_Call struct {
*mock.Call
}
// Do is a helper method to define mock.On call
// - ctx context.Context
// - in clean.Input
func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInterface_Do_Call {
return &MockInterface_Do_Call{Call: _e.mock.On("Do", ctx, in)}
}
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in clean.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(clean.Input))
})
return _c
}
func (_c *MockInterface_Do_Call) Return(_a0 error) *MockInterface_Do_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(context.Context, clean.Input) error) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,84 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package credentialplugin_mock
import (
context "context"
credentialplugin "github.com/int128/kubelogin/pkg/usecases/credentialplugin"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function with given fields: ctx, in
func (_m *MockInterface) Do(ctx context.Context, in credentialplugin.Input) error {
ret := _m.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, credentialplugin.Input) error); ok {
r0 = rf(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Do_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Do'
type MockInterface_Do_Call struct {
*mock.Call
}
// Do is a helper method to define mock.On call
// - ctx context.Context
// - in credentialplugin.Input
func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInterface_Do_Call {
return &MockInterface_Do_Call{Call: _e.mock.On("Do", ctx, in)}
}
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in credentialplugin.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(credentialplugin.Input))
})
return _c
}
func (_c *MockInterface_Do_Call) Return(_a0 error) *MockInterface_Do_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(context.Context, credentialplugin.Input) error) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,116 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package setup_mock
import (
context "context"
setup "github.com/int128/kubelogin/pkg/usecases/setup"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// DoStage1 provides a mock function with no fields
func (_m *MockInterface) DoStage1() {
_m.Called()
}
// MockInterface_DoStage1_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DoStage1'
type MockInterface_DoStage1_Call struct {
*mock.Call
}
// DoStage1 is a helper method to define mock.On call
func (_e *MockInterface_Expecter) DoStage1() *MockInterface_DoStage1_Call {
return &MockInterface_DoStage1_Call{Call: _e.mock.On("DoStage1")}
}
func (_c *MockInterface_DoStage1_Call) Run(run func()) *MockInterface_DoStage1_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockInterface_DoStage1_Call) Return() *MockInterface_DoStage1_Call {
_c.Call.Return()
return _c
}
func (_c *MockInterface_DoStage1_Call) RunAndReturn(run func()) *MockInterface_DoStage1_Call {
_c.Run(run)
return _c
}
// DoStage2 provides a mock function with given fields: ctx, in
func (_m *MockInterface) DoStage2(ctx context.Context, in setup.Stage2Input) error {
ret := _m.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for DoStage2")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, setup.Stage2Input) error); ok {
r0 = rf(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_DoStage2_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DoStage2'
type MockInterface_DoStage2_Call struct {
*mock.Call
}
// DoStage2 is a helper method to define mock.On call
// - ctx context.Context
// - in setup.Stage2Input
func (_e *MockInterface_Expecter) DoStage2(ctx interface{}, in interface{}) *MockInterface_DoStage2_Call {
return &MockInterface_DoStage2_Call{Call: _e.mock.On("DoStage2", ctx, in)}
}
func (_c *MockInterface_DoStage2_Call) Run(run func(ctx context.Context, in setup.Stage2Input)) *MockInterface_DoStage2_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(setup.Stage2Input))
})
return _c
}
func (_c *MockInterface_DoStage2_Call) Return(_a0 error) *MockInterface_DoStage2_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_DoStage2_Call) RunAndReturn(run func(context.Context, setup.Stage2Input) error) *MockInterface_DoStage2_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,84 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package standalone_mock
import (
context "context"
standalone "github.com/int128/kubelogin/pkg/usecases/standalone"
mock "github.com/stretchr/testify/mock"
)
// MockInterface is an autogenerated mock type for the Interface type
type MockInterface struct {
mock.Mock
}
type MockInterface_Expecter struct {
mock *mock.Mock
}
func (_m *MockInterface) EXPECT() *MockInterface_Expecter {
return &MockInterface_Expecter{mock: &_m.Mock}
}
// Do provides a mock function with given fields: ctx, in
func (_m *MockInterface) Do(ctx context.Context, in standalone.Input) error {
ret := _m.Called(ctx, in)
if len(ret) == 0 {
panic("no return value specified for Do")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, standalone.Input) error); ok {
r0 = rf(ctx, in)
} else {
r0 = ret.Error(0)
}
return r0
}
// MockInterface_Do_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Do'
type MockInterface_Do_Call struct {
*mock.Call
}
// Do is a helper method to define mock.On call
// - ctx context.Context
// - in standalone.Input
func (_e *MockInterface_Expecter) Do(ctx interface{}, in interface{}) *MockInterface_Do_Call {
return &MockInterface_Do_Call{Call: _e.mock.On("Do", ctx, in)}
}
func (_c *MockInterface_Do_Call) Run(run func(ctx context.Context, in standalone.Input)) *MockInterface_Do_Call {
_c.Call.Run(func(args mock.Arguments) {
run(args[0].(context.Context), args[1].(standalone.Input))
})
return _c
}
func (_c *MockInterface_Do_Call) Return(_a0 error) *MockInterface_Do_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockInterface_Do_Call) RunAndReturn(run func(context.Context, standalone.Input) error) *MockInterface_Do_Call {
_c.Call.Return(run)
return _c
}
// NewMockInterface creates a new instance of MockInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockInterface(t interface {
mock.TestingT
Cleanup(func())
}) *MockInterface {
mock := &MockInterface{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -0,0 +1,77 @@
// Code generated by mockery v2.51.0. DO NOT EDIT.
package io_mock
import mock "github.com/stretchr/testify/mock"
// MockCloser is an autogenerated mock type for the Closer type
type MockCloser struct {
mock.Mock
}
type MockCloser_Expecter struct {
mock *mock.Mock
}
func (_m *MockCloser) EXPECT() *MockCloser_Expecter {
return &MockCloser_Expecter{mock: &_m.Mock}
}
// Close provides a mock function with no fields
func (_m *MockCloser) Close() error {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for Close")
}
var r0 error
if rf, ok := ret.Get(0).(func() error); ok {
r0 = rf()
} else {
r0 = ret.Error(0)
}
return r0
}
// MockCloser_Close_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Close'
type MockCloser_Close_Call struct {
*mock.Call
}
// Close is a helper method to define mock.On call
func (_e *MockCloser_Expecter) Close() *MockCloser_Close_Call {
return &MockCloser_Close_Call{Call: _e.mock.On("Close")}
}
func (_c *MockCloser_Close_Call) Run(run func()) *MockCloser_Close_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *MockCloser_Close_Call) Return(_a0 error) *MockCloser_Close_Call {
_c.Call.Return(_a0)
return _c
}
func (_c *MockCloser_Close_Call) RunAndReturn(run func() error) *MockCloser_Close_Call {
_c.Call.Return(run)
return _c
}
// NewMockCloser creates a new instance of MockCloser. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockCloser(t interface {
mock.TestingT
Cleanup(func())
}) *MockCloser {
mock := &MockCloser{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}

View File

@@ -7,38 +7,27 @@ import (
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/authentication/devicecode"
"github.com/int128/kubelogin/pkg/usecases/authentication/ropc"
"github.com/spf13/pflag"
)
type authenticationOptions struct {
GrantType string
ListenAddress []string
ListenPort []int // deprecated
AuthenticationTimeoutSec int
SkipOpenBrowser bool
LocalServerCertFile string
LocalServerKeyFile string
OpenURLAfterAuthentication string
RedirectURLHostname string
AuthRequestExtraParams map[string]string
Username string
Password string
}
const oobRedirectURI = "urn:ietf:wg:oauth:2.0:oob"
// determineListenAddress returns the addresses from the flags.
// Note that --listen-address is always given due to the default value.
// If --listen-port is not set, it returns --listen-address.
// If --listen-port is set, it returns the strings of --listen-port.
func (o *authenticationOptions) determineListenAddress() []string {
if len(o.ListenPort) == 0 {
return o.ListenAddress
}
var a []string
for _, p := range o.ListenPort {
a = append(a, fmt.Sprintf("127.0.0.1:%d", p))
}
return a
type authenticationOptions struct {
GrantType string
ListenAddress []string
AuthenticationTimeoutSec int
SkipOpenBrowser bool
BrowserCommand string
LocalServerCertFile string
LocalServerKeyFile string
OpenURLAfterAuthentication string
RedirectURLHostname string
RedirectURLAuthCodeKeyboard string
AuthRequestExtraParams map[string]string
Username string
Password string
}
var allGrantType = strings.Join([]string{
@@ -46,22 +35,20 @@ var allGrantType = strings.Join([]string{
"authcode",
"authcode-keyboard",
"password",
"device-code",
}, "|")
func (o *authenticationOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.GrantType, "grant-type", "auto", fmt.Sprintf("Authorization grant type to use. One of (%s)", allGrantType))
f.StringSliceVar(&o.ListenAddress, "listen-address", defaultListenAddress, "[authcode] Address to bind to the local server. If multiple addresses are set, it will try binding in order")
//TODO: remove the deprecated flag
f.IntSliceVar(&o.ListenPort, "listen-port", nil, "[authcode] deprecated: port to bind to the local server")
if err := f.MarkDeprecated("listen-port", "use --listen-address instead"); err != nil {
panic(err)
}
f.BoolVar(&o.SkipOpenBrowser, "skip-open-browser", false, "[authcode] Do not open the browser automatically")
f.StringVar(&o.BrowserCommand, "browser-command", "", "[authcode] Command to open the browser")
f.IntVar(&o.AuthenticationTimeoutSec, "authentication-timeout-sec", defaultAuthenticationTimeoutSec, "[authcode] Timeout of authentication in seconds")
f.StringVar(&o.LocalServerCertFile, "local-server-cert", "", "[authcode] Certificate path for the local server")
f.StringVar(&o.LocalServerKeyFile, "local-server-key", "", "[authcode] Certificate key path for the local server")
f.StringVar(&o.OpenURLAfterAuthentication, "open-url-after-authentication", "", "[authcode] If set, open the URL in the browser after authentication")
f.StringVar(&o.RedirectURLHostname, "oidc-redirect-url-hostname", "localhost", "[authcode] Hostname of the redirect URL")
f.StringVar(&o.RedirectURLAuthCodeKeyboard, "oidc-redirect-url-authcode-keyboard", oobRedirectURI, "[authcode-keyboard] Redirect URL")
f.StringToStringVar(&o.AuthRequestExtraParams, "oidc-auth-request-extra-params", nil, "[authcode, authcode-keyboard] Extra query parameters to send with an authentication request")
f.StringVar(&o.Username, "username", "", "[password] Username for resource owner password credentials grant")
f.StringVar(&o.Password, "password", "", "[password] Password for resource owner password credentials grant")
@@ -76,8 +63,9 @@ func (o *authenticationOptions) grantOptionSet() (s authentication.GrantOptionSe
switch {
case o.GrantType == "authcode" || (o.GrantType == "auto" && o.Username == ""):
s.AuthCodeBrowserOption = &authcode.BrowserOption{
BindAddress: o.determineListenAddress(),
BindAddress: o.ListenAddress,
SkipOpenBrowser: o.SkipOpenBrowser,
BrowserCommand: o.BrowserCommand,
AuthenticationTimeout: time.Duration(o.AuthenticationTimeoutSec) * time.Second,
LocalServerCertFile: o.LocalServerCertFile,
LocalServerKeyFile: o.LocalServerKeyFile,
@@ -88,12 +76,18 @@ func (o *authenticationOptions) grantOptionSet() (s authentication.GrantOptionSe
case o.GrantType == "authcode-keyboard":
s.AuthCodeKeyboardOption = &authcode.KeyboardOption{
AuthRequestExtraParams: o.AuthRequestExtraParams,
RedirectURL: o.RedirectURLAuthCodeKeyboard,
}
case o.GrantType == "password" || (o.GrantType == "auto" && o.Username != ""):
s.ROPCOption = &ropc.Option{
Username: o.Username,
Password: o.Password,
}
case o.GrantType == "device-code":
s.DeviceCodeOption = &devicecode.Option{
SkipOpenBrowser: o.SkipOpenBrowser,
BrowserCommand: o.BrowserCommand,
}
default:
err = fmt.Errorf("grant-type must be one of (%s)", allGrantType)
}

View File

@@ -31,6 +31,7 @@ func Test_authenticationOptions_grantOptionSet(t *testing.T) {
"--listen-address", "127.0.0.1:10080",
"--listen-address", "127.0.0.1:20080",
"--skip-open-browser",
"--browser-command", "firefox",
"--authentication-timeout-sec", "10",
"--local-server-cert", "/path/to/local-server-cert",
"--local-server-key", "/path/to/local-server-key",
@@ -45,6 +46,7 @@ func Test_authenticationOptions_grantOptionSet(t *testing.T) {
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: []string{"127.0.0.1:10080", "127.0.0.1:20080"},
SkipOpenBrowser: true,
BrowserCommand: "firefox",
AuthenticationTimeout: 10 * time.Second,
LocalServerCertFile: "/path/to/local-server-cert",
LocalServerKeyFile: "/path/to/local-server-key",
@@ -54,40 +56,25 @@ func Test_authenticationOptions_grantOptionSet(t *testing.T) {
},
},
},
"when --listen-port is set, it should convert the port to address": {
args: []string{
"--listen-port", "10080",
"--listen-port", "20080",
},
want: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: []string{"127.0.0.1:10080", "127.0.0.1:20080"},
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
},
},
},
"when --listen-port is set, it should ignore --listen-address flags": {
args: []string{
"--listen-port", "10080",
"--listen-port", "20080",
"--listen-address", "127.0.0.1:30080",
"--listen-address", "127.0.0.1:40080",
},
want: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: []string{"127.0.0.1:10080", "127.0.0.1:20080"},
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
},
},
},
"GrantType=authcode-keyboard": {
args: []string{
"--grant-type", "authcode-keyboard",
},
want: authentication.GrantOptionSet{
AuthCodeKeyboardOption: &authcode.KeyboardOption{},
AuthCodeKeyboardOption: &authcode.KeyboardOption{
RedirectURL: oobRedirectURI,
},
},
},
"GrantType=authcode-keyboard with full options": {
args: []string{
"--grant-type", "authcode-keyboard",
"--oidc-redirect-url-authcode-keyboard", "http://localhost",
},
want: authentication.GrantOptionSet{
AuthCodeKeyboardOption: &authcode.KeyboardOption{
RedirectURL: "http://localhost",
},
},
},
"GrantType=password": {

56
pkg/cmd/clean.go Normal file
View File

@@ -0,0 +1,56 @@
package cmd
import (
"fmt"
"github.com/int128/kubelogin/pkg/usecases/clean"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
type cleanOptions struct {
tokenCacheOptions tokenCacheOptions
}
func (o *cleanOptions) addFlags(f *pflag.FlagSet) {
o.tokenCacheOptions.addFlags(f)
}
func (o *cleanOptions) expandHomedir() {
o.tokenCacheOptions.expandHomedir()
}
type Clean struct {
Clean clean.Interface
}
func (cmd *Clean) New() *cobra.Command {
var o cleanOptions
c := &cobra.Command{
Use: "clean [flags]",
Short: "Delete the token cache",
Long: `Delete the token cache.
This deletes both the OS keyring and the directory by default.
If you encounter an error of keyring, try --token-cache-storage=disk.
`,
Args: cobra.NoArgs,
RunE: func(c *cobra.Command, _ []string) error {
o.expandHomedir()
tokenCacheConfig, err := o.tokenCacheOptions.tokenCacheConfig()
if err != nil {
return fmt.Errorf("clean: %w", err)
}
in := clean.Input{
TokenCacheConfig: tokenCacheConfig,
}
if err := cmd.Clean.Do(c.Context(), in); err != nil {
return fmt.Errorf("clean: %w", err)
}
return nil
},
}
c.Flags().SortFlags = false
o.addFlags(c.Flags())
return c
}

View File

@@ -2,7 +2,6 @@ package cmd
import (
"context"
"path/filepath"
"runtime"
"github.com/google/wire"
@@ -17,6 +16,7 @@ var Set = wire.NewSet(
wire.Struct(new(Root), "*"),
wire.Struct(new(GetToken), "*"),
wire.Struct(new(Setup), "*"),
wire.Struct(new(Clean), "*"),
)
type Interface interface {
@@ -24,7 +24,6 @@ type Interface interface {
}
var defaultListenAddress = []string{"127.0.0.1:8000", "127.0.0.1:18000"}
var defaultTokenCacheDir = filepath.Join("~", ".kube", "cache", "oidc-login")
const defaultAuthenticationTimeoutSec = 180
@@ -33,6 +32,7 @@ type Cmd struct {
Root *Root
GetToken *GetToken
Setup *Setup
Clean *Clean
Logger logger.Interface
}
@@ -50,6 +50,9 @@ func (cmd *Cmd) Run(ctx context.Context, args []string, version string) int {
setupCmd := cmd.Setup.New()
rootCmd.AddCommand(setupCmd)
cleanCmd := cmd.Clean.New()
rootCmd.AddCommand(cleanCmd)
versionCmd := &cobra.Command{
Use: "version",
Short: "Print the version information",

View File

@@ -7,16 +7,16 @@ import (
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/usecases/credentialplugin_mock"
"github.com/int128/kubelogin/mocks/github.com/int128/kubelogin/pkg/usecases/standalone_mock"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/testing/logger"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
"github.com/int128/kubelogin/pkg/tokencache"
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/credentialplugin"
"github.com/int128/kubelogin/pkg/usecases/credentialplugin/mock_credentialplugin"
"github.com/int128/kubelogin/pkg/usecases/standalone"
"github.com/int128/kubelogin/pkg/usecases/standalone/mock_standalone"
)
func TestCmd_Run(t *testing.T) {
@@ -63,12 +63,11 @@ func TestCmd_Run(t *testing.T) {
}
for name, c := range tests {
t.Run(name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
ctx := context.TODO()
mockStandalone := mock_standalone.NewMockInterface(ctrl)
mockStandalone := standalone_mock.NewMockInterface(t)
mockStandalone.EXPECT().
Do(ctx, c.in)
Do(ctx, c.in).
Return(nil)
cmd := Cmd{
Root: &Root{
Standalone: mockStandalone,
@@ -84,11 +83,9 @@ func TestCmd_Run(t *testing.T) {
}
t.Run("TooManyArgs", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cmd := Cmd{
Root: &Root{
Standalone: mock_standalone.NewMockInterface(ctrl),
Standalone: standalone_mock.NewMockInterface(t),
Logger: logger.New(t),
},
Logger: logger.New(t),
@@ -117,11 +114,14 @@ func TestCmd_Run(t *testing.T) {
"--oidc-client-id", "YOUR_CLIENT_ID",
},
in: credentialplugin.Input{
TokenCacheDir: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Provider: oidc.Provider{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT_ID",
},
TokenCacheConfig: tokencache.Config{
Directory: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Storage: tokencache.StorageAuto,
},
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
@@ -139,16 +139,46 @@ func TestCmd_Run(t *testing.T) {
"--oidc-client-secret", "YOUR_CLIENT_SECRET",
"--oidc-extra-scope", "email",
"--oidc-extra-scope", "profile",
"--token-cache-storage", "disk",
"-v1",
},
in: credentialplugin.Input{
TokenCacheDir: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Provider: oidc.Provider{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT_ID",
ClientSecret: "YOUR_CLIENT_SECRET",
ExtraScopes: []string{"email", "profile"},
},
TokenCacheConfig: tokencache.Config{
Directory: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Storage: tokencache.StorageDisk,
},
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
AuthenticationTimeout: defaultAuthenticationTimeoutSec * time.Second,
RedirectURLHostname: "localhost",
},
},
},
},
"AccessToken": {
args: []string{executable,
"get-token",
"--oidc-issuer-url", "https://issuer.example.com",
"--oidc-client-id", "YOUR_CLIENT_ID",
"--oidc-use-access-token=true",
},
in: credentialplugin.Input{
Provider: oidc.Provider{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT_ID",
UseAccessToken: true,
},
TokenCacheConfig: tokencache.Config{
Directory: filepath.Join(userHomeDir, ".kube/cache/oidc-login"),
Storage: tokencache.StorageAuto,
},
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
@@ -169,11 +199,14 @@ func TestCmd_Run(t *testing.T) {
"--token-cache-dir", "~/.kube/oidc-cache",
},
in: credentialplugin.Input{
TokenCacheDir: filepath.Join(userHomeDir, ".kube/oidc-cache"),
Provider: oidc.Provider{
IssuerURL: "https://issuer.example.com",
ClientID: "YOUR_CLIENT_ID",
},
TokenCacheConfig: tokencache.Config{
Directory: filepath.Join(userHomeDir, ".kube/oidc-cache"),
Storage: tokencache.StorageAuto,
},
GrantOptionSet: authentication.GrantOptionSet{
AuthCodeBrowserOption: &authcode.BrowserOption{
BindAddress: defaultListenAddress,
@@ -191,12 +224,11 @@ func TestCmd_Run(t *testing.T) {
}
for name, c := range tests {
t.Run(name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
ctx := context.TODO()
getToken := mock_credentialplugin.NewMockInterface(ctrl)
getToken := credentialplugin_mock.NewMockInterface(t)
getToken.EXPECT().
Do(ctx, c.in)
Do(ctx, c.in).
Return(nil)
cmd := Cmd{
Root: &Root{
Logger: logger.New(t),
@@ -215,15 +247,13 @@ func TestCmd_Run(t *testing.T) {
}
t.Run("MissingMandatoryOptions", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
ctx := context.TODO()
cmd := Cmd{
Root: &Root{
Logger: logger.New(t),
},
GetToken: &GetToken{
GetToken: mock_credentialplugin.NewMockInterface(ctrl),
GetToken: credentialplugin_mock.NewMockInterface(t),
Logger: logger.New(t),
},
Logger: logger.New(t),
@@ -235,15 +265,13 @@ func TestCmd_Run(t *testing.T) {
})
t.Run("TooManyArgs", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
ctx := context.TODO()
cmd := Cmd{
Root: &Root{
Logger: logger.New(t),
},
GetToken: &GetToken{
GetToken: mock_credentialplugin.NewMockInterface(ctrl),
GetToken: credentialplugin_mock.NewMockInterface(t),
Logger: logger.New(t),
},
Logger: logger.New(t),

View File

@@ -17,9 +17,12 @@ type getTokenOptions struct {
ClientID string
ClientSecret string
ExtraScopes []string
TokenCacheDir string
UseAccessToken bool
tokenCacheOptions tokenCacheOptions
tlsOptions tlsOptions
pkceOptions pkceOptions
authenticationOptions authenticationOptions
ForceRefresh bool
}
func (o *getTokenOptions) addFlags(f *pflag.FlagSet) {
@@ -27,16 +30,18 @@ func (o *getTokenOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.ClientID, "oidc-client-id", "", "Client ID of the provider (mandatory)")
f.StringVar(&o.ClientSecret, "oidc-client-secret", "", "Client secret of the provider")
f.StringSliceVar(&o.ExtraScopes, "oidc-extra-scope", nil, "Scopes to request to the provider")
f.StringVar(&o.TokenCacheDir, "token-cache-dir", defaultTokenCacheDir, "Path to a directory for token cache")
f.BoolVar(&o.UseAccessToken, "oidc-use-access-token", false, "Instead of using the id_token, use the access_token to authenticate to Kubernetes")
f.BoolVar(&o.ForceRefresh, "force-refresh", false, "If set, refresh the ID token regardless of its expiration time")
o.tokenCacheOptions.addFlags(f)
o.tlsOptions.addFlags(f)
o.pkceOptions.addFlags(f)
o.authenticationOptions.addFlags(f)
}
func (o *getTokenOptions) expandHomedir() error {
o.TokenCacheDir = expandHomedir(o.TokenCacheDir)
func (o *getTokenOptions) expandHomedir() {
o.tokenCacheOptions.expandHomedir()
o.authenticationOptions.expandHomedir()
o.tlsOptions.expandHomedir()
return nil
}
type GetToken struct {
@@ -62,23 +67,32 @@ func (cmd *GetToken) New() *cobra.Command {
return nil
},
RunE: func(c *cobra.Command, _ []string) error {
if err := o.expandHomedir(); err != nil {
return err
}
o.expandHomedir()
grantOptionSet, err := o.authenticationOptions.grantOptionSet()
if err != nil {
return fmt.Errorf("get-token: %w", err)
}
tokenCacheConfig, err := o.tokenCacheOptions.tokenCacheConfig()
if err != nil {
return fmt.Errorf("get-token: %w", err)
}
pkceMethod, err := o.pkceOptions.pkceMethod()
if err != nil {
return fmt.Errorf("get-token: %w", err)
}
in := credentialplugin.Input{
Provider: oidc.Provider{
IssuerURL: o.IssuerURL,
ClientID: o.ClientID,
ClientSecret: o.ClientSecret,
ExtraScopes: o.ExtraScopes,
IssuerURL: o.IssuerURL,
ClientID: o.ClientID,
ClientSecret: o.ClientSecret,
PKCEMethod: pkceMethod,
UseAccessToken: o.UseAccessToken,
ExtraScopes: o.ExtraScopes,
},
TokenCacheDir: o.TokenCacheDir,
GrantOptionSet: grantOptionSet,
TLSClientConfig: o.tlsOptions.tlsClientConfig(),
ForceRefresh: o.ForceRefresh,
TokenCacheConfig: tokenCacheConfig,
GrantOptionSet: grantOptionSet,
TLSClientConfig: o.tlsOptions.tlsClientConfig(),
}
if err := cmd.GetToken.Do(c.Context(), in); err != nil {
return fmt.Errorf("get-token: %w", err)

40
pkg/cmd/pkce.go Normal file
View File

@@ -0,0 +1,40 @@
package cmd
import (
"fmt"
"strings"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/spf13/pflag"
)
var allPKCEMethods = strings.Join([]string{"auto", "no", "S256"}, "|")
type pkceOptions struct {
UsePKCE bool
PKCEMethod string
}
func (o *pkceOptions) addFlags(f *pflag.FlagSet) {
f.BoolVar(&o.UsePKCE, "oidc-use-pkce", false, "Force PKCE S256 code challenge method")
if err := f.MarkDeprecated("oidc-use-pkce", "use --oidc-pkce-method instead. For the most providers, you don't need to set the flag."); err != nil {
panic(err)
}
f.StringVar(&o.PKCEMethod, "oidc-pkce-method", "auto", fmt.Sprintf("PKCE code challenge method. Automatically determined by default. One of (%s)", allPKCEMethods))
}
func (o *pkceOptions) pkceMethod() (oidc.PKCEMethod, error) {
if o.UsePKCE {
return oidc.PKCEMethodS256, nil
}
switch o.PKCEMethod {
case "auto":
return oidc.PKCEMethodAuto, nil
case "no":
return oidc.PKCEMethodNo, nil
case "S256":
return oidc.PKCEMethodS256, nil
default:
return 0, fmt.Errorf("oidc-pkce-method must be one of (%s)", allPKCEMethods)
}
}

View File

@@ -2,6 +2,7 @@ package cmd
import (
"fmt"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/kubeconfig"
"github.com/int128/kubelogin/pkg/usecases/standalone"

View File

@@ -2,6 +2,7 @@ package cmd
import (
"fmt"
"github.com/int128/kubelogin/pkg/usecases/setup"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
@@ -13,7 +14,9 @@ type setupOptions struct {
ClientID string
ClientSecret string
ExtraScopes []string
UseAccessToken bool
tlsOptions tlsOptions
pkceOptions pkceOptions
authenticationOptions authenticationOptions
}
@@ -22,7 +25,9 @@ func (o *setupOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.ClientID, "oidc-client-id", "", "Client ID of the provider")
f.StringVar(&o.ClientSecret, "oidc-client-secret", "", "Client secret of the provider")
f.StringSliceVar(&o.ExtraScopes, "oidc-extra-scope", nil, "Scopes to request to the provider")
f.BoolVar(&o.UseAccessToken, "oidc-use-access-token", false, "Instead of using the id_token, use the access_token to authenticate to Kubernetes")
o.tlsOptions.addFlags(f)
o.pkceOptions.addFlags(f)
o.authenticationOptions.addFlags(f)
}
@@ -41,17 +46,26 @@ func (cmd *Setup) New() *cobra.Command {
if err != nil {
return fmt.Errorf("setup: %w", err)
}
pkceMethod, err := o.pkceOptions.pkceMethod()
if err != nil {
return fmt.Errorf("setup: %w", err)
}
in := setup.Stage2Input{
IssuerURL: o.IssuerURL,
ClientID: o.ClientID,
ClientSecret: o.ClientSecret,
ExtraScopes: o.ExtraScopes,
UseAccessToken: o.UseAccessToken,
PKCEMethod: pkceMethod,
GrantOptionSet: grantOptionSet,
TLSClientConfig: o.tlsOptions.tlsClientConfig(),
}
if c.Flags().Lookup("listen-address").Changed {
in.ListenAddressArgs = o.authenticationOptions.ListenAddress
}
if c.Flags().Lookup("oidc-pkce-method").Changed {
in.PKCEMethodArg = o.pkceOptions.PKCEMethod
}
if in.IssuerURL == "" || in.ClientID == "" {
cmd.Setup.DoStage1()
return nil

View File

@@ -18,7 +18,7 @@ type tlsOptions struct {
func (o *tlsOptions) addFlags(f *pflag.FlagSet) {
f.StringArrayVar(&o.CACertFilename, "certificate-authority", nil, "Path to a cert file for the certificate authority")
f.StringArrayVar(&o.CACertData, "certificate-authority-data", nil, "Base64 encoded cert for the certificate authority")
f.BoolVar(&o.SkipTLSVerify, "insecure-skip-tls-verify", false, "If set, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure")
f.BoolVar(&o.SkipTLSVerify, "insecure-skip-tls-verify", false, "[SECURITY RISK] If set, the server's certificate will not be checked for validity")
f.BoolVar(&o.RenegotiateOnceAsClient, "tls-renegotiation-once", false, "If set, allow a remote server to request renegotiation once per connection")
f.BoolVar(&o.RenegotiateFreelyAsClient, "tls-renegotiation-freely", false, "If set, allow a remote server to repeatedly request renegotiation")
}

52
pkg/cmd/tokencache.go Normal file
View File

@@ -0,0 +1,52 @@
package cmd
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/int128/kubelogin/pkg/tokencache"
"github.com/spf13/pflag"
)
func getDefaultTokenCacheDir() string {
// https://github.com/int128/kubelogin/pull/975
if kubeCacheDir, ok := os.LookupEnv("KUBECACHEDIR"); ok {
return filepath.Join(kubeCacheDir, "oidc-login")
}
return filepath.Join("~", ".kube", "cache", "oidc-login")
}
var allTokenCacheStorage = strings.Join([]string{"auto", "keyring", "disk"}, "|")
type tokenCacheOptions struct {
TokenCacheDir string
TokenCacheStorage string
}
func (o *tokenCacheOptions) addFlags(f *pflag.FlagSet) {
f.StringVar(&o.TokenCacheDir, "token-cache-dir", getDefaultTokenCacheDir(), "Path to a directory of the token cache")
f.StringVar(&o.TokenCacheStorage, "token-cache-storage", "auto", fmt.Sprintf("Storage for the token cache. One of (%s)", allTokenCacheStorage))
}
func (o *tokenCacheOptions) expandHomedir() {
o.TokenCacheDir = expandHomedir(o.TokenCacheDir)
}
func (o *tokenCacheOptions) tokenCacheConfig() (tokencache.Config, error) {
config := tokencache.Config{
Directory: o.TokenCacheDir,
}
switch o.TokenCacheStorage {
case "auto":
config.Storage = tokencache.StorageAuto
case "keyring":
config.Storage = tokencache.StorageKeyring
case "disk":
config.Storage = tokencache.StorageDisk
default:
return tokencache.Config{}, fmt.Errorf("token-cache-storage must be one of (%s)", allTokenCacheStorage)
}
return config, nil
}

View File

@@ -0,0 +1,39 @@
// Package reader provides a loader for the credential plugin.
package reader
import (
"encoding/json"
"fmt"
"os"
"github.com/google/wire"
"github.com/int128/kubelogin/pkg/credentialplugin"
"k8s.io/client-go/pkg/apis/clientauthentication"
)
var Set = wire.NewSet(
wire.Struct(new(Reader), "*"),
wire.Bind(new(Interface), new(*Reader)),
)
type Interface interface {
Read() (credentialplugin.Input, error)
}
type Reader struct{}
// Read parses the environment variable KUBERNETES_EXEC_INFO.
// If the environment variable is not given by kubectl, Read returns a zero value.
func (r Reader) Read() (credentialplugin.Input, error) {
execInfo := os.Getenv("KUBERNETES_EXEC_INFO")
if execInfo == "" {
return credentialplugin.Input{}, nil
}
var execCredential clientauthentication.ExecCredential
if err := json.Unmarshal([]byte(execInfo), &execCredential); err != nil {
return credentialplugin.Input{}, fmt.Errorf("invalid KUBERNETES_EXEC_INFO: %w", err)
}
return credentialplugin.Input{
ClientAuthenticationAPIVersion: execCredential.APIVersion,
}, nil
}

View File

@@ -0,0 +1,44 @@
package reader
import (
"testing"
"github.com/google/go-cmp/cmp"
"github.com/int128/kubelogin/pkg/credentialplugin"
)
func TestReader_Read(t *testing.T) {
var reader Reader
t.Run("KUBERNETES_EXEC_INFO is empty", func(t *testing.T) {
input, err := reader.Read()
if err != nil {
t.Errorf("Read returned error: %v", err)
}
want := credentialplugin.Input{}
if diff := cmp.Diff(want, input); diff != "" {
t.Errorf("input mismatch (-want +got):\n%s", diff)
}
})
t.Run("KUBERNETES_EXEC_INFO is invalid JSON", func(t *testing.T) {
t.Setenv("KUBERNETES_EXEC_INFO", "invalid")
_, err := reader.Read()
if err == nil {
t.Errorf("Read wants error but no error")
}
})
t.Run("KUBERNETES_EXEC_INFO is v1", func(t *testing.T) {
t.Setenv(
"KUBERNETES_EXEC_INFO",
`{"kind":"ExecCredential","apiVersion":"client.authentication.k8s.io/v1","spec":{"interactive":true}}`,
)
input, err := reader.Read()
if err != nil {
t.Errorf("Read returned error: %v", err)
}
want := credentialplugin.Input{ClientAuthenticationAPIVersion: "client.authentication.k8s.io/v1"}
if diff := cmp.Diff(want, input); diff != "" {
t.Errorf("input mismatch (-want +got):\n%s", diff)
}
})
}

View File

@@ -3,8 +3,15 @@ package credentialplugin
import "time"
// Input represents an input object of the credential plugin.
// This may be a zero value if the input is not available.
type Input struct {
ClientAuthenticationAPIVersion string
}
// Output represents an output object of the credential plugin.
type Output struct {
Token string
Expiry time.Time
Token string
Expiry time.Time
ClientAuthenticationAPIVersion string
}

View File

@@ -1,4 +1,4 @@
// Package writer provides a writer for a credential plugin.
// Package writer provides a writer for the credential plugin.
package writer
import (
@@ -9,11 +9,10 @@ import (
"github.com/int128/kubelogin/pkg/credentialplugin"
"github.com/int128/kubelogin/pkg/infrastructure/stdio"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clientauthenticationv1 "k8s.io/client-go/pkg/apis/clientauthentication/v1"
clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
)
//go:generate mockgen -destination mock_writer/mock_writer.go github.com/int128/kubelogin/pkg/credentialplugin/writer Interface
var Set = wire.NewSet(
wire.Struct(new(Writer), "*"),
wire.Bind(new(Interface), new(*Writer)),
@@ -29,19 +28,44 @@ type Writer struct {
// Write writes the ExecCredential to standard output for kubectl.
func (w *Writer) Write(out credentialplugin.Output) error {
ec := &clientauthenticationv1beta1.ExecCredential{
TypeMeta: metav1.TypeMeta{
APIVersion: "client.authentication.k8s.io/v1beta1",
Kind: "ExecCredential",
},
Status: &clientauthenticationv1beta1.ExecCredentialStatus{
Token: out.Token,
ExpirationTimestamp: &metav1.Time{Time: out.Expiry},
},
execCredential, err := generateExecCredential(out)
if err != nil {
return fmt.Errorf("generate ExecCredential: %w", err)
}
e := json.NewEncoder(w.Stdout)
if err := e.Encode(ec); err != nil {
return fmt.Errorf("could not write the ExecCredential: %w", err)
if err := json.NewEncoder(w.Stdout).Encode(execCredential); err != nil {
return fmt.Errorf("write ExecCredential: %w", err)
}
return nil
}
func generateExecCredential(out credentialplugin.Output) (any, error) {
switch out.ClientAuthenticationAPIVersion {
// If the API version is not available, fall back to v1beta1.
case clientauthenticationv1beta1.SchemeGroupVersion.String(), "":
return &clientauthenticationv1beta1.ExecCredential{
TypeMeta: metav1.TypeMeta{
APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(),
Kind: "ExecCredential",
},
Status: &clientauthenticationv1beta1.ExecCredentialStatus{
Token: out.Token,
ExpirationTimestamp: &metav1.Time{Time: out.Expiry},
},
}, nil
case clientauthenticationv1.SchemeGroupVersion.String():
return &clientauthenticationv1.ExecCredential{
TypeMeta: metav1.TypeMeta{
APIVersion: clientauthenticationv1.SchemeGroupVersion.String(),
Kind: "ExecCredential",
},
Status: &clientauthenticationv1.ExecCredentialStatus{
Token: out.Token,
ExpirationTimestamp: &metav1.Time{Time: out.Expiry},
},
}, nil
default:
return nil, fmt.Errorf("unknown apiVersion: %s", out.ClientAuthenticationAPIVersion)
}
}

View File

@@ -1,48 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/int128/kubelogin/pkg/credentialplugin/writer (interfaces: Interface)
// Package mock_writer is a generated GoMock package.
package mock_writer
import (
gomock "github.com/golang/mock/gomock"
credentialplugin "github.com/int128/kubelogin/pkg/credentialplugin"
reflect "reflect"
)
// MockInterface is a mock of Interface interface
type MockInterface struct {
ctrl *gomock.Controller
recorder *MockInterfaceMockRecorder
}
// MockInterfaceMockRecorder is the mock recorder for MockInterface
type MockInterfaceMockRecorder struct {
mock *MockInterface
}
// NewMockInterface creates a new mock instance
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
mock := &MockInterface{ctrl: ctrl}
mock.recorder = &MockInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
return m.recorder
}
// Write mocks base method
func (m *MockInterface) Write(arg0 credentialplugin.Output) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Write", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Write indicates an expected call of Write
func (mr *MockInterfaceMockRecorder) Write(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Write", reflect.TypeOf((*MockInterface)(nil).Write), arg0)
}

View File

@@ -1,4 +1,5 @@
//+build wireinject
//go:build wireinject
// +build wireinject
// Package di provides dependency injection.
package di
@@ -6,11 +7,11 @@ package di
import (
"github.com/google/wire"
"github.com/int128/kubelogin/pkg/cmd"
"github.com/int128/kubelogin/pkg/credentialplugin/writer"
credentialpluginreader "github.com/int128/kubelogin/pkg/credentialplugin/reader"
credentialpluginwriter "github.com/int128/kubelogin/pkg/credentialplugin/writer"
"github.com/int128/kubelogin/pkg/infrastructure/browser"
"github.com/int128/kubelogin/pkg/infrastructure/clock"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/infrastructure/mutex"
"github.com/int128/kubelogin/pkg/infrastructure/reader"
"github.com/int128/kubelogin/pkg/infrastructure/stdio"
kubeconfigLoader "github.com/int128/kubelogin/pkg/kubeconfig/loader"
@@ -19,6 +20,7 @@ import (
"github.com/int128/kubelogin/pkg/tlsclientconfig/loader"
"github.com/int128/kubelogin/pkg/tokencache/repository"
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/clean"
"github.com/int128/kubelogin/pkg/usecases/credentialplugin"
"github.com/int128/kubelogin/pkg/usecases/setup"
"github.com/int128/kubelogin/pkg/usecases/standalone"
@@ -46,6 +48,7 @@ func NewCmdForHeadless(clock.Interface, stdio.Stdin, stdio.Stdout, logger.Interf
standalone.Set,
credentialplugin.Set,
setup.Set,
clean.Set,
// infrastructure
cmd.Set,
@@ -55,8 +58,8 @@ func NewCmdForHeadless(clock.Interface, stdio.Stdin, stdio.Stdout, logger.Interf
repository.Set,
client.Set,
loader.Set,
writer.Set,
mutex.Set,
credentialpluginreader.Set,
credentialpluginwriter.Set,
)
return nil
}

View File

@@ -1,17 +1,18 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate wire
//+build !wireinject
//go:generate go run -mod=mod github.com/google/wire/cmd/wire
//go:build !wireinject
// +build !wireinject
package di
import (
"github.com/int128/kubelogin/pkg/cmd"
reader2 "github.com/int128/kubelogin/pkg/credentialplugin/reader"
writer2 "github.com/int128/kubelogin/pkg/credentialplugin/writer"
"github.com/int128/kubelogin/pkg/infrastructure/browser"
"github.com/int128/kubelogin/pkg/infrastructure/clock"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/infrastructure/mutex"
"github.com/int128/kubelogin/pkg/infrastructure/reader"
"github.com/int128/kubelogin/pkg/infrastructure/stdio"
loader2 "github.com/int128/kubelogin/pkg/kubeconfig/loader"
@@ -21,7 +22,9 @@ import (
"github.com/int128/kubelogin/pkg/tokencache/repository"
"github.com/int128/kubelogin/pkg/usecases/authentication"
"github.com/int128/kubelogin/pkg/usecases/authentication/authcode"
"github.com/int128/kubelogin/pkg/usecases/authentication/devicecode"
"github.com/int128/kubelogin/pkg/usecases/authentication/ropc"
"github.com/int128/kubelogin/pkg/usecases/clean"
"github.com/int128/kubelogin/pkg/usecases/credentialplugin"
"github.com/int128/kubelogin/pkg/usecases/setup"
"github.com/int128/kubelogin/pkg/usecases/standalone"
@@ -30,6 +33,7 @@ import (
// Injectors from di.go:
// NewCmd returns an instance of infrastructure.Cmd.
func NewCmd() cmd.Interface {
clockReal := &clock.Real{}
stdin := _wireFileValue
@@ -45,6 +49,7 @@ var (
_wireOsFileValue = os.Stdout
)
// NewCmdForHeadless returns an instance of infrastructure.Cmd for headless testing.
func NewCmdForHeadless(clockInterface clock.Interface, stdin stdio.Stdin, stdout stdio.Stdout, loggerInterface logger.Interface, browserInterface browser.Interface) cmd.Interface {
loaderLoader := loader.Loader{}
factory := &client.Factory{
@@ -67,13 +72,17 @@ func NewCmdForHeadless(clockInterface clock.Interface, stdin stdio.Stdin, stdout
Reader: readerReader,
Logger: loggerInterface,
}
deviceCode := &devicecode.DeviceCode{
Browser: browserInterface,
Logger: loggerInterface,
}
authenticationAuthentication := &authentication.Authentication{
ClientFactory: factory,
Logger: loggerInterface,
Clock: clockInterface,
AuthCodeBrowser: authcodeBrowser,
AuthCodeKeyboard: keyboard,
ROPC: ropcROPC,
DeviceCode: deviceCode,
}
loader3 := &loader2.Loader{}
writerWriter := &writer.Writer{}
@@ -82,24 +91,26 @@ func NewCmdForHeadless(clockInterface clock.Interface, stdin stdio.Stdin, stdout
KubeconfigLoader: loader3,
KubeconfigWriter: writerWriter,
Logger: loggerInterface,
Clock: clockInterface,
}
root := &cmd.Root{
Standalone: standaloneStandalone,
Logger: loggerInterface,
}
repositoryRepository := &repository.Repository{}
repositoryRepository := &repository.Repository{
Logger: loggerInterface,
}
reader3 := &reader2.Reader{}
writer3 := &writer2.Writer{
Stdout: stdout,
}
mutexMutex := &mutex.Mutex{
Logger: loggerInterface,
}
getToken := &credentialplugin.GetToken{
Authentication: authenticationAuthentication,
TokenCacheRepository: repositoryRepository,
Writer: writer3,
Mutex: mutexMutex,
Logger: loggerInterface,
Authentication: authenticationAuthentication,
TokenCacheRepository: repositoryRepository,
CredentialPluginReader: reader3,
CredentialPluginWriter: writer3,
Logger: loggerInterface,
Clock: clockInterface,
}
cmdGetToken := &cmd.GetToken{
GetToken: getToken,
@@ -112,10 +123,18 @@ func NewCmdForHeadless(clockInterface clock.Interface, stdin stdio.Stdin, stdout
cmdSetup := &cmd.Setup{
Setup: setupSetup,
}
cleanClean := &clean.Clean{
TokenCacheRepository: repositoryRepository,
Logger: loggerInterface,
}
cmdClean := &cmd.Clean{
Clean: cleanClean,
}
cmdCmd := &cmd.Cmd{
Root: root,
GetToken: cmdGetToken,
Setup: cmdSetup,
Clean: cmdClean,
Logger: loggerInterface,
}
return cmdCmd

View File

@@ -1,14 +1,14 @@
package browser
import (
"context"
"os"
"os/exec"
"github.com/google/wire"
"github.com/pkg/browser"
)
//go:generate mockgen -destination mock_browser/mock_browser.go github.com/int128/kubelogin/pkg/infrastructure/browser Interface
func init() {
// In credential plugin mode, some browser launcher writes a message to stdout
// and it may break the credential json for client-go.
@@ -23,6 +23,7 @@ var Set = wire.NewSet(
type Interface interface {
Open(url string) error
OpenCommand(ctx context.Context, url, command string) error
}
type Browser struct{}
@@ -31,3 +32,11 @@ type Browser struct{}
func (*Browser) Open(url string) error {
return browser.OpenURL(url)
}
// OpenCommand opens the browser using the command.
func (*Browser) OpenCommand(ctx context.Context, url, command string) error {
c := exec.CommandContext(ctx, command, url)
c.Stdout = os.Stderr // see above
c.Stderr = os.Stderr
return c.Run()
}

View File

@@ -1,47 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/int128/kubelogin/pkg/infrastructure/browser (interfaces: Interface)
// Package mock_browser is a generated GoMock package.
package mock_browser
import (
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockInterface is a mock of Interface interface
type MockInterface struct {
ctrl *gomock.Controller
recorder *MockInterfaceMockRecorder
}
// MockInterfaceMockRecorder is the mock recorder for MockInterface
type MockInterfaceMockRecorder struct {
mock *MockInterface
}
// NewMockInterface creates a new mock instance
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
mock := &MockInterface{ctrl: ctrl}
mock.recorder = &MockInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
return m.recorder
}
// Open mocks base method
func (m *MockInterface) Open(arg0 string) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Open", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Open indicates an expected call of Open
func (mr *MockInterfaceMockRecorder) Open(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Open", reflect.TypeOf((*MockInterface)(nil).Open), arg0)
}

View File

@@ -1,64 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/int128/kubelogin/pkg/infrastructure/mutex (interfaces: Interface)
// Package mock_mutex is a generated GoMock package.
package mock_mutex
import (
context "context"
gomock "github.com/golang/mock/gomock"
mutex "github.com/int128/kubelogin/pkg/infrastructure/mutex"
reflect "reflect"
)
// MockInterface is a mock of Interface interface
type MockInterface struct {
ctrl *gomock.Controller
recorder *MockInterfaceMockRecorder
}
// MockInterfaceMockRecorder is the mock recorder for MockInterface
type MockInterfaceMockRecorder struct {
mock *MockInterface
}
// NewMockInterface creates a new mock instance
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
mock := &MockInterface{ctrl: ctrl}
mock.recorder = &MockInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
return m.recorder
}
// Acquire mocks base method
func (m *MockInterface) Acquire(arg0 context.Context, arg1 string) (*mutex.Lock, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Acquire", arg0, arg1)
ret0, _ := ret[0].(*mutex.Lock)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Acquire indicates an expected call of Acquire
func (mr *MockInterfaceMockRecorder) Acquire(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Acquire", reflect.TypeOf((*MockInterface)(nil).Acquire), arg0, arg1)
}
// Release mocks base method
func (m *MockInterface) Release(arg0 *mutex.Lock) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Release", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// Release indicates an expected call of Release
func (mr *MockInterfaceMockRecorder) Release(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Release", reflect.TypeOf((*MockInterface)(nil).Release), arg0)
}

View File

@@ -1,88 +0,0 @@
package mutex
import (
"context"
"fmt"
"github.com/alexflint/go-filemutex"
"github.com/google/wire"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"os"
"path"
)
//go:generate mockgen -destination mock_mutex/mock_mutex.go github.com/int128/kubelogin/pkg/infrastructure/mutex Interface
var Set = wire.NewSet(
wire.Struct(new(Mutex), "*"),
wire.Bind(new(Interface), new(*Mutex)),
)
type Interface interface {
Acquire(ctx context.Context, name string) (*Lock, error)
Release(lock *Lock) error
}
// Lock holds the lock data.
type Lock struct {
Data interface{}
Name string
}
type Mutex struct {
Logger logger.Interface
}
// internalAcquire wait for acquisition of the lock
func internalAcquire(fm *filemutex.FileMutex) chan error {
result := make(chan error)
go func() {
if err := fm.Lock(); err != nil {
result <- err
}
close(result)
}()
return result
}
// internalRelease disposes of resources associated with a lock
func internalRelease(fm *filemutex.FileMutex, lfn string, log logger.Interface) error {
err := fm.Close()
if err != nil {
log.V(1).Infof("Error closing lock file %s: %s", lfn, err)
}
return err
}
// LockFileName get the lock file name from the lock name.
func LockFileName(name string) string {
return path.Join(os.TempDir(), fmt.Sprintf(".kubelogin.%s.lock", name))
}
// Acquire acquire a lock for the specified name. The context could be used to set a timeout.
func (m *Mutex) Acquire(ctx context.Context, name string) (*Lock, error) {
lfn := LockFileName(name)
fm, err := filemutex.New(lfn)
if err != nil {
return nil, fmt.Errorf("error creating mutex file %s: %w", lfn, err)
}
lockChan := internalAcquire(fm)
select {
case <-ctx.Done():
_ = internalRelease(fm, lfn, m.Logger)
return nil, ctx.Err()
case err := <-lockChan:
if err != nil {
_ = internalRelease(fm, lfn, m.Logger)
return nil, fmt.Errorf("error acquiring lock on file %s: %w", lfn, err)
}
return &Lock{Data: fm, Name: name}, nil
}
}
// Release release the specified lock
func (m *Mutex) Release(lock *Lock) error {
fm := lock.Data.(*filemutex.FileMutex)
lfn := LockFileName(lock.Name)
return internalRelease(fm, lfn, m.Logger)
}

View File

@@ -1,64 +0,0 @@
package mutex
import (
"fmt"
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"golang.org/x/net/context"
"math/rand"
"sync"
"testing"
"time"
)
func TestMutex(t *testing.T) {
t.Run("Test successful parallel acquisition with no reentry allowed", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
nbConcurrency := 20
wg := sync.WaitGroup{}
events := make(chan int, nbConcurrency*2)
errors := make(chan error, nbConcurrency)
doLockUnlock := func() {
defer wg.Done()
m := Mutex{
Logger: logger.New(),
}
if mutex, err := m.Acquire(ctx, "test"); err == nil {
events <- 1
var dur = time.Duration(rand.Intn(5000))
time.Sleep(dur * time.Microsecond)
events <- -1
if err := m.Release(mutex); err != nil {
errors <- fmt.Errorf("Release error: %w", err)
}
} else {
errors <- fmt.Errorf("Acquire error: %w", err)
}
}
for i := 0; i < nbConcurrency; i++ {
wg.Add(1)
go doLockUnlock()
}
wg.Wait()
close(events)
close(errors)
countConcurrent := 0
for delta := range events {
countConcurrent += delta
if countConcurrent > 1 {
t.Errorf("The mutex did not prevented reentry: %d", countConcurrent)
}
}
for anError := range errors {
t.Errorf("The gorouting returned an error: %s", anError)
}
})
}

View File

@@ -1,63 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/int128/kubelogin/pkg/infrastructure/reader (interfaces: Interface)
// Package mock_reader is a generated GoMock package.
package mock_reader
import (
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockInterface is a mock of Interface interface
type MockInterface struct {
ctrl *gomock.Controller
recorder *MockInterfaceMockRecorder
}
// MockInterfaceMockRecorder is the mock recorder for MockInterface
type MockInterfaceMockRecorder struct {
mock *MockInterface
}
// NewMockInterface creates a new mock instance
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
mock := &MockInterface{ctrl: ctrl}
mock.recorder = &MockInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
return m.recorder
}
// ReadPassword mocks base method
func (m *MockInterface) ReadPassword(arg0 string) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ReadPassword", arg0)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ReadPassword indicates an expected call of ReadPassword
func (mr *MockInterfaceMockRecorder) ReadPassword(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadPassword", reflect.TypeOf((*MockInterface)(nil).ReadPassword), arg0)
}
// ReadString mocks base method
func (m *MockInterface) ReadString(arg0 string) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ReadString", arg0)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ReadString indicates an expected call of ReadString
func (mr *MockInterfaceMockRecorder) ReadString(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadString", reflect.TypeOf((*MockInterface)(nil).ReadString), arg0)
}

View File

@@ -13,8 +13,6 @@ import (
"golang.org/x/term"
)
//go:generate mockgen -destination mock_reader/mock_reader.go github.com/int128/kubelogin/pkg/infrastructure/reader Interface
// Set provides an implementation and interface for Reader.
var Set = wire.NewSet(
wire.Struct(new(Reader), "*"),

View File

@@ -11,8 +11,6 @@ import (
"k8s.io/client-go/tools/clientcmd/api"
)
//go:generate mockgen -destination mock_loader/mock_loader.go github.com/int128/kubelogin/pkg/kubeconfig/loader Interface
var Set = wire.NewSet(
wire.Struct(new(Loader), "*"),
wire.Bind(new(Interface), new(*Loader)),

View File

@@ -11,8 +11,7 @@ import (
func Test_loadByDefaultRules(t *testing.T) {
t.Run("google.yaml>keycloak.yaml", func(t *testing.T) {
setenv(t, "KUBECONFIG", "testdata/kubeconfig.google.yaml"+string(os.PathListSeparator)+"testdata/kubeconfig.keycloak.yaml")
defer unsetenv(t, "KUBECONFIG")
t.Setenv("KUBECONFIG", "testdata/kubeconfig.google.yaml"+string(os.PathListSeparator)+"testdata/kubeconfig.keycloak.yaml")
config, err := loadByDefaultRules("")
if err != nil {
@@ -36,8 +35,7 @@ func Test_loadByDefaultRules(t *testing.T) {
})
t.Run("keycloak.yaml>google.yaml", func(t *testing.T) {
setenv(t, "KUBECONFIG", "testdata/kubeconfig.keycloak.yaml"+string(os.PathListSeparator)+"testdata/kubeconfig.google.yaml")
defer unsetenv(t, "KUBECONFIG")
t.Setenv("KUBECONFIG", "testdata/kubeconfig.keycloak.yaml"+string(os.PathListSeparator)+"testdata/kubeconfig.google.yaml")
config, err := loadByDefaultRules("")
if err != nil {
@@ -61,20 +59,6 @@ func Test_loadByDefaultRules(t *testing.T) {
})
}
func setenv(t *testing.T, key, value string) {
t.Helper()
if err := os.Setenv(key, value); err != nil {
t.Fatalf("Could not set the env var %s=%s: %s", key, value, err)
}
}
func unsetenv(t *testing.T, key string) {
t.Helper()
if err := os.Unsetenv(key); err != nil {
t.Fatalf("Could not unset the env var %s: %s", key, err)
}
}
func Test_findCurrentAuthProvider(t *testing.T) {
t.Run("CurrentContext", func(t *testing.T) {
got, err := findCurrentAuthProvider(&api.Config{

View File

@@ -1,49 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/int128/kubelogin/pkg/kubeconfig/loader (interfaces: Interface)
// Package mock_loader is a generated GoMock package.
package mock_loader
import (
gomock "github.com/golang/mock/gomock"
kubeconfig "github.com/int128/kubelogin/pkg/kubeconfig"
reflect "reflect"
)
// MockInterface is a mock of Interface interface
type MockInterface struct {
ctrl *gomock.Controller
recorder *MockInterfaceMockRecorder
}
// MockInterfaceMockRecorder is the mock recorder for MockInterface
type MockInterfaceMockRecorder struct {
mock *MockInterface
}
// NewMockInterface creates a new mock instance
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
mock := &MockInterface{ctrl: ctrl}
mock.recorder = &MockInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
return m.recorder
}
// GetCurrentAuthProvider mocks base method
func (m *MockInterface) GetCurrentAuthProvider(arg0 string, arg1 kubeconfig.ContextName, arg2 kubeconfig.UserName) (*kubeconfig.AuthProvider, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetCurrentAuthProvider", arg0, arg1, arg2)
ret0, _ := ret[0].(*kubeconfig.AuthProvider)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetCurrentAuthProvider indicates an expected call of GetCurrentAuthProvider
func (mr *MockInterfaceMockRecorder) GetCurrentAuthProvider(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCurrentAuthProvider", reflect.TypeOf((*MockInterface)(nil).GetCurrentAuthProvider), arg0, arg1, arg2)
}

View File

@@ -1,48 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/int128/kubelogin/pkg/kubeconfig/writer (interfaces: Interface)
// Package mock_writer is a generated GoMock package.
package mock_writer
import (
gomock "github.com/golang/mock/gomock"
kubeconfig "github.com/int128/kubelogin/pkg/kubeconfig"
reflect "reflect"
)
// MockInterface is a mock of Interface interface
type MockInterface struct {
ctrl *gomock.Controller
recorder *MockInterfaceMockRecorder
}
// MockInterfaceMockRecorder is the mock recorder for MockInterface
type MockInterfaceMockRecorder struct {
mock *MockInterface
}
// NewMockInterface creates a new mock instance
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
mock := &MockInterface{ctrl: ctrl}
mock.recorder = &MockInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
return m.recorder
}
// UpdateAuthProvider mocks base method
func (m *MockInterface) UpdateAuthProvider(arg0 kubeconfig.AuthProvider) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UpdateAuthProvider", arg0)
ret0, _ := ret[0].(error)
return ret0
}
// UpdateAuthProvider indicates an expected call of UpdateAuthProvider
func (mr *MockInterfaceMockRecorder) UpdateAuthProvider(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAuthProvider", reflect.TypeOf((*MockInterface)(nil).UpdateAuthProvider), arg0)
}

View File

@@ -9,8 +9,6 @@ import (
"k8s.io/client-go/tools/clientcmd"
)
//go:generate mockgen -destination mock_writer/mock_writer.go github.com/int128/kubelogin/pkg/kubeconfig/writer Interface
var Set = wire.NewSet(
wire.Struct(new(Writer), "*"),
wire.Bind(new(Interface), new(*Writer)),

View File

@@ -1,8 +1,8 @@
package writer
import (
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/google/go-cmp/cmp"
@@ -14,13 +14,8 @@ func TestKubeconfig_UpdateAuth(t *testing.T) {
t.Run("MinimumKeys", func(t *testing.T) {
f := newKubeconfigFile(t)
defer func() {
if err := os.Remove(f.Name()); err != nil {
t.Errorf("Could not remove the temp file: %s", err)
}
}()
if err := w.UpdateAuthProvider(kubeconfig.AuthProvider{
LocationOfOrigin: f.Name(),
LocationOfOrigin: f,
UserName: "google",
IDPIssuerURL: "https://accounts.google.com",
ClientID: "GOOGLE_CLIENT_ID",
@@ -30,7 +25,7 @@ func TestKubeconfig_UpdateAuth(t *testing.T) {
}); err != nil {
t.Fatalf("Could not update auth: %s", err)
}
b, err := ioutil.ReadFile(f.Name())
b, err := os.ReadFile(f)
if err != nil {
t.Fatalf("Could not read kubeconfig: %s", err)
}
@@ -61,13 +56,8 @@ users:
t.Run("FullKeys", func(t *testing.T) {
f := newKubeconfigFile(t)
defer func() {
if err := os.Remove(f.Name()); err != nil {
t.Errorf("Could not remove the temp file: %s", err)
}
}()
if err := w.UpdateAuthProvider(kubeconfig.AuthProvider{
LocationOfOrigin: f.Name(),
LocationOfOrigin: f,
UserName: "google",
IDPIssuerURL: "https://accounts.google.com",
ClientID: "GOOGLE_CLIENT_ID",
@@ -80,7 +70,7 @@ users:
}); err != nil {
t.Fatalf("Could not update auth: %s", err)
}
b, err := ioutil.ReadFile(f.Name())
b, err := os.ReadFile(f)
if err != nil {
t.Fatalf("Could not read kubeconfig: %s", err)
}
@@ -113,8 +103,8 @@ users:
})
}
func newKubeconfigFile(t *testing.T) *os.File {
content := `apiVersion: v1
const kubeconfigContent = `
apiVersion: v1
clusters: []
kind: Config
preferences: {}
@@ -124,13 +114,12 @@ users:
auth-provider:
config:
idp-issuer-url: https://accounts.google.com
name: oidc`
f, err := ioutil.TempFile("", "kubeconfig")
if err != nil {
t.Fatalf("Could not create a file: %s", err)
}
defer f.Close()
if _, err := f.Write([]byte(content)); err != nil {
name: oidc
`
func newKubeconfigFile(t *testing.T) string {
f := filepath.Join(t.TempDir(), "kubeconfig")
if err := os.WriteFile(f, []byte(kubeconfigContent), 0644); err != nil {
t.Fatalf("Could not write kubeconfig: %s", err)
}
return f

View File

@@ -12,18 +12,19 @@ import (
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/pkce"
"github.com/int128/oauth2cli"
"github.com/int128/oauth2dev"
"golang.org/x/oauth2"
)
//go:generate mockgen -destination mock_client/mock_client.go github.com/int128/kubelogin/pkg/oidc/client Interface
type Interface interface {
GetAuthCodeURL(in AuthCodeURLInput) string
ExchangeAuthCode(ctx context.Context, in ExchangeAuthCodeInput) (*oidc.TokenSet, error)
GetTokenByAuthCode(ctx context.Context, in GetTokenByAuthCodeInput, localServerReadyChan chan<- string) (*oidc.TokenSet, error)
NegotiatedPKCEMethod() pkce.Method
GetTokenByROPC(ctx context.Context, username, password string) (*oidc.TokenSet, error)
GetDeviceAuthorization(ctx context.Context) (*oauth2dev.AuthorizationResponse, error)
ExchangeDeviceCode(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error)
Refresh(ctx context.Context, refreshToken string) (*oidc.TokenSet, error)
SupportedPKCEMethods() []string
}
type AuthCodeURLInput struct {
@@ -54,12 +55,14 @@ type GetTokenByAuthCodeInput struct {
}
type client struct {
httpClient *http.Client
provider *gooidc.Provider
oauth2Config oauth2.Config
clock clock.Interface
logger logger.Interface
supportedPKCEMethods []string
httpClient *http.Client
provider *gooidc.Provider
oauth2Config oauth2.Config
clock clock.Interface
logger logger.Interface
negotiatedPKCEMethod pkce.Method
deviceAuthorizationEndpoint string
useAccessToken bool
}
func (c *client) wrapContext(ctx context.Context) context.Context {
@@ -113,34 +116,33 @@ func (c *client) ExchangeAuthCode(ctx context.Context, in ExchangeAuthCodeInput)
return c.verifyToken(ctx, token, in.Nonce)
}
func authorizationRequestOptions(n string, p pkce.Params, e map[string]string) []oauth2.AuthCodeOption {
o := []oauth2.AuthCodeOption{
func authorizationRequestOptions(nonce string, pkceParams pkce.Params, extraParams map[string]string) []oauth2.AuthCodeOption {
opts := []oauth2.AuthCodeOption{
oauth2.AccessTypeOffline,
gooidc.Nonce(n),
gooidc.Nonce(nonce),
}
if !p.IsZero() {
o = append(o,
oauth2.SetAuthURLParam("code_challenge", p.CodeChallenge),
oauth2.SetAuthURLParam("code_challenge_method", p.CodeChallengeMethod),
)
if pkceParams.CodeChallenge != "" {
opts = append(opts, oauth2.SetAuthURLParam("code_challenge", pkceParams.CodeChallenge))
}
for key, value := range e {
o = append(o, oauth2.SetAuthURLParam(key, value))
if pkceParams.CodeChallengeMethod != "" {
opts = append(opts, oauth2.SetAuthURLParam("code_challenge_method", pkceParams.CodeChallengeMethod))
}
return o
for key, value := range extraParams {
opts = append(opts, oauth2.SetAuthURLParam(key, value))
}
return opts
}
func tokenRequestOptions(p pkce.Params) (o []oauth2.AuthCodeOption) {
if !p.IsZero() {
o = append(o, oauth2.SetAuthURLParam("code_verifier", p.CodeVerifier))
func tokenRequestOptions(pkceParams pkce.Params) []oauth2.AuthCodeOption {
var opts []oauth2.AuthCodeOption
if pkceParams.CodeVerifier != "" {
opts = append(opts, oauth2.SetAuthURLParam("code_verifier", pkceParams.CodeVerifier))
}
return
return opts
}
// SupportedPKCEMethods returns the PKCE methods supported by the provider.
// This may return nil if PKCE is not supported.
func (c *client) SupportedPKCEMethods() []string {
return c.supportedPKCEMethods
func (c *client) NegotiatedPKCEMethod() pkce.Method {
return c.negotiatedPKCEMethod
}
// GetTokenByROPC performs the resource owner password credentials flow.
@@ -153,6 +155,26 @@ func (c *client) GetTokenByROPC(ctx context.Context, username, password string)
return c.verifyToken(ctx, token, "")
}
// GetDeviceAuthorization initializes the device authorization code challenge
func (c *client) GetDeviceAuthorization(ctx context.Context) (*oauth2dev.AuthorizationResponse, error) {
ctx = c.wrapContext(ctx)
config := c.oauth2Config
config.Endpoint = oauth2.Endpoint{
AuthURL: c.deviceAuthorizationEndpoint,
}
return oauth2dev.RetrieveCode(ctx, config)
}
// ExchangeDeviceCode exchanges the device to an oidc.TokenSet
func (c *client) ExchangeDeviceCode(ctx context.Context, authResponse *oauth2dev.AuthorizationResponse) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
tokenResponse, err := oauth2dev.PollToken(ctx, c.oauth2Config, *authResponse)
if err != nil {
return nil, fmt.Errorf("device-code: exchange failed: %w", err)
}
return c.verifyToken(ctx, tokenResponse, "")
}
// Refresh sends a refresh token request and returns a token set.
func (c *client) Refresh(ctx context.Context, refreshToken string) (*oidc.TokenSet, error) {
ctx = c.wrapContext(ctx)
@@ -173,7 +195,7 @@ func (c *client) Refresh(ctx context.Context, refreshToken string) (*oidc.TokenS
func (c *client) verifyToken(ctx context.Context, token *oauth2.Token, nonce string) (*oidc.TokenSet, error) {
idToken, ok := token.Extra("id_token").(string)
if !ok {
return nil, fmt.Errorf("id_token is missing in the token response: %s", token)
return nil, fmt.Errorf("id_token is missing in the token response: %#v", token)
}
verifier := c.provider.Verifier(&gooidc.Config{ClientID: c.oauth2Config.ClientID, Now: c.clock.Now})
verifiedIDToken, err := verifier.Verify(ctx, idToken)
@@ -183,6 +205,32 @@ func (c *client) verifyToken(ctx context.Context, token *oauth2.Token, nonce str
if nonce != "" && nonce != verifiedIDToken.Nonce {
return nil, fmt.Errorf("nonce did not match (wants %s but got %s)", nonce, verifiedIDToken.Nonce)
}
if c.useAccessToken {
accessToken, ok := token.Extra("access_token").(string)
if !ok {
return nil, fmt.Errorf("access_token is missing in the token response: %#v", accessToken)
}
// We intentionally do not perform a ClientID check here because there
// are some use cases in access_tokens where we *expect* the audience
// to differ. For example, one can explicitly set
// `audience=CLUSTER_CLIENT_ID` as an extra auth parameter.
verifier = c.provider.Verifier(&gooidc.Config{ClientID: "", Now: c.clock.Now, SkipClientIDCheck: true})
_, err := verifier.Verify(ctx, accessToken)
if err != nil {
return nil, fmt.Errorf("could not verify the access token: %w", err)
}
// There is no `nonce` to check on the `access_token`. We rely on the
// above `nonce` check on the `id_token`.
return &oidc.TokenSet{
IDToken: accessToken,
RefreshToken: token.RefreshToken,
}, nil
}
return &oidc.TokenSet{
IDToken: idToken,
RefreshToken: token.RefreshToken,

View File

@@ -5,6 +5,7 @@ import (
"context"
"fmt"
"net/http"
"slices"
gooidc "github.com/coreos/go-oidc/v3/oidc"
"github.com/google/wire"
@@ -12,20 +13,19 @@ import (
"github.com/int128/kubelogin/pkg/infrastructure/logger"
"github.com/int128/kubelogin/pkg/oidc"
"github.com/int128/kubelogin/pkg/oidc/client/logging"
"github.com/int128/kubelogin/pkg/pkce"
"github.com/int128/kubelogin/pkg/tlsclientconfig"
"github.com/int128/kubelogin/pkg/tlsclientconfig/loader"
"golang.org/x/oauth2"
)
//go:generate mockgen -destination mock_client/mock_factory.go github.com/int128/kubelogin/pkg/oidc/client FactoryInterface
var Set = wire.NewSet(
wire.Struct(new(Factory), "*"),
wire.Bind(new(FactoryInterface), new(*Factory)),
)
type FactoryInterface interface {
New(ctx context.Context, p oidc.Provider, tlsClientConfig tlsclientconfig.Config) (Interface, error)
New(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config) (Interface, error)
}
type Factory struct {
@@ -35,7 +35,7 @@ type Factory struct {
}
// New returns an instance of infrastructure.Interface with the given configuration.
func (f *Factory) New(ctx context.Context, p oidc.Provider, tlsClientConfig tlsclientconfig.Config) (Interface, error) {
func (f *Factory) New(ctx context.Context, prov oidc.Provider, tlsClientConfig tlsclientconfig.Config) (Interface, error) {
rawTLSClientConfig, err := f.Loader.Load(tlsClientConfig)
if err != nil {
return nil, fmt.Errorf("could not load the TLS client config: %w", err)
@@ -53,7 +53,7 @@ func (f *Factory) New(ctx context.Context, p oidc.Provider, tlsClientConfig tlsc
}
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)
provider, err := gooidc.NewProvider(ctx, p.IssuerURL)
provider, err := gooidc.NewProvider(ctx, prov.IssuerURL)
if err != nil {
return nil, fmt.Errorf("oidc discovery error: %w", err)
}
@@ -61,27 +61,57 @@ func (f *Factory) New(ctx context.Context, p oidc.Provider, tlsClientConfig tlsc
if err != nil {
return nil, fmt.Errorf("could not determine supported PKCE methods: %w", err)
}
deviceAuthorizationEndpoint, err := extractDeviceAuthorizationEndpoint(provider)
if err != nil {
return nil, fmt.Errorf("could not determine device authorization endpoint: %w", err)
}
return &client{
httpClient: httpClient,
provider: provider,
oauth2Config: oauth2.Config{
Endpoint: provider.Endpoint(),
ClientID: p.ClientID,
ClientSecret: p.ClientSecret,
Scopes: append(p.ExtraScopes, gooidc.ScopeOpenID),
ClientID: prov.ClientID,
ClientSecret: prov.ClientSecret,
Scopes: append(prov.ExtraScopes, gooidc.ScopeOpenID),
},
clock: f.Clock,
logger: f.Logger,
supportedPKCEMethods: supportedPKCEMethods,
clock: f.Clock,
logger: f.Logger,
negotiatedPKCEMethod: determinePKCEMethod(supportedPKCEMethods, prov.PKCEMethod),
deviceAuthorizationEndpoint: deviceAuthorizationEndpoint,
useAccessToken: prov.UseAccessToken,
}, nil
}
func determinePKCEMethod(supportedMethods []string, preferredMethod oidc.PKCEMethod) pkce.Method {
switch preferredMethod {
case oidc.PKCEMethodNo:
return pkce.NoMethod
case oidc.PKCEMethodS256:
return pkce.MethodS256
default:
if slices.Contains(supportedMethods, "S256") {
return pkce.MethodS256
}
return pkce.NoMethod
}
}
func extractSupportedPKCEMethods(provider *gooidc.Provider) ([]string, error) {
var d struct {
var claims struct {
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
}
if err := provider.Claims(&d); err != nil {
if err := provider.Claims(&claims); err != nil {
return nil, fmt.Errorf("invalid discovery document: %w", err)
}
return d.CodeChallengeMethodsSupported, nil
return claims.CodeChallengeMethodsSupported, nil
}
func extractDeviceAuthorizationEndpoint(provider *gooidc.Provider) (string, error) {
var claims struct {
DeviceAuthorizationEndpoint string `json:"device_authorization_endpoint"`
}
if err := provider.Claims(&claims); err != nil {
return "", fmt.Errorf("invalid discovery document: %w", err)
}
return claims.DeviceAuthorizationEndpoint, nil
}

View File

@@ -7,7 +7,6 @@ import (
"strings"
"testing"
"github.com/golang/mock/gomock"
"github.com/int128/kubelogin/pkg/testing/logger"
)
@@ -22,9 +21,6 @@ func (t *mockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
}
func TestLoggingTransport_RoundTrip(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
req := httptest.NewRequest("GET", "http://example.com/hello", nil)
resp, err := http.ReadResponse(bufio.NewReader(strings.NewReader(`HTTP/1.1 200 OK
Host: example.com

View File

@@ -1,124 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/int128/kubelogin/pkg/oidc/client (interfaces: Interface)
// Package mock_client is a generated GoMock package.
package mock_client
import (
context "context"
gomock "github.com/golang/mock/gomock"
oidc "github.com/int128/kubelogin/pkg/oidc"
client "github.com/int128/kubelogin/pkg/oidc/client"
reflect "reflect"
)
// MockInterface is a mock of Interface interface
type MockInterface struct {
ctrl *gomock.Controller
recorder *MockInterfaceMockRecorder
}
// MockInterfaceMockRecorder is the mock recorder for MockInterface
type MockInterfaceMockRecorder struct {
mock *MockInterface
}
// NewMockInterface creates a new mock instance
func NewMockInterface(ctrl *gomock.Controller) *MockInterface {
mock := &MockInterface{ctrl: ctrl}
mock.recorder = &MockInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockInterface) EXPECT() *MockInterfaceMockRecorder {
return m.recorder
}
// ExchangeAuthCode mocks base method
func (m *MockInterface) ExchangeAuthCode(arg0 context.Context, arg1 client.ExchangeAuthCodeInput) (*oidc.TokenSet, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ExchangeAuthCode", arg0, arg1)
ret0, _ := ret[0].(*oidc.TokenSet)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ExchangeAuthCode indicates an expected call of ExchangeAuthCode
func (mr *MockInterfaceMockRecorder) ExchangeAuthCode(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ExchangeAuthCode", reflect.TypeOf((*MockInterface)(nil).ExchangeAuthCode), arg0, arg1)
}
// GetAuthCodeURL mocks base method
func (m *MockInterface) GetAuthCodeURL(arg0 client.AuthCodeURLInput) string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetAuthCodeURL", arg0)
ret0, _ := ret[0].(string)
return ret0
}
// GetAuthCodeURL indicates an expected call of GetAuthCodeURL
func (mr *MockInterfaceMockRecorder) GetAuthCodeURL(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAuthCodeURL", reflect.TypeOf((*MockInterface)(nil).GetAuthCodeURL), arg0)
}
// GetTokenByAuthCode mocks base method
func (m *MockInterface) GetTokenByAuthCode(arg0 context.Context, arg1 client.GetTokenByAuthCodeInput, arg2 chan<- string) (*oidc.TokenSet, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTokenByAuthCode", arg0, arg1, arg2)
ret0, _ := ret[0].(*oidc.TokenSet)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTokenByAuthCode indicates an expected call of GetTokenByAuthCode
func (mr *MockInterfaceMockRecorder) GetTokenByAuthCode(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTokenByAuthCode", reflect.TypeOf((*MockInterface)(nil).GetTokenByAuthCode), arg0, arg1, arg2)
}
// GetTokenByROPC mocks base method
func (m *MockInterface) GetTokenByROPC(arg0 context.Context, arg1, arg2 string) (*oidc.TokenSet, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetTokenByROPC", arg0, arg1, arg2)
ret0, _ := ret[0].(*oidc.TokenSet)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetTokenByROPC indicates an expected call of GetTokenByROPC
func (mr *MockInterfaceMockRecorder) GetTokenByROPC(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTokenByROPC", reflect.TypeOf((*MockInterface)(nil).GetTokenByROPC), arg0, arg1, arg2)
}
// Refresh mocks base method
func (m *MockInterface) Refresh(arg0 context.Context, arg1 string) (*oidc.TokenSet, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Refresh", arg0, arg1)
ret0, _ := ret[0].(*oidc.TokenSet)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Refresh indicates an expected call of Refresh
func (mr *MockInterfaceMockRecorder) Refresh(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Refresh", reflect.TypeOf((*MockInterface)(nil).Refresh), arg0, arg1)
}
// SupportedPKCEMethods mocks base method
func (m *MockInterface) SupportedPKCEMethods() []string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SupportedPKCEMethods")
ret0, _ := ret[0].([]string)
return ret0
}
// SupportedPKCEMethods indicates an expected call of SupportedPKCEMethods
func (mr *MockInterfaceMockRecorder) SupportedPKCEMethods() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SupportedPKCEMethods", reflect.TypeOf((*MockInterface)(nil).SupportedPKCEMethods))
}

View File

@@ -1,52 +0,0 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/int128/kubelogin/pkg/oidc/client (interfaces: FactoryInterface)
// Package mock_client is a generated GoMock package.
package mock_client
import (
context "context"
gomock "github.com/golang/mock/gomock"
oidc "github.com/int128/kubelogin/pkg/oidc"
client "github.com/int128/kubelogin/pkg/oidc/client"
tlsclientconfig "github.com/int128/kubelogin/pkg/tlsclientconfig"
reflect "reflect"
)
// MockFactoryInterface is a mock of FactoryInterface interface
type MockFactoryInterface struct {
ctrl *gomock.Controller
recorder *MockFactoryInterfaceMockRecorder
}
// MockFactoryInterfaceMockRecorder is the mock recorder for MockFactoryInterface
type MockFactoryInterfaceMockRecorder struct {
mock *MockFactoryInterface
}
// NewMockFactoryInterface creates a new mock instance
func NewMockFactoryInterface(ctrl *gomock.Controller) *MockFactoryInterface {
mock := &MockFactoryInterface{ctrl: ctrl}
mock.recorder = &MockFactoryInterfaceMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockFactoryInterface) EXPECT() *MockFactoryInterfaceMockRecorder {
return m.recorder
}
// New mocks base method
func (m *MockFactoryInterface) New(arg0 context.Context, arg1 oidc.Provider, arg2 tlsclientconfig.Config) (client.Interface, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "New", arg0, arg1, arg2)
ret0, _ := ret[0].(client.Interface)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// New indicates an expected call of New
func (mr *MockFactoryInterfaceMockRecorder) New(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "New", reflect.TypeOf((*MockFactoryInterface)(nil).New), arg0, arg1, arg2)
}

View File

@@ -11,12 +11,23 @@ import (
// Provider represents an OIDC provider.
type Provider struct {
IssuerURL string
ClientID string
ClientSecret string // optional
ExtraScopes []string // optional
IssuerURL string
ClientID string
ClientSecret string // optional
ExtraScopes []string // optional
PKCEMethod PKCEMethod
UseAccessToken bool
}
// PKCEMethod represents a preferred method of PKCE.
type PKCEMethod int
const (
PKCEMethodAuto PKCEMethod = iota
PKCEMethodNo
PKCEMethodS256
)
// TokenSet represents a set of ID token and refresh token.
type TokenSet struct {
IDToken string

View File

@@ -10,11 +10,12 @@ import (
"fmt"
)
var Plain Params
type Method int
const (
// code challenge methods defined as https://tools.ietf.org/html/rfc7636#section-4.3
methodS256 = "S256"
// Code challenge methods defined as https://tools.ietf.org/html/rfc7636#section-4.3
NoMethod Method = iota
MethodS256
)
// Params represents a set of the PKCE parameters.
@@ -24,27 +25,21 @@ type Params struct {
CodeVerifier string
}
func (p Params) IsZero() bool {
return p == Params{}
}
// New returns a parameters supported by the provider.
// You need to pass the code challenge methods defined in RFC7636.
// It returns Plain if no method is available.
func New(methods []string) (Params, error) {
for _, method := range methods {
if method == methodS256 {
return NewS256()
}
// It returns a zero value if no method is available.
func New(method Method) (Params, error) {
if method == MethodS256 {
return NewS256()
}
return Plain, nil
return Params{}, nil
}
// NewS256 generates a parameters for S256.
func NewS256() (Params, error) {
b, err := random32()
if err != nil {
return Plain, fmt.Errorf("could not generate a random: %w", err)
return Params{}, fmt.Errorf("could not generate a random: %w", err)
}
return computeS256(b), nil
}
@@ -63,7 +58,7 @@ func computeS256(b []byte) Params {
_, _ = s.Write([]byte(v))
return Params{
CodeChallenge: base64URLEncode(s.Sum(nil)),
CodeChallengeMethod: methodS256,
CodeChallengeMethod: "S256",
CodeVerifier: v,
}
}

View File

@@ -2,40 +2,33 @@ package pkce
import (
"testing"
"github.com/google/go-cmp/cmp"
)
func TestNew(t *testing.T) {
t.Run("S256", func(t *testing.T) {
p, err := New([]string{"plain", "S256"})
params, err := New(MethodS256)
if err != nil {
t.Fatalf("New error: %s", err)
}
if p.CodeChallengeMethod != "S256" {
t.Errorf("CodeChallengeMethod wants S256 but was %s", p.CodeChallengeMethod)
if params.CodeChallengeMethod != "S256" {
t.Errorf("CodeChallengeMethod wants S256 but was %s", params.CodeChallengeMethod)
}
if p.CodeChallenge == "" {
if params.CodeChallenge == "" {
t.Errorf("CodeChallenge wants non-empty but was empty")
}
if p.CodeVerifier == "" {
if params.CodeVerifier == "" {
t.Errorf("CodeVerifier wants non-empty but was empty")
}
})
t.Run("plain", func(t *testing.T) {
p, err := New([]string{"plain"})
t.Run("NoMethod", func(t *testing.T) {
params, err := New(NoMethod)
if err != nil {
t.Fatalf("New error: %s", err)
}
if !p.IsZero() {
t.Errorf("IsZero wants true but was false")
}
})
t.Run("nil", func(t *testing.T) {
p, err := New(nil)
if err != nil {
t.Fatalf("New error: %s", err)
}
if !p.IsZero() {
t.Errorf("IsZero wants true but was false")
if diff := cmp.Diff(Params{}, params); diff != "" {
t.Errorf("mismatch (-want +got):\n%s", diff)
}
})
}

View File

@@ -5,7 +5,7 @@ import (
"crypto/rsa"
"testing"
"github.com/dgrijalva/jwt-go"
"github.com/golang-jwt/jwt/v5"
)
var PrivateKey = generateKey(1024)
@@ -19,7 +19,7 @@ func generateKey(b int) *rsa.PrivateKey {
}
type Claims struct {
jwt.StandardClaims
jwt.RegisteredClaims
// aud claim is either a string or an array of strings.
// https://tools.ietf.org/html/rfc7519#section-4.1.3
Audience []string `json:"aud,omitempty"`

Some files were not shown because too many files have changed in this diff Show More