How do I get instance id/name from public ip address of VM in azure via python sdk - azure

def get_instance_id_from_pip(self, pip):
subscription_id="69ff3a41-a66a-4d31-8c7d-9a1ef44595c3"
compute_client = ComputeManagementClient(self.credentials, subscription_id)
network_client = NetworkManagementClient(self.credentials, subscription_id)
print("Get all public IP")
for public_ip in network_client.public_ip_addresses.list_all():
if public_ip.ip_address == pip:
print(public_ip)
# Get id
pip_id= public_ip.id.split('/')
print("pip id : {}".format(pip_id))
rg_from_pip = pip_id[4].lower()
print("RG : {}".format(rg_from_pip))
pip_name = pip_id[-1]
print("pip name : {}".format(pip_name))
for vm in compute_client.virtual_machines.list_all():
vm_id = vm.id.split('/')
#print("vm ref id: {}".format(vm_id))
rg_from_vm = vm_id[4].lower()
if rg_from_pip == rg_from_vm:
## this is the VM in the same rg as pip
for ni_reference in vm.network_profile.network_interfaces:
ni_reference = ni_reference.id.split('/')
ni_name = ni_reference[8]
print("ni reference: {}".format(ni_reference))
net_interface = network_client.network_interfaces.get(rg_from_pip, ni_name)
print("net interface ref {}".format(net_interface))
public_ip_reference = net_interface.ip_configurations[0].public_ip_address
if public_ip_reference:
public_ip_reference = public_ip_reference.id.split('/')
ip_group = public_ip_reference[4]
ip_name = public_ip_reference[8]
print("IP group {}, IP name {}".format(ip_group, ip_name))
if ip_name == pip_name:
print("Thank god. Finallly !!!!")
print("VM ID :-> {}".format(vm.id))
return vm.id
I have above code to get the VM instance ID from Public ip but its not working. What is real surprising is that for all instances, I am getting x.public_ip_address.ip_address as None value.
I had multiple readthedocs references for python SDK of Azure. but, some how all links not working. Good job Azure :)
Some of them:
https://azure-sdk-for-python.readthedocs.io/en/v1.0.3/resourcemanagementcomputenetwork.html
https://azure-storage.readthedocs.io/en/latest/ref/azure.storage.file.fileservice.html
Second edit:
I got the answer to this and above code will return vm id given the public ip address. Though, you can see it is not absolutely optimized answer. Hence, better answers are welcome. Thanks!

Docs have moved here:
https://learn.microsoft.com/python/azure/
We made some redirection, but unfortunately it's not possible to go global redirection on RTD, so some pages are 404 :/
About your trouble, I would try to use the publicip operation group directly:
https://learn.microsoft.com/en-us/python/api/azure.mgmt.network.v2017_11_01.operations.publicipaddressesoperations?view=azure-python
You get this one in the Network client, as client.public_ip_addresses

Related

How to get list of running VMs from AzureML

I am a beginner with Python and with AzureML.
Currently, my task is to list all the running VMs (or Compute Instances) with status and (if running) for how long they ran.
I managed to connect to AzureML and list Subscriptions, Resource Groups and Workspaces, but I'm stuck on how to list running VMs now.
Here's the code that I have currently:
# get subscriptions list using credentials
subscription_client = SubscriptionClient(credentials)
sub_list = subscription_client.subscriptions.list()
print("Subscription ID".ljust(column_width) + "Display name")
print(separator)
for group in list(sub_list):
print(f'{group.subscription_id:<{column_width}}{group.display_name}')
subscription_id = group.subscription_id
resource_client = ResourceManagementClient(credentials, subscription_id)
group_list = resource_client.resource_groups.list()
print(" Resource Groups:")
for group in list(group_list):
print(f" {group.name}{group.location}")
print(" Workspaces:")
my_ml_client = Workspace.list(subscription_id, credentials, group.name)
for ws in list(my_ml_client):
try:
print(f" {ws}")
if ws:
compute = ComputeTarget(workspace=ws, name=group.name)
print('Found existing compute: ' + group.name)
except:()
Please note that this is more or less a learning exercise and it's not the final shape of the code, I will refactor once I get it to work.
Edit: I found an easy way to do this:
workspace = Workspace(
subscription_id=subscription_id,
resource_group=group.name,
workspace_name=ws,
)
print(workspace.compute_targets)
Edit2: If anyone stumbles on this question and is just beginning to understand Python+Azure just like I do, all this information is from official documentation (which is just hard to follow as a beginner).
The result from 'workspace.compute_targets' will contain both Compute Instances and AML Instances.
If you need to retrieve only the VMs (like I do) you need to take an extra step to filter the result like this:
if type(compute_list[vm]) == ComputeInstance:

Use for loop with dictionary

