Terraform - Dict with values as list convert to string - terraform

dataset_bindings = {
"infra":[
"group:infra-team#xxxx.com",
],
"finance":[
"group:finance-data#xxx.com",
],
"marketing": [
"group:marketing#xxx.com"
]
}
How can I get all the emails as string. I need to loop thru the dict and get the values and convert those values to string.

You can do this with values and flatten:
locals {
dataset_bindings = {
"infra":[
"group:infra-team#xxxx.com",
],
"finance":[
"group:finance-data#xxx.com",
],
"marketing": [
"group:marketing#xxx.com"
]
}
list_of_emails = flatten(values(local.dataset_bindings))
}
results in:
list_of_emails = [
"group:finance-data#xxx.com",
"group:infra-team#xxxx.com",
"group:marketing#xxx.com",
]

Related

Convert string in a existing dictionary to list

I have a dictionary below. I want to convert the string to list in Body section ("Body":"{"abc": "test"}"). My requirement is that I will post the whole dictionary and it will convert that into valid json object.
details = {
"bb":[
{
"bb_name":[
"baca"
]
}
],
"spd":[
{
"id_":1,
"schema":{
"method":"GET",
"url":"http://api.myapi.com/12232",
"Headers":[
],
"Parameters":[
],
"Body":"{\"abc\": \"test\"}"
}
}
]
}

Parse JSON Dictionary with Python3

I have a JSON representation that looks like the following:
{
"results": [
{
"vulnerabilities": [
],
}
]
}
I tried to output just the vulnerabilities portion, but the following doesnt work:
for key, value in json_object.items():
print(key, ' : ', value)
This prints out the whole results but not just the vulnerabilities
Assuming multiple dicts in results, each with a vulnerabilities key, you can do:
json_object = {
"results": [
{
"vulnerabilities": [
],
}
]
}
for result in json_object['results']:
for vuln in result['vulnerabilities']:
print(vuln)

Arango DB Filter query for print array of value

Given the following document structure:
{
"name": [
{
"use": "official",
"family": "Chalmers",
"given": [
"Peter",
"James"
]
},
{
"use": "usual",
"given": [
"Jim"
]
},
{
"use": "maiden",
"family": "Windsor",
"given": [
"Peter",
"James"
]
}
]
}
Query:
FOR client IN Patient FILTER client.name[*].use=='official' RETURN client.name[*].given
I have telecom and name array.
I want to query to compare if name[*].use=='official' then print corresponding give array.
Expected result:
"given": [
"Peter",
"James"
]
client.name[*].use is an array, so you need to use an array operator. It can be either of the following:
'string' in doc.attribute
doc.attribute ANY == 'string'
doc.attribute ANY IN ['string']
To return just the given names from the 'official' array, you can use a subquery:
RETURN { given:
FIRST(FOR name IN client.name FILTER name.use == 'official' LIMIT 1 RETURN name.given)
}
Alternatively, you can use an inline expression:
FOR client IN Patient
FILTER 'official' IN client.name[*].use
RETURN { given:
FIRST(client.name[* FILTER CURRENT.use == 'official' LIMIT 1 RETURN CURRENT.given])
}
Result:
[
{
"given": [
"Peter",
"James"
]
}
]
In your original post, the example document and query didn't match, but assuming the following structure:
{
"telecom": [
{
"use": "official",
"value": "+1 (03) 5555 6473 82"
},
{
"use": "mobile",
"value": "+1 (252) 5555 910 920 3"
}
],
"name": [
{
"use": "official",
"family": "Chalmers",
"given": [
"Peter",
"James"
]
},
{
"use": "usual",
"given": [
"Jim"
]
},
{
"use": "maiden",
"family": "Windsor",
"given": [
"Peter",
"James"
]
}
]
}
… here is a possible query:
FOR client IN Patient
FILTER LENGTH(client.telecom[* FILTER
CONTAINS(CURRENT.value, "(03) 5555 6473") AND
CURRENT.use == 'official']
)
RETURN {
given: client.name[* FILTER CURRENT.use == 'official' RETURN CURRENT.given]
}
Note that client.telecom[*].value LIKE "..." causes the array of phone numbers to be cast to a string "[\"+1 (03) 5555 6473 82\",\"+1 (252) 5555 910 920 3\"]" against which the LIKE operation is run - this kind of works, but it's not ideal.
CONTAINS() is also faster than LIKE with % wildcards on both sides.
It would be possible that there are multiple 'official' elements, which might require an extra level of array nesting. Above query produces:
[
{
"given": [
[
"Peter",
"James"
]
]
}
]
If you know that there is only one element or restrict it to one element explicitly then you can get rid of one of the wrapping square brackets with FIRST() or FLATTEN().

