import boto3
import ipaddress
import json
import logging
import os
import requests
import uuid

logger = logging.getLogger()
logger.setLevel(logging.INFO)

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(os.environ['DYNAMODB_TABLE'])
    
client = boto3.client('ssm')

def downloader(instance, latest, parameter, link):
    
    r = requests.get(link)
    cidrs = r.json()
    
    if r.status_code == 200:
        for cidr in cidrs:
            try:
                if len(cidr['ips']) != 0:
                    for ip in cidr['ips']:
                        sortkey = 'O365#'+instance+'#'+cidr['serviceArea']+'#'+ip
                        hostmask = ip.split('/')
                        iptype = ipaddress.ip_address(hostmask[0])
                        nametype = 'IPv'+str(iptype.version)+'#'
                        if nametype == 'IPv4#':
                            netrange = ipaddress.IPv4Network(ip)
                            first, last = netrange[0], netrange[-1]
                            firstip = int(ipaddress.IPv4Address(first))
                            lastip = int(ipaddress.IPv4Address(last))
                        elif nametype == 'IPv6#':
                            netrange = ipaddress.IPv6Network(ip)
                            first, last = netrange[0], netrange[-1]
                            firstip = int(ipaddress.IPv6Address(first))
                            lastip = int(ipaddress.IPv6Address(last))
                        table.put_item(
                            Item= {  
                                'pk': nametype,
                                'sk': sortkey,
                                'service': cidr['serviceArea'],
                                'cidr': ip,
                                'created': latest,
                                'endpoint': instance,
                                'firstip': firstip,
                                'lastip': lastip
                            }
                        )
            except:
                pass
            
        logger.info('o365 '+instance+' IP Ranges Updated')
        
        response = client.put_parameter(
            Name = parameter,
            Value = str(latest),
            Type = 'String',
            Overwrite = True
        )   

def handler(event, context):
    
    r = requests.get('https://endpoints.office.com/version?clientrequestid='+str(uuid.uuid4()))
    logger.info('Link Status Code: '+str(r.status_code))
    
    if r.status_code == 200:
        versions = r.json()
        logger.info(versions)
        for version in versions:
            if version['instance'] == 'Worldwide':
                response = client.get_parameter(Name=os.environ['WORLD_PARAMETER'])
                prevtoken = response['Parameter']['Value']
                if prevtoken != str(version['latest']):
                    logger.info('Updating o365 Worldwide IP Ranges')
                    link = 'https://endpoints.office.com/endpoints/worldwide?clientrequestid='+str(uuid.uuid4())
                    downloader(version['instance'], version['latest'], os.environ['WORLD_PARAMETER'], link)
            elif version['instance'] == 'USGovDoD':
                response = client.get_parameter(Name=os.environ['DOD_PARAMETER'])
                prevtoken = response['Parameter']['Value']
                if prevtoken != str(version['latest']):
                    logger.info('Updating o365 USGovDoD IP Ranges')
                    link = 'https://endpoints.office.com/endpoints/USGOVDoD?clientrequestid='+str(uuid.uuid4())
                    downloader(version['instance'], version['latest'], os.environ['DOD_PARAMETER'], link)
            elif version['instance'] == 'USGovGCCHigh':
                response = client.get_parameter(Name=os.environ['HIGH_PARAMETER'])
                prevtoken = response['Parameter']['Value']
                if prevtoken != str(version['latest']):
                    logger.info('Updating o365 USGovGCCHigh IP Ranges')
                    link = 'https://endpoints.office.com/endpoints/USGOVGCCHigh?clientrequestid='+str(uuid.uuid4())
                    downloader(version['instance'], version['latest'], os.environ['HIGH_PARAMETER'], link)
            elif version['instance'] == 'China':
                response = client.get_parameter(Name=os.environ['CHINA_PARAMETER'])
                prevtoken = response['Parameter']['Value']
                if prevtoken != str(version['latest']):
                    logger.info('Updating o365 China IP Ranges')
                    link = 'https://endpoints.office.com/endpoints/China?clientrequestid='+str(uuid.uuid4())
                    downloader(version['instance'], version['latest'], os.environ['CHINA_PARAMETER'], link)
            elif version['instance'] == 'Germany':
                response = client.get_parameter(Name=os.environ['GERMANY_PARAMETER'])
                prevtoken = response['Parameter']['Value']
                if prevtoken != str(version['latest']):
                    logger.info('Updating o365 Germany IP Ranges')
                    link = 'https://endpoints.office.com/endpoints/Germany?clientrequestid='+str(uuid.uuid4())
                    downloader(version['instance'], version['latest'], os.environ['GERMANY_PARAMETER'], link)
    else:
        logger.info('No o365 IP Range Updates')

    return {
        'statusCode': 200,
        'body': json.dumps('Download o365 IP Ranges')
    }