I'm using Napalm to change the hostname of many network devices. Since the config will be different for each device, I need the script to assign the proper config to each device based on it's IP address. This seems like a dictionary would work best.
devicelist = {'10.255.32.1': 'device1.cfg', '10.255.32.5': 'device2.cfg'}
I need help calling the key value in the script below for each IP address. I have highlighted the line of code where this is required.
from napalm import get_network_driver
devicelist = ['10.255.32.1',
'10.255.32.5'
]
for ip_address in devicelist:
print ("Connecting to " + str(ip_address))
driver = get_network_driver('ios')
iosv = driver(ip_address, 'admin', 'password')
iosv.open()
**iosv.load_merge_candidate(filename='device1.cfg')**
diffs = iosv.compare_config()
if len(diffs) > 0:
print(diffs)
iosv.commit_config()
else:
print('No changes required.')
iosv.discard_config()
iosv.close()
You are asking for a simple access by key on your dictionary, combined with a for loop over the dictionary which is automatically a for loop over the keys. Minimal example:
devicelist = {'10.255.32.1': 'device1.cfg', '10.255.32.5': 'device2.cfg'}
for ipAdress in devicelist:
print("This IP : {} maps to this name: {}".format(ipAdress, devicelist[ipAdress]))
Output:
This IP : 10.255.32.1 maps to this name: device1.cfg
This IP : 10.255.32.5 maps to this name: device2.cfg

Compute pancake pair address via python3

This question is quite related to Compute uniswap pair address via python
I am trying to do the same but for panckage swap v2.
I am using the CAKE/WBNB pair as an example:
CONTRACTS = {
"CAKE": "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82",
}
PANCAKE_SWAP_FACTORY = "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73"
PANCAKE_SWAP_ROUTER = "0x10ED43C718714eb63d5aA57B78B54704E256024E"
WBNB_ADDRESS = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"
hexadem_ ='0x00fb7f630766e6a796048ea87d01acd3068e8ff67d078148a3fa3f4a84f69bd5'
factory = PANCAKE_SWAP_FACTORY
abiEncoded_1 = encode_abi_packed(['address', 'address'], (CONTRACTS['CAKE'], WBNB_ADDRESS))
salt_ = pancakeswap.w3.solidityKeccak(['bytes'], ['0x' +abiEncoded_1.hex()])
abiEncoded_2 = encode_abi_packed([ 'address', 'bytes32'], ( factory, salt_))
resPair = pancakeswap.w3.solidityKeccak(['bytes','bytes'], ['0xff' + abiEncoded_2.hex(), hexadem_])[12:]
# resPair is the address for the pancakeswap CAKE/WBNB pair
print(resPair.hex())
print('0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6')
print(resPair.hex() == '0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6')
print()
My first problem is the code is not working, it is not producint the correct contract address, in fact it prints:
0x0ed7e52944161450477ee417de9cd3a859b14fd0
0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6
False
I think the problem is the value of the constant hexadem_, which can be found in:
hexadem_ = '0xd0d4c4cd0848c93cb4fd1f498d7013ee6bfb25783ea21593d5834f5d250ece66' # from https://github.com/pancakeswap/pancake-swap-periphery/blob/master/contracts/libraries/PancakeLibrary.sol
hexadem_ ='0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' # from uniswap (most likely wrong...)
hexadem_ ='0x00fb7f630766e6a796048ea87d01acd3068e8ff67d078148a3fa3f4a84f69bd5' # from https://bscscan.com/address/0x10ED43C718714eb63d5aA57B78B54704E256024E#code line 298
The address you obtained is correct. The address that you are attempting to match to is for pancake V1.
You can see this by clicking on "contract creator" for the 2 addresses, and you will see the pancake factory versions for 0x0ed7e52944161450477ee417de9cd3a859b14fd0 and 0xA527a61703D82139F8a06Bc30097cC9CAA2df5A6.

Terraform .11 to .12 conversion of deeply nested data