Groovy object retrieval using String notation

Writing a utility method for Jenkins pipeline using groovy and noticed its not easy to get value from a deeply nested map using externalised object retrieval notation as string.
Question: If you see the example below, you will notice that its not possible to retrieve object in the form datas."bankctrl.deployment.clientConfigMap.enabled". You definitely can do datas."bankctrl"."deployment"."clientConfigMap"."enabled". I have a workaround, but question is if there is any known best approach to do this?
datas = [
"ao":[
deployment:[
clientConfigMap:[
enabled:"true", name:"volume-ao-custom"
], image:[
name:"test/mit/ao",
tag:"10.0.0-3.0.0",
pullPolicy:"IfNotPresent"
]
]
], "bankctrl":[
deployment:[
clientConfigMap:[
enabled:"false",
name:"volume-bankctrl-custom"
], image:[
name:"test/mit/bankctrl",
tag:"10.0.0-3.0.0",
pullPolicy:"IfNotPresent"
]
]
]
]
String name = "bankctrl"
datas."${name}".deployment.clientConfigMap.enabled = true
println datas
//following does't work as dots within string are not evaluated.
String elementNameToUpdate = "bankctrl.deployment.clientConfigMap.enabled"
datas."${elementNameToUpdate}" = true
Following code works when you need to access values using externalised string:
String s = "bankctrl.deployment.clientConfigMap.enabled"
def q = s.split( /\./ ).inject( datas ) { obj1, prop -> obj1?."$prop" }
println q
Even this works when you need to access values using externalised string:
String s = "bankctrl.deployment.clientConfigMap.enabled"
Eval.x(datas,"x.${s}")
def gpathSet = { obj,path,value -> Eval.xy(obj, value, "x.${path}=y") }
datas = [
"bankctrl":[
deployment:[
clientConfigMap:[
enabled:"false",
name:"volume-bankctrl-custom"
], image:[
name:"test/mit/bankctrl",
tag:"10.0.0-3.0.0",
pullPolicy:"IfNotPresent"
]
]
]
]
String elementNameToUpdate = "bankctrl.deployment.clientConfigMap.enabled"
gpathSet(datas, elementNameToUpdate, true)
One way of workaround.
String s = "bankctrl.deployment.clientConfigMap.enabled"
def setDeepProps(s,datas, value) {
s.split(/\./).inject(datas) {
obj, prop ->
if (obj."$prop" instanceof Map)
obj?."$prop"
else
obj."$prop" = value
}
}
setDeepProps(s,datas,true)
println datas
Groovy doesn't have this functionality out-of-box, so you have to either go wild and use Eval :) which for this certain case is a bit fragile (if the path-string is misspelled it can produce RuntimeExceptions) and not the best performer (due to run-time compilation).
You can solve your problem with a simple recursion like so:
def datas = [
"ao":[
deployment:[
clientConfigMap:[
enabled:"true", name:"volume-ao-custom"
], image:[
name:"test/mit/ao",
tag:"10.0.0-3.0.0",
pullPolicy:"IfNotPresent"
]
]
], "bankctrl":[
deployment:[
clientConfigMap:[
enabled:"false",
name:"volume-bankctrl-custom"
], image:[
name:"test/mit/bankctrl",
tag:"10.0.0-3.0.0",
pullPolicy:"IfNotPresent"
]
]
]
]
def traverser
traverser = { map, path ->
int ix = path.indexOf '.'
if( -1 == ix ) return map[ path ]
def val = map[ path[ 0..<ix ] ]
if( val in Map )
traverser val, path.substring( ix + 1 )
else
null
}
traverser datas, "bankctrl.deployment.clientConfigMap.enabled"
Below workaround worked for me. The reason I preferred this over any other solution is cause Jenkins is very picky about what script you invoke and hence wanted to have a work around that would not force me to accept script execution in Jenkins while getting around this requirement.
On a side note, would have loved if Jenkins would let me explore full power of Groovy and unfortunately it doesn't because of security reasons.
datas = [
"ao":[
deployment:[
clientConfigMap:[
enabled:"false",
name:"volume-ao-custom"
], image:[
name:"test/mit/ao",
tag:"10.0.0-3.0.0",
pullPolicy:"IfNotPresent"
]
]
], "bankctrl":[
deployment:[
clientConfigMap:[
enabled:"false",
name:"volume-bankctrl-custom"
], image:[
name:"test/mit/bankctrl",
tag:"10.0.0-3.0.0",
pullPolicy:"IfNotPresent"
]
]
]
]
boolean customConfigFolderExists = true
String elementNameToUpdate = "bankctrl.deployment.clientConfigMap.enabled"
String[] elementNameToUpdateArray = "${elementNameToUpdate}".split("\\.")
def tempDatas = datas
//get property like datas.bankctrl.deployment.clientConfigMap (note that we are leaving enabled out which would be invoked in the following steps)
for (int i=0; i<elementNameToUpdateArray.length-1; i++) {
println "elementNameToUpdateArray[i] -> ${elementNameToUpdateArray[i]}"
tempDatas = tempDatas?."${elementNameToUpdateArray[i]}"
}
//we are invoking property returned from for loop above using the last element from elementNameToUpdateArray
tempDatas?."${elementNameToUpdateArray[elementNameToUpdateArray.length-1]}" = true
println "datas = ${datas}"

