0
votes

Currently I fail to run an azure CLI command from Groovy because of the JSON Part in the Command.

There is an azure command to run custom scripts on a virtual machine. The CommandToExecute on the Machine is passes as JSON.

WORKING Example:

REQUEST-CALL in Console:az vm extension set -g demo --vm-name demo-cfg01 --name CustomScript --publisher Microsoft.Azure.Extensions --settings '{"commandToExecute":"ls"}'

RESPONSE: {
  "autoUpgradeMinorVersion": true,
  "forceUpdateTag": null,
  "id": "/subscriptions/xxxxxxxxxx-xxxxxx-xxxx-xxxx-xxxxxxxxxxxxx/resourceGroups/demo/providers/Microsoft.Compute/virtualMachines/demo-cfg01/extensions/CustomScript",
  "instanceView": null,
  "location": "germanycentral",
  "name": "CustomScript",
  "protectedSettings": null,
  "provisioningState": "Succeeded",
  "publisher": "Microsoft.Azure.Extensions",
  "resourceGroup": "demo",
  "settings": {
    "commandToExecute": "ls"
  },
  "tags": null,
  "type": "Microsoft.Compute/virtualMachines/extensions",
  "typeHandlerVersion": "2.0",
  "virtualMachineExtensionType": "CustomScript"
}

This script works fine.

"Same" Command executed with Groovy leads to following:

def process
        StopWatch.withTimeRecording("EXECUTING COMMAND '" + cargs + "'",_logger, Level.ALL) {
            process = (cargs).execute(null,null);
            process.waitForProcessOutput(sout, serr)
        }

Please notice the StopWatch which logs the StringArray containing the params:

EXECUTING COMMAND '[az, vm, extension, set, -g, demo, --vm-name, demo-cfg01, --name, CustomScript, --publisher, Microsoft.Azure.Extensions, --settings, '{"commandToExecute":"ls"}']'

The Params looks the same as in the console

The Response from Azure is:

VM has reported a failure when processing extension 'CustomScript'. Error message: "Enable failed: failed to get configuration: error reading extension configuration: error parsing settings file: error parsing json: json: cannot unmarshal string into Go value of type map[string]interface {}

I think groovy somehow escapes the characters before execution, i cannot figure out what went wrong. Any suggestion?

3

3 Answers

0
votes

when you call execute on array groovy (actually java) doublequotes each parameter.

just build your command line as you need in a string

string in groovy has the same execute method as an array...

def cmd = """az vm extension set -g demo --vm-name demo-cfg01 --name CustomScript --publisher Microsoft.Azure.Extensions --settings '{"commandToExecute":"ls"}' """
def process = cmd.execute()

when you use execute on string groovy will execute the exact command you've provided

0
votes

Found a "workaround". The az command also accept an *.json file as settings parameter. Therefor i first create the command in a temporary json file and passes the json file as parameter. Works!

0
votes

You are quoting for an .execute() call. You dont need to quote there, because no shell or command parser is involved here.

Your command there gets '{"commandToExecute":"ls"}', which is a valid JSON String (no Map) and this is also what the error message states:

error parsing json: json: cannot unmarshal string into Go value of type map[string]interface

Just use {"commandToExecute": "ls"} (no surrounding ') as argument there.