So, in my old .11 code, I have a file where i my output modules locals section, I'm building:
this_assigned_nat_ip = google_compute_instance.this_public.*.network_interface.0.access_config.0.assigned_nat_ip--
Which later gets fed to the output statement.  This module could create N instances. So what it used to do was give me the first nat ip on the first access_config block on the first network interface of all the instances we created.  (Someone locally wrote the code so we know that there's only going to be one network interface with one access config block).
How do I translate that to t12?  I'm unsure of the syntax to keep the nesting.
Update:
Here's a chunk of the raw data out of a terraform show from tf11 (slightly sanitized)
module.gcp_bob_servers_ams.google_compute_instance.this_public.0:
machine_type = n1-standard-2
min_cpu_platform =
network_interface.# = 1
network_interface.0.access_config.# = 1
network_interface.0.access_config.0.assigned_nat_ip =
network_interface.0.access_config.0.nat_ip = 1.2.3.4
network_interface.0.access_config.0.network_tier = PREMIUM
Terraform show of equivalent host in tf12:
# module.bob.module.bob_gcp_ams.module.atom_d.google_compute_instance.this[1]:
resource "google_compute_instance" "this" {
allow_stopping_for_update = true
network_interface {
name = "nic0"
network = "https://www.googleapis.com/compute/v1/projects/stuff-scratch/global/networks/scratch-public"
network_ip = "10.112.112.6"
subnetwork = "https://www.googleapis.com/compute/v1/projects/stuff-scratch/regions/europe-west4/subnetworks/scratch-europe-west4-x-public-subnet"
subnetwork_project = "stuff-scratch"
access_config {
nat_ip = "35.204.132.177"
network_tier = "PREMIUM"
}
}
scheduling {
automatic_restart = true
on_host_maintenance = "MIGRATE"
preemptible = false
}
}
If I understand correctly this_assigned_nat_ip is a list of IPs. You should be able to get the same thing in Terraform 0.12 by doing:
this_assigned_nat_ip = [for i in google_compute_instance.this_public : i.network_interface.0.access_config.0.assigned_nat_ip]
I did not test is, so I might have some small syntax error, but the for is the key to get that done.
Turns out this[*].network_interface[*].access_config[*].nat_ip[*] gave me what I needed. Given there's only every going to be one address on the interface, it comes out fine.

Creating a pool in Azure with python SDK

I'm trying to create a pool based on standard marketplace ubuntu image. I'm using Azure 4.0.0, image refernce, vm config reference and other things are written based off learn.microsoft.com
Here's my code:
import azure.batch as batch
from azure.batch import BatchServiceClient
from azure.batch.batch_auth import SharedKeyCredentials
from azure.batch import models
import sys
account = 'mybatch'
key = 'Acj1hh7vMR6DSodYgYEghjce7mHmfgfdgodYgYEghjce7mHmfgodYgYEghjce7mHmfgCj/7f3Zs1rHdfgPsdlA=='
batch_url = 'https://mybatch.westeurope.batch.azure.com'
creds = SharedKeyCredentials(account, key)
batch_client = BatchServiceClient(creds, base_url = batch_url)
pool_id = 'mypool3'
if batch_client.pool.exists( pool_id ):
print( 'pool exists' )
sys.exit()
vmc = models.VirtualMachineConfiguration(
image_reference = models.ImageReference(
offer = 'UbuntuServer',
publisher = 'Canonical',
sku = '16.04.0-LTS',
version = 'latest',
virtual_machine_image_id = None
) ,
node_agent_sku_id = 'batch.node.ubuntu 16.04'
)
pool_config = models.CloudServiceConfiguration(os_family = '5')
new_pool = models.PoolAddParameter(
id = pool_id,
vm_size = 'small',
cloud_service_configuration = pool_config,
target_dedicated_nodes = 1,
virtual_machine_configuration = vmc
)
batch_client.pool.add(new_pool)
Here are some image values I took from the azure portal ( Add pool JSON Editor ):
>
"imageReference": {
"publisher": "Canonical",
"offer": "UbuntuServer",
"sku": "16.04.0-LTS"
},
But when I ran the code I get an error:
Traceback (most recent call last):
File "a.py", line 80, in <module>
batch_client.pool.add(new_pool)
File "/root/miniconda/lib/python3.6/site-packages/azure/batch/operations/pool_operations.py", line 310, in add
raise models.BatchErrorException(self._deserialize, response)
azure.batch.models.batch_error_py3.BatchErrorException: {'additional_properties': {}, 'lang': 'en-US', 'value': 'The value provided for one of the properties in the request body is invalid.\nRequestId:d8a1f7fa-6f40-4e4e-8f41-7958egas6efa\nTime:2018-12-05T16:18:44.5453610Z'}
What image values are wrong ? Is this possible to get more information on this error with RequestId ?
UPDATE
I found a newer example here which is using this helper select_latest_verified_vm_image_with_node_agent_sku to get the image ref. Same error The value provided for one of the properties in the request body is invalid.
I did the test with your code and get the same error. Then I research and change some things in the code. And the problem caused by two things.
First:
pool_config = models.CloudServiceConfiguration(os_family = '5')
You can take a look at the description of the models.CloudServiceConfiguration:
os_family: The Azure Guest OS family to be installed on the virtual
machines in the pool. Possible values are: 2 - OS Family 2, equivalent to
Windows Server 2008 R2 SP1. 3 - OS Family 3, equivalent to Windows Server
2012. 4 - OS Family 4, equivalent to Windows Server 2012 R2. 5 - OS Family
5, equivalent to Windows Server 2016. For more information, see Azure
Guest OS Releases
Maybe this property is set for windows. You can take away this configuration.
Second:
vm_size = 'small',
You should set the vmSize with a real VM size. For example, Standard_A1. See Choose a VM size for compute nodes in an Azure Batch pool.
Hope this will help you. If you need more help please give me the message.
I think there are a lof of confusing examples on the net, or they simply match older version of SDK.
Digging deeper into the docs I found this.
cloud_service_configuration CloudServiceConfiguration The cloud
service configuration for the pool. This property and
virtualMachineConfiguration are mutually exclusive and one of the
properties must be specified. This property cannot be specified if the
Batch account was created with its poolAllocationMode property set to
'UserSubscription'.
In my case I could use only
cloud_service_configuration = pool_config or virtual_machine_configuration = vmc, but not both at the same time.
This is the working code:
new_pool = models.PoolAddParameter(
id = pool_id,
vm_size = 'BASIC_A1',
target_dedicated_nodes = 1,
virtual_machine_configuration = vmc
)

Resources