use super::*;
#[derive(Clone, Debug, Args)]
#[command(arg_required_else_help(true), verbatim_doc_comment)]
pub struct CreateDockerRegistrySecret {
name: String,
#[command(flatten)]
args: CreateDockerRegistrySecretArgs,
}
impl CreateDockerRegistrySecret {
pub async fn secret(&self) -> kube::Result<corev1::Secret> {
self.args.secret(&self.name).await
}
}
#[derive(Clone, Debug, Default, Args)]
#[group(multiple = false, required = true)]
struct CreateDockerRegistrySecretArgs {
#[command(flatten)]
direct: Option<DirectDockerRegistry>,
#[command(flatten)]
file: Option<FromFileDockerRegistry>,
}
impl CreateDockerRegistrySecretArgs {
async fn secret(&self, name: &str) -> kube::Result<corev1::Secret> {
let secret = if let Some(file) = self.file.as_ref() {
file.load(name)?
} else if let Some(direct) = self.direct.as_ref() {
direct.load(name)
} else {
unreachable!()
};
Ok(secret)
}
}
#[derive(Clone, Debug, Args)]
struct DirectDockerRegistry {
#[arg(
long,
value_name = "DOCKER_REGISTRY_SERVER",
default_value = "https://index.docker.io/v1/"
)]
docker_server: String,
#[arg(long)]
docker_username: String,
#[arg(long)]
docker_password: String,
#[arg(long)]
docker_email: Option<String>,
}
impl DirectDockerRegistry {
fn load(&self, name: &str) -> corev1::Secret {
let registry = &self.docker_server;
let username = &self.docker_username;
let password = &self.docker_password;
corev1::Secret::image_pull_secret(name, registry, username, password)
}
}
#[derive(Clone, Debug, Args)]
struct FromFileDockerRegistry {
#[arg(long, value_parser = File::validating_value_parser(FromFileDockerRegistry::validate))]
from_file: File,
}
impl FromFileDockerRegistry {
fn validate(file: File) -> Result<File, String> {
match file.key() {
Some(".dockerconfigjson") => Ok(file),
Some(other) => Err(format!("key '{other}' is invalid for this operation")),
None => Ok(file),
}
}
fn load(&self, name: &str) -> kube::Result<corev1::Secret> {
let (key, config) = self.load_data()?.into_pair();
debug_assert_eq!(key, corev1::Secret::SECRET_TYPE_DOCKER_CONFIG_JSON);
let secret = corev1::Secret::docker_config_json_binary(name, config);
Ok(secret)
}
fn load_data(&self) -> kube::Result<KeyValue<k8s::ByteString>> {
let items = self
.from_file
.load()
.map_err(serde::ser::Error::custom)
.map_err(kube::Error::SerdeError)?;
let Result::<[_; 1], _>::Ok([item]) = items.try_into() else {
return Err(kube::Error::LinesCodecMaxLineLengthExceeded);
};
Ok(item.byte_string())
}
}