Esempio n. 1
0
def delete_dashboard(dashboard_name):
    '''
      Deletes a Cloudwatch Dashboard
    '''
    print("deleting", dashboard_name)
    response = CLIENT.delete_dashboards(DashboardNames=[dashboard_name])
    show('delete_dashboards returns')
    show(response)
Esempio n. 2
0
def get_dashboard_dynamodb(prefix, environment):
    '''
      Reads the tags from the s3 buckets and returns a list of dictionaries.
      Each dict has a key containing the dashboard name, and their values
      have properties that contains a list of all the dynamodb table that
      are tagged with that dashboard name.
    '''
    list_tables_response = CLIENT.list_tables()

    #print('list_tables_response')
    if DEBUG:
        show(list_tables_response)
    ret = []
    tables_by_dashboard = {}
    offset = len(f'{prefix}-{environment}') + 1

    for table_name in list_tables_response['TableNames']:
        if f'{prefix}-{environment}' in table_name:
            if DEBUG:
                print("\n\n\ntable_name", table_name)
            describe_table_response = CLIENT.describe_table(TableName=table_name)

            table_arn = describe_table_response['Table']['TableArn']
            tags = CLIENT.list_tags_of_resource(ResourceArn=table_arn)
            if DEBUG:
                print("tags")
                show(tags)
            dashboard_list = DEFAULT_DASHBOARD_NAME
            for tag in tags['Tags']:
                if DEBUG:
                    print('tag', tag)
                if tag['Key'] == TAG_NAME:
                    dashboard_list = tag['Value']

            if DEBUG:
                print("dashboard_list", dashboard_list)
            for dashboard_name in dashboard_list.split('[ ,;]'):
                if DEBUG:
                    print("dashboard_name", dashboard_name)

                if dashboard_name not in tables_by_dashboard:
                    # make a new dashboard name
                    if DEBUG:
                        print(f"----dynamodb: making a new dashboard object for {dashboard_name}")
                    tables_by_dashboard[dashboard_name] = {
                        'dashboard_type': 'dynamodb',
                        'metric_names': list(map(lambda m: m['name'], DYNAMODB_METRICS)),
                        'names': []
                    }
                tables_by_dashboard[dashboard_name]['names'].append(table_name[offset:])
    if DEBUG:
        print('tables_by_dashboard', json.dumps(tables_by_dashboard, indent=4))
        print('offset', offset)

    for key, value in tables_by_dashboard.items():
        ret.append({key: value})
    return ret
def lambda_handler(event, _):
    '''
       normal lambda entrypoint
    '''
    messages = []
    show(event)
    ret = {'messages': messages}
    try:
        ret['result'] = update_dashboards(event)
    except Exception as exc:
        print("Caught exception %s" % str(exc))
        ret['result'] = "Caught exception %s" % str(exc)
    return ret
Esempio n. 4
0
def get_dashboard_apigws(prefix, environment):
    '''
      Similar to `get_dashboard_lambdas`, but for the restapis in the API Gateway service.
    '''
    ret = []

    get_rest_apis_response = CLIENT.get_rest_apis()
    apigws_by_dashboard = {}
    offset = len(f'{prefix}-{environment}') + 1

    for item in get_rest_apis_response['items']:
        rest_id = item['id']
        name = item['name']

        if DEBUG:
            print('item')
            show(item)
        if f'{prefix}-{environment}' in name:
            if DEBUG:
                print("\n\n\nid", rest_id)
                print('name', name)
            arn = f'arn:aws:apigateway:{get_region()}::/restapis/{rest_id}'
            tags = CLIENT.get_tags(resourceArn=arn)
            if DEBUG:
                print("tags")
                show(tags)
            dashboard_list = DEFAULT_DASHBOARD_NAME
            if TAG_NAME not in tags['tags']:
                if DEBUG:
                    print(TAG_NAME, "not found above")
            else:
                dashboard_list = tags['tags'][TAG_NAME]
                
            if DEBUG:
                print("dashboard_list", dashboard_list)
            for dashboard_name in dashboard_list.split('[ ,;]'):
                if DEBUG:
                    print(".1 dashboard_name", dashboard_name)
                if dashboard_name not in apigws_by_dashboard:
                    # make a new dashboard name
                    if DEBUG:
                        print(f"----apigw: making a new dashboard object for {dashboard_name}")
                    apigws_by_dashboard[dashboard_name] = {
                        'dashboard_type': SERVICE_NAME,
                        'metric_names' : list(map(lambda m: m['name'], APIGW_METRICS)),
                        'names' : []
                    }
                apigws_by_dashboard[dashboard_name]['names'].append(name[offset:])


    if DEBUG:
        print('apigws_by_dashboard')
        show(apigws_by_dashboard)
        print('offset', offset)

    for key, value in apigws_by_dashboard.items():
        ret.append({key: value})
    return ret
