#!/usr/bin/python

""" Sample client for CCU

Licensed under Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

Author: <NAME> <<EMAIL>>

Note that in order for this to work you need to provision credentials
specifically for CCU - you cannot extend existing credentials to add
CCU as it's managed under "CCU" in the API credential system.

Configure->Organization->Manage APIs
Select "CCU APIs"
Create client collections/clients
Add authorization

Put the credentials in ~/.edgerc like:

[ccu]
host = akab-blah-blah.purge.akamaiapis.net/
client_token = akab-blah-blah
client_secret = <PASSWORD>string+sosecret=
access_token = akab-getthis-fromtheportal

Usage:
   ccu.py --cpcode #####
   ccu.py --file file.txt
   ccu.py --check UUID-from-prior-run

"""

import requests, logging, json
from random import randint
from akamai.edgegrid import EdgeGridAuth
from urlparse import urljoin
import urllib
import os, sys
import argparse
import ConfigParser

#Snag some arguments, namely invalidate by CPCode or URL/ARLs in a file.
parser = argparse.ArgumentParser(
								formatter_class=argparse.RawDescriptionHelpFormatter,
								description="""
Implements the Akamai Content Control Utility

Example Commands:
   ccu.py --cpcode #####
   ccu.py --file file.txt
   ccu.py --check UUID-from-prior-run
   ccu.py --debug --network staging --config_file /etc/edgerc --config_section globalcreds --cpcode 0123456
""")

parser.add_argument('--config_file', default='~/.edgerc', type=str, metavar='FILENAME',
					help='Path to your edgerc config file.')
parser.add_argument('--debug', action='store_true',
					help='Way too much information.')
parser.add_argument('--network', default="production", choices=['production','staging'],
					help='Act on the production or staging network.')
parser.add_argument('--config_section', default='ccu', type=str,
					help='Which section of the edgerc file to use? [ccu] or [myname] for example.')

#Can't invalidate by CPCode and URL list in a single call.
args_exclusive = parser.add_mutually_exclusive_group(required=True)
args_exclusive.add_argument('--cpcode', type=int, 
							help="CPCode to purge.")
args_exclusive.add_argument('--file', type=str, 
							help="URL file to load. One URL per line.")
args_exclusive.add_argument('--check', type=str, metavar='PURGE_ID', 
							help="Check a running invalidate request.")

args = parser.parse_args()

# Build the JSON blob to send to Akamai. 
# It MUST be a list, even if it's just the one.
def BuildCPCodeReqBody(network, cpcode):
	req = {
		"objects" : [ cpcode ],
		"action" : "invalidate",
		"type" : "cpcode",
		"domain" : network
		}
	return json.dumps(req)

def BuildURLReqBody(network, urlfile):
	urlfile = os.path.expanduser(urlfile)
	if debug: print "DEBUG: urlfile", urlfile
	
	if os.path.isfile(urlfile):
		with open(urlfile, 'r') as f:
			urls = f.read().splitlines()
		f.close()
		
		#Snag a trailing newline / newline only lines / empty lines
		urls = [ x for x in urls if (x != "\n" and x != '')]
		
		if debug: print "URL list:", urls
	else:
		print "Missing configuration file.  Run python gen_creds.py to get your credentials file set up once you've provisioned credentials in LUNA."
		exit()

	req = {
		"objects" : urls,
		"action" : "invalidate",
		"type" : "arl",
		"domain" : network
		}
		
	if debug: print json.dumps(req)
	return json.dumps(req)

#Load your edgerc file, parse it out into the format EdgeGridAuth likes.	
def AkamaiEdgeGridConfig_Setup(config_file, section):
	config_file = os.path.expanduser(config_file)	
	if debug: print "DEBUG: config_file", config_file
	
	#Currently unused.
	required_options = ['client_token','client_secret','host','access_token']
	EdgeGridConfig = {}

	if os.path.isfile(config_file):
		config = ConfigParser.ConfigParser()
		config.readfp(open(config_file))
		for key, value in config.items(section):
			# ConfigParser lowercases magically
			EdgeGridConfig[key] = value
	else:
		print "Missing configuration file.  Run python gen_creds.py to get your credentials file set up once you've provisioned credentials in LUNA."
		exit()

	EdgeGridConfig['host'] = '%s://%s' % ('https', EdgeGridConfig['host'])
	
	if debug: print EdgeGridConfig
	return EdgeGridConfig

