Writing Python scripts to run from the OCI Console Cloud Shell
This article was partially inspired by a question on Reddit asking how to list all Oracle Cloud Infrastructure instances and their IP addresses.
One way to approach this is using a simple Python script with the OCI Python-SDK, but I also wanted to find a way to run this directly in Cloud Shell from the OCI Console, to minimize any additional setup needed to run the script.
When you launch the Cloud Shell from OCI Console you are provided a terminal environment with a number of common tools and utilities pre-installed including the OCI CLI and the Python SDK.
When writing Python scripts to run in the cloud shell we can take advantage of shells existing authentication, avoiding the step to manually configure separate API keys typically needed when executing scripts from an external environment. To do this we load the existing instance principle delegation token within the shell to create an API request signer.
#!/usr/bin/env pythonimport oci# get the cloud shell delegated authentication token
delegation_token = open('/etc/oci/delegation_token', 'r').read()# create the api request signer
signer = oci.auth.signers.InstancePrincipalsDelegationTokenSigner(
delegation_token=delegation_token
)
The signer
is then used to create an authenticated client, passing an empty dictionary in the place of the regular config
settings, e.g. to create the search client:
# create an authenticated api client
search_client = oci.resource_search.ResourceSearchClient(
config={},
signer=signer
)
With this search client, we can now search for all instances in the current region.
Hint: if you need to target a different region other than the default home region you can set config={"region":"ca-toronto-1"}
# search for all instances
resp = search_client.search_resources(
oci.resource_search.models.StructuredSearchDetails(
type="Structured",
query="query instance resources"
)
)
To query additional details about the instances and to get the IP addresses, we need two additional API clients for the compute and network resources.
compute_client = oci.core.ComputeClient({},signer=signer)
network_client = oci.core.VirtualNetworkClient({},signer=signer)
Finally, to get the IP addresses for each instance we query all the vnic attachments for the instance, then for each vnic we can output both its public and private IP address.
for instance in resp.data.items:
# for each instance get its vnic attachments
resp = compute_client.list_vnic_attachments(
compartment_id=instance.compartment_id,
instance_id=instance.identifier
) for vnic_attachment in resp.data:
# for each vnic get the vnic details
vnic = network_client.get_vnic(vnic_attachment.vnic_id).data
# print tab separated list of instances and ips
print("\t".join([
instance.display_name,
vnic.display_name,
vnic.private_ip,
vnic.public_ip
]))
Here’s the complete script you can copy into a list-instance-ips.py
file in your cloud shell terminal window.
#!/usr/bin/env pythonimport ocidelegation_token = open('/etc/oci/delegation_token', 'r').read()
signer = oci.auth.signers.InstancePrincipalsDelegationTokenSigner(
delegation_token=delegation_token
)search_client = oci.resource_search.ResourceSearchClient({},signer=signer)
compute_client = oci.core.ComputeClient({},signer=signer)
network_client = oci.core.VirtualNetworkClient({},signer=signer)resp = search_client.search_resources(
oci.resource_search.models.StructuredSearchDetails(
type="Structured",
query="query instance resources"
)
)for instance in resp.data.items:
resp = compute_client.list_vnic_attachments(
compartment_id=instance.compartment_id,
instance_id=instance.identifier
) for vnic_attachment in resp.data:
vnic = network_client.get_vnic(vnic_attachment.vnic_id).data
print("\t".join([
instance.display_name,
vnic.display_name,
vnic.private_ip,
vnic.public_ip
]))
And here’s an example from running the script. I only have one instance currently running in my free tier account, so the output is not particularly interesting, but you get the idea.
More Information
Note — Free Tier users may experience changes to services included with their account.