I have two functions that only store variables. Example:
Function datanode1(){
homedirectory = "/path/to/file"
ConfigDirectory = "/path/to/file"
user = "john"
max_open_Files = 262114
}
datanode2 is exactly the same, just different path files.
I would like to do something like this:
if [ "$a1" == "all" ]; then
for i in [datanode2, datanode1] do
*execute Script*
done
fi
Is this possible? How are the functions acting as arrays?
If you have functions named datanode2 and datanode1, and you want to execute them in a loop, you could write like this:
for fun in datanode2 datanode1; do
"$fun"
done
Btw the function definition in your example has some syntax error. It should be more like this:
datanode1() {
homedirectory="/path/to/file"
ConfigDirectory="/path/to/file"
user="john"
max_open_Files=262114
}
Related
String elkEndpoint = 'https://elastic.beta.tower.am.health.ge.com/'
I need to use value of elkEndpoint somewhere in code like below:
// Some code
'metrics': [
'elasticEndpoint': elkEndpoint,
'esConnection': ''
],
// Some code
I tried using below, but its not working:
'elasticEndpoint': elkEndpoint,
2 'elasticEndpoint': ${elkEndpoint},
3 'elasticEndpoint': $elkEndpoint,
What is way to use value of a variable?
What is way to use value of a variable?
You can do this:
String elkEndpoint = 'https://elastic.beta.tower.am.health.ge.com/'
Map metrics = [ elasticEndpoint: elkEndpoint, esConnection: '' ]
println metrics
That will output the following:
[elasticEndpoint:https://elastic.beta.tower.am.health.ge.com/, esConnection:]
I have a json output (y) like this below.
{
"WebACL":{
"Name":"aBlockKnownBadInputs-WebAcl",
"Id":"4312a5d0-9878-4feb-a083-09d7a9cfcfbb",
"ARN":"arn:aws:wafv2:us-east-1:100467320728:regional/webacl/aBlockKnownBadInputs-WebAcl/4312a5d0-9878-4feb-a083-09d7a9cfcfbb",
"DefaultAction":{
"Allow":{
}
},
"Description":"",
"Rules":[
{
"Name":"AWS-AWSManagedRulesKnownBadInputsRuleSet",
"Priority":500,
"Statement":{
"ManagedRuleGroupStatement":{
"VendorName":"AWS",
"Name":"AWSManagedRulesKnownBadInputsRuleSet"
}
},
"OverrideAction":{
"None":{
}
},
"VisibilityConfig":{
"SampledRequestsEnabled":true,
"CloudWatchMetricsEnabled":true,
"MetricName":"AWS-AWSManagedRulesKnownBadInputsRuleSet"
}
}
]
}
}
I want to extract "AWS-AWSManagedRulesKnownBadInputsRuleSet" from the section:-
"Name":"AWS-AWSManagedRulesKnownBadInputsRuleSet",
"Priority":500,
"Statement":{
"ManagedRuleGroupStatement":{
"VendorName":"AWS",
"Name":"AWSManagedRulesKnownBadInputsRuleSet"*
At the minute my code is returning a key error:
KeyError: 'Rules[].Statement[].ManagedRuleGroupStatement[].Name'
The format of this line is clearly wrong, but I don't know why.
ruleset = y['Rules[].Statement[].ManagedRuleGroupStatement[].Name']
My code block:
respons = client.get_web_acl(Name=(acl),Scope='REGIONAL',Id=(ids))
for y in response['WebACLs']:
ruleset = y['Rules[].Statement[].ManagedRuleGroupStatement[].Name']
Does anyone know what I'm doing wrong here?
UPDATE :- In case anyone else comes up against this problem, I fixed this by doing it a slightly different way.
#Requesting the info from AWS via get_web_acl request
respons = client.get_web_acl(Name=(acl),Scope='REGIONAL',Id=(ids))
#Converting the dict output to a string to make it searchable
result = json.dumps(respons)
#Defining what I want to search for
fullstring = "AWS-AWSManagedRulesKnownBadInputsRuleSet"
#Searching the output & printing the result: if = true / else = false
if fullstring in result:
print("Found WAF ruleset: AWS-AWSManagedRulesKnownBadInputsRuleSet!")
else:
print("WAF ruleset not found!")
Also, as part of my research I found a cool thing called jello.
(https://github.com/kellyjonbrazil/jello).
jello is similar to jq in that it processes JSON and JSON Lines data except it uses standard python dict and list syntax.
So, I copied my json into a file called file.json
Ran cat file.json | jello -s to print a grep-able schema by using the -s option
Found the bit I was interested in - in my case the name of the ManagedRuleGroupStatement and ran the following:
cat file.json | jello -s _.WebACL.Rules[0].Statement.ManagedRuleGroupStatement.Name
This gave me exactly what I wanted!
It doesn't work inside a python script but was something new and interesting to learn!
I must be being incredibly stupid but I can't figure out how to do simple string concatenation in Terraform.
I have the following data null_data_source:
data "null_data_source" "api_gw_url" {
inputs = {
main_api_gw = "app.api.${var.env_name == "prod" ? "" : var.env_name}mydomain.com"
}
}
So when env_name="prod" I want the output app.api.mydomain.com and for anything else - let's say env_name="staging" I want app.api.staging.mydomain.com.
But the above will output app.api.stagingmydomain.com <-- notice the missing dot after staging.
I tried concating the "." if the env_name was anything but "prod" but Terraform errors:
data "null_data_source" "api_gw_url" {
inputs = {
main_api_gw = "app.api.${var.env_name == "prod" ? "" : var.env_name + "."}mydomain.com"
}
}
The error is __builtin_StringToInt: strconv.ParseInt: parsing ""
The concat() function in TF appears to be for lists not strings.
So as the title says: How do you do simple string concatenation in Terraform?
I can't believe I'm asking how to concat 2 strings together XD
Update:
For anyone that has a similar issue I did this horrific workaround for the time being:
main_api_gw = "app.api.${var.env_name == "prod" ? "" : var.env_name}${var.env_name == "prod" ? "" : "."}mydomain.com"
I know this was already answered, but I wanted to share my favorite:
format("%s/%s",var.string,"string2")
Real world example:
locals {
documents_path = "${var.documents_path == "" ? format("%s/%s",path.module,"documents") : var.documents_path}"
}
More info:
https://www.terraform.io/docs/configuration/functions/format.html
so to add a simple answer to a simple question:
enclose all strings you want to concatenate into one pair of ""
reference variables inside the quotes with ${var.name}
Example: var.foo should be concatenated with bar string and separated by a dash
Solution: "${var.foo}-bar"
Try Below data resource :
data "null_data_source" "api_gw_url" {
inputs = {
main_api_gw = "app.api${var.env_name == "prod" ? "." : ".${var.env_name}."}mydomain.com"
}
}
For Terraform 0.12 and later, you can use join() function:
join(separator, list)
Example:
> join(", ", ["foo", "bar", "baz"])
foo, bar, baz
> join(", ", ["foo"])
foo
If you just want to concatenate without a separator like "foo"+"bar" = "foobar", then:
> join("", ["foo", "bar"])
foobar
Reference: https://www.terraform.io/docs/configuration/functions/join.html
Use the Interpolation Syntax for versions < 0.12
Here is a simple example:
output "s3_static_website_endpoint" {
value = "http://${aws_s3_bucket.bucket_tf.website_endpoint}"
}
Reference the Terraform Interpolation docs:
https://developer.hashicorp.com/terraform/language/expressions/strings#string-templates
after lot of research, It finally worked for me. I was trying to follow https://www.hashicorp.com/blog/terraform-0-12-preview-first-class-expressions/, but it did not work. Seems string can't be handled inside the expressions.
data "aws_vpc" "vpc" {
filter {
name = "tag:Name"
values = ["${var.old_cluster_fqdn == "" ? "${var.cluster_fqdn}" : "${var.old_cluster_fqdn}"}-vpc"]
}
}
I have input data of type
abc 12d
uy 76d
ce 12a
with the lines being separated by \n and the values by \t.
The data comes from a shell command:
brlist = 'mycommand'.execute().text
Then I want to get this into a map:
brmap = brlist.split("\n").collectEntries {
tkns = it.tokenize("\t")
[ (tkns[0]): tkns[1] ]
}
I also tried
brmap = brlist.split("\n").collectEntries {
it.tokenize("\t").with { [ (it[0]): it[1] ] }
}
Both ways gave the same result, which is a map with a single entry:
brmap.toString()
# prints "[abc:12d]"
Why does only the first line of the input data end up being in the map?
Your code works, which means the input String brlist isn't what you say it is...
Are you sure that's what you have? Try printing brlist, and then it inside collectEntries
As an aside, this does the same thing as your code:
brlist.split('\n')*.split('\t')*.toList().collectEntries()
Or you could try (incase it's spaces not tabs, this will expect both)
brlist.split('\n')*.split(/\s+/)*.toList().collectEntries()
This code works
// I use 4 spaces as tab.
def text = 'sh abc.sh'.execute().text.replaceAll(" " * 4, "\t")
brmap = text.split("\n").collectEntries {
tkns = it.tokenize("\t")
[(tkns[0]) : tkns[1]]
}
assert[abc:"12d", uy:"76d", ce:"12a"] == brmap
abc.sh
#!/bin/sh
echo "abc 12d"
echo "uy 76d"
echo "ce 12a
Also, I think your groovy code is correct. maybe your mycommand has some problem.
Ok, thanks for the hints, it is a bug in Jenkins: https://issues.jenkins-ci.org/browse/JENKINS-26481.
And it has been mentioned here before: Groovy .each only iterates one time
Can you think of a way to solve this problem in Puppet?
I have a custom fact with generates a string of IP addresses depending on the domain it is run on, it can resolve to have 1 to n addresses.
"10.1.29.1"
"10.1.29.1,10.1.29.5"
"10.1.29.1,10.1.29.5,10.1.29.7"
etc
I want to add these to the host file with a generated server names of servernameX for example;
10.1.29.1 myservername1
10.1.29.5 myservername2
10.1.29.7 myservername3
So how can you do this as puppet doesn't have an array iterator like "for each"?
Sadly, even if you go about and use a custom "define" to iterate over an array upon splitting your custom fact on a comma, the result will be rather not what you expect and not even close to a "for each" loop -- aside of causing you a headache, probably.
Said that, I am not sure if this is what you want to achieve, but have a look at this approach:
$fact = '1.1.1.1,2.2.2.2,3.3.3.3'
$servers = split($::fact, ',')
$count = size($servers)
$names = bracket_expansion("host[01-${count}].address")
file { '/tmp/test.txt':
content => inline_template('<%= #servers.each_with_index.map {|v,i| "#{v}\t\t#{#names[i]}\n" } %>'),
ensure => present
}
What we have there are two custom functions: size() and bracket_expansion(); which we then use values that they provide inside a hack that leverages the inline_template() function to render content of the file utilising parallel access to two arrays -- one with IP addresses from your fact and one with host names that should follow.
The result is a follows:
matti#acrux ~ $ cat | puppet apply
$fact = '1.1.1.1,2.2.2.2,3.3.3.3'
$servers = split($::fact, ',')
$count = size($servers)
$names = bracket_expansion("host[01-${count}].address")
file { '/tmp/test.txt':
content => inline_template('<%= #servers.each_with_index.map {|v,i| "#{v}\t\t#{#names[i]}\n" } %>'),
ensure => present
}
notice: /Stage[main]//File[/tmp/test.txt]/ensure: created
notice: Finished catalog run in 0.07 seconds
matti#acrux ~ $ cat /tmp/test.txt
1.1.1.1 host01.address
2.2.2.2 host02.address
3.3.3.3 host03.address
matti#acrux ~ $
Both size() and bracket_expansion() functions can be found here:
https://github.com/kwilczynski/puppet-functions/tree/master/lib/puppet/parser/functions/
I hope this helps a little :-)