Azure-cli: az vm get-instance-view doesn’t accept multiple ids...

Created on 12 Nov 2018  Â·  13Comments  Â·  Source: Azure/azure-cli

Describe the bug
az vm get-instance-view doesn’t accept multiple ids

To Reproduce
Single id works:
az vm list --query "[0:1].id" -o tsv | az vm get-instance-view --ids @- --query instanceView.statuses[1] --output table
Two and more won’t work:
az vm list --query "[0:2].id" -o tsv | az vm get-instance-view --ids @- --query instanceView.statuses[1] --output table

Expected behavior
Command should work with multiple ids passed

Environment summary
Install Method (e.g. pip, interactive script, apt-get, Docker, MSI, edge build) / CLI version (az --version) / OS version / Shell Type (e.g. bash, cmd.exe, Bash on Windows)
MSI / azure-cli (2.0.42) / Windows server 2016 / cmd / Python (Windows) 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 16:07:46) [MSC v.1900 32 bit (Intel)]

Additional context
Add any other context about the problem here.
Nothing

Compute-cli bug question

All 13 comments

The following command works:

az vm list --query "[0:2].id" -o tsv | az vm get-instance-view --ids @- \
--query [].instanceView.statuses[1] --output table

Notice the modified query.

vm get-instance-view returns a json object representing the vm instance (if one vm name/id is passed as an argument) but a list of objects if more than one vm (resource id) is passed as an argument.

To determine whether an issue is a cli issue or JMESPATH issue, it can help to try the command without any queries first and then use the default output.

Please let me know if you have any other questions.

Notice the modified query.

I don’t think the query was the issue in my case.
It fails before it gets to query part, IMO.

Without query I got very same error for 2 ids:
az vm list --query "[0:2].id" -o tsv | az vm get-instance-view --ids @-
_Operation failed with status: 'Bad Request'. Details: 400 Client Error: Bad Request for url: https://management.azure.com/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-a%0A?$expand=instanceView&api-version=2017-12-01_

Note, VM name is adfs-a, not adfs-a%0A

And no error for one:
az vm list --query "[0].id" -o tsv | az vm get-instance-view --ids @-
_{
"availabilitySet": {
"id": "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/availabilitySets/ADFS",
"resourceGroup": "ADFS"
},
...
}_

BTW: Could you show how pass two or more ids instead of “@-“, please?
az vm get-instance-view --ids @-

What version of the cli are you using? Could you try updating to the latest and rerunning this command?
If updating the CLI isn't possible. I have some questions:

  • Was this error message the full error message you got?
  • Could you share what the response body of that bad request is? You can get it by running --debug and searching for the bad request message.

Thanks.

Also to pass the two ids, if you are using a linux-based shell, you can do any of the following:

Get ids, store in shell variable, use this shell variable to get vm instances.

VM_IDS=$(az vm list --query "[0].id" -o tsv) \
az vm get-instance-view --ids $VM_IDS

Get ids, assign to shell variable, if successful, use these ids to get the instances:

VM_IDS=$(az vm list --query "[0].id" -o tsv) && az vm get-instance-view --ids $VM_IDS

Get ids and pass the result to get-instance-view:
az vm get-instance-view --ids $(az vm list --query "[0].id" -o tsv)

I think we got it!
Thanks a lot for your tip! 👍
Long story short:
az vm list --query "[0:2].id" -o tsv
_/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-a
/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-b_

Notice, the results are separated by "crlf ", not "space"!
I'd use
| tr '\n' ' '
to handle it on linux, but I've no clue how it's done on Windows...

As a result VM name in next request gets changed from “adfs-a” to “adfs-a%0A”.
You can see it on my prev. post.
The latter doesn’t exist obviously, thus all that juzz.

I’m azure-cli (2.0.42), I assume that’s the latest one?

Could you show how pass two or more ids instead of “@-“, please?

az vm get-instance-view -ids
ids separated by space works fine, but cannot separate by Line feed (0x0A)
I guess, not a big deal to fix it (for poor souls who have to use Windows to manage Azure)

What do we do next?

BTW: Try to simulate it on linux with
az vm list --query "[0:2].id" -o tsv | tr ' ' '\n' | az vm get-instance-view --ids @-

No problem! :)

Yes, I just tested this scenario on a windows machine and it seems that the newline / carriage return is the issue. The command you asked me to simulate ran successfully on a linux-based machine. The CLI should recognize the carriage-return/linefeed as whitespace, so this is likely a bug. We will work on a fix for it.