Power Query Expression error: A value of type "Record" cannot converted into type "Text"

I have the issue that I'm not able to execute the following code. The syntax seems to be okay, but when I try to execute it, I get the response, that:
Expression.Error: We cannot convert a value of type Record to type "Text".
Details:
Value=[Record]
Type=[Type]
let
body="{
""page"": ""1"",
""pageSize"": ""100"",
""requestParams"": {
""deviceUids"": [
""xxx-yyy-xxx-yyyy-xxxx"",
""yyy-xxx-yyy-xxxx-yyyy"",
""aaa-bbb-aaa-bbbb-aaaa"",
""ccc-ddd-ccc-dddd-cccc""
],
""entityColumns"": [
{
""entityId"": ""144"",
""joinColumnName"": ""device_uid"",
""columnName"": ""device_random_date""
}
],
""columnNames"": [
""ts"",
""device_uid"",
""1"",
""32"",
""55"",
""203"",
""204""
],
""startUnixTsMs"": ""1583413637000"",
""endUnixTsMs"": ""1583413640000"",
""columnFilters"": [
{
""filterType"": ""eq"",
""columnName"": ""55"",
""value"": ""1234""
}
],
""sortOrder"": [
{
""column"": ""ts"",
""order"": ""DESC""
},
{
""column"": ""55"",
""order"": ""ASC""
}
],
""entityFilters"": [
{
""entityId"": ""144"",
""entityEntryIds"": [
""12345-221-232-1231-123456""
]
}
]
}
}",
Parsed_JSON = Json.Document(body),
BuildQueryString = Uri.BuildQueryString(Parsed_JSON),
Quelle = Json.Document(Web.Contents("http://localhost:8101/device-data-reader-api/read-paginated/xxx-xxx-yyyy-yyyy", [Headers=[#"Content-Type"="application/json"], Content = Text.ToBinary(BuildQueryString)]))
in
Quelle
I tried to remove the quotes of the numbers, but this leads to the same issue, as system complains it cannot convert numbers into text.
I need the body which needs to be handed over with the request in order to do a POST request. What I'm doing wrong?
Since you seem to want to send this as application/json, I think you would change this bit in your code:
Content = Text.ToBinary(BuildQueryString)
to:
Content = Text.ToBinary(body)
and then you'd also get rid of the lines below (since you don't need them):
Parsed_JSON = Json.Document(body),
BuildQueryString = Uri.BuildQueryString(Parsed_JSON),
I don't think you would need Uri.BuildQueryString unless you wanted to send as application/x-www-form-urlencoded (i.e. URL encoded key-value pairs).
Unrelated: If it helps, you can build the structure in M and then use JSON.FromValue to turn the structure into bytes which can be put directly into the POST body. Untested example is below.
let
body = [
page = "1",
pageSize = "100",
requestParams = [
deviceUids = {
"xxx-yyy-xxx-yyyy-xxxx",
"yyy-xxx-yyy-xxxx-yyyy",
"aaa-bbb-aaa-bbbb-aaaa",
"ccc-ddd-ccc-dddd-cccc"
},
entityColumns = {
[
entityId = "144",
joinColumnName = "device_uid",
columnName = "device_random_date"
]
},
columnNames = {
"ts",
"device_uid",
"1",
"32",
"55",
"203",
"204"
},
startUnixTsMs = "1583413637000",
endUnixTsMs = "1583413640000",
columnFilters = {
[
filterType = "eq",
columnName = "55",
value = "1234"
]
},
sortOrder = {
[
column = "ts",
order = "DESC"
],
[
column = "55",
order = "ASC"
]
},
entityFilters = {
[
entityId = "144",
entityEntryIds = {
"12345-221-232-1231-123456"
}
]
}
]
],
Quelle = Json.Document(
Web.Contents(
"http://localhost:8101/device-data-reader-api/read-paginated/xxx-xxx-yyyy-yyyy",
[
Headers = [#"Content-Type" = "application/json"],
Content = Json.FromValue(body)
]
)
)
in
Quelle
It might look a little weird (since M uses [] instead of {}, {} instead of [] and = instead of :), but just mentioning in case it helps.

Resources