How to access Azure AD with Python SDK? - python

I could manage to get access to Azure resources with the code bellow:
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.graphrbac import GraphRbacManagementClient
subscription_id = "aaaa"
tenant_id = "bbbb"
credentials = ServicePrincipalCredentials(
client_id="cccc",
secret="dddd",
tenant=tenant_id
)
client = ResourceManagementClient(credentials, subscription_id)
for item in client.resource_groups.list():
print item
compute_client = ComputeManagementClient(credentials, subscription_id)
disks = compute_client.disks.list()
for disk in disks:
print disk
But I can't access Azure AD with the same code!!! Is there a different way to access it? Why is it different?! See the code bellow:
graphrbac_client = GraphRbacManagementClient(credentials, subscription_id)
for item in graphrbac_client.groups.list():
print item
Error:
GraphErrorExceptionTraceback (most recent call last)
in ()
1 graphrbac_client = GraphRbacManagementClient(credentials, subscription_id)
2
----> 3 for item in graphrbac_client.groups.list():
4 print item
/home/andre/.local/lib/python2.7/site-packages/msrest/paging.pyc in
next(self)
129 return response
130 else:
--> 131 self.advance_page()
132 return self.next()
133
/home/andre/.local/lib/python2.7/site-packages/msrest/paging.pyc in
advance_page(self)
115 raise StopIteration("End of paging")
116 self._current_page_iter_index = 0
--> 117 self._response = self._get_next(self.next_link)
118 self._derserializer(self, self._response)
119 return self.current_page
/home/andre/.local/lib/python2.7/site-packages/azure/graphrbac/operations/groups_operations.pyc
in internal_paging(next_link, raw)
336
337 if response.status_code not in [200]:
--> 338 raise models.GraphErrorException(self._deserialize, response)
339
340 return response
GraphErrorException: Access Token missing or malformed.
azure-common version = 1.1.14

Access Token missing or malformed.
ComputeManagementClient resource path is https://management.azure.com
But for GraphRbacManagementClient the resource path is https://graph.windows.net. So you got the exception.
How to access Azure AD with Python SDK?
You could get the answer from this link. The following code is the snippet from the document.
from azure.graphrbac import GraphRbacManagementClient
from azure.common.credentials import UserPassCredentials
# See above for details on creating different types of AAD credentials
credentials = UserPassCredentials(
'user#domain.com', # Your user
'my_password', # Your password
resource="https://graph.windows.net"
)
tenant_id = "myad.onmicrosoft.com"
graphrbac_client = GraphRbacManagementClient(
credentials,
tenant_id
)

Related

azure log analytics InsufficientAccessError

