Saltstack cloud.map with Bash variables

150 Views Asked by At

I'm trying to provision a Windows virtual machine in VMWare using Salt Cloud wrapped in a bash script so that I can parameterise it but I'm having a problem with the escaping of the map_data.

my command is:

#!/bin/bash
salt salt-cloud cloud.map_run map_data='{"PROFILE":[{"HOSTNAME":{"folder":"FOLDER","devices":{"network":{"Network adapter 1":{"ip":"MYIP"}}}}}]}'

This works fine however I would like HOSTNAME, FOLDER and MYIP to be variables ($hostname $folder and $ip) and I'm struggling a bit with the escaping so that the variables are expanded and passed correctly to salt.

I have tried putting the variable inline in the command:

salt salt-cloud cloud.map_run map_data='{"PROFILE":[{"$hostname":{"folder":"$folder,"devices":{"network":{"Network adapter 1":{"ip":"$ip"}}}}}]}'

This gets as far as copying the template in the profile before bombing out with a vmware error about the variblised elements being incorrect

I have also tried to encapsulate the whole map data in a variable, escaping the double quotes and passing that, e.g,

data="'{\"PROFILE\":[{\"$hostname\":{\"folder\":\"$folder\",\"devices\":{\"network\":{\"Network adapter 1\":{\"ip\":\"$ip\"}}}}}]}'"

This appears to expand correctly if I echo it out but when I add it to my command:

salt salt-cloud cloud.map_run map_data=$data

I get the following error:

Passed invalid arguments to cloud.map_run: map_run() takes at most 1 argument (10 given)

I know that this is probably not strictly Salt's problem but I wondered if anyone out there could give me some pointers on how to proceed?

2

There are 2 best solutions below

0
On

Did you try the concatenation of strings like that :

salt salt-cloud cloud.map_run map_data='{"PROFILE":[{"'$hostname'":{"folder":"'$folder',"devices":{"network":{"Network adapter 1":{"ip":"'$ip'"}}}}}]}'
1
On

I don't use the cloud app myself, so I can't test it but looking at the first command you give:

salt salt-cloud cloud.map_run map_data='{"PROFILE":[{"$hostname":{"folder":"$folder,"devices":{"network":{"Network adapter 1":{"ip":"$ip"}}}}}]}'

Because the variables are in single quotes, they won't expand. So that won't work.

The second command you gave:

data="'{\"PROFILE\":[{\"$hostname\":{\"folder\":\"$folder\",\"devices\":{\"network\":{\"Network adapter 1\":{\"ip\":\"$ip\"}}}}}]}'"

Looks correct, it will expand the variables, but compared to the first command it will also add single quotes to the string (I think you forgot to remove those?).

Also in your first command a " seems to be missing after $folder.

Fixing those mistakes gives me the command:

salt salt-cloud cloud.map_run map_data="{\"PROFILE\":[{\"$hostname\":{\"folder\":\"$folder\",\"devices\":{\"network\":{\"Network adapter 1\":{\"ip\":\"$ip\"}}}}}]}"

which I think would work. If you put an echo in front of your command, and just copy your json, you can copy/paste it into a json formatter like https://jsonformatter.curiousconcept.com/ and it will tell you if the json you used is correct. This will help you find things like missing quotes.