[((105, 124), 'logging.getLogger', 'logging.getLogger', ([], {}), '()\n', (122, 124), False, 'import logging\n'), ((167, 193), 'boto3.resource', 'boto3.resource', (['"""dynamodb"""'], {}), "('dynamodb')\n", (181, 193), False, 'import boto3\n'), ((261, 280), 'boto3.client', 'boto3.client', (['"""ssm"""'], {}), "('ssm')\n", (273, 280), False, 'import boto3\n'), ((346, 364), 'requests.get', 'requests.get', (['link'], {}), '(link)\n', (358, 364), False, 'import requests\n'), ((5422, 5459), 'json.dumps', 'json.dumps', (['"""Download o365 IP Ranges"""'], {}), "('Download o365 IP Ranges')\n", (5432, 5459), False, 'import json\n'), ((2416, 2428), 'uuid.uuid4', 'uuid.uuid4', ([], {}), '()\n', (2426, 2428), False, 'import uuid\n'), ((713, 746), 'ipaddress.ip_address', 'ipaddress.ip_address', (['hostmask[0]'], {}), '(hostmask[0])\n', (733, 746), False, 'import ipaddress\n'), ((899, 924), 'ipaddress.IPv4Network', 'ipaddress.IPv4Network', (['ip'], {}), '(ip)\n', (920, 924), False, 'import ipaddress\n'), ((3031, 3043), 'uuid.uuid4', 'uuid.uuid4', ([], {}), '()\n', (3041, 3043), False, 'import uuid\n'), ((1035, 1063), 'ipaddress.IPv4Address', 'ipaddress.IPv4Address', (['first'], {}), '(first)\n', (1056, 1063), False, 'import ipaddress\n'), ((1106, 1133), 'ipaddress.IPv4Address', 'ipaddress.IPv4Address', (['last'], {}), '(last)\n', (1127, 1133), False, 'import ipaddress\n'), ((1224, 1249), 'ipaddress.IPv6Network', 'ipaddress.IPv6Network', (['ip'], {}), '(ip)\n', (1245, 1249), False, 'import ipaddress\n'), ((3568, 3580), 'uuid.uuid4', 'uuid.uuid4', ([], {}), '()\n', (3578, 3580), False, 'import uuid\n'), ((1360, 1388), 'ipaddress.IPv6Address', 'ipaddress.IPv6Address', (['first'], {}), '(first)\n', (1381, 1388), False, 'import ipaddress\n'), ((1431, 1458), 'ipaddress.IPv6Address', 'ipaddress.IPv6Address', (['last'], {}), '(last)\n', (1452, 1458), False, 'import ipaddress\n'), ((4116, 4128), 'uuid.uuid4', 'uuid.uuid4', ([], {}), '()\n', (4126, 4128), False, 'import uuid\n'), ((4645, 4657), 'uuid.uuid4', 'uuid.uuid4', ([], {}), '()\n', (4655, 4657), False, 'import uuid\n'), ((5183, 5195), 'uuid.uuid4', 'uuid.uuid4', ([], {}), '()\n', (5193, 5195), False, 'import uuid\n')]