CloudFormation syntax for ParameterOverrides - aws-cloudformation

I'm getting stuck on overriding multiple parameters within a CloudFormation that is passing them to CodePipeline.
I can successful override a single parameter like this:
ParameterOverrides: "{ \"StageName\": \"stage\" }"
But when I try this:
ParameterOverrides: '{ "StageName": "prod", "EnvValue", "prod" }'
I have also tried these combinations:
ParameterOverrides: "{\"StageName\": \"prod\", \"EnvValue\", \"prod\"}"
Codepipeline throws an error of: ParameterOverrides property is not valid
I have looked at this help article a half a dozen times and it seems I'm following the format to the T.
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/continuous-delivery-codepipeline-parameter-override-functions.html
What am I missing? Does anyone have this working in a CloudFormation template?

When dealing with embedded JSON in your YAML, the folded (>) or literal (|) block style, rather than a quoted string, will increase clarity. So something like:
ParameterOverrides: >
{
"StageName": "prod",
"EnvValue": "prod"
}
This will let you see the actual JSON without quite as much noise from the backslash escapes in the way. This can be seen in the "Example Create Stack B Stage" section of the page you linked to (it uses the literal block style with |). The difference between | and > can be seen on the YAML Multiline site.

I found out what the problem was, fat fingered.
I put this:
ParameterOverrides: "{\"StageName\": \"prod\", \"EnvValue\", \"prod\"}"
and it should have been this:
ParameterOverrides: "{\"StageName\": \"prod\", \"EnvValue\": \"prod\"}"
NOTICE: the missing colon on after the second key.

Related

Grafana: Overrriding series with metric named `/var(avail_MB)`: "Panel rendering error '/var(avail_MB)' is not a valid regular expression."

