Skip to content

Commit

Permalink
genpolicy: Add support for envFrom
Browse files Browse the repository at this point in the history
Signed-off-by: Saul Paredes <[email protected]>
  • Loading branch information
Redent0r committed Dec 19, 2023
1 parent 522463c commit 9f91c31
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 0 deletions.
21 changes: 21 additions & 0 deletions src/tools/genpolicy/src/config_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,27 @@ pub fn get_value(value_from: &pod::EnvVarSource, config_maps: &Vec<ConfigMap>) -
None
}

//eg ["key1=value1", "key2=value2"]
pub fn get_values(config_map_name: &str, config_maps: &Vec<ConfigMap>) -> Option<Vec<String>> {
for config_map in config_maps {
if config_map_name == &config_map.metadata.name.clone().unwrap() {
return config_map
.data
.as_ref()?
.keys()
.map(|key| {
let value = config_map.data.as_ref().unwrap().get(key).unwrap();
format!("{}={value}", &key)
})
.collect::<Vec<String>>()
.into();
}
}

None
}


#[async_trait]
impl yaml::K8sResource for ConfigMap {
async fn init(
Expand Down
77 changes: 77 additions & 0 deletions src/tools/genpolicy/src/pod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ pub struct Container {
#[serde(skip_serializing_if = "Option::is_none")]
env: Option<Vec<EnvVar>>,

#[serde(skip_serializing_if = "Option::is_none")]
envFrom: Option<Vec<EnvFromSource>>,

#[serde(skip_serializing_if = "Option::is_none")]
resources: Option<ResourceRequirements>,

Expand Down Expand Up @@ -373,6 +376,37 @@ pub struct ConfigMapKeySelector {
optional: Option<bool>,
}

/// See Reference / Kubernetes API / Workload Resources / Pod.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EnvFromSource {
#[serde(skip_serializing_if = "Option::is_none")]
pub configMapRef: Option<ConfigMapEnvSource>,

#[serde(skip_serializing_if = "Option::is_none")]
pub secretRef: Option<SecretEnvSource>,

#[serde(skip_serializing_if = "Option::is_none")]
pub prefix: Option<String>,
}

/// See Reference / Kubernetes API / Workload Resources / Pod.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SecretEnvSource {
pub name: String,

#[serde(skip_serializing_if = "Option::is_none")]
optional: Option<bool>,
}

/// See Reference / Kubernetes API / Workload Resources / Pod.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConfigMapEnvSource {
pub name: String,

#[serde(skip_serializing_if = "Option::is_none")]
optional: Option<bool>,
}

/// See Reference / Kubernetes API / Common Definitions / ResourceFieldSelector.
#[derive(Clone, Debug, Serialize, Deserialize)]
struct ResourceFieldSelector {
Expand Down Expand Up @@ -498,6 +532,21 @@ impl Container {
}
}
}

if let Some(env_from_sources) = &self.envFrom {
for env_from_source in env_from_sources {
let env_from_source_values = env_from_source.get_values(
config_maps,
secrets,
);

for value in env_from_source_values {
if !dest_env.contains(&value) {
dest_env.push(value.clone());
}
}
}
}
}

pub fn is_privileged(&self) -> bool {
Expand Down Expand Up @@ -588,6 +637,34 @@ impl Container {
}
}

impl EnvFromSource {
pub fn get_values(
&self,
config_maps: &Vec<config_map::ConfigMap>,
secrets: &Vec<secret::Secret>,
) -> Vec<String> {

if let Some(config_map_env_source) = &self.configMapRef {
if let Some(value) = config_map::get_values(&config_map_env_source.name, config_maps) {
return value.clone();
}
else {
panic!("Couldn't get values from configmap ref: {}", &config_map_env_source.name);
}
}

if let Some(secret_env_source) = &self.secretRef {
if let Some(value) = secret::get_values(&secret_env_source.name, secrets) {
return value.clone();
}
else {
panic!("Couldn't get values from secret ref: {}", &secret_env_source.name);
}
}
panic!("envFrom: no configmap or secret source found!");
}
}

impl EnvVar {
pub fn get_value(
&self,
Expand Down
23 changes: 23 additions & 0 deletions src/tools/genpolicy/src/secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::yaml;

use async_trait::async_trait;
use base64::{engine::general_purpose, Engine as _};
use serde::de::value;
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;

Expand Down Expand Up @@ -68,6 +69,28 @@ pub fn get_value(value_from: &pod::EnvVarSource, secrets: &Vec<Secret>) -> Optio
None
}

//eg ["key1=secret1", "key2=secret2"]
pub fn get_values(secret_name: &str, secrets: &Vec<Secret>) -> Option<Vec<String>> {
for secret in secrets {
if secret_name == &secret.metadata.name.clone().unwrap() {
return secret
.data
.as_ref()?
.keys()
.map(|key| {
let value = secret.data.as_ref().unwrap().get(key).unwrap();
let value_bytes = general_purpose::STANDARD.decode(&value).unwrap();
let value_string = std::str::from_utf8(&value_bytes).unwrap();
format!("{}={value_string}", &key)
})
.collect::<Vec<String>>()
.into();
}
}

None
}

#[async_trait]
impl yaml::K8sResource for Secret {
async fn init(&mut self, _use_cache: bool, doc_mapping: &serde_yaml::Value, _silent: bool) {
Expand Down

0 comments on commit 9f91c31

Please sign in to comment.