Skip to content

Commit 31d0a6b

Browse files
authored
[SVLS-7885] update tag splitting to allow for ',' and ' ' (#916)
## Overview We currently split the`DD_TAGS` only by `,`. Customer is asking if we can also split by spaces since that is common for container images and lambda lets you deploy images. (https://docs.datadoghq.com/getting_started/tagging/assigning_tags/?tab=noncontainerizedenvironments)
1 parent 290016e commit 31d0a6b

File tree

1 file changed

+92
-4
lines changed

1 file changed

+92
-4
lines changed

bottlecap/src/config/mod.rs

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -551,15 +551,17 @@ where
551551
E: serde::de::Error,
552552
{
553553
let mut map = HashMap::new();
554-
555-
for tag in value.split(',') {
554+
for tag in value.split(&[',', ' ']) {
555+
if tag.is_empty() {
556+
continue;
557+
}
556558
let parts = tag.split(':').collect::<Vec<&str>>();
557-
if parts.len() == 2 {
559+
if parts.len() == 2 && !parts[0].is_empty() && !parts[1].is_empty() {
558560
map.insert(parts[0].to_string(), parts[1].to_string());
559561
} else {
560562
error!(
561563
"Failed to parse tag '{}', expected format 'key:value', ignoring",
562-
tag.trim()
564+
tag
563565
);
564566
}
565567
}
@@ -1263,6 +1265,62 @@ pub mod tests {
12631265
});
12641266
}
12651267

1268+
#[test]
1269+
fn test_tags_comma_separated() {
1270+
figment::Jail::expect_with(|jail| {
1271+
jail.clear_env();
1272+
jail.set_env("DD_TAGS", "team:serverless,env:prod,version:1.0");
1273+
let config = get_config(Path::new(""));
1274+
assert_eq!(config.tags.get("team"), Some(&"serverless".to_string()));
1275+
assert_eq!(config.tags.get("env"), Some(&"prod".to_string()));
1276+
assert_eq!(config.tags.get("version"), Some(&"1.0".to_string()));
1277+
assert_eq!(config.tags.len(), 3);
1278+
Ok(())
1279+
});
1280+
}
1281+
1282+
#[test]
1283+
fn test_tags_space_separated() {
1284+
figment::Jail::expect_with(|jail| {
1285+
jail.clear_env();
1286+
jail.set_env("DD_TAGS", "team:serverless env:prod version:1.0");
1287+
let config = get_config(Path::new(""));
1288+
assert_eq!(config.tags.get("team"), Some(&"serverless".to_string()));
1289+
assert_eq!(config.tags.get("env"), Some(&"prod".to_string()));
1290+
assert_eq!(config.tags.get("version"), Some(&"1.0".to_string()));
1291+
assert_eq!(config.tags.len(), 3);
1292+
Ok(())
1293+
});
1294+
}
1295+
1296+
#[test]
1297+
fn test_tags_space_separated_with_extra_spaces() {
1298+
figment::Jail::expect_with(|jail| {
1299+
jail.clear_env();
1300+
jail.set_env("DD_TAGS", "team:serverless env:prod version:1.0");
1301+
let config = get_config(Path::new(""));
1302+
assert_eq!(config.tags.get("team"), Some(&"serverless".to_string()));
1303+
assert_eq!(config.tags.get("env"), Some(&"prod".to_string()));
1304+
assert_eq!(config.tags.get("version"), Some(&"1.0".to_string()));
1305+
assert_eq!(config.tags.len(), 3);
1306+
Ok(())
1307+
});
1308+
}
1309+
1310+
#[test]
1311+
fn test_tags_mixed_separators() {
1312+
figment::Jail::expect_with(|jail| {
1313+
jail.clear_env();
1314+
jail.set_env("DD_TAGS", "team:serverless,env:prod version:1.0");
1315+
let config = get_config(Path::new(""));
1316+
assert_eq!(config.tags.get("team"), Some(&"serverless".to_string()));
1317+
assert_eq!(config.tags.get("env"), Some(&"prod".to_string()));
1318+
assert_eq!(config.tags.get("version"), Some(&"1.0".to_string()));
1319+
assert_eq!(config.tags.len(), 3);
1320+
Ok(())
1321+
});
1322+
}
1323+
12661324
#[test]
12671325
fn test_parse_bool_from_anything() {
12681326
figment::Jail::expect_with(|jail| {
@@ -1388,4 +1446,34 @@ pub mod tests {
13881446
Value { duration: None }
13891447
);
13901448
}
1449+
1450+
#[test]
1451+
fn test_deserialize_key_value_pairs_ignores_empty_keys() {
1452+
#[derive(Deserialize, Debug, PartialEq)]
1453+
struct TestStruct {
1454+
#[serde(deserialize_with = "deserialize_key_value_pairs")]
1455+
tags: HashMap<String, String>,
1456+
}
1457+
1458+
let result = serde_json::from_str::<TestStruct>(r#"{"tags": ":value,valid:tag"}"#)
1459+
.expect("failed to parse JSON");
1460+
let mut expected = HashMap::new();
1461+
expected.insert("valid".to_string(), "tag".to_string());
1462+
assert_eq!(result.tags, expected);
1463+
}
1464+
1465+
#[test]
1466+
fn test_deserialize_key_value_pairs_ignores_empty_values() {
1467+
#[derive(Deserialize, Debug, PartialEq)]
1468+
struct TestStruct {
1469+
#[serde(deserialize_with = "deserialize_key_value_pairs")]
1470+
tags: HashMap<String, String>,
1471+
}
1472+
1473+
let result = serde_json::from_str::<TestStruct>(r#"{"tags": "key:,valid:tag"}"#)
1474+
.expect("failed to parse JSON");
1475+
let mut expected = HashMap::new();
1476+
expected.insert("valid".to_string(), "tag".to_string());
1477+
assert_eq!(result.tags, expected);
1478+
}
13911479
}

0 commit comments

Comments
 (0)