Jenkinsfile : CascadeChoice parameter plugin to have two referencedaprameters - groovy

I have Cascade choice parameter 'mount_name' which is to form its value from referencing two other parameters. I tried -
choice(name: "project_name", choices: ["xxx", "null", "yyy"], description: "choose the appropriate project"),
choice(name: "environment", choices: ["dev", "qa", "pre-prod", "prod"], description: "choose the appropriate environment"),
[$class: 'CascadeChoiceParameter',
name: 'mount_name_name', choiceType: 'PT_SINGLE_SELECT', description: 'Choose the appropriate name',
filterLength: 1, filterable: false, referencedParameters: 'environment',
script: [$class: 'GroovyScript',
script: [
classpath: [],
sandbox: true,
script: """
if (environment == 'prod' || environment == 'pre-prod') {
return["efs-${params.project_name.replace('-','')}-prod"]
} else if (environment == 'dev') {
return["efs-${params.project_name.replace('-','')}-dev"]
} else {
return["efs-${params.project_name.replace('-','')}"]
}
""".stripIndent()
]
]
],
Expected result : environment = 'prod' , project_name='b2b-srv' then mount_name = 'efs-b2bsrv-prod'
Current result : environment = 'prod' , project_name='b2b-srv' then mount_name = nothing

Related

How to set multipe values in CascadeChoiceParameter's for referencedParameters