I can try to get back to you with an automatic work around tomorrow. But for now your best bet is manually converting the carriage return to line space using a text editor.

adewaleo,

I can try to get back to you with an automatic work around tomorrow.

Thanks again! 👍
I’m not in any rush with it.
I’m sure you have more important thing to do too.

But for now your best bet is manually converting the carriage return to line space using a text editor.

Ugh... I’ve tried slightly different approach.
I’ve got GNU sed from here:
http://gnuwin32.sourceforge.net/packages/sed.htm

And run right into another bug, probably:
The steps to reproduce are:

# get VMs list separated by “space” into ids.txt
az vm list --query "[0:3].id" -o tsv | sed ":a;N;$!ba;s/\n/ /g" > ids.txt

# piping the list returns first VM from it only
type ids.txt | az vm get-instance-view --ids @- > result.txt

# same list inline returns all VMs
az vm get-instance-view --ids /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-a /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-a0 /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/ADFS/providers/Microsoft.Compute/virtualMachines/adfs-b > result-1.txt

I wonder why most of the examples suggest “inline-ing”:
az vm get-instance-view --ids $(az vm list --query "[0].id" -o tsv)
instead of piping:
az vm list --query "[0].id" -o tsv | az vm get-instance-view --ids -@
The former works for Linux only, while there latter should be good for everybody, right?

I wonder why most of the examples suggest “inline-ing”:
az vm get-instance-view --ids $(az vm list --query "[0].id" -o tsv)
instead of piping:
az vm list --query "[0].id" -o tsv | az vm get-instance-view --ids -@
The former works for Linux only, while there latter should be good for everybody, right?

Either way works. I imagine it's more of a matter of style. However, inlining could be useful in instances where multiple arguments are the results of multiple commands. Moreover, I am not sure why the command above worked where supplying @- somehow read from the piped stdin.

Either way works. I imagine it's more of a matter of style. However, inlining could be useful in instances where multiple arguments are the results of multiple commands.

Yep, definitely agree with the latter, tho long commands are a bit more difficult to understand.

Moreover, I am not sure why the command above worked where supplying @- somehow read from the piped stdin.

@- have to to read parameters from stdin, that’s the only way it can work, IMO.

BTW: Tried to google smth. like
az cli +"@-", but it keeps dropping last term, don’t know how convince it not to!

So it turns out that "@-" is a CLI feature. Generally --param @filename, passes the contents of filename as the value of --param. The CLI treats @- specially, as reading from stdin.

We will most likely document the use of @- as a param value in our docs or upcoming blog post, but the @ symbol's use in the cli is documented in a few example such as VM create's example "Create a Debian VM with SSH key authentication and a public DNS entry..."

Finally, it also turns out that resource IDS passed through --ids can be json objects (containing an id field) and/or id strings from tsv output.

So for example, one could run the following:

Regular way:

$  az vm list --query [0:2].id -o tsv | az vm get-instance-view --ids @- --query "[].{name:name,id:id}" -otsv

Passing json list of ids:

$  az vm list --query "[0:2].{id:id}" | az vm get-instance-view --ids @- --query "[].{name:name,id:id}" -otsv

Passing json list of full data (containing vm ids):

$  az vm list --query [0:2] | az vm get-instance-view --ids @- --query "[].{name:name,id:id}" -otsv

Mix json output with tsv output:

$ VM3_ID=$(az vm show -n tosin-vm-3 --query "id" -o tsv)
$ echo $VM3_ID
/subscriptions/0000000000000.../resourceGroups/ova-test/providers/Microsoft.Compute/virtualMachines/tosin-vm-3
$  az vm list --query [0:2] | az vm get-instance-view --ids @- $VM3_ID --query "[].{name:name,id:id}" -otsv

I assume “Regular way” will be fixed in next public release, right?
Thanks a lot for the workaround with “Passing json list of ids”! :)
And Happy Thanksgiving!

I assume “Regular way” will be fixed in next public release, right?
Thanks a lot for the workaround with “Passing json list of ids”! :)
And Happy Thanksgiving!

Yes, "the regular way", will be fixed in the next public release; the pr for the fix has been merged.

Thanks! Have a Happy Thanksgiving as well!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

binderjoe picture binderjoe  Â·  3Comments

amarzavery picture amarzavery  Â·  3Comments

williexu picture williexu  Â·  3Comments

PrHar picture PrHar  Â·  3Comments

dhermans picture dhermans  Â·  3Comments