1
1
package datadog .trace .bootstrap .config .provider ;
2
2
3
- import datadog .cli .CLIHelper ;
4
3
import datadog .trace .bootstrap .config .provider .stableconfigyaml .ConfigurationMap ;
5
4
import datadog .trace .bootstrap .config .provider .stableconfigyaml .Rule ;
6
5
import datadog .trace .bootstrap .config .provider .stableconfigyaml .Selector ;
7
6
import datadog .trace .bootstrap .config .provider .stableconfigyaml .StableConfigYaml ;
8
7
import datadog .yaml .YamlParser ;
9
8
import java .io .IOException ;
9
+ import java .nio .charset .StandardCharsets ;
10
+ import java .nio .file .Files ;
11
+ import java .nio .file .Paths ;
10
12
import java .util .Collections ;
11
13
import java .util .HashMap ;
12
- import java .util .HashSet ;
13
14
import java .util .List ;
14
- import java .util .Set ;
15
15
import java .util .function .BiPredicate ;
16
16
import org .slf4j .Logger ;
17
17
import org .slf4j .LoggerFactory ;
18
18
19
19
public class StableConfigParser {
20
20
private static final Logger log = LoggerFactory .getLogger (StableConfigParser .class );
21
21
22
- private static final Set <String > VM_ARGS = new HashSet <>(CLIHelper .getVmArgs ());
22
+ private static final String ENVIRONMENT_VARIABLES_PREFIX = "environment_variables['" ;
23
+ private static final String PROCESS_ARGUMENTS_PREFIX = "process_arguments['" ;
24
+ private static final String UNDEFINED_VALUE = "UNDEFINED" ;
23
25
24
26
/**
25
27
* Parses a configuration file and returns a stable configuration object.
@@ -37,7 +39,9 @@ public class StableConfigParser {
37
39
*/
38
40
public static StableConfigSource .StableConfig parse (String filePath ) throws IOException {
39
41
try {
40
- StableConfigYaml data = YamlParser .parse (filePath , StableConfigYaml .class );
42
+ String content = new String (Files .readAllBytes (Paths .get (filePath )), StandardCharsets .UTF_8 );
43
+ String processedContent = processTemplate (content );
44
+ StableConfigYaml data = YamlParser .parse (processedContent , StableConfigYaml .class );
41
45
42
46
String configId = data .getConfig_id ();
43
47
ConfigurationMap configMap = data .getApm_configuration_default ();
@@ -66,7 +70,9 @@ public static StableConfigSource.StableConfig parse(String filePath) throws IOEx
66
70
67
71
} catch (IOException e ) {
68
72
log .debug (
69
- "Stable configuration file either not found or not readable at filepath {}" , filePath );
73
+ "Stable configuration file either not found or not readable at filepath {}. Error: {}" ,
74
+ filePath ,
75
+ e .getMessage ());
70
76
}
71
77
return StableConfigSource .StableConfig .EMPTY ;
72
78
}
@@ -166,14 +172,100 @@ static boolean selectorMatch(String origin, List<String> matches, String operato
166
172
return false ;
167
173
}
168
174
case "process_arguments" :
169
- // For now, always return true if `key` exists in the JVM Args
170
175
// TODO: flesh out the meaning of each operator for process_arguments
171
- return VM_ARGS .contains (key );
176
+ if (!key .startsWith ("-D" )) {
177
+ log .warn (
178
+ "Ignoring unsupported process_arguments entry in selector match, '{}'. Only system properties specified with the '-D' prefix are supported." ,
179
+ key );
180
+ return false ;
181
+ }
182
+ // Cut the -D prefix
183
+ return System .getProperty (key .substring (2 )) != null ;
172
184
case "tags" :
173
185
// TODO: Support this down the line (Must define the source of "tags" first)
174
186
return false ;
175
187
default :
176
188
return false ;
177
189
}
178
190
}
191
+
192
+ static String processTemplate (String content ) throws IOException {
193
+ // Do nothing if there are no variables to process
194
+ int openIndex = content .indexOf ("{{" );
195
+ if (openIndex == -1 ) {
196
+ return content ;
197
+ }
198
+
199
+ StringBuilder result = new StringBuilder (content .length ());
200
+
201
+ // Add everything before the opening braces
202
+ result .append (content , 0 , openIndex );
203
+
204
+ while (true ) {
205
+
206
+ // Find the closing braces
207
+ int closeIndex = content .indexOf ("}}" , openIndex );
208
+ if (closeIndex == -1 ) {
209
+ throw new IOException ("Unterminated template in config" );
210
+ }
211
+
212
+ // Extract the template variable
213
+ String templateVar = content .substring (openIndex + 2 , closeIndex ).trim ();
214
+
215
+ // Process the template variable and get its value
216
+ String value = processTemplateVar (templateVar );
217
+
218
+ // Add the processed value
219
+ result .append (value );
220
+
221
+ // Continue with the next template variable
222
+ openIndex = content .indexOf ("{{" , closeIndex );
223
+ if (openIndex == -1 ) {
224
+ // Stop and add everything left after the final closing braces
225
+ result .append (content , closeIndex + 2 , content .length ());
226
+ break ;
227
+ } else {
228
+ // Add everything between the last braces and the next
229
+ result .append (content , closeIndex + 2 , openIndex );
230
+ }
231
+ }
232
+
233
+ return result .toString ();
234
+ }
235
+
236
+ private static String processTemplateVar (String templateVar ) throws IOException {
237
+ if (templateVar .startsWith (ENVIRONMENT_VARIABLES_PREFIX ) && templateVar .endsWith ("']" )) {
238
+ String envVar =
239
+ templateVar
240
+ .substring (ENVIRONMENT_VARIABLES_PREFIX .length (), templateVar .length () - 2 )
241
+ .trim ();
242
+ if (envVar .isEmpty ()) {
243
+ throw new IOException ("Empty environment variable name in template" );
244
+ }
245
+ String value = System .getenv (envVar .toUpperCase ());
246
+ if (value == null || value .isEmpty ()) {
247
+ return UNDEFINED_VALUE ;
248
+ }
249
+ return value ;
250
+ } else if (templateVar .startsWith (PROCESS_ARGUMENTS_PREFIX ) && templateVar .endsWith ("']" )) {
251
+ String processArg =
252
+ templateVar .substring (PROCESS_ARGUMENTS_PREFIX .length (), templateVar .length () - 2 ).trim ();
253
+ if (processArg .isEmpty ()) {
254
+ throw new IOException ("Empty process argument in template" );
255
+ }
256
+ if (!processArg .startsWith ("-D" )) {
257
+ log .warn (
258
+ "Ignoring unsupported process_arguments entry in template variable, '{}'. Only system properties specified with the '-D' prefix are supported." ,
259
+ processArg );
260
+ return UNDEFINED_VALUE ;
261
+ }
262
+ String value = System .getProperty (processArg .substring (2 ));
263
+ if (value == null || value .isEmpty ()) {
264
+ return UNDEFINED_VALUE ;
265
+ }
266
+ return value ;
267
+ } else {
268
+ return UNDEFINED_VALUE ;
269
+ }
270
+ }
179
271
}
0 commit comments