@@ -182,33 +182,45 @@ impl Agent {
182182 . values_mut ( )
183183 . try_for_each ( |v| -> Result < ( ) , AgentTypeError > {
184184 if let Some ( TrivialValue :: File ( f) ) = & mut v. final_value {
185- const CONF_DIR : & str = "agentconfigs" ;
186- // get current path
187- let wd = std:: env:: current_dir ( ) ?;
188- let dir = wd. join ( CONF_DIR ) ;
189- if !dir. exists ( ) {
190- fs:: create_dir ( dir. as_path ( ) ) ?;
191- }
192- let uuid = Uuid :: new_v4 ( ) . to_string ( ) ;
193- let path = format ! ( "{}/{}-config.yaml" , dir. to_string_lossy( ) , uuid) ; // FIXME: PATH?
194- let mut file = fs:: OpenOptions :: new ( )
195- . create ( true )
196- . write ( true )
197- . open ( & path) ?;
198-
199- writeln ! ( file, "{}" , f. content) ?;
200- f. path = path;
201- // f.path = file
202- // .path()
203- // .to_str()
204- // .ok_or(AgentTypeError::InvalidFilePath)?
205- // .to_string();
185+ write_file ( f) ?
186+ } else if let Some ( TrivialValue :: Map ( m) ) = & mut v. final_value {
187+ return m. iter_mut ( ) . try_for_each ( |( _, mut file) | {
188+ if let TrivialValue :: File ( f) = & mut file {
189+ write_file ( f) ?;
190+ }
191+ Ok ( ( ) )
192+ } ) ;
206193 }
207194 Ok ( ( ) )
208195 } )
209196 }
210197}
211198
199+ fn write_file ( file : & mut FilePathWithContent ) -> Result < ( ) , io:: Error > {
200+ const CONF_DIR : & str = "agentconfigs" ;
201+ // get current path
202+ let wd = std:: env:: current_dir ( ) ?;
203+ let dir = wd. join ( CONF_DIR ) ;
204+ if !dir. exists ( ) {
205+ fs:: create_dir ( dir. as_path ( ) ) ?;
206+ }
207+ let uuid = Uuid :: new_v4 ( ) . to_string ( ) ;
208+ let path = format ! ( "{}/{}-config.yaml" , dir. to_string_lossy( ) , uuid) ; // FIXME: PATH?
209+ let mut fs_file = fs:: OpenOptions :: new ( )
210+ . create ( true )
211+ . write ( true )
212+ . open ( & path) ?;
213+
214+ writeln ! ( fs_file, "{}" , file. content) ?;
215+ file. path = path;
216+ // f.path = file
217+ // .path()
218+ // .to_str()
219+ // .ok_or(AgentTypeError::InvalidFilePath)?
220+ // .to_string();
221+ Ok ( ( ) )
222+ }
223+
212224impl TryFrom < RawAgent > for Agent {
213225 type Error = AgentTypeError ;
214226 /// Convert a [`RawAgent`] into an [`Agent`].
@@ -251,6 +263,22 @@ impl TrivialValue {
251263 }
252264 Ok ( self )
253265 }
266+ ( TrivialValue :: Map ( m) , VariableType :: MapStringFile ) => {
267+ if !m. iter ( ) . all ( |( _, v) | matches ! ( v, TrivialValue :: String ( _) ) ) {
268+ return Err ( AgentTypeError :: InvalidMap ) ;
269+ }
270+
271+ Ok ( TrivialValue :: Map (
272+ m. into_iter ( )
273+ . map ( |( k, v) | {
274+ (
275+ k,
276+ TrivialValue :: File ( FilePathWithContent :: new ( v. to_string ( ) ) ) ,
277+ )
278+ } )
279+ . collect ( ) ,
280+ ) )
281+ }
254282 ( TrivialValue :: String ( s) , VariableType :: File ) => {
255283 Ok ( TrivialValue :: File ( FilePathWithContent :: new ( s) ) )
256284 }
@@ -347,6 +375,8 @@ pub enum VariableType {
347375 File ,
348376 #[ serde( rename = "map[string]string" ) ]
349377 MapStringString ,
378+ #[ serde( rename = "map[string]file" ) ]
379+ MapStringFile ,
350380 // #[serde(rename = "map[string]number")]
351381 // MapStringNumber,
352382 // #[serde(rename = "map[string]bool")]
@@ -684,9 +714,6 @@ fn normalize_agent_spec(spec: AgentVariables) -> Result<NormalizedVariables, Age
684714 if v. default . is_none ( ) && !v. required {
685715 return Err ( AgentTypeError :: MissingDefaultWithKey ( k. clone ( ) ) ) ;
686716 }
687- if let Some ( default) = v. default . clone ( ) {
688- default. check_type ( v. type_ ) ?;
689- }
690717 Ok ( ( ) )
691718 } ) ?;
692719 Ok ( r. into_iter ( ) . chain ( n_spec) . collect ( ) )
@@ -949,6 +976,13 @@ variables:
949976 description: "Newrelic infra configuration yaml"
950977 type: map[string]string
951978 required: true
979+ integrations:
980+ description: "Newrelic integrations configuration yamls"
981+ type: map[string]file
982+ required: true
983+ default:
984+ kafka: |
985+ bootstrap: zookeeper
952986deployment:
953987 on_host:
954988 executables:
@@ -961,6 +995,11 @@ deployment:
961995config3:
962996 log_level: trace
963997 forward: "true"
998+ integrations:
999+ kafka: |
1000+ strategy: bootstrap
1001+ redis: |
1002+ user: redis
9641003config: |
9651004 license_key: abc123
9661005 staging: true
@@ -983,4 +1022,95 @@ config: |
9831022
9841023 println ! ( "Output: {:#?}" , actual) ;
9851024 }
1025+
1026+ // Obsolete test
1027+
1028+ /*const EXAMPLE_AGENT_YAML_REPLACE_WITH_DEFAULT: &str = r#"
1029+ name: nrdot
1030+ namespace: newrelic
1031+ version: 0.1.0
1032+ variables:
1033+ config:
1034+ description: "Path to the agent"
1035+ type: file
1036+ required: false
1037+ default: "test"
1038+ deployment:
1039+ on_host:
1040+ path:
1041+ description: "Path to the agent"
1042+ type: string
1043+ required: false
1044+ default: "/default_path"
1045+ args:
1046+ description: "Args passed to the agent"
1047+ type: string
1048+ required: false
1049+ default: "--verbose true"
1050+ integrations:
1051+ description: "Newrelic integrations configuration yamls"
1052+ type: map[string]file
1053+ required: false
1054+ default:
1055+ kafka: |
1056+ bootstrap: zookeeper
1057+ deployment:
1058+ on_host:
1059+ executables:
1060+ - path: ${deployment.on_host.args}/otelcol
1061+ args: "-c ${deployment.on_host.args}"
1062+ env: ""
1063+ "#;
1064+
1065+ #[test]
1066+ fn test_validate_with_default() {
1067+ let input_structure =
1068+ serde_yaml::from_str::<SupervisorConfig>("").unwrap();
1069+ let agent_type =
1070+ serde_yaml::from_str::<Agent>(EXAMPLE_AGENT_YAML_REPLACE_WITH_DEFAULT).unwrap();
1071+
1072+ let expected = Map::from([
1073+ (
1074+ "deployment.on_host.args".to_string(),
1075+ TrivialValue::String("--verbose true".to_string()),
1076+ ),
1077+ (
1078+ "deployment.on_host.path".to_string(),
1079+ TrivialValue::String("/default_path".to_string()),
1080+ ),
1081+ (
1082+ "config".to_string(),
1083+ TrivialValue::File(FilePathWithContent::new("test".to_string())),
1084+ ),
1085+ (
1086+ "integrations".to_string(),
1087+ TrivialValue::Map(Map::from([(
1088+ "kafka".to_string(),
1089+ TrivialValue::File(FilePathWithContent::new(
1090+ "bootstrap: zookeeper\n".to_string(),
1091+ )),
1092+ )])),
1093+ ),
1094+ ]);
1095+ let actual = agent_type
1096+ .populate(input_structure)
1097+ .expect("Failed to populate the AgentType's runtime_config field");
1098+
1099+ expected.iter().for_each(|(key, expected_value)|{
1100+ let actual_value = actual.clone().get_variables(key.to_string()).unwrap().final_value;
1101+ if let Some(TrivialValue::File(actual_file)) = actual_value {
1102+ let TrivialValue::File(expected_file) = expected_value else { unreachable!() };
1103+ assert_eq!(expected_file.content, actual_file.content);
1104+ } else if let Some(TrivialValue::Map(actual_map)) = actual_value {
1105+ actual_map.iter().for_each(|(a,actual_map)|{
1106+ let TrivialValue::File(actual_file) = actual_map else { unreachable!() };
1107+ let TrivialValue::Map(expected_map) = expected_value else { unreachable!() };
1108+ let TrivialValue::File(expected_file) = expected_map.get(a).unwrap() else { unreachable!() };
1109+ assert_eq!(expected_file.content, actual_file.content);
1110+ });
1111+ } else {
1112+ assert_eq!(*expected_value, actual_value.unwrap())
1113+ }
1114+ });
1115+ }*/
9861116}
0 commit comments