#Setup a EdgeGrid Session using the EdgeGridConfig previously loaded.
def AkamaiEdgeGridSession_Setup(AkamaiEdgeGridConfig):
	session = requests.Session()
	
	session.auth = EdgeGridAuth(
				client_token=AkamaiEdgeGridConfig['client_token'],
				client_secret=AkamaiEdgeGridConfig['client_secret'],
				access_token=AkamaiEdgeGridConfig['access_token']
	)
	
	return session

#Actually call akamai and return the result.
def DoInvalidateRequest(session, url, req):
	itsjson = {'content-type': 'application/json'}
	
	result = session.post(url,data=req,headers=itsjson)
	if (result.status_code == 201):
		purge_id_url = result.headers['content-location'].split('/')
		purge_id = purge_id_url[-1]
		return purge_id
	else:
		print "Request failed:", result.status_code
		return False

def DoCheckStatus(session, url, purge_id):
	url = url + purge_id
	
	result = session.get(url)

	if (result.status_code == 200):
		#json.load the text before json.dumping it. Using seemingly saner methods wasn't working.
		print json.dumps(json.loads(result.text),sort_keys=True, indent=4, separators=(',', ': '))

		return True
	else:
		print "Request failed:", result.status_code
		return False
	
# Enable debugging for the requests module
debug = args.debug
if debug:
	import httplib as http_client
	http_client.HTTPConnection.debuglevel = 1
	logging.basicConfig()
	logging.getLogger().setLevel(logging.DEBUG)
	requests_log = logging.getLogger("requests.packages.urllib3")
	requests_log.setLevel(logging.DEBUG)
	requests_log.propagate = True
else:
	requests.packages.urllib3.disable_warnings()

# Set the config options
AkamaiEdgeGridConfig = AkamaiEdgeGridConfig_Setup(args.config_file, args.config_section)
AkamaiEdgeGridSession = AkamaiEdgeGridSession_Setup(AkamaiEdgeGridConfig)

#Endpoints!
queue_url = AkamaiEdgeGridConfig['host'] + 'ccu/v2/queues/default'
check_url = AkamaiEdgeGridConfig['host'] + 'ccu/v2/purges/'

if (args.cpcode):
	print 'Invalidate by CPCode:', args.cpcode, '\n'
	
	req = BuildCPCodeReqBody(args.network,args.cpcode)
	if debug: print req
	
	purge_id = DoInvalidateRequest(AkamaiEdgeGridSession, queue_url, req)
	if purge_id:
		print "Request successful to invalidate cpcode", args.cpcode
		print "Check status with", sys.argv[0], "--check", purge_id
	else:
		print "Request failed."
		
elif (args.file):
	print 'Invalidate by URLs in file:', args.file
	req = BuildURLReqBody(args.network, args.file)
	purge_id = DoInvalidateRequest(AkamaiEdgeGridSession, queue_url, req)

	if purge_id:
		print "Request successful to invalidate urls in file", args.file
		print "Check status with", sys.argv[0], "--check", purge_id
	else:
		print "Request failed."

elif (args.check):
	print 'Checking status of purge:', args.check
	DoCheckStatus(AkamaiEdgeGridSession, check_url, args.check)


#!/usr/bin/python

""" Sample client for CCU

Licensed under Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

Author: <NAME> <<EMAIL>>

Note that in order for this to work you need to provision credentials
specifically for CCU - you cannot extend existing credentials to add
CCU as it's managed under "CCU" in the API credential system.

Configure->Organization->Manage APIs
Select "CCU APIs"
Create client collections/clients
Add authorization

Put the credentials in ~/.edgerc like:

[ccu]
host = akab-blah-blah.purge.akamaiapis.net/
client_token = akab-blah-blah
client_secret = <PASSWORD>string+sosecret=
access_token = akab-getthis-fromtheportal

Usage:
   ccu.py --cpcode #####
   ccu.py --file file.txt
   ccu.py --check UUID-from-prior-run

"""

import requests, logging, json
from random import randint
from akamai.edgegrid import EdgeGridAuth
from urlparse import urljoin
import urllib
import os, sys
import argparse
import ConfigParser

