3

When using azure-cli in python 3.5 and calling the commands from a script I have no control on the output in the console.

When a command is executed it prints the result to the console, but I'm struggling to just take the result and put it in a variable to analyze it.

from azure.cli.core import get_default_cli

class AzureCmd():
        def __init__(self, username, password):
            self.username = username
            self.password = password

        def login(self, tenant):
            login_successfull = get_default_cli().invoke(['login',
                                                          '--tenant', tenant,
                                                          '--username', self.username,
                                                          '--password', self.password]) == 0
            return login_successfull

        def list_vm(self, tenant):
            list_vm = get_default_cli().invoke(['vm', 'list', '--output', 'json'])
            print(list_vm)


    tenant = 'mytenant.onmicrosoft.com'
    cmd = AzureCmd('login', 'mypassword')
    cmd.login(tenant)
    cmd.list_vm(tenant)

Here is my my script attempt.

What I want to achieve : not getting any output when cmd.login(tenant) is executed. Instead of getting 0 (success) or 1 (failure) in my variables login_successfull and list_vm, I want to save the output of the get_default_cli().invoke() in it.

1
  • 1
    If it is success return 0. It is implemented by get_default_cli().invoke() function in the python sdk. If you try to use that function, it seems that you can't get the command output, you could give your great ideas to azure team. Commented Sep 19, 2018 at 8:08

5 Answers 5

1

I ran into the same problem, and found a solution, I also found out many people offered the standard solution that normally works in most cases, but they didn't verify it works for this scenario, and it turns out az cli is an edge case.
I think the issue has something to do with az cli is based on python.

Win10CommandPrompt:\> where az C:\Program Files (x86)\Microsoft SDKs\Azure\CLI2\wbin\az.cmd

If you look in that file you'll see something like this and discover that Azure CLI is just python:

python.exe -IBm azure.cli

So to do what you want to do, try this (it works for me):

import subprocess
out = subprocess.run(['python', '-IBm', 'azure.cli', '-h'], stdout=subprocess.PIPE).stdout.decode('utf-8')
print(out) 
#this is equivalent to "az -h'

The above syntax won't work unless every single arg is a comma separated list of strings, I found a syntax I like alot more after reading how to do multiple args with python popen:

import subprocess
azcmd = "az ad sp create-for-rbac --name " + SPName + " --scopes /subscriptions/" + subscriptionid
out = subprocess.run(azcmd, shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8')
print(out)
Sign up to request clarification or add additional context in comments.

2 Comments

Going to try this ! Thanks a lot :)
It worked .. I was working with multiple venvs & hit the same issue. I did like this ` import sys # Get the current python env v_env = sys.executable azure_cmd = ' containers log -n CONTAINER_NAME -g RESOURCE_GROUP' comp_cmd = v_env + azure_cmd out = subprocess.run( comp_cmd.split(), shell=True, stdout=subprocess.PIPE).stdout.decode('utf-8') print(out) `
1

I faced the same problem while trying to save the log of Azure Container Instance. None of the above solutions worked exactly as they are. After debugging the azure cli python code (File : \Python39\Lib\site-packages\azure\cli\command_modules\container\custom.py , function : container_logs() ), i see that the container logs are just printed to the console but not returned. If you want to save the logs to any variable, add the return line (Not exactly a great solution but works for now). Hoping MS Azure updates their azure cli in upcoming versions.

def container_logs(cmd, resource_group_name, name, container_name=None, follow=False):
    """Tail a container instance log. """
    container_client = cf_container(cmd.cli_ctx)
    container_group_client = cf_container_groups(cmd.cli_ctx)
    container_group = container_group_client.get(resource_group_name, name)

    # If container name is not present, use the first container.
    if container_name is None:
        container_name = container_group.containers[0].name
    if not follow:
        log = container_client.list_logs(resource_group_name, name, container_name)
        print(log.content)
        # Return the log
        return(log.content)
    else:
        _start_streaming(
            terminate_condition=_is_container_terminated,
            terminate_condition_args=(container_group_client, resource_group_name, name, container_name),
            shupdown_grace_period=5,
            stream_target=_stream_logs,
            stream_args=(container_client, resource_group_name, name, container_name, container_group.restart_policy))

With this modification and along with the above solutions given (Using the get_default_cli), we can store the log of the Azure container instance in a variable.

from azure.cli.core import get_default_cli

def az_cli(args_str):
    args = args_str.split()
    cli = get_default_cli()
    res = cli.invoke(args)
    if cli.result.result:
       jsondata = cli.result.result
    elif cli.result.error:
       print(cli.result.error)

Comments

0

I think you can use the subprocess and call the az cli to get the output instead using get_default_cli.

import subprocess
import json

process = subprocess.Popen(['az','network', 'ddos-protection', 'list'], stdout=subprocess.PIPE)
out, err = process.communicate()
d = json.loads(out)
print(d)

Comments

0

Well, we can execute the Azure CLI commands in Python as shown below. Here, the res variable usually stores a value of integer type and therefore we might not be able to access the json response. To store the response in a variable, we need to do cli.result.result.

from azure.cli.core import get_default_cli

def az_cli(args_str):
    args = args_str.split()
    cli = get_default_cli()
    res = cli.invoke(args)```
    if cli.result.result:
       jsondata = cli.result.result
    elif cli.result.error:
       print(cli.result.error)

Comments

0

Here is how to get the result:

az_cli = get_default_cli()
az_cli.invoke([]) # fill in command here

result = az_cli.result
if result.exit_code == 0:
    object_id = result.result
    print(object_id)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.