I am trying to read log analytics in python.
Here is my code:
AZURE_CLIENT_ID = ''
AZURE_CLIENT_SECRET = ''
AZURE_TENANT_ID = ''
workspace_id = ''
from azure.identity import ClientSecretCredential
from datetime import datetime
from azure.monitor.query import LogsQueryClient, LogsQueryStatus
start_time = datetime(2022, 1, 1)
end_time = datetime(2023, 1, 2)
credential = ClientSecretCredential(
client_id = AZURE_CLIENT_ID,
client_secret = AZURE_CLIENT_SECRET,
tenant_id = AZURE_TENANT_ID
)
client = LogsQueryClient(credential)
query = "ContainerLog"
response = client.query_workspace(workspace_id=workspace_id,
query=query, timespan=(start_time, end_time - start_time))
if response.status == LogsQueryStatus.PARTIAL:
error = response.partial_error
print('Results are partial', error.message)
elif response.status == LogsQueryStatus.SUCCESS:
results = []
for table in response.tables:
for row in table.rows:
results.append(dict(zip(table.columns, row)))
print(convert_azure_table_to_dict(results))
and it is failing:
Traceback (most recent call last):
File "c:\temp\x.py", line 24, in <module>
response = client.query_workspace(workspace_id=workspace_id,
File "C:\kourosh\venv\lib\site-packages\azure\core\tracing\decorator.py", line 78, in wrapper_use_tracer
return func(*args, **kwargs)
File "C:\kourosh\venv\lib\site-packages\azure\monitor\query\_logs_query_client.py", line 136, in query_workspace
process_error(err, LogsQueryError)
File "C:\kourosh\venv\lib\site-packages\azure\monitor\query\_helpers.py", line 141, in process_error
raise HttpResponseError(message=error.message, response=error.response, model=model)
azure.core.exceptions.HttpResponseError: (InsufficientAccessError) The provided credentials have insufficient access to perform the requested operation
Code: InsufficientAccessError
Message: The provided credentials have insufficient access to perform the requested operation
I have added Log Analytics API -> Data.Read permission to the registered app that I'm using.
Any idea what is causing this?
Data.Read provides permissions to use the API and grant your app access to your Log Analytics Workspace. However, for accessing data within log analytics workspace, you need to provide permissions as per the data you need access to.
References:
https://learn.microsoft.com/en-us/azure/azure-monitor/logs/api/access-api
https://learn.microsoft.com/en-us/azure/azure-monitor/logs/manage-access?tabs=portal

How to get the data instead of <azure.mgmt.compute.v2017_09_01.models.resource_sku_restrictions_py3.ResourceSkuRestrictions object at 0x071D8A10>?

I'm trying to fetch all the virtual machines details using from azure.mgmt.compute module ComputeManagementClient. As such I'm getting a json result of the data but at some places I'm getting this value . How do I get data from this object? Or please could you please explain what this means?
I haven't tried much because I'm not sure how to proceed forward with this kind of data
from azure.mgmt.compute import ComputeManagementClient
from azure.common.credentials import ServicePrincipalCredentials
def trial(cred, subscription_id):
GROUP_NAME = 'please provide the resource group name of your subscription'
compute_client = ComputeManagementClient(cred, subscription_id)
temp = {}
for rsku in compute_client.resource_skus.list():
temp[rsku.name] = {
"tier": rsku.tier,
"size": rsku.size,
"family": rsku.family,
"kind": rsku.kind,
"capacity": rsku.capacity,
"locations": rsku.locations[0],
"costs": rsku.costs,
"restrictions": rsku.restrictions
}
print(temp, "\n")
def authenticate():
subscription_id = '0000000000000000000000000'
try:
credentials = ServicePrincipalCredentials(
client_id = '00000000000000000000',
secret = '0000000000000000000000',
tenant = '00000000000000000000000'
)
return credentials, subscription_id
except :
return ("We are stuck")
if __name__ == "__main__":
cred, subscription_id = authenticate()
trial(cred, subscription_id)
'restrictions': [<azure.mgmt.compute.v2017_09_01.models.resource_sku_restrictions_py3.ResourceSkuRestrictions object at 0x071D8A10>]}
Hi there so figured out where I went wrong.
As such the output that was coming was a location of object.
So, I user
print(dir(rsku))
which gave out all the functions available for the object. The most relevant was value.
so I used
print(rsku.restriction.value)
Hope this helps

How to get output from paging container into a variable | Getting single virtual network from resource group

Thanks in advance, I have variable at the top of my code, LOCATION, VNET_NAME, SUBNET, SUBNETRANGE. I want to fill this information from the output of function List_VNET. Using this function I'm getting virtual network from resource group on azure (I've only single virtual network per resource group). And then wanted to populate it into the variable but it is giving output as paging container. I mostly work on powershell hence i know about arrays and we can get an instance using array[0].
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.compute.models import DiskCreateOption
from azure.mgmt.network.v2017_03_01.models import NetworkSecurityGroup
from azure.mgmt.network.v2017_03_01.models import SecurityRule
import azure.mgmt.network.models
SUBSCRIPTION_ID = 'xxx'
GROUP_NAME = 'AQRG'
LOCATION = ''
VM_NAME = 'myVM'
VNET_NAME = ''
SUBNET_NAME = ''
SUBNETRANGE = ''
def List_VNET(network_client):
result_create = network_client.virtual_networks.list(
GROUP_NAME,
)
SUBNET_NAME = result_create
return SUBNET_NAME
def get_credentials():
credentials = ServicePrincipalCredentials(
client_id = 'xxxx',
secret = 'xxxx',
tenant = 'xxxx'
)
return credentials
if __name__ == "__main__":
credentials = get_credentials()
resource_group_client = ResourceManagementClient(
credentials,
SUBSCRIPTION_ID
)
network_client = NetworkManagementClient(
credentials,
SUBSCRIPTION_ID
)
creation_result = List_VNET(network_client)
print("------------------------------------------------------")
print(creation_result)
input('Press enter to continue...')
Getting output as below
<azure.mgmt.network.v2018_12_01.models.virtual_network_paged.VirtualNetworkPaged object at 0x0000023776C13908>
Update: Define the VNET_NAME as global in the function List_VNET:
SUBSCRIPTION_ID = 'xxx'
GROUP_NAME = 'AQRG'
LOCATION = ''
VM_NAME = 'myVM'
VNET_NAME = ''
SUBNET_NAME = ''
SUBNETRANGE = ''
def List_VNET(network_client):
result_create = network_client.virtual_networks.list(
GROUP_NAME
)
global VNET_NAME
for re in result_create:
VNET_NAME=re.name
return VNET_NAME
After the code: creation_result = List_VNET(network_client)
add the following code:
for re in creation_result:
print(re.name)
Then you can get all the virtual networks' name.

Getting all the properties of a vnet using python | List function only gives name

