mirror of
https://github.com/kubernetes/client-go.git
synced 2025-09-03 16:16:06 +00:00
exec credential provider: InteractiveMode support
The value here is that the exec plugin author can use the kubeconfig to assert how standard input is treated with respect to the exec plugin, e.g., - an exec plugin author can ensure that kubectl fails if it cannot provide standard input to an exec plugin that needs it (Always) - an exec plugin author can ensure that an client-go process will still call an exec plugin that prefers standard input even if standard input is not available (IfAvailable) Signed-off-by: Andrew Keesler <akeesler@vmware.com> Kubernetes-commit: cd83d89ac94c5b61fdd38840098e7223e5af0d34
This commit is contained in:
committed by
Kubernetes Publisher
parent
1bccfc8c60
commit
37ed584bed
@@ -162,10 +162,10 @@ func (s *sometimes) Do(f func()) {
|
||||
|
||||
// GetAuthenticator returns an exec-based plugin for providing client credentials.
|
||||
func GetAuthenticator(config *api.ExecConfig, cluster *clientauthentication.Cluster) (*Authenticator, error) {
|
||||
return newAuthenticator(globalCache, config, cluster)
|
||||
return newAuthenticator(globalCache, term.IsTerminal, config, cluster)
|
||||
}
|
||||
|
||||
func newAuthenticator(c *cache, config *api.ExecConfig, cluster *clientauthentication.Cluster) (*Authenticator, error) {
|
||||
func newAuthenticator(c *cache, isTerminalFunc func(int) bool, config *api.ExecConfig, cluster *clientauthentication.Cluster) (*Authenticator, error) {
|
||||
key := cacheKey(config, cluster)
|
||||
if a, ok := c.get(key); ok {
|
||||
return a, nil
|
||||
@@ -196,11 +196,11 @@ func newAuthenticator(c *cache, config *api.ExecConfig, cluster *clientauthentic
|
||||
clock: clock.RealClock{},
|
||||
},
|
||||
|
||||
stdin: os.Stdin,
|
||||
stderr: os.Stderr,
|
||||
interactive: term.IsTerminal(int(os.Stdin.Fd())),
|
||||
now: time.Now,
|
||||
environ: os.Environ,
|
||||
stdin: os.Stdin,
|
||||
stderr: os.Stderr,
|
||||
interactiveFunc: func() (bool, error) { return isInteractive(isTerminalFunc, config) },
|
||||
now: time.Now,
|
||||
environ: os.Environ,
|
||||
|
||||
defaultDialer: defaultDialer,
|
||||
connTracker: connTracker,
|
||||
@@ -213,6 +213,33 @@ func newAuthenticator(c *cache, config *api.ExecConfig, cluster *clientauthentic
|
||||
return c.put(key, a), nil
|
||||
}
|
||||
|
||||
func isInteractive(isTerminalFunc func(int) bool, config *api.ExecConfig) (bool, error) {
|
||||
var shouldBeInteractive bool
|
||||
switch config.InteractiveMode {
|
||||
case api.NeverExecInteractiveMode:
|
||||
shouldBeInteractive = false
|
||||
case api.IfAvailableExecInteractiveMode:
|
||||
shouldBeInteractive = !config.StdinUnavailable && isTerminalFunc(int(os.Stdin.Fd()))
|
||||
case api.AlwaysExecInteractiveMode:
|
||||
if !isTerminalFunc(int(os.Stdin.Fd())) {
|
||||
return false, errors.New("standard input is not a terminal")
|
||||
}
|
||||
if config.StdinUnavailable {
|
||||
suffix := ""
|
||||
if len(config.StdinUnavailableMessage) > 0 {
|
||||
// only print extra ": <message>" if the user actually specified a message
|
||||
suffix = fmt.Sprintf(": %s", config.StdinUnavailableMessage)
|
||||
}
|
||||
return false, fmt.Errorf("standard input is unavailable%s", suffix)
|
||||
}
|
||||
shouldBeInteractive = true
|
||||
default:
|
||||
return false, fmt.Errorf("unknown interactiveMode: %q", config.InteractiveMode)
|
||||
}
|
||||
|
||||
return shouldBeInteractive, nil
|
||||
}
|
||||
|
||||
// Authenticator is a client credential provider that rotates credentials by executing a plugin.
|
||||
// The plugin input and output are defined by the API group client.authentication.k8s.io.
|
||||
type Authenticator struct {
|
||||
@@ -231,11 +258,11 @@ type Authenticator struct {
|
||||
installHint string
|
||||
|
||||
// Stubbable for testing
|
||||
stdin io.Reader
|
||||
stderr io.Writer
|
||||
interactive bool
|
||||
now func() time.Time
|
||||
environ func() []string
|
||||
stdin io.Reader
|
||||
stderr io.Writer
|
||||
interactiveFunc func() (bool, error)
|
||||
now func() time.Time
|
||||
environ func() []string
|
||||
|
||||
// defaultDialer is used for clients which don't specify a custom dialer
|
||||
defaultDialer *connrotation.Dialer
|
||||
@@ -376,10 +403,15 @@ func (a *Authenticator) maybeRefreshCreds(creds *credentials, r *clientauthentic
|
||||
// refreshCredsLocked executes the plugin and reads the credentials from
|
||||
// stdout. It must be called while holding the Authenticator's mutex.
|
||||
func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) error {
|
||||
interactive, err := a.interactiveFunc()
|
||||
if err != nil {
|
||||
return fmt.Errorf("exec plugin cannot support interactive mode: %w", err)
|
||||
}
|
||||
|
||||
cred := &clientauthentication.ExecCredential{
|
||||
Spec: clientauthentication.ExecCredentialSpec{
|
||||
Response: r,
|
||||
Interactive: a.interactive,
|
||||
Interactive: interactive,
|
||||
},
|
||||
}
|
||||
if a.provideClusterInfo {
|
||||
@@ -398,7 +430,7 @@ func (a *Authenticator) refreshCredsLocked(r *clientauthentication.Response) err
|
||||
cmd.Env = env
|
||||
cmd.Stderr = a.stderr
|
||||
cmd.Stdout = stdout
|
||||
if a.interactive {
|
||||
if interactive {
|
||||
cmd.Stdin = a.stdin
|
||||
}
|
||||
|
||||
|
@@ -244,12 +244,25 @@ func TestCacheKey(t *testing.T) {
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
}
|
||||
|
||||
// c7 should be the same as c6, except c7 has stdin marked as unavailable
|
||||
c7 := &api.ExecConfig{
|
||||
Command: "foo-bar",
|
||||
Args: []string{"1", "2"},
|
||||
Env: []api.ExecEnvVar{
|
||||
{Name: "3", Value: "4"},
|
||||
{Name: "5", Value: "6"},
|
||||
},
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
StdinUnavailable: true,
|
||||
}
|
||||
|
||||
key1 := cacheKey(c1, c1c)
|
||||
key2 := cacheKey(c2, c2c)
|
||||
key3 := cacheKey(c3, c3c)
|
||||
key4 := cacheKey(c4, c4c)
|
||||
key5 := cacheKey(c5, c5c)
|
||||
key6 := cacheKey(c6, nil)
|
||||
key7 := cacheKey(c7, nil)
|
||||
if key1 != key2 {
|
||||
t.Error("key1 and key2 didn't match")
|
||||
}
|
||||
@@ -268,6 +281,9 @@ func TestCacheKey(t *testing.T) {
|
||||
if key6 == key4 {
|
||||
t.Error("key6 and key4 matched")
|
||||
}
|
||||
if key6 == key7 {
|
||||
t.Error("key6 and key7 matched")
|
||||
}
|
||||
}
|
||||
|
||||
func compJSON(t *testing.T, got, want []byte) {
|
||||
@@ -290,23 +306,25 @@ func compJSON(t *testing.T, got, want []byte) {
|
||||
|
||||
func TestRefreshCreds(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config api.ExecConfig
|
||||
exitCode int
|
||||
cluster *clientauthentication.Cluster
|
||||
output string
|
||||
interactive bool
|
||||
response *clientauthentication.Response
|
||||
wantInput string
|
||||
wantCreds credentials
|
||||
wantExpiry time.Time
|
||||
wantErr bool
|
||||
wantErrSubstr string
|
||||
name string
|
||||
config api.ExecConfig
|
||||
stdinUnavailable bool
|
||||
exitCode int
|
||||
cluster *clientauthentication.Cluster
|
||||
output string
|
||||
isTerminal bool
|
||||
response *clientauthentication.Response
|
||||
wantInput string
|
||||
wantCreds credentials
|
||||
wantExpiry time.Time
|
||||
wantErr bool
|
||||
wantErrSubstr string
|
||||
}{
|
||||
{
|
||||
name: "basic-request",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
@@ -325,9 +343,10 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "interactive",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
interactive: true,
|
||||
isTerminal: true,
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
"apiVersion":"client.authentication.k8s.io/v1alpha1",
|
||||
@@ -347,7 +366,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "response",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
response: &clientauthentication.Response{
|
||||
Header: map[string][]string{
|
||||
@@ -381,7 +401,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "expiry",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
@@ -402,7 +423,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "no-group-version",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
@@ -420,7 +442,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "no-status",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
@@ -436,7 +459,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "no-creds",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
@@ -453,7 +477,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "TLS credentials",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
@@ -473,7 +498,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "bad TLS credentials",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
@@ -493,7 +519,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "cert but no key",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
@@ -512,12 +539,207 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "beta-basic-request",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {}
|
||||
"spec": {
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"status": {
|
||||
"token": "foo-bar"
|
||||
}
|
||||
}`,
|
||||
wantCreds: credentials{token: "foo-bar"},
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-never-interactive-mode",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.NeverExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"status": {
|
||||
"token": "foo-bar"
|
||||
}
|
||||
}`,
|
||||
wantCreds: credentials{token: "foo-bar"},
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-never-interactive-mode-and-stdin-unavailable",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.NeverExecInteractiveMode,
|
||||
StdinUnavailable: true,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"status": {
|
||||
"token": "foo-bar"
|
||||
}
|
||||
}`,
|
||||
wantCreds: credentials{token: "foo-bar"},
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-if-available-interactive-mode",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"status": {
|
||||
"token": "foo-bar"
|
||||
}
|
||||
}`,
|
||||
wantCreds: credentials{token: "foo-bar"},
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-if-available-interactive-mode-and-stdin-unavailable",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
StdinUnavailable: true,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"status": {
|
||||
"token": "foo-bar"
|
||||
}
|
||||
}`,
|
||||
wantCreds: credentials{token: "foo-bar"},
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-if-available-interactive-mode-and-terminal",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
isTerminal: true,
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {
|
||||
"interactive": true
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"status": {
|
||||
"token": "foo-bar"
|
||||
}
|
||||
}`,
|
||||
wantCreds: credentials{token: "foo-bar"},
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-if-available-interactive-mode-and-terminal-and-stdin-unavailable",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
StdinUnavailable: true,
|
||||
},
|
||||
isTerminal: true,
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"status": {
|
||||
"token": "foo-bar"
|
||||
}
|
||||
}`,
|
||||
wantCreds: credentials{token: "foo-bar"},
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-always-interactive-mode",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.AlwaysExecInteractiveMode,
|
||||
},
|
||||
wantErr: true,
|
||||
wantErrSubstr: "exec plugin cannot support interactive mode: standard input is not a terminal",
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-always-interactive-mode-and-terminal-and-stdin-unavailable",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.AlwaysExecInteractiveMode,
|
||||
StdinUnavailable: true,
|
||||
},
|
||||
isTerminal: true,
|
||||
wantErr: true,
|
||||
wantErrSubstr: "exec plugin cannot support interactive mode: standard input is unavailable",
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-always-interactive-mode-and-terminal-and-stdin-unavailable-with-message",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.AlwaysExecInteractiveMode,
|
||||
StdinUnavailable: true,
|
||||
StdinUnavailableMessage: "some message",
|
||||
},
|
||||
isTerminal: true,
|
||||
wantErr: true,
|
||||
wantErrSubstr: "exec plugin cannot support interactive mode: standard input is unavailable: some message",
|
||||
},
|
||||
{
|
||||
name: "beta-basic-request-with-always-interactive-mode-and-terminal",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.AlwaysExecInteractiveMode,
|
||||
},
|
||||
isTerminal: true,
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {
|
||||
"interactive": true
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
@@ -531,12 +753,15 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "beta-expiry",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantInput: `{
|
||||
"kind": "ExecCredential",
|
||||
"apiVersion": "client.authentication.k8s.io/v1beta1",
|
||||
"spec": {}
|
||||
"spec": {
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
@@ -552,7 +777,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "beta-no-group-version",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
@@ -565,7 +791,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "beta-no-status",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
@@ -576,7 +803,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "beta-no-token",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
@@ -588,9 +816,10 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "unknown-binary",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
Command: "does not exist",
|
||||
InstallHint: "some install hint",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
Command: "does not exist",
|
||||
InstallHint: "some install hint",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
wantErr: true,
|
||||
wantErrSubstr: "some install hint",
|
||||
@@ -598,7 +827,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "binary-fails",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
exitCode: 73,
|
||||
wantErr: true,
|
||||
@@ -607,7 +837,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "alpha-with-cluster-is-ignored",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
cluster: &clientauthentication.Cluster{
|
||||
Server: "foo",
|
||||
@@ -657,6 +888,7 @@ func TestRefreshCreds(t *testing.T) {
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
ProvideClusterInfo: true,
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
cluster: &clientauthentication.Cluster{
|
||||
Server: "foo",
|
||||
@@ -693,7 +925,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
"audience": "snorlax"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
@@ -708,7 +941,8 @@ func TestRefreshCreds(t *testing.T) {
|
||||
{
|
||||
name: "beta-with-cluster-and-without-provide-cluster-info-is-not-serialized",
|
||||
config: api.ExecConfig{
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
},
|
||||
cluster: &clientauthentication.Cluster{
|
||||
Server: "foo",
|
||||
@@ -733,7 +967,9 @@ func TestRefreshCreds(t *testing.T) {
|
||||
wantInput: `{
|
||||
"kind":"ExecCredential",
|
||||
"apiVersion":"client.authentication.k8s.io/v1beta1",
|
||||
"spec": {}
|
||||
"spec": {
|
||||
"interactive": false
|
||||
}
|
||||
}`,
|
||||
output: `{
|
||||
"kind": "ExecCredential",
|
||||
@@ -762,14 +998,13 @@ func TestRefreshCreds(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
a, err := newAuthenticator(newCache(), &c, test.cluster)
|
||||
a, err := newAuthenticator(newCache(), func(_ int) bool { return test.isTerminal }, &c, test.cluster)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
stderr := &bytes.Buffer{}
|
||||
a.stderr = stderr
|
||||
a.interactive = test.interactive
|
||||
a.environ = func() []string { return nil }
|
||||
|
||||
if err := a.refreshCredsLocked(test.response); err != nil {
|
||||
@@ -837,10 +1072,11 @@ func TestRoundTripper(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(handler))
|
||||
|
||||
c := api.ExecConfig{
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
}
|
||||
a, err := newAuthenticator(newCache(), &c, nil)
|
||||
a, err := newAuthenticator(newCache(), func(_ int) bool { return false }, &c, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -943,7 +1179,7 @@ func TestAuthorizationHeaderPresentCancelsExecAction(t *testing.T) {
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
a, err := newAuthenticator(newCache(), &api.ExecConfig{
|
||||
a, err := newAuthenticator(newCache(), func(_ int) bool { return false }, &api.ExecConfig{
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
}, nil)
|
||||
@@ -985,9 +1221,10 @@ func TestTLSCredentials(t *testing.T) {
|
||||
server.StartTLS()
|
||||
defer server.Close()
|
||||
|
||||
a, err := newAuthenticator(newCache(), &api.ExecConfig{
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
a, err := newAuthenticator(newCache(), func(_ int) bool { return false }, &api.ExecConfig{
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -1078,7 +1315,7 @@ func TestConcurrentUpdateTransportConfig(t *testing.T) {
|
||||
Command: "./testdata/test-plugin.sh",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
}
|
||||
a, err := newAuthenticator(newCache(), &c, nil)
|
||||
a, err := newAuthenticator(newCache(), func(_ int) bool { return false }, &c, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -1141,11 +1378,12 @@ func TestInstallHintRateLimit(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
c := api.ExecConfig{
|
||||
Command: "does not exist",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InstallHint: "some install hint",
|
||||
Command: "does not exist",
|
||||
APIVersion: "client.authentication.k8s.io/v1alpha1",
|
||||
InstallHint: "some install hint",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
}
|
||||
a, err := newAuthenticator(newCache(), &c, nil)
|
||||
a, err := newAuthenticator(newCache(), func(_ int) bool { return false }, &c, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@@ -140,9 +140,10 @@ func TestCallsMetric(t *testing.T) {
|
||||
{Name: "TEST_EXIT_CODE", Value: fmt.Sprintf("%d", exitCode)},
|
||||
{Name: "TEST_OUTPUT", Value: goodOutput},
|
||||
},
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
}
|
||||
|
||||
a, err := newAuthenticator(newCache(), &c, nil)
|
||||
a, err := newAuthenticator(newCache(), func(_ int) bool { return false }, &c, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -171,10 +172,11 @@ func TestCallsMetric(t *testing.T) {
|
||||
// metric values.
|
||||
refreshCreds := func(command string) {
|
||||
c := api.ExecConfig{
|
||||
Command: "does not exist",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
Command: "does not exist",
|
||||
APIVersion: "client.authentication.k8s.io/v1beta1",
|
||||
InteractiveMode: api.IfAvailableExecInteractiveMode,
|
||||
}
|
||||
a, err := newAuthenticator(newCache(), &c, nil)
|
||||
a, err := newAuthenticator(newCache(), func(_ int) bool { return false }, &c, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user