import os import base64 import json import logging from google.cloud.bigtable import Client from slack_client import SlackClient from config import Config MIN_NODES = 1 def scale(data: dict) -> int: slack_client = SlackClient(slack_token=Config.slack_token) meta_info = Config.get_config_str() + '\n' + str(data) logging.info(meta_info) try: if Config.cluster_baseline < 1: raise Exception('Invalid cluster baseline') client = Client(project=Config.project_id, admin=True) instance = client.instance(Config.instance_id) cluster = instance.cluster(Config.cluster_id) cluster.reload() logging.info(cluster.__dict__) if 'scale' in data: serve_nodes = Config.cluster_baseline + int(data['scale']) if serve_nodes < MIN_NODES: raise Exception( 'Unable to change size of cluster to less than MIN_NODES') if serve_nodes <= Config.cluster_max_size: cluster.serve_nodes = serve_nodes cluster.update() else: raise Exception('Failed to scaled - exceeded max nodes amount') elif 'to_baseline' in data: if cluster.serve_nodes != Config.cluster_baseline: cluster.serve_nodes = Config.cluster_baseline cluster.update() else: raise Exception('Unknown operation') operation_status = "Operation has been performed successfully" logging.info(operation_status) slack_client.post_success_message(channel=Config.slack_channel_id, blocks=[meta_info, operation_status]) return 0 except Exception as e: slack_client.post_error_message( channel=Config.slack_channel_id, blocks=[meta_info, f"Exception msg:\n{str(e)}"]) logging.error(str(e)) raise RuntimeError from e def main(event, context): """Background Cloud Function to be triggered by Pub/Sub. Args: event (dict): The dictionary with data specific to this type of event. The `data` field contains the PubsubMessage message. The `attributes` field will contain custom attributes if there are any. context (google.cloud.functions.Context): The Cloud Functions event metadata. The `event_id` field contains the Pub/Sub message ID. The `timestamp` field contains the publish time. """ print("""This Function was triggered by messageId {} published at {} """.format(context.event_id, context.timestamp)) logging.basicConfig(encoding='utf-8', level=logging.INFO) if 'data' in event: data = json.loads(base64.b64decode(event['data']).decode('utf-8')) return scale(data) else: raise Exception('data is missing')