backend/main.py (85 lines of code) (raw):
# Copyright 2024 Google LLC
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# https://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tag Automator to easily manage tags from GCP resources."""
import os
from flask import Flask, jsonify, request, Blueprint
from list_possible_tags import getTags
from update_resources_tags import update_gcp_tags, bulk_update_gcp_tags
from list_resources_tags import formatResources, search_resources_by_type
from delete_resources_tags import del_gcp_tags
scope = os.environ.get("SCOPE")
if not scope:
raise Exception("SCOPE env variable must be provided.")
asset_type = os.environ.get(
"ASSET_TYPES",
[
"compute.googleapis.com/Instance",
"storage.googleapis.com/Bucket",
"bigquery.googleapis.com/Table",
"bigquery.googleapis.com/Dataset",
"sqladmin.googleapis.com/Instance",
"cloudresourcemanager.googleapis.com/Folder",
"cloudresourcemanager.googleapis.com/Organization",
"cloudresourcemanager.googleapis.com/Project",
"run.googleapis.com/Service",
"container.googleapis.com/Cluster",
"compute.googleapis.com/Network",
"compute.googleapis.com/Subnetwork",
],
)
api = Blueprint("api", __name__, url_prefix="/api")
# Endpoint 2: GET /resources
@api.route("/resources", methods=["GET"])
def get_resources():
"""Retrieve resources based on filters."""
instance_resources = search_resources_by_type(scope, asset_type)
filtered_resources = formatResources(instance_resources)
return jsonify(filtered_resources)
# Endpoint 3: GET /tags
@api.route("/tags", methods=["GET"])
def get_tags():
"""List all available tags."""
return jsonify(getTags(scope))
# Endpoint 4: POST /resource
@api.route("/resource", methods=["POST"])
def create_resource():
"""Create a new resource."""
data = request.get_json()
if not all(key in data for key in ("id", "tags")):
return jsonify({"error": "Missing required fields (id, tags)"}), 400
response = update_gcp_tags(data.get("id"), data.get("tags"), data.get("location"))
if response:
return (jsonify({"message": "Tag applied created successfully"}), 200)
return (jsonify({"message": "Fail to apply tags on resource"}), 500)
# Endpoint 4: DEL /resource
@api.route("/resources/tags", methods=["DELETE"])
def delete_tags_from_resources():
"""Delete tags from multiple resources."""
data = request.get_json()
response = del_gcp_tags(data.get("resources"), data.get("tags"))
if not response:
return (
jsonify({"message": "Tags delete successfully", "errors": response}),
200,
)
else:
return (
jsonify(
{
"message": "Fail to apply tags on resources",
"errors": response,
}
),
200,
)
# Endpoint : POST /resource/tags
@api.route("/resources/tags", methods=["POST"])
def bulk_tags_from_resources():
"""Add tags to multiple resources."""
data = request.get_json()
if not all(key in data for key in ("resources", "tags")):
return jsonify({"error": "Missing required fields (id, tags)"}), 400
response = bulk_update_gcp_tags(data.get("resources"), data.get("tags"), scope)
if not response:
return (
jsonify(
{"message": "Tag applied created successfully", "errors": response}
),
200,
)
else:
return (
jsonify({"message": "Fail to apply tags on resource", "errors": response}),
200,
)
app = Flask(__name__)
app.register_blueprint(api)
if __name__ == "__main__":
app.run(debug=True)