Esempio n. 5
0
'''
   main entrypoint for invoking from a zip file:
      python3 cloudwatch_dashboards.zip
'''

import json
import os
import sys

from cloudwatch_dashboards.cloudwatch_dashboards import update_dashboards
from cloudwatch_dashboards.helpers.util import show

print("sys.argv", sys.argv)

if len(sys.argv) < 2:
    print("Usage: cloudwatch_dashboards.py event.json")
    sys.exit(1)

event = json.loads(open(sys.argv[1]).read())
response = update_dashboards(event)
show(response)
def update_dashboards(event):
    prefix = os.getenv(
        "PREFIX", "timba"
    )  # from the environment sections of terraform/lambda_function.tf
    environment = os.getenv(
        "ENVIRONMENT", "none"
    )  # from the environment sections of terraform/lambda_function.tf
    show(event)

    source = event['source']
    if source not in SOURCE_MAPPINGS:
        return {'message', f'unknown source: "{source}"'}

    dashboard_type = DASHBOARD_TYPE_MAPPINGS[source]

    new_dashboards = SOURCE_MAPPINGS[source](prefix, environment)
    remaining_dashboards = get_existing_dashboards(prefix, environment)
    original_remaining_dashboard_count = len(remaining_dashboards)
    if DEBUG:
        print('original_remaining_dashboard_count',
              original_remaining_dashboard_count)
        print('remaining_dashboards')
        show(remaining_dashboards)

    for dashboard in new_dashboards:
        if DEBUG:
            print("dashboard", type(dashboard))
            show(dashboard)
        for dashboard_name, details in dashboard.items():
            names = details["names"]
            metric_names = details["metric_names"]
            dashboard_type = details["dashboard_type"]

            create_dashboard(
                prefix=prefix,
                environment=environment,
                dashboard_type=dashboard_type,
                metric_names=metric_names,
                basename=dashboard_name,
                names=names,
            )
            # remove current dashboard from list of remaining dashboards,
            # so we can delete them at the end of the this loop
            remaining_dashboards = list(
                filter(
                    lambda x: x !=
                    f'{prefix}-{environment}-{dashboard_name}-{dashboard_type}',
                    remaining_dashboards))

    deleted_dashboard_count = 0
    for remaining_dashboard in remaining_dashboards:
        # only delete if it has the same suffix/dashboard_type
        # as the service we're handling.
        if remaining_dashboard.endswith(f'-{dashboard_type}'):
            delete_dashboard(remaining_dashboard)
            deleted_dashboard_count = deleted_dashboard_count + 1

    return {
        'new_dashboard_count': len(new_dashboards),
        'original_dashboard_count': original_remaining_dashboard_count,
        'remaining_dashboards': len(remaining_dashboards),
        'deleted_dashboard_count': deleted_dashboard_count
    }
Esempio n. 7
0
def get_dashboard_cloudfront(prefix, environment):
    '''
      Reads the tags from the cloudfront distributions and returns a list of dictionaries.
      Each dict has a key containing the dashboard name, and their values have
      properties that contains a list of all the distributions that
      are tagged with that dashboard name.
    '''
    list_distributions_response = CLIENT.list_distributions()
    if DEBUG:
        print('list_distributions_response')
        show(list_distributions_response)

    ret = []
    cloudfronts_by_dashboard = {}
    if 'Items' not in list_distributions_response['DistributionList']:
        return ret # no cloudfront distributions found
    for dist in list_distributions_response['DistributionList']['Items']:
        cloudfront_dist = None
        matches_prefix_environment = False
        for origin in dist['Origins']['Items']:
            if f'{prefix}-{environment}' in origin['Id']:
                matches_prefix_environment = True
                cloudfront_dist = dist
        if matches_prefix_environment:
            if DEBUG:
                print("\n\n\ncloudfront_dist", cloudfront_dist)
                show(dist)
            tags = CLIENT.list_tags_for_resource(Resource=cloudfront_dist['ARN'])
            if DEBUG:
                print("tags")
                show(tags)

            dashboard_list = DEFAULT_DASHBOARD_NAME
            for item in tags['Tags']['Items']:
                if item['Key'] == TAG_NAME:
                    dashboard_list = item['Value']

            if DEBUG:
                print("dashboard_list", dashboard_list)
            for dashboard_name in dashboard_list.split('[ ,;]'):
                if DEBUG:
                    print("dashboard_name", dashboard_name)

                if dashboard_name not in cloudfronts_by_dashboard:
                    # make a new dashboard name
                    if DEBUG:
                        print(f"----cloudfront: making a new dashboard object for {dashboard_name}")
                    cloudfronts_by_dashboard[dashboard_name] = {
                        'dashboard_type': 'cloudfront',
                        'metric_names' : list(map(lambda m: m['name'], CLOUDFRONT_METRICS)),
                        'names' : []
                    }
                dist_id = dist['Id']
                if DEBUG:
                    print('dist_id', dist_id)
                cloudfronts_by_dashboard[dashboard_name]['names'].append(dist_id)
    if DEBUG:
        print('cloudfronts_by_dashboard')
        show(cloudfronts_by_dashboard)

    for key, value in cloudfronts_by_dashboard.items():
        ret.append({key: value})
    return ret
