Skip to content

Commit dffdbb0

Browse files
armandpicardcluxkazk
authored
Fix interactivity in auth exec (#1083)
* Fix interactivity in auth exec Signed-off-by: armandpicard <[email protected]> * Add derive Eq for test Signed-off-by: armandpicard <[email protected]> * Update kube-client/src/client/auth/mod.rs Co-authored-by: kazk <[email protected]> Signed-off-by: Eirik A <[email protected]> Signed-off-by: armandpicard <[email protected]> Signed-off-by: Eirik A <[email protected]> Co-authored-by: Eirik A <[email protected]> Co-authored-by: kazk <[email protected]>
1 parent cde4530 commit dffdbb0

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

kube-client/src/client/auth/mod.rs

+29-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use thiserror::Error;
1818
use tokio::sync::{Mutex, RwLock};
1919
use tower::{filter::AsyncPredicate, BoxError};
2020

21-
use crate::config::{AuthInfo, AuthProviderConfig, ExecConfig};
21+
use crate::config::{AuthInfo, AuthProviderConfig, ExecConfig, ExecInteractiveMode};
2222

2323
#[cfg(feature = "oauth")] mod oauth;
2424
#[cfg(feature = "oauth")] pub use oauth::Error as OAuthError;
@@ -66,6 +66,10 @@ pub enum Error {
6666
#[error("failed to parse auth exec output: {0}")]
6767
AuthExecParse(#[source] serde_json::Error),
6868

69+
/// Fail to serialize input
70+
#[error("failed to serialize input: {0}")]
71+
AuthExecSerialize(#[source] serde_json::Error),
72+
6973
/// Failed to exec auth
7074
#[error("failed exec auth: {0}")]
7175
AuthExec(String),
@@ -461,13 +465,17 @@ pub struct ExecCredential {
461465
#[serde(rename = "apiVersion")]
462466
pub api_version: Option<String>,
463467
pub spec: Option<ExecCredentialSpec>,
468+
#[serde(skip_serializing_if = "Option::is_none")]
464469
pub status: Option<ExecCredentialStatus>,
465470
}
466471

467472
/// ExecCredenitalSpec holds request and runtime specific information provided
468473
/// by transport.
469474
#[derive(Clone, Debug, Serialize, Deserialize)]
470-
pub struct ExecCredentialSpec {}
475+
pub struct ExecCredentialSpec {
476+
#[serde(skip_serializing_if = "Option::is_none")]
477+
interactive: Option<bool>,
478+
}
471479

472480
/// ExecCredentialStatus holds credentials for the transport to use.
473481
#[derive(Clone, Debug, Serialize, Deserialize)]
@@ -500,6 +508,25 @@ fn auth_exec(auth: &ExecConfig) -> Result<ExecCredential, Error> {
500508
cmd.envs(envs);
501509
}
502510

511+
let interactive = auth.interactive_mode != Some(ExecInteractiveMode::Never);
512+
if interactive {
513+
cmd.stdin(std::process::Stdio::inherit());
514+
} else {
515+
cmd.stdin(std::process::Stdio::piped());
516+
}
517+
518+
// Provide exec info to child process
519+
let exec_info = serde_json::to_string(&ExecCredential {
520+
api_version: auth.api_version.clone(),
521+
kind: None,
522+
spec: Some(ExecCredentialSpec {
523+
interactive: Some(interactive),
524+
}),
525+
status: None,
526+
})
527+
.map_err(Error::AuthExecSerialize)?;
528+
cmd.env("KUBERNETES_EXEC_INFO", exec_info);
529+
503530
if let Some(envs) = &auth.drop_env {
504531
for env in envs {
505532
cmd.env_remove(env);

kube-client/src/config/file_config.rs

+17
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,23 @@ pub struct ExecConfig {
255255
/// It has been suggested in client-go via https://github.com/kubernetes/client-go/issues/1177
256256
#[serde(skip)]
257257
pub drop_env: Option<Vec<String>>,
258+
259+
/// Interative mode of the auth plugins
260+
#[serde(rename = "interactiveMode")]
261+
#[serde(skip_serializing_if = "Option::is_none")]
262+
pub interactive_mode: Option<ExecInteractiveMode>,
263+
}
264+
265+
/// ExecInteractiveMode define the interactity of the child process
266+
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
267+
#[cfg_attr(test, derive(Eq))]
268+
pub enum ExecInteractiveMode {
269+
/// Never get interactive
270+
Never,
271+
/// If available et interactive
272+
IfAvailable,
273+
/// Alwayes get interactive
274+
Always,
258275
}
259276

260277
/// NamedContext associates name with context.

kube-client/src/config/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,8 @@ const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(295);
401401

402402
// Expose raw config structs
403403
pub use file_config::{
404-
AuthInfo, AuthProviderConfig, Cluster, Context, ExecConfig, Kubeconfig, NamedAuthInfo, NamedCluster,
405-
NamedContext, NamedExtension, Preferences,
404+
AuthInfo, AuthProviderConfig, Cluster, Context, ExecConfig, ExecInteractiveMode, Kubeconfig,
405+
NamedAuthInfo, NamedCluster, NamedContext, NamedExtension, Preferences,
406406
};
407407

408408
#[cfg(test)]

0 commit comments

Comments
 (0)