mirror of
https://github.com/int128/kubelogin.git
synced 2026-02-14 16:39:51 +00:00
Provide a token-cache-storage type of none (#1285)
Co-authored-by: Hidetake Iwata <int128@gmail.com>
This commit is contained in:
@@ -14,7 +14,7 @@ Flags:
|
||||
--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 (disk|keyring) (default "disk")
|
||||
--token-cache-storage string Storage for the token cache. One of (disk|keyring|none) (default "disk")
|
||||
--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 [SECURITY RISK] If set, the server's certificate will not be checked for validity
|
||||
@@ -122,6 +122,8 @@ Deleted the token cache at /home/user/.kube/cache/oidc-login
|
||||
Deleted the token cache from the keyring
|
||||
```
|
||||
|
||||
For systems with immutable storage and no keyring, a cache type of none is available.
|
||||
|
||||
### Home directory expansion
|
||||
|
||||
If a value in the following options begins with a tilde character `~`, it is expanded to the home directory.
|
||||
|
||||
@@ -18,7 +18,7 @@ func getDefaultTokenCacheDir() string {
|
||||
return filepath.Join("~", ".kube", "cache", "oidc-login")
|
||||
}
|
||||
|
||||
var allTokenCacheStorage = strings.Join([]string{"disk", "keyring"}, "|")
|
||||
var allTokenCacheStorage = strings.Join([]string{"disk", "keyring", "none"}, "|")
|
||||
|
||||
type tokenCacheOptions struct {
|
||||
TokenCacheDir string
|
||||
@@ -43,6 +43,8 @@ func (o *tokenCacheOptions) tokenCacheConfig() (tokencache.Config, error) {
|
||||
config.Storage = tokencache.StorageDisk
|
||||
case "keyring":
|
||||
config.Storage = tokencache.StorageKeyring
|
||||
case "none":
|
||||
config.Storage = tokencache.StorageNone
|
||||
default:
|
||||
return tokencache.Config{}, fmt.Errorf("token-cache-storage must be one of (%s)", allTokenCacheStorage)
|
||||
}
|
||||
|
||||
@@ -57,6 +57,8 @@ func (r *Repository) FindByKey(config tokencache.Config, key tokencache.Key) (*o
|
||||
return readFromFile(config, checksum)
|
||||
case tokencache.StorageKeyring:
|
||||
return readFromKeyring(checksum)
|
||||
case tokencache.StorageNone:
|
||||
return nil, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown storage mode: %v", config.Storage)
|
||||
}
|
||||
@@ -110,6 +112,8 @@ func (r *Repository) Save(config tokencache.Config, key tokencache.Key, tokenSet
|
||||
return writeToFile(config, checksum, tokenSet)
|
||||
case tokencache.StorageKeyring:
|
||||
return writeToKeyring(checksum, tokenSet)
|
||||
case tokencache.StorageNone:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unknown storage mode: %v", config.Storage)
|
||||
}
|
||||
@@ -142,7 +146,15 @@ func writeToKeyring(checksum string, tokenSet oidc.TokenSet) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Implement io.Closer for noneStorage type
|
||||
type noneStorageCloser struct{}
|
||||
|
||||
func (c noneStorageCloser) Close() error { return nil }
|
||||
|
||||
func (r *Repository) Lock(config tokencache.Config, key tokencache.Key) (io.Closer, error) {
|
||||
if config.Storage == tokencache.StorageNone {
|
||||
return noneStorageCloser{}, nil
|
||||
}
|
||||
checksum, err := computeChecksum(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not compute the key: %w", err)
|
||||
@@ -174,6 +186,8 @@ func (r *Repository) DeleteAll(config tokencache.Config) error {
|
||||
return fmt.Errorf("keyring delete: %w", err)
|
||||
}
|
||||
return nil
|
||||
case tokencache.StorageNone:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unknown storage mode: %v", config.Storage)
|
||||
}
|
||||
|
||||
@@ -29,4 +29,6 @@ const (
|
||||
StorageDisk Storage = iota
|
||||
// StorageDisk will only store cached keys in the OS keyring.
|
||||
StorageKeyring
|
||||
// StorageNone will not store cached keys.
|
||||
StorageNone
|
||||
)
|
||||
|
||||
@@ -112,6 +112,63 @@ func TestGetToken_Do(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("TokenCacheNoneReturnsNone", func(t *testing.T) {
|
||||
tokenCacheKey := tokencache.Key{
|
||||
Provider: oidc.Provider{
|
||||
IssuerURL: "https://accounts.google.com",
|
||||
ClientID: "YOUR_CLIENT_ID",
|
||||
ClientSecret: "YOUR_CLIENT_SECRET",
|
||||
},
|
||||
}
|
||||
ctx := context.TODO()
|
||||
in := Input{
|
||||
Provider: dummyProvider,
|
||||
TokenCacheConfig: tokencache.Config{
|
||||
Storage: tokencache.StorageNone,
|
||||
},
|
||||
GrantOptionSet: grantOptionSet,
|
||||
}
|
||||
mockAuthentication := authentication_mock.NewMockInterface(t)
|
||||
mockAuthentication.EXPECT().
|
||||
Do(ctx, authentication.Input{
|
||||
Provider: dummyProvider,
|
||||
GrantOptionSet: grantOptionSet,
|
||||
}).
|
||||
Return(&authentication.Output{TokenSet: issuedTokenSet}, nil)
|
||||
mockCloser := io_mock.NewMockCloser(t)
|
||||
mockCloser.EXPECT().
|
||||
Close().
|
||||
Return(nil)
|
||||
mockRepository := repository_mock.NewMockInterface(t)
|
||||
mockRepository.EXPECT().
|
||||
Lock(in.TokenCacheConfig, tokenCacheKey).
|
||||
Return(mockCloser, nil)
|
||||
mockRepository.EXPECT().
|
||||
FindByKey(in.TokenCacheConfig, tokenCacheKey).
|
||||
Return(nil, nil)
|
||||
mockRepository.EXPECT().
|
||||
Save(in.TokenCacheConfig, tokenCacheKey, issuedTokenSet).
|
||||
Return(nil)
|
||||
mockReader := reader_mock.NewMockInterface(t)
|
||||
mockReader.EXPECT().
|
||||
Read().
|
||||
Return(credentialpluginInput, nil)
|
||||
mockWriter := writer_mock.NewMockInterface(t)
|
||||
mockWriter.EXPECT().
|
||||
Write(issuedOutput).
|
||||
Return(nil)
|
||||
u := GetToken{
|
||||
Authentication: mockAuthentication,
|
||||
TokenCacheRepository: mockRepository,
|
||||
CredentialPluginReader: mockReader,
|
||||
CredentialPluginWriter: mockWriter,
|
||||
Logger: logger.New(t),
|
||||
Clock: clock.Fake(expiryTime.Add(-time.Hour)),
|
||||
}
|
||||
if err := u.Do(ctx, in); err != nil {
|
||||
t.Errorf("Do returned error: %+v", err)
|
||||
}
|
||||
})
|
||||
t.Run("ROPC", func(t *testing.T) {
|
||||
grantOptionSet := authentication.GrantOptionSet{
|
||||
ROPCOption: &ropc.Option{Username: "YOUR_USERNAME"},
|
||||
|
||||
Reference in New Issue
Block a user