Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# This is a comment. Each line is a file pattern followed by one or more owners.

# These owners will be the default owners for everything in the repo. @oneanupam will be requested for review when someone opens a pull request.

- @oneanupam
5 changes: 5 additions & 0 deletions .github/conventional-commit-lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Config for GitHub App that ensures that commit messages and pull requests are based on conventionalcommits.org
# https://github.com/googleapis/repo-automation-bots/tree/main/packages/conventional-commit-lint

enabled: true
always_check_pr_title: true
15 changes: 15 additions & 0 deletions .github/pull-request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Description
Please include a short summary of the update made along with the context.

## Checklist
- [ ] Self-review of the code is performed.
- [ ] Code has been fully tested and completely functional.

## Type of Change
- [ ] break: Resolved a breaking change. This will increment the major version.
- [ ] feat: A new feature or enhancement added to the codebase. This will increment the minor version.
- [ ] fix: A bug fix or correction to resolve an issue. This will increment the patch version.
- [ ] chore: Other changes not directly affecting the code (e.g., documentation update). No version increment.

## Reference
https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository
40 changes: 40 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Pull Request Checks

on:
pull_request:
branches:
- master
types:
- opened
- synchronize
- reopened

jobs:
pull-request-check:
runs-on: ubuntu-latest
steps:
# Checkout the repository code
- name: Code checkout
id: code_checkout
uses: actions/checkout@v4

# Check PR title prefix to ensure it follows the convention
- name: Check PR title prefix
run: |
echo "PR Title: '${{ github.event.pull_request.title }}'"

if [[ ! "${{ github.event.pull_request.title }}" =~ ^(ci|feat|fix|chore|docs|refactor): ]]; then
echo "❌ PR title must start with one of: ci:, feat:, fix:, chore:, docs:, refactor:"
exit 1
else
echo "✅ PR title is valid."
fi

# Scan the repo for any sensitive information like secrets etc
- name: Secret Scanning
uses: trufflesecurity/trufflehog@main
with:
path: ./ # Code repository path
base: "" # Start scanning from here
head: ${{ github.head_ref || github.ref_name }} # Scan commits until here
extra_args: --only-verified
27 changes: 27 additions & 0 deletions python/gcp-compute/get_compute_engine_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import argparse
from google.cloud import compute_v1

def get_compute_instances(project_id):
""" Prints all the google compute instances of a project """

instance_client = compute_v1.InstancesClient()

request = compute_v1.AggregatedListInstancesRequest()
request.project = project_id
request.max_results = 50

agg_list = instance_client.aggregated_list(request=request)

for zone, response in agg_list:
if response.instances:
for instance in response.instances:
print(f"Instance Name: {instance.name}, Instance ID: {instance.id}, Instance Zone: {zone}")

def main():
parser = argparse.ArgumentParser()
parser.add_argument("project_id", help="Your Google Cloud project ID.")
args = parser.parse_args()
get_compute_instances(args.project_id)

if __name__ == "__main__":
main()
34 changes: 34 additions & 0 deletions python/gcp-compute/get_gce_metadata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Import the required python libraries
import requests

def get_instance_metadata(root_url, request_header, metadata_list):
"""
This function returns the google compute instance metadata.

Note: You can query the contents of the metadata server by making a request to the root URLs from within
a virtual machine instance.
Use the http://metadata.google.internal/computeMetadata/v1/ root URL to make requests to metadata server.

Ref: https://cloud.google.com/compute/docs/metadata/overview#querying
"""

for metadata in metadata_list:
try:
response = requests.get(root_url + metadata, headers=request_header)
print(response.text)
except Exception as error:
print(f'Error occurred: {error}')

def main():
"""
This main function calls the `get_instance_metadata` function to get google compute instance metadata.
"""

root_url = "http://metadata.google.internal/computeMetadata/v1/"
request_header = {"Metadata-Flavor": "Google"}
metadata_list = ["instance/hostname", "instance/network-interfaces/0/ip"]

get_instance_metadata(root_url, request_header, metadata_list)

if __name__ == "__main__":
main()
34 changes: 34 additions & 0 deletions python/gcp-compute/get_gce_properties.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Import the required python libraries
from google.cloud import compute_v1

def get_instance_properties(project_id, zone, instance_name):
"""
This function returns the google compute instance properties.
"""

instances_client = compute_v1.InstancesClient()

try:
instance_properties = instances_client.get(project=project_id, zone=zone, instance=instance_name)
if instance_properties:
print(f"Instance Name: {instance_properties.name}")
print(f"Instance ID: {instance_properties.id}")
print(f"Instance Status: {instance_properties.status}")
print(f"Instance Machine Type: {instance_properties.machine_type}")
print(f"Instance Creation Time: {instance_properties.creation_timestamp}")
except Exception as error:
print(f"Error retrieving instance properties: {error}")

def main():
"""
This main function calls the `get_instance_properties` function to get google compute instance properties.
"""

project_id = "UPDATE_ME"
zone = "UPDATE_ME"
instance_name = "UPDATE_ME"

get_instance_properties(project_id, zone, instance_name)

if __name__ == "__main__":
main()
25 changes: 25 additions & 0 deletions python/gcp-compute/get_instances_with_eips.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import argparse
from google.cloud import compute_v1

def get_gce_with_eips(project_id):
""" Prints all the instances with external IP in any of its network interface """

instance_client = compute_v1.InstancesClient()
agg_list = instance_client.aggregated_list(project=project_id)

for zone, response in agg_list:
if response.instances:
for instance in response.instances:
for interface in instance.network_interfaces:
if interface.access_configs:
print(f"Instance Name: {instance.name}, Instance ID: {instance.id}, Instance Zone: {zone}")
break