Trying to set multiple values in CascadeChoiceParameter's for referencedParameters. What the format should be? Docs documentation said that it should be 'string', but in case of setting referencedParameters: 'param1,param2' it goes to fallback script.
here is the class:
[$class: 'CascadeChoiceParameter',
name: 'SOME_PARAM',
description: 'some description',
randomName: '',
script: [$class: 'GroovyScript',
fallbackScript: [
classpath: [],
sandbox: true,
script: 'return ["item_1"]'
],
script: [
classpath: [],
sandbox: true,
script: """
if(PARAM_2.equals("some_value") && PARAM_3.equals("some_value")) {
return ["item_1", "item_2", "item_3"]
} else if((PARAM_2.equals("E2E_Tests") || (PARAM_2.equals("Real_API")) && PARAM_3.equals("knox_guard")) {
return ["item_1", "item_2", "item_4"]
} else {
return ["item_1"]
}
""".stripIndent()
]
],
choiceType: 'PT_SINGLE_SELECT',
referencedParameters: 'PARAM_2,PARAM_3',
filterable: false,
filterLength: 1
],
The fallback script is used if/when there is any kind of exception/error when attempting to execute the main script. In your case, there is a compilation error in the else if((PARAM_2.equals("E2E_Tests") || (PARAM_2.equals("Real_API")) && PARAM_3.equals("knox_guard")) line. All the open parenthesis haven't been closed - there are 6 open parenthesis and only 5 close parenthesis. Anyway, I haven't tested a CascadeChoiceParameter version of the pipeline. I have tested using activeChoiceReactiveParam. Below is a working job DSL:
String choicesScript = """
if(PARAM_2.equals("some_value") && PARAM_3.equals("some_value")) {
return ["item_1", "item_2", "item_3"]
} else if((PARAM_2.equals("E2E_Tests") || (PARAM_2.equals("Real_API")) && PARAM_3.equals("knox_guard"))) {
return ["item_1", "item_2", "item_4"]
} else {
return ["item_5"]
}
""".stripIndent()
String pipeline = '''
pipeline {
agent any
stages {
stage('Show parameter values') {
steps {
echo "PARAM_2: ${params.PARAM_2}, PARAM_3: ${params.PARAM_3}, SOME_PARAM: ${params.SOME_PARAM}"
}
}
}
}
'''.stripIndent()
pipelineJob('reactive-params') {
parameters {
activeChoiceParam('PARAM_2') {
description('First test parameter')
choiceType('SINGLE_SELECT')
groovyScript {
script('return ["some_value", "E2E_Tests", "Real_API"]')
}
}
activeChoiceParam('PARAM_3') {
description('Second test parameter')
choiceType('SINGLE_SELECT')
groovyScript {
script('return ["some_value", "knox_guard"]')
}
}
activeChoiceReactiveParam('SOME_PARAM') {
description('some description')
choiceType('SINGLE_SELECT')
referencedParameter('PARAM_2')
referencedParameter('PARAM_3')
groovyScript {
script(choicesScript)
fallbackScript('return ["item_1"]')
}
}
}
definition {
cps {
script(pipeline)
}
}
}

print from json with a given condition in terraform

I'm into the terraform world recently and learning based on the requirements. I've a question on printing the values with a given condition
json file:
{
"team1" : [
{
"engg_name" : "Alex",
"guid" : 1001,
"scope" : "QA"
},
{
"engg_name" : "Trex",
"guid" : 1002,
"scope" : "QA"
},
{
"engg_name" : "Jessica",
"guid" : 1003,
"scope" : "QA"
},
{
"engg_name" : "Tom",
"guid" : 1004,
"scope" : "DEV"
}
],
"team2" : [
{
"engg_name" : "Roger",
"guid" : 2001,
"scope" : "DEV"
},
{
"engg_name" : "Jhonny",
"guid" : 2002,
"scope" : "DEV"
}
]
}
What I'm trying:
print the engg whose scope is DEV from the json file
locals {
teams = jsondecode(file("${path.module}/teams_info.json"))
engg_with_scope_dev = flatten([for i in local.teams : i.teams if keys(local.teams).scope == "DEV"])
}
Error:
engg_with_scope_dev = flatten([for i in local.teams : i.teams if keys(local.teams).scope == "DEV"])
|----------------
| local.teams is object with 2 attributes
This value does not have any attributes.
Can someone suggest me what's the right way to just print based on the condition?
output must be as following:
engg_with_scope_dev = ["Tom", "Roger", "Jhonny"]
You need an embedded for loop for this:
locals {
teams = jsondecode(file("${path.module}/teams_info.json"))
engg_with_scope_dev = flatten([for team in local.teams : [
for engineer in team : engineer.engg_name if engineer.scope == "DEV"
]])
}
Other solution would be to use a concatenation of the lists with ellipsis operator:
locals {
teams = jsondecode(file("${path.module}/teams_info.json"))
engg_with_scope_dev = ([
for engineer in concat(values(local.teams)...) : engineer.engg_name if engineer.scope == "DEV"
])
}
But also, a simple flatten with values would work as well:
locals {
teams = jsondecode(file("${path.module}/teams_info.json"))
engg_with_scope_dev = ([
for engineer in flatten(values(local.teams)) : engineer.engg_name if engineer.scope == "DEV"
])
}

Terraform: nested for loop from yaml

I am trying to run nested for loop on terraform.
I have the following Yaml file:
Employees:
- Department:
- Dev:
- name: "danielf"
role: developer
details:
email : danielf#example.com
firstname : daniel
lastname : folsik
- name: "johnb"
role: developer
details:
email : johnb#example.com
firstname : john
lastname : belk
- Ops:
- name: "benol"
role: devops
details:
email : benol#example.com
firstname : ben
lastname : olkin
- name: "pauld"
role: devops
details:
email : pauld#example.com
firstname : paul
lastname : dempler
I am using locals to get the yaml data:
locals {
ou_config = yamldecode(file("employees.yaml"))
}
I want to run into the list of objects on "Dev" and "Ops" lists using for_each.
for example, I want to run on the "Dev" list to get the following list of objects in the first iteration:
[
{
key = "email"
value = "danielf#example.com"
},
{
key = "firstname"
value = "daniel"
},
{
key = "lastname"
value = "folskin"
}
]
The next run on the for_each will be:
[
{
key = "email"
value = "johnb#example.com"
},
{
key = "firstname"
value = "john"
},
{
key = "lastname"
value = "belk"
}
]
etc.
How can I do it on terraform?
If I understand correctly, all you are trying to extract is the details portion of that yaml file ...
Here is what I would do to get all:
locals {
ou_config = yamldecode(file("employees.yaml"))
expanded_names = flatten([
for e in local.ou_config.Employees : [
for d in e.Department : [
for key, person in d : [
for key, value in person : [
value.details
]
]
]
]
])
}
output "test" {
value = local.expanded_names
}
And if we want to filter we add an if key == "Dev"
locals {
ou_config = yamldecode(file("employees.yaml"))
expanded_names = flatten([
for e in local.ou_config.Employees : [
for d in e.Department : [
for key, person in d : [
for key, value in person : [
value.details
]
] if key == "Dev"
]
]
])
}
output "test" {
value = local.expanded_names
}
A terraform plan on that will look like:
Changes to Outputs:
+ test = [
+ {
+ email = "danielf#example.com"
+ firstname = "daniel"
+ lastname = "folsik"
},
+ {
+ email = "johnb#example.com"
+ firstname = "john"
+ lastname = "belk"
},
]
That format should be easier to loop in the final resource than the key value you suggested

Do DynamoDB update expressions allow condition expressions to target specific components of an update expressions?

I have an item where multiple attributes may need to be updated (but not always), and each of them requires a different set of conditions. In the below example, I would like to do the following:
Set a new JobTitle if it has changed, and the LastUpdated value is more recent
Append a Project ID to the ProjectsList list and Project to Projects if a new Project ID listed.
Is it possible to run all of these updates within a single update_item expression, or is it necessary to use transactions?
Example item:
{
'PK': 'PERSON#123456789',
'SK': 'PERSON#123456789',
'ID': '123456789',
'Name': 'Bob Smith',
'Birthday': '01/01/2000',
'Street': '65 LEXINGTON AVE',
'Zip': '12345',
'City': 'NEW YORK',
'State': 'NY',
'JobTitle': 'Project Manager',
'LastUpdated': '20210101',
'Projects': [
{
'Name': 'Project A',
'ID': '987654321'
},
{
'Name': 'Project B',
'ID': '756394733'
},
],
"ProjectList": ['987654321', '756394733']
}
Each separate update expressions (via a Table resource):
# Update job title if changed
r = table.update_item(
Key = {
"PK": data['PK'],
"SK": data['SK']
},
UpdateExpression = "SET #JobTitle = :JobTitle",
ExpressionAttributeNames = {
"#JobTitle": "JobTitle",
"#LastUpdated": "LastUpdated"
},
ExpressionAttributeValues = {
":JobTitle": "Senior Project Manager",
":LastUpdated": '20210102'
},
ConditionExpression = "#LastUpdated < :LastUpdated AND #JobTitle <> :JobTitle"
)
# Update projects if not in list
r = table.update_item(
Key = {
"PK": data['PK'],
"SK": data['SK']
},
UpdateExpression = """
SET #Projects = list_append(if_not_exists(#Projects, :empty_list), :ProjectMap),
#ProjectList = list_append(if_not_exists(#ProjectList, :empty_list), :ProjectID)
""",
ConditionExpression = "not(contains(#ProjectList, :ProjectID))",
ExpressionAttributeNames = {
"#Projects": "Projects",
"#ProjectList": "ProjectList"
},
ExpressionAttributeValues = {
":empty_list": [],
":ProjectMap": [{
"Name": "Project C"
"ID": "7463848373"
}],
":ProjectID": ["7463848373"]
}
)
What I want to do
# (1) Update job title if changed or (2) update projects if not in list
r = table.update_item(
Key = {
"PK": data['PK'],
"SK": data['SK']
},
UpdateExpression = """
SET
#JobTitle = :JobTitle,
#Projects = list_append(if_not_exists(#Projects, :empty_list), :ProjectMap),
#ProjectList = list_append(if_not_exists(#ProjectList, :empty_list), :ProjectID)
""",
ExpressionAttributeNames = {
"#JobTitle": "JobTitle",
"#LastUpdated": "LastUpdated",
"#Projects": "Projects",
"#ProjectList": "ProjectList"
},
ExpressionAttributeValues = {
":empty_list": [],
":JobTitle": "Senior Project Manager",
":LastUpdated": '20210102'
":ProjectMap": [{
"Name": "Project C"
"ID": "7463848373"
}],
":ProjectID": ["7463848373"]
},
ConditionExpression = "(#LastUpdated < :LastUpdated AND #JobTitle <> :JobTitle) OR not(contains(#ProjectList, :ProjectID))"
)
I'm skeptical that this is possible due to this line in the AWS documentation:
For these data manipulation operations, you can specify a condition expression to determine which items should be modified. If the condition expression evaluates to true, the operation succeeds; otherwise, the operation fails.

Substitute variable in an array from another array

Using groovy, how can I substitute the value of an array in another array variable?
For eg.:
def Env = [
'Env1',
'Env2',
'Env3'
]
def Job = [
[
name: "Job1",
label: "<$Env>",
action: #!/usr/bin/bash
blah
blah
],
[
name: "Job2",
label: "<$Env>",
action: #!/usr/bin/bash
blah
blah
]
]
I want the label field in the second array Job to be populated by every item in Env
If the code isn't dynamic you can just do:
def Env = ['Env1','Env2', 'Env3']
def Job = [
[
name: "Job1",
label: "<${Env[0]}>",
action: '#!/usr/bin/bash'
],
[
name: "Job2",
label: "<${Env[1]}>",
action: '#!/usr/bin/bash'
]
]
If it's dynamic you can do:
Job.eachWithIndex{ obj, idx ->
obj.label = Env[idx]
}

Resources