John Mark Causing

System Administrator | Hosting Support Engineer

Bacolod City, Philippines

+639393497018

John Mark Causing

System Administrator | Hosting Support Engineer

Bacolod City, Philippines

+639393497018

Get all GCP instance data like name, status, internal IP.

# Credentials from specific GCP SA
import os
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]="majestic-layout-340900-668e5ad81962.json"

# Set variable `compute` to connect to GCP compute engine
import googleapiclient.discovery
compute   = googleapiclient.discovery.build('compute', 'v1')

# Set GCP project and zone
project_s = 'majestic-layout-340900'

# Disabled - This is for specific zone only .list()
# zone_s    = 'us-central1-c'
# Set var `result` to get the data array of all GCP instances on a zpecific zone
# https://developers.google.com/resources/api-libraries/documentation/compute/v1/python/latest/compute_v1.instances.html#list
# result = compute.instances().list(project=project_s, zone=*).execute()

# To get all instances for all regions and zones
# https://developers.google.com/resources/api-libraries/documentation/compute/v1/python/latest/compute_v1.instances.html#list
result = compute.instances().aggregatedList(project=project_s).execute()


# Create class to get GCP instances
class gcp_instances:

    # Get all instances function
    def get_instances(self):

        for _, labels_scoped_list in result['items'].items():

            # Loop all values for the key 'instances' only
            if 'instances' in labels_scoped_list:
                for entry in labels_scoped_list['instances']:
                    # Print instance name, status and internal IP
                    instance_name = entry['name']
                    instance_status = entry['status']
                    instance_int_ip = entry['networkInterfaces'][0]['networkIP']
                    print(instance_name, ':', instance_int_ip, ':', instance_status)
      
# Call the function `get_instances` inside the class `gcp_instances`     
class_gcp_instances = gcp_instances()
class_gcp_instances.get_instances()

GCP Python Get instances

Update GCP Cloud DNS (delete and add from Instances)

The code below will delete all DNS A records from the GCP Cloud DNS zone (the first zone), get the VM Instances details (name and its internal IP), then add each of those to the Cloud DNS A records.

# Import GCP client library to use compute instance functions
import googleapiclient.discovery

# Setup GCP Credentials 
from google.auth import compute_engine

# Import GCP client library to use compute instance functions
import googleapiclient.discovery

class update_dns_a_records_from_instances():
    
    def __init__(self):   

        # Default values for GCP Project
        self.project= None


    def setup(self):

        # Fetch the GCP Project from the environment - This is currently not working!
        # self.project = os.environ.get('GCP_PROJECT')    

        # Set GCP project and zone
        self.project = 'majestic-layout-340900'


         # Set up the Google Cloud Compute client
        credentials = compute_engine.Credentials()
        self.computeadmin = googleapiclient.discovery.build('compute', 'v1', credentials=credentials, cache_discovery=False)   
        
        # Setup Google Clouid DNS client
        self.dns_service = googleapiclient.discovery.build('dns', 'v1', credentials=credentials)

        # Get the first Zone.
        # Use this if you have one zone only! 
        # Otherwise, enter a static zone name manually like below:
        # self.zone_name = "zone1"
        get_zone_request = self.dns_service.managedZones().list(project=self.project)
        get_zone_response = get_zone_request.execute()
        self.zone_name = get_zone_response['managedZones'][0]['name']

        # Get DNS name
        dns_name_request = self.dns_service.managedZones().get(project=self.project, managedZone=self.zone_name)
        dns_name_response = dns_name_request.execute()
        self.dns_name = dns_name_response['dnsName']

    def update_dns(self):

        # List all DNS A records then delete        
        list_dns_request = self.dns_service.resourceRecordSets().list(project=self.project, managedZone=self.zone_name)
        list_dns_response = list_dns_request.execute()
  
        # print("Gather all DNS A records for deletion..") 
        for dns_list in list_dns_response['rrsets']:
            if dns_list['type'] == "A":
                current_dns_name = dns_list['name']
                current_dns_type = dns_list['type']
                current_dns_rrdata = dns_list['rrdatas']
                current_dns_ttl = dns_list['ttl']

                # Generate deletion var list for each dns entry
                delete_dns = {
                    "deletions": [          
                        {
                        "name": current_dns_name,
                        "type": current_dns_type,
                        "ttl": current_dns_ttl,
                        "rrdata": current_dns_rrdata
                        }
                    ]
                }

                # Print for debug - ex output: instance-1.zone1.test. A ['10.128.0.35'] 300  
                # print(current_dns_name, current_dns_type, current_dns_rrdata, current_dns_ttl)

                # Delete each DNS entry from this loop
                del_dns_request = self.dns_service.changes().create(project=self.project, managedZone=self.zone_name, body=delete_dns)
                del_dns_response = del_dns_request.execute()
    
        # Request to get all instances (500 max results but this will loop via aggregatedList_next to get all instances)
        request = self.computeadmin.instances().aggregatedList(project=self.project, includeAllScopes=True)

        while request is not None:
            response = request.execute()
            # Run the loop - fetch all instances
            for _, list_of_instances in response['items'].items():
                # Check if we have instances returned
                if 'instances' in list_of_instances:
                    # Loop through the instances dict 
                    for entry in list_of_instances['instances']:
                        instance_name = entry['name']
                        instance_status = entry['status']
                        instance_int_ip = entry['networkInterfaces'][0]['networkIP']

                        # Add DNS entry A record for each instances internal IP and its instance names
                        add_dns = {
                            "additions": [          
                                {
                                "name": instance_name + "." + self.dns_name,
                                "type": "A",
                                "ttl": 300,
                                "rrdata": [
                                    instance_int_ip
                                ]
                                }
                            ]
                        }
                        request = self.dns_service.changes().create(project=self.project, managedZone=self.zone_name, body=add_dns)
                        response = request.execute()

            request = self.computeadmin.instances().aggregatedList_next(previous_request=request,
                                                                        previous_response=response)

    def run(self):
        # Set up our environment.
        self.setup()

        # RUN update_dns() fuction
        update_dns = self.update_dns()