An Icinga2 plugin (written by myself) returns performance data with metrics named /var(avail_MB), /var(total_MB) and similar. Data is forwarded to an InfluxDB with Grafana as Frontend.
I'm using "GROUP BY" "tag(metric)" and "ALIAS BY" "$tag_metric" in a dashboard's panel query.
The metric names are displayed correctly below the graph then.
However when I try to override series by specifying "alias or regex" /var(avail_MB) it does not seem to work, and when going back from panel configuration to dashboard, I get an error message saying "Panel rendering error '/var(avail_MB)' is not a valid regular expression.".
I tried to put a backslash in front of ( and ), but that didn't help.
To make matters worse, the whole graph disappeared, and when trying to open the "Query Inspector", the frontend seems to take forever (Query never appears).
What is the problem, and how could I fix it?
I'm new to Icinga2, Grafana and InfluxDB (I'm just a "user" not administrator of those).
The color change is not applied to the graph.
Here is an example of plugin output:
OK: /var: 3114/5632MB (55.30%), slope is NaN|/var(total_MB)=5631.56MB;;;0 /var(avail_pct)=55.30%;25;5;0;100 /var(avail_MB)=3114.12MB;10;5;0;5632 /var(est_avail_MB)=nanMB;10;5;0;5632
(The "nanMB" was a bug in the plugin that has been fixed already, but that data wasn't from the machine in question.)
The problems seems to be the beginning of the string ("/var").
Grafana seems to treat every string starting with / as regular expression, and it expects any regular expression to start with /, too (it seems).
So the fix was to add a trailing /, and escape the literal / as \/.
Unfortunately this only removes the error message, but doesn't make the override work (match).
It is also required to backslash-escape the parentheses and the slash(es):
Instead of /var(total_MB) you need to write /\/var\(total_MB\).
The original problem has two origins:
The monitoring plugin specification at https://www.monitoring-plugins.org/doc/guidelines.html#AEN201 states: "2. label can contain any characters except the equals sign or single quote (')") states that any character except = and ' is allowed as metric name.
Grafana v6.7.3 proposes the incorrect (i.e.: unescaped) values for "alias or regex".
That is how I had created the problem.

TOML multi-level table syntax inside array -- illegal or not

I'm seeing an error during parsing with the Python and JS parsers. I can't seem to find an example in the TOML repo about whether this should be accepted or not:
[[somearray]]
one.two = false # fails, '.' not allowed in key
I know I can express this as:
[[somearray]]
[somearray.one]
two = false # OK
The TOML readme offers this example (among others):
[fruit]
apple.color = "red"
apple.taste.sweet = true
which does not involve arrays but seems to legitimize this syntax.
I also observe that a plain file with this content:
apple.color = "red"
is rejected. In conclusion, until you enter "table mode" (so to say) with an actual bracketed table, keys can only be singles.
Now again, in the TOML readme it says (although in the tables section):
"Dotted keys define everything to the left of each dot as a table."
Obviously, if mainstream parsers choke on it, it's not a good idea to use it, but I'd like to understand if/why it's a known no-no. Is here some ambiguity I'm not seeing?
These cases are confirmed valid TOML, per the 1.0 spec, which adds many more examples: https://github.com/toml-lang/toml/blob/1.0.0/toml.md
The following is definitely valid Toml syntax:
[[somearray]]
one.two = false
It should result in a model that is equivalent to this Json syntax:
{
"somearray": [
{
"one": {
"two": false
}
}
]
}
It can be validated here.
Dotted keys should indeed define everything to the left of each dot as a table.

Using where() node to filter empty tags in Kapacitor

Using Kapacitor 1.3 and I am trying to use the following where node to keep measurements with an empty tag. Nothing is passing through and I get the same result with ==''.
| where(lambda: 'process-cpu__process-name' =~ /^$/)
I can workaround this issue using a default value for missing tags and filter on this default tag, in the following node but I am wondering if there is a better way structure the initial where statement and avoid an extra node.
| default()
.tag('process-cpu__process-name','system')
| where(lambda: \"process-cpu__process-name\" == 'system' )
Sure it doesn't pass, 'cause this
'process-cpu__process-name'
is a string literal it TICKScript, not a reference to a field, which is
"process-cpu__process-name"
You obviously got the condition always false in this case.
Quite common mistake though, especially for someone with previous experience with the languages that tolerates both single & double quote for mere string. :-)
Also, there's a function in TICKScript lambda called strLength(), find the doc here, please.

Apply Command to String-type custom fields with YouTrack Rest API

and thanks for looking!
I have an instance of YouTrack with several custom fields, some of which are String-type. I'm implementing a module to create a new issue via the YouTrack REST API's PUT request, and then updating its fields with user-submitted values by applying commands. This works great---most of the time.
I know that I can apply multiple commands to an issue at the same time by concatenating them into the query string, like so:
Type Bug Priority Critical add Fix versions 5.1 tag regression
will result in
Type: Bug
Priority: Critical
Fix versions: 5.1
in their respective fields (as well as adding the regression tag). But, if I try to do the same thing with multiple String-type custom fields, then:
Foo something Example Something else Bar P0001
results in
Foo: something Example Something else Bar P0001
Example:
Bar:
The command only applies to the first field, and the rest of the query string is treated like its String value. I can apply the command individually for each field, but is there an easier way to combine these requests?
Thanks again!
This is an expected result because all string after foo is considered a value of this field, and spaces are also valid symbols for string custom fields.
If you try to apply this command via command window in the UI, you will actually see the same result.
Such a good question.
I encountered the same issue and have spent an unhealthy amount of time in frustration.
Using the command window from the YouTrack UI I noticed it leaves trailing quotations and I was unable to find anything in the documentation which discussed finalizing or identifying the end of a string value. I was also unable to find any mention of setting string field values in the command reference, grammer documentation or examples.
For my solution I am using Python with the requests and urllib modules. - Though I expect you could turn the solution to any language.
The rest API will accept explicit strings in the POST
import requests
import urllib
from collections import OrderedDict
URL = 'http://youtrack.your.address:8000/rest/issue/{issue}/execute?'.format(issue='TEST-1234')
params = OrderedDict({
'State': 'New',
'Priority': 'Critical',
'String Field': '"Message to submit"',
'Other Details': '"Fold the toilet paper to a point when you are finished."'
})
str_cmd = ' '.join(' '.join([k, v]) for k, v in params.items())
command_url = URL + urllib.urlencode({'command':str_cmd})
result = requests.post(command_url)
# The command result:
# http://youtrack.your.address:8000/rest/issue/TEST-1234/execute?command=Priority+Critical+State+New+String+Field+%22Message+to+submit%22+Other+Details+%22Fold+the+toilet+paper+to+a+point+when+you+are+finished.%22
I'm sad to see this one go unanswered for so long. - Hope this helps!
edit:
After continuing my work, I have concluded that sending all the field
updates as a single POST is marginally better for the YouTrack
server, but requires more effort than it's worth to:
1) know all fields in the Issues which are string values
2) pre-process all the string values into string literals
3) If you were to send all your field updates as a single request and just one of them was missing, failed to set, or was an unexpected value, then the entire request will fail and you potentially lose all the other information.
I wish the YouTrack documentation had some mention or discussion of
these considerations.

