Skip to content

Commit

Permalink
Enable secret data conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
nightkr committed Jun 21, 2023
1 parent 45c1de4 commit c839b08
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 19 deletions.
6 changes: 4 additions & 2 deletions rust/operator-binary/src/backend/k8s_search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use std::collections::{BTreeMap, HashSet};
use async_trait::async_trait;
use snafu::{OptionExt, ResultExt, Snafu};
use stackable_operator::{
k8s_openapi::{api::core::v1::Secret, apimachinery::pkg::apis::meta::v1::LabelSelector},
k8s_openapi::{
api::core::v1::Secret, apimachinery::pkg::apis::meta::v1::LabelSelector, ByteString,
},
kube::api::ListParams,
};

Expand Down Expand Up @@ -85,7 +87,7 @@ impl SecretBackend for K8sSearch {
.data
.unwrap_or_default()
.into_iter()
.map(|(k, v)| (k.into(), v.0))
.map(|(k, ByteString(v))| (k, v))
.collect(),
)))
}
Expand Down
19 changes: 12 additions & 7 deletions rust/operator-binary/src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@ pub mod tls;
use async_trait::async_trait;
use serde::{Deserialize, Deserializer};
use stackable_operator::k8s_openapi::chrono::{DateTime, FixedOffset};
use std::{
collections::{HashMap, HashSet},
convert::Infallible,
path::PathBuf,
};
use std::{collections::HashSet, convert::Infallible};

pub use dynamic::Dynamic;
pub use k8s_search::K8sSearch;
Expand Down Expand Up @@ -54,7 +50,18 @@ pub struct SecretVolumeSelector {
/// The name of the `Pod`'s `Namespace`, provided by Kubelet
#[serde(rename = "csi.storage.k8s.io/pod.namespace")]
pub namespace: String,
/// The desired format of the mounted secrets
///
/// Currently supported formats:
/// - (TLS) `pem-certificate` - A Kubernetes-style triple of PEM-encoded certificate files (`tls.crt`, `tls.key`, `ca.crt`).
/// - (TLS) `pkcs12-certificate` - A PKCS#12 trust store named `truststore.p12`.
/// - (Kerberos) `kerberos-keytab` - A Kerberos keytab named `keytab`.
///
/// Defaults to passing through the native format of the secret backend.
#[serde(rename = "secrets.stackable.tech/secret.format")]
pub format: Option<SecretFormat>,

/// The Kerberos service names (`SERVICE_NAME/hostname@realm`)
#[serde(
rename = "secrets.stackable.tech/kerberos.service.names",
default = "SecretVolumeSelector::default_kerberos_service_names",
Expand Down Expand Up @@ -108,8 +115,6 @@ impl SecretVolumeSelector {
}
}

type SecretFiles = HashMap<PathBuf, Vec<u8>>;

#[derive(Debug)]
pub struct SecretContents {
pub data: SecretData,
Expand Down
14 changes: 12 additions & 2 deletions rust/operator-binary/src/csi_server/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::{
backend::{
self, pod_info, pod_info::PodInfo, SecretBackendError, SecretContents, SecretVolumeSelector,
},
format::{self, SecretFormat},
grpc::csi::v1::{
node_server::Node, NodeExpandVolumeRequest, NodeExpandVolumeResponse,
NodeGetCapabilitiesRequest, NodeGetCapabilitiesResponse, NodeGetInfoRequest,
Expand Down Expand Up @@ -58,6 +59,8 @@ enum PublishError {
source: std::io::Error,
path: PathBuf,
},
#[snafu(display("failed to convert secret data into desired format"))]
FormatData { source: format::IntoFilesError },
#[snafu(display("failed to set volume permissions for {}", path.display()))]
SetDirPermissions {
source: std::io::Error,
Expand Down Expand Up @@ -94,6 +97,7 @@ impl From<PublishError> for Status {
}
PublishError::CreateDir { .. } => Status::unavailable(full_msg),
PublishError::Mount { .. } => Status::unavailable(full_msg),
PublishError::FormatData { .. } => Status::unavailable(full_msg),
PublishError::SetDirPermissions { .. } => Status::unavailable(full_msg),
PublishError::CreateFile { .. } => Status::unavailable(full_msg),
PublishError::WriteFile { .. } => Status::unavailable(full_msg),
Expand Down Expand Up @@ -186,6 +190,7 @@ impl SecretProvisionerNode {
&self,
target_path: &Path,
data: SecretContents,
format: Option<SecretFormat>,
) -> Result<(), PublishError> {
let create_secret = {
let mut opts = OpenOptions::new();
Expand All @@ -197,7 +202,11 @@ impl SecretProvisionerNode {
.mode(0o640);
opts
};
for (k, v) in data.data.into_files() {
for (k, v) in data
.data
.into_files(format)
.context(publish_error::FormatDataSnafu)?
{
let item_path = target_path.join(k);
if let Some(item_path_parent) = item_path.parent() {
create_dir_all(item_path_parent)
Expand Down Expand Up @@ -348,7 +357,8 @@ impl Node for SecretProvisionerNode {
self.tag_pod(&self.client, &request.volume_id, &selector, &data)
.await?;
self.prepare_secret_dir(&target_path).await?;
self.save_secret_data(&target_path, data).await?;
self.save_secret_data(&target_path, data, selector.format)
.await?;
Ok(Response::new(NodePublishVolumeResponse {}))
}
.await,
Expand Down
31 changes: 24 additions & 7 deletions rust/operator-binary/src/format/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::collections::HashMap;

use snafu::Snafu;

pub use self::{
convert::ConvertError,
well_known::{FromFilesError as ParseError, SecretFormat, WellKnownSecretData},
Expand All @@ -17,17 +19,32 @@ pub enum SecretData {
Unknown(SecretFiles),
}
impl SecretData {
pub fn into_files(self) -> SecretFiles {
match self {
SecretData::WellKnown(data) => data.into_files(),
SecretData::Unknown(files) => files,
}
}

pub fn parse(self) -> Result<WellKnownSecretData, ParseError> {
match self {
Self::WellKnown(x) => Ok(x),
Self::Unknown(files) => WellKnownSecretData::from_files(files),
}
}

pub fn into_files(self, format: Option<SecretFormat>) -> Result<SecretFiles, IntoFilesError> {
if let Some(format) = format {
Ok(self.parse()?.convert_to(format)?.into_files())
} else {
Ok(match self {
SecretData::WellKnown(data) => data.into_files(),
SecretData::Unknown(files) => files,
})
}
}
}

#[derive(Snafu, Debug)]
pub enum IntoFilesError {
#[snafu(display("failed to parse secret data"), context(false))]
Parse { source: ParseError },
#[snafu(
display("failed to convert secret data into desired format"),
context(false)
)]
Convert { source: ConvertError },
}
7 changes: 6 additions & 1 deletion rust/operator-binary/src/format/well_known.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{convert, ConvertError, SecretFiles};
use serde::Deserialize;
use snafu::{OptionExt, Snafu};
use strum::EnumDiscriminants;

Expand Down Expand Up @@ -32,7 +33,11 @@ pub struct KerberosKeytab {
}

#[derive(Debug, EnumDiscriminants)]
#[strum_discriminants(name(SecretFormat))]
#[strum_discriminants(
name(SecretFormat),
derive(Deserialize),
serde(rename_all = "kebab-case")
)]
pub enum WellKnownSecretData {
PemCertificate(PemCertificate),
Pkcs12Certificate(Pkcs12Certificate),
Expand Down

0 comments on commit c839b08

Please sign in to comment.