#Snag some arguments, namely invalidate by CPCode or URL/ARLs in a file.
parser = argparse.ArgumentParser(
								formatter_class=argparse.RawDescriptionHelpFormatter,
								description="""
Implements the Akamai Content Control Utility

Example Commands:
   ccu.py --cpcode #####
   ccu.py --file file.txt
   ccu.py --check UUID-from-prior-run
   ccu.py --debug --network staging --config_file /etc/edgerc --config_section globalcreds --cpcode 0123456
""")

parser.add_argument('--config_file', default='~/.edgerc', type=str, metavar='FILENAME',
					help='Path to your edgerc config file.')
parser.add_argument('--debug', action='store_true',
					help='Way too much information.')
parser.add_argument('--network', default="production", choices=['production','staging'],
					help='Act on the production or staging network.')
parser.add_argument('--config_section', default='ccu', type=str,
					help='Which section of the edgerc file to use? [ccu] or [myname] for example.')

#Can't invalidate by CPCode and URL list in a single call.
args_exclusive = parser.add_mutually_exclusive_group(required=True)
args_exclusive.add_argument('--cpcode', type=int, 
							help="CPCode to purge.")
args_exclusive.add_argument('--file', type=str, 
							help="URL file to load. One URL per line.")
args_exclusive.add_argument('--check', type=str, metavar='PURGE_ID', 
							help="Check a running invalidate request.")

args = parser.parse_args()

# Build the JSON blob to send to Akamai. 
# It MUST be a list, even if it's just the one.
def BuildCPCodeReqBody(network, cpcode):
	req = {
		"objects" : [ cpcode ],
		"action" : "invalidate",
		"type" : "cpcode",
		"domain" : network
		}
	return json.dumps(req)

def BuildURLReqBody(network, urlfile):
	urlfile = os.path.expanduser(urlfile)
	if debug: print "DEBUG: urlfile", urlfile
	
	if os.path.isfile(urlfile):
		with open(urlfile, 'r') as f:
			urls = f.read().splitlines()
		f.close()
		
		#Snag a trailing newline / newline only lines / empty lines
		urls = [ x for x in urls if (x != "\n" and x != '')]
		
		if debug: print "URL list:", urls
	else:
		print "Missing configuration file.  Run python gen_creds.py to get your credentials file set up once you've provisioned credentials in LUNA."
		exit()

	req = {
		"objects" : urls,
		"action" : "invalidate",
		"type" : "arl",
		"domain" : network
		}
		
	if debug: print json.dumps(req)
	return json.dumps(req)

#Load your edgerc file, parse it out into the format EdgeGridAuth likes.	
def AkamaiEdgeGridConfig_Setup(config_file, section):
	config_file = os.path.expanduser(config_file)	
	if debug: print "DEBUG: config_file", config_file
	
	#Currently unused.
	required_options = ['client_token','client_secret','host','access_token']
	EdgeGridConfig = {}

	if os.path.isfile(config_file):
		config = ConfigParser.ConfigParser()
		config.readfp(open(config_file))
		for key, value in config.items(section):
			# ConfigParser lowercases magically
			EdgeGridConfig[key] = value
	else:
		print "Missing configuration file.  Run python gen_creds.py to get your credentials file set up once you've provisioned credentials in LUNA."
		exit()

	EdgeGridConfig['host'] = '%s://%s' % ('https', EdgeGridConfig['host'])
	
	if debug: print EdgeGridConfig
	return EdgeGridConfig

#Setup a EdgeGrid Session using the EdgeGridConfig previously loaded.
def AkamaiEdgeGridSession_Setup(AkamaiEdgeGridConfig):
	session = requests.Session()
	
	session.auth = EdgeGridAuth(
				client_token=AkamaiEdgeGridConfig['client_token'],
				client_secret=AkamaiEdgeGridConfig['client_secret'],
				access_token=AkamaiEdgeGridConfig['access_token']
	)
	
	return session

#Actually call akamai and return the result.
def DoInvalidateRequest(session, url, req):
	itsjson = {'content-type': 'application/json'}
	
	result = session.post(url,data=req,headers=itsjson)
	if (result.status_code == 201):
		purge_id_url = result.headers['content-location'].split('/')
		purge_id = purge_id_url[-1]
		return purge_id
	else:
		print "Request failed:", result.status_code
		return False