Thanks in advance, I wanted to get the region property of a vnet but using list function it only gives name property. Do we have to use another function to get the full details? currently i cannot do re.region. it only works with re.name
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource import ResourceManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
from azure.mgmt.compute.models import DiskCreateOption
from azure.mgmt.network.v2017_03_01.models import NetworkSecurityGroup
from azure.mgmt.network.v2017_03_01.models import SecurityRule
import azure.mgmt.network.models
SUBSCRIPTION_ID = 'xxxx'
GROUP_NAME = 'AQRG'
LOCATION = ''
VM_NAME = 'myVM'
VNET_NAME = ''
SUBNET = ''
def List_VNET(network_client):
result_create = network_client.virtual_networks.list(
GROUP_NAME,
)
global VNET_NAME
for re in result_create:
VNET_NAME = re.name
Region = re.region // This is not valid
return VNET_NAME
def get_credentials():
credentials = ServicePrincipalCredentials(
client_id = 'xxx',
secret = 'xxx',
tenant = 'xxxx'
)
return credentials
if __name__ == "__main__":
credentials = get_credentials()
resource_group_client = ResourceManagementClient(
credentials,
SUBSCRIPTION_ID
)
network_client = NetworkManagementClient(
credentials,
SUBSCRIPTION_ID
)
compute_client = ComputeManagementClient(
credentials,
SUBSCRIPTION_ID
)
creation_result_listvnet = List_VNET(network_client)
print("------------------------------------------------------")
print(creation_result_listvnet)
input('Press enter to continue...')
it should be re.location instead of re.region.
and I just found that you can fetch all the properties of virtual network with print(re). Then you can use any properties in the output.
FYI: The doc of VirtualNetwork class, which lists the properties.

Pandas: noauth_local_webserver

I haven't used io within pandas to access google analytic's API for a few weeks but it had been working fine to my knowledge historically without hiccups. I ran it again today and it looks as though the tools.run syntax is deprecated, so I made a pull and replaced tools.py with this update and I've changed to auth.py within pandas to be:
def authenticate(flow, storage=None):
"""
Try to retrieve a valid set of credentials from the token store if possible
Otherwise use the given authentication flow to obtain new credentials
and return an authenticated http object
Parameters
----------
flow : authentication workflow
storage: token storage, default None
"""
http = httplib2.Http()
# Prepare credentials, and authorize HTTP object with them.
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = tools.run_flow(flow, storage, FLAGS)
http = credentials.authorize(http)
return http
I have a feeling my usage of FLAGS there is incorrect.
Any help? Thanks!
Here's my code and the error:
df = ga.read_ga(
account_id = id,
profile_id = profile,
property_id = property,
metrics = ['transactionRevenue', 'transactions'],
dimensions = ['transactionId', 'city', 'region', 'date', 'hour', 'minute', 'cityId'],
start_date = "2015-07-11",
end_date = "2015-07-16",
index_col = 0,
parse_dates = {'new_date': [3,4,5]})
The error thrown up:
C:\Users\mburke\AppData\Local\Continuum\Anaconda64\lib\site-packages\pandas\io\auth.py in authenticate(flow, storage)
106 credentials = storage.get()
107 if credentials is None or credentials.invalid:
--> 108 credentials = tools.run_flow(flow, storage, FLAGS)
109
110 http = credentials.authorize(http)
C:\Users\mburke\AppData\Local\Continuum\Anaconda64\lib\site-packages\oauth2client\util.pyc in positional_wrapper(*args, **kwargs)
140 else: # IGNORE
141 pass
--> 142 return wrapped(*args, **kwargs)
143 return positional_wrapper
144
C:\Users\mburke\AppData\Local\Continuum\Anaconda64\lib\site-packages\oauth2client\tools.pyc in run_flow(flow, storage, flags, http)
148 logging.getLogger().setLevel(getattr(logging, flags.logging_level))
--> 149 if not flags.noauth_local_webserver:
150 success = False
151 port_number = 0
C:\Users\mburke\AppData\Local\Continuum\Anaconda64\lib\site-packages\python_gflags-2.0-py2.7.egg\gflags.pyc in __getattr__(self, name)
1057 fl = self.FlagDict()
1058 if name not in fl:
-> 1059 raise AttributeError(name)
1060 return fl[name].value
1061
AttributeError: noauth_local_webserver
I did a little digging and you are correct in your assumption that the usage of FLAGS is incorrect. The docstring for tools.run_flow() states:
flags: ``argparse.Namespace``, The command-line flags. This is the
object returned from calling ``parse_args()`` on
``argparse.ArgumentParser`` as described above.
The quick-n-dirty fix would be something like this:
credentials = tools.run_flow(flow, storage, tools.argparser.parse_args([]))
I believe a more robust solution would be for the maintainers of pandas.io to update it to the new workflow if tools.run is really deprecated.

Categories