def main(request): # pragma: no cover

    try:
        check = update_dns_a_records_from_instances()
        check.run()

    except Exception as e:
        print(e)

# Simplify running in a development environment.
if __name__ == "__main__": # pragma: no cover
    main(None)

Python + GKE – Get the pods!

requirements.txt

kubernetes
google-api-python-client
google-cloud-container
python-hosts
import base64
import google.auth.transport.requests
from google.oauth2 import service_account
from google.cloud.container_v1 import ClusterManagerClient
from kubernetes import client
from python_hosts.hosts import Hosts, HostsEntry


class gke:
    def get_clusters(self):
        print("Get clusters!")

    project_id = 'majestic-layout-340900'

    zone = "us-central1-c"
    cluster_id = "cluster-1"

    # Use a service account configured in GCP console,
    # authenticating with a JSON key
    credentials = service_account.Credentials \
        .from_service_account_file('majestic-layout-340900-668e5ad81962.json')

    # Get cluster details
    cluster_manager_client = ClusterManagerClient(credentials=credentials)
    cluster = cluster_manager_client.get_cluster(
            project_id=project_id, zone=zone,
            cluster_id=cluster_id)

    # Save cluster certificate for SSL verification
    cert = base64.b64decode(cluster.master_auth.cluster_ca_certificate)
    cert_filename = 'cluster_ca_cert'
    cert_file = open(cert_filename, 'wb')
    cert_file.write(cert)
    cert_file.close()

    # Configure hostname for SSL verification
    hosts = Hosts()
    hosts.add([HostsEntry(
            entry_type='ipv4',
            address=cluster.endpoint, names=['kubernetes'])])
    hosts.write()

    # Get a token with the scopes required by GKE
    kubeconfig_creds = credentials.with_scopes(
            ['https://www.googleapis.com/auth/cloud-platform',
             'https://www.googleapis.com/auth/userinfo.email'])
    auth_req = google.auth.transport.requests.Request()
    kubeconfig_creds.refresh(auth_req)

    configuration = client.Configuration()
    configuration.host = "https://kubernetes"
    configuration.ssl_ca_cert = cert_filename
    kubeconfig_creds.apply(configuration.api_key)
    client.Configuration.set_default(configuration)

    v1 = client.CoreV1Api()
    print("Listing pods with their IPs:")
    pods = v1.list_pod_for_all_namespaces(watch=False)
    for i in pods.items:
        print("%s\t%s\t%s" % (i.status.pod_ip, i.metadata.namespace, i.metadata.name))



run = gke()
run.get_clusters()