def DoCheckStatus(session, url, purge_id):
	url = url + purge_id
	
	result = session.get(url)

	if (result.status_code == 200):
		#json.load the text before json.dumping it. Using seemingly saner methods wasn't working.
		print json.dumps(json.loads(result.text),sort_keys=True, indent=4, separators=(',', ': '))

		return True
	else:
		print "Request failed:", result.status_code
		return False
	
# Enable debugging for the requests module
debug = args.debug
if debug:
	import httplib as http_client
	http_client.HTTPConnection.debuglevel = 1
	logging.basicConfig()
	logging.getLogger().setLevel(logging.DEBUG)
	requests_log = logging.getLogger("requests.packages.urllib3")
	requests_log.setLevel(logging.DEBUG)
	requests_log.propagate = True
else:
	requests.packages.urllib3.disable_warnings()

# Set the config options
AkamaiEdgeGridConfig = AkamaiEdgeGridConfig_Setup(args.config_file, args.config_section)
AkamaiEdgeGridSession = AkamaiEdgeGridSession_Setup(AkamaiEdgeGridConfig)

#Endpoints!
queue_url = AkamaiEdgeGridConfig['host'] + 'ccu/v2/queues/default'
check_url = AkamaiEdgeGridConfig['host'] + 'ccu/v2/purges/'

if (args.cpcode):
	print 'Invalidate by CPCode:', args.cpcode, '\n'
	
	req = BuildCPCodeReqBody(args.network,args.cpcode)
	if debug: print req
	
	purge_id = DoInvalidateRequest(AkamaiEdgeGridSession, queue_url, req)
	if purge_id:
		print "Request successful to invalidate cpcode", args.cpcode
		print "Check status with", sys.argv[0], "--check", purge_id
	else:
		print "Request failed."
		
elif (args.file):
	print 'Invalidate by URLs in file:', args.file
	req = BuildURLReqBody(args.network, args.file)
	purge_id = DoInvalidateRequest(AkamaiEdgeGridSession, queue_url, req)

	if purge_id:
		print "Request successful to invalidate urls in file", args.file
		print "Check status with", sys.argv[0], "--check", purge_id
	else:
		print "Request failed."

elif (args.check):
	print 'Checking status of purge:', args.check
	DoCheckStatus(AkamaiEdgeGridSession, check_url, args.check)


#!/usr/bin/python Sample client for CCU  Licensed under Apache License                            Version 2.0, January 2004                         http://www.apache.org/licenses/  Author: <NAME> <<EMAIL>>  Note that in order for this to work you need to provision credentials specifically for CCU - you cannot extend existing credentials to add CCU as it's managed under "CCU" in the API credential system.  Configure->Organization->Manage APIs Select "CCU APIs" Create client collections/clients Add authorization  Put the credentials in ~/.edgerc like:  [ccu] host = akab-blah-blah.purge.akamaiapis.net/ client_token = akab-blah-blah client_secret = <PASSWORD>string+sosecret= access_token = akab-getthis-fromtheportal  Usage:    ccu.py --cpcode #####    ccu.py --file file.txt    ccu.py --check UUID-from-prior-run #Snag some arguments, namely invalidate by CPCode or URL/ARLs in a file. Implements the Akamai Content Control Utility  Example Commands:    ccu.py --cpcode #####    ccu.py --file file.txt    ccu.py --check UUID-from-prior-run    ccu.py --debug --network staging --config_file /etc/edgerc --config_section globalcreds --cpcode 0123456 #Can't invalidate by CPCode and URL list in a single call. # Build the JSON blob to send to Akamai. # It MUST be a list, even if it's just the one. #Snag a trailing newline / newline only lines / empty lines #Load your edgerc file, parse it out into the format EdgeGridAuth likes. #Currently unused. # ConfigParser lowercases magically #Setup a EdgeGrid Session using the EdgeGridConfig previously loaded. #Actually call akamai and return the result. #json.load the text before json.dumping it. Using seemingly saner methods wasn't working. # Enable debugging for the requests module # Set the config options #Endpoints!