Macro name expanded from another macro in makefile

I have a makefile with the following format. First I define what my outputs are;
EXEFILES = myexe1.exe myexe2.exe
Then I define what the dependencies are for those outputs;
myexe1.exe : myobj1.obj
myexe2.exe : myobj2.obj
Then I have some macros that define extra dependencies for linking;
DEP_myexe1 = lib1.lib lib2.lib
DEP_myexe2 = lib3.lib lib4.lib
Then I have the target for transforming .obj to .exe;
$(EXEFILES):
$(LINK) -OUT:"Exe\$#" -ADDOBJ:"Obj\$<" -IMPLIB:$($($(DEP_$*)):%=Lib\\%)
What I want to happen is (example for myexe1.exe)
DEP_$* -> DEP_myexe1
$(DEP_myexe1) -> lib1.lib lib2.lib
$(lib1.lib lib2.lib:%=Lib\\%) -> Lib\lib1.lib Lib\lib2.lib
Unfortunately this is not working. When I run make --just-print, the -IMPLIB: arguments are empty. However, if I run $(warning DEP_$*) I get
DEP_myexe1
And when I run $(warning $(DEP_myexe1)) I get
lib1.lib lib2.lib
So for some reason, make does not like the combination of $(DEP_$*). Perhaps it cannot resolve macro names dynamically like this. What can I do to get this to work? Is there an alternative?
Where does $(warning DEP_$*) give you DEP_myexe1 as output exactly? Because given your makefile above it shouldn't.
$* is the stem of the target pattern that matched. In your case, because you have explicit target names, you have no patten match and so no stem and so $* is always empty.
Additionally, you are attempting a few too many expansions. You are expanding $* to get myexe1 directly (assuming for the moment that variable works the way you intended). You then prefix that with DEP_ and used $(DEP_$*) to get the lib1.lib lib2.lib. You then expand that result $($(DEP_$*)) and then expand that (empty) result again (to do your substitution) $($($(DEP_$*)):%=Lib\\%).
You want to either use $(#:.exe=) instead of $* in your rule body or use %.exe as your target and then use $* to get myexe1/myexe2.
You then want to drop two levels of expansion from $($($(DEP_$*)):%=Lib\\%) and use $(DEP_$*:%=Lib\\%) instead.
So (assuming you use the pattern rule) you end up with:
%.exe:
$(LINK) -OUT:"Exe\$#" -ADDOBJ:"Obj\$<" -IMPLIB:$(DEP_$*:%=Lib\\%)
I managed to get it working without needing to resolve macros in the way described above. I modified the linking dependencies like this;
myexe1.exe : myobj1.obj lib1.lib lib2.lib
myexe2.exe : myobj2.obj lib3.lib lib4.lib
Then I need to filter these files by extension in the target recipe;
$(EXEFILES):
$(LINK) -OUT:"$(EXE_PATH)\$#" -ADDOBJ:$(patsubst %, Obj\\%, $(filter %.obj, $^)) -IMPLIB:$(patsubst %, Lib\\%, $(filter %.lib, $^))
The $(pathsubst ...) is used to prepend the path that the relevant files are in.
In the case of myexe1.exe, the link command expands to;
slink -OUT:"Exe\myexe1.exe" -ADDOBJ: Obj\myexe1.obj -IMPLIB: Lib\lib1.lib Lib\lib2.lib
Out of interest's sake, I would still like to know if it is possible to resolve macro names like in the question.