Esempio n. 8
0
def create_dashboard(*, prefix, environment, metric_names, dashboard_type,
                     basename, names):
    '''
      Creates a Cloudwatch Dashboard for one such element returned
      from `get_dashboard_lambdas()` and `get_dashboard_apigws()`
    '''
    row_number = 0
    dashboard_name = f"{prefix}-{environment.lower()}-{basename}-{dashboard_type}"
    print(f"create_dashboard({dashboard_name})... ", end='')
    widgets = []
    #
    #  put in a descriptor
    #
    descriptor = {
        "type": "text",
        "x": 0,
        "y": row_number,
        "width": len(DURATIONS) * 8,
        "height": 2,
        "properties": {
            "markdown": "\n# " + dashboard_name + "\n"
        }
    }
    widgets.append(descriptor)
    #
    #  add a graph for each metric_name
    #
    col_number = 0
    for duration in DURATIONS:
        row_number = 0
        for metric_name in metric_names:
            metrics = _create_metrics(metric_name, dashboard_type, prefix,
                                      environment, names)
            widget = {
                'type': 'metric',
                'x': col_number,
                'y': row_number,
                'width': 8,
                'height': 6,
                'properties': {
                    'title': f'{metric_name}-{duration}m',
                    # multiple lambdas on each graph
                    'metrics': metrics,
                    'period': duration * 60,
                    'stat': 'Maximum',
                    'region': os.getenv('AWS_DEFAULT_REGION', 'us-east-1')
                }
            }
            widgets.append(widget)
            row_number += 1
        col_number += 8

    dashboard_body = {'widgets': widgets}
    dashboard_body_j = json.dumps(dashboard_body)
    response = CLIENT.put_dashboard(DashboardName=dashboard_name,
                                    DashboardBody=dashboard_body_j)
    show(response)

    print('created!')

    if DEBUG:
        print(f'dashboard_body for {dashboard_name}')
        show(dashboard_body)
def get_dashboard_s3(prefix, environment):
    '''
      Reads the tags from the s3 buckets and returns a list of dictionaries.
      Each dict has a key containing the dashboard name, and their values
      have properties that contains a list of all the buckets that
      are tagged with that dashboard name.
    '''
    list_buckets_response = CLIENT.list_buckets()
    ret = []
    buckets_by_dashboard = {}
    offset = len(f'{prefix}-{environment}') + 1
    show(list_buckets_response)
    for bucket in list_buckets_response['Buckets']:
        bucket_name = bucket['Name']
        if f'{prefix}-{environment}' in bucket_name:
            if DEBUG:
                print("\n\n\nbucket_name", bucket_name)

            dashboard_list = DEFAULT_DASHBOARD_NAME
            try:
                tags = CLIENT.get_bucket_tagging(Bucket=bucket_name)
                if DEBUG:
                    print("tags")
                    show(tags)
                for tag in tags['TagSet']:
                    if DEBUG:
                        print('tag', tag)
                    if tag['Key'] == TAG_NAME:
                        dashboard_list = tag['Value']
            except Exception as exc:
                # If the get_bucket_tagging fails, assume the default
                pass

            if DEBUG:
                print("dashboard_list", dashboard_list)
            for dashboard_name in dashboard_list.split('[ ,;]'):
                if DEBUG:
                    print("dashboard_name", dashboard_name)

                if dashboard_name not in buckets_by_dashboard:
                    # make a new dashboard name
                    if DEBUG:
                        print(
                            f"----s3: making a new dashboard object for {dashboard_name}"
                        )
                    buckets_by_dashboard[dashboard_name] = {
                        'dashboard_type':
                        's3',
                        'metric_names':
                        list(map(lambda m: m['name'], BUCKET_METRICS)),
                        'names': []
                    }
                buckets_by_dashboard[dashboard_name]['names'].append(
                    bucket_name[offset:])
        else:
            if DEBUG:
                print("skipping bucket_name", bucket_name)
    if DEBUG:
        print('buckets_by_dashboard')
        show(buckets_by_dashboard)
        print('offset', offset)

    for key, value in buckets_by_dashboard.items():
        ret.append({key: value})
    return ret