def main():
parser = argparse.ArgumentParser()
parser.add_argument("project_id", help="Your Google Cloud project ID.")
args = parser.parse_args()
get_gce_with_eips(args.project_id)

if __name__ == "__main__":
main()
20 changes: 20 additions & 0 deletions python/gcp-compute/get_unused_compute_disks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from google.cloud import compute_v1

def get_unused_compute_disks(project_id):
"""
Prints the unused regional/zonal compute disks of a project.
"""

addresses_client = compute_v1.DisksClient()
for zone, response in addresses_client.aggregated_list(project=project_id):
if response.disks:
for disk in response.disks:
if len(disk.users) == 0:
print(f"Disk Name: {disk.name}, Disk Size: {disk.size_gb}, Disk Location: {zone}")

def main(project_id):
get_unused_compute_disks(project_id)

if __name__ == "__main__":
project_id = "UPDATE_ME"
main(project_id)
26 changes: 26 additions & 0 deletions python/gcp-compute/get_unused_external_ips_1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# from google.oauth2 import service_account
from google.cloud import compute_v1

# Use this, if authentication to be done via service account
# credentials = service_account.Credentials.from_service_account_file('sa-key.json')
# addresses_client = compute_v1.AddressesClient(credentials=credentials)

def get_reserved_ips(project_ids):
addresses_client = compute_v1.AddressesClient()

for project_id in project_ids:
request = compute_v1.AggregatedListAddressesRequest()
request.project = project_id

for region, response in addresses_client.aggregated_list(request=request):
if response.addresses:
for address in response.addresses:
if(address.address_type == "EXTERNAL" and address.status == "RESERVED"):
print("External IP:", address.name, "Region:", region)

def main():
project_ids = ["UPDATE_ME"]
get_reserved_ips(project_ids)

if __name__ == "__main__":
main()
74 changes: 74 additions & 0 deletions python/gcp-compute/get_unused_external_ips_2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""Get Unsed External IP Addresses

This script prints all the unused external IP addresses of all the projects
present under a parent(folder/organization) along with details like (region,
external IP name, project ID)

This script requires that Cloud Client Libraries of gcp services
`google-cloud-compute` and `google-cloud-resource-manager` be installed
within the Python environment you are running this script in.

This file can also be imported as a module and contains the following
functions:

* get_gcp_projects - returns the list of projects under a parent
* get_reserved_ips - prints the unused eips along with details
* main - the main function of the script
"""

from google.cloud import compute_v1, resourcemanager_v3

def get_gcp_projects(parent):
"""Returns the list of projects under a parent (folder/org)

Args:
parent (str): the id of the parent whose projects to be returned

Returns:
list: a list of strings representing the projects under a parent
"""

project_ids = []

# Create a client
client = resourcemanager_v3.ProjectsClient()
# Initialize request argument(s)
request = resourcemanager_v3.ListProjectsRequest(parent=parent)
# Make the request
page_result = client.list_projects(request=request)
# Handle the response
for response in page_result:
project_ids.append(response.project_id)
return project_ids

def get_reserved_ips(project_ids):
"""Prints the list of unused external IPs of a GCP Project

Args:
project_ids (list): the list of the projects whose unused external
IP addresses to be printed

Returns:
it returns None as the function doesn't have any return statement
but it prints the list of unused external IPs of a GCP Project
"""

addresses_client = compute_v1.AddressesClient()

for project_id in project_ids:
request = compute_v1.AggregatedListAddressesRequest()
request.project = project_id

for region, response in addresses_client.aggregated_list(request=request):
if response.addresses:
for address in response.addresses:
if(address.address_type == "EXTERNAL" and address.status == "RESERVED"):
print(f"Project ID: {project_id} External IP: {address.name} Region: {region}")

def main():
parent="organizations/UPDATE_ME" # For folder, use "folders/UPDATE_ME"
project_ids = get_gcp_projects(parent)
get_reserved_ips(project_ids)

if __name__ == "__main__":
main()
3 changes: 3 additions & 0 deletions python/gcp-compute/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
requests
google-cloud-compute==1.11.0
google-cloud-resource-manager==1.10.1
44 changes: 44 additions & 0 deletions python/gcp-compute/stop_compute_instance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from google.cloud import compute_v1

def get_compute_instances(project_id):
"""
Gets the details list of targetted Google Compute Engine instances.
"""

instance_list = [] # Initialize an empty list to store instance details

instance_client = compute_v1.InstancesClient()
agg_list = instance_client.aggregated_list(project=project_id)

for zone, response in agg_list:
if response.instances:
for instance in response.instances:
if ("purpose", "test") in instance.labels.items():
temp_instance_dict = {} # Initialize a dictionary to temporary hold and dump values in a dict
temp_instance_dict.update({"instance_name" : instance.name})
temp_instance_dict.update({"instance_zone" : zone.split("/")[1]})
temp_instance_dict.update({"instance_project" : project_id})
instance_list.append(temp_instance_dict)
return instance_list

def stop_compute_instances(instance_list):
"""
Stops running Google Compute Engine instances.
"""
instance_client = compute_v1.InstancesClient()

for instance in instance_list:
operation = instance_client.stop(
project=instance["instance_project"], zone=instance["instance_zone"], instance=instance["instance_name"]
)
result = operation.result(timeout=300)

print("Stop operation completed for targetted compute instances.")

def main(project_id):
instance_list = get_compute_instances(project_id)
stop_compute_instances(instance_list)

if __name__ == "__main__":
project_id = "UPDATE_ME"
main(project_id)
Loading