Create New ASM Policy with iControl REST
Problem this snippet solves:
Proof of concept code to show how to create a new ASM policy using iControl REST.
How to use this snippet:
./create_new_asm_policy.py usage: create_new_asm_policy.py [-h] --bigip BIGIP --user USER --policyname POLICYNAME [--language {utf-8,auto-detect}] [--protocolindependence {false,true}] [--caseinsensitive {false,true}] [--enforcement {blocking,transparent}] [--template {Fundamental,Comprehensive}] [--virtual [VIRTUAL [VIRTUAL ...]]] [--learningmode {automatic,manual,disabled}]
Code :
#!/usr/bin/python # create_new_asm_policy.py # Author: Chad Jenison (c.jenison at f5.com) # Version 1.0 # # Script that creates new ASM policy using iControl REST and allows some customization of initial optionso # --virtual option allows attaching policy to one or more virtuals import argparse import sys import requests import json import getpass #Setup command line arguments using Python argparse parser = argparse.ArgumentParser(description='A tool to parse web log files and add them to an ASM security policy') parser.add_argument('--bigip', '-b', help='IP or hostname of BIG-IP Management or Self IP', required=True) parser.add_argument('--user', '-u', help='username to use for authentication', required=True) parser.add_argument('--policyname', '-p', help='ASM security policy name', required=True) parser.add_argument('--language', '-l', help='Application Language', default='utf-8', choices=['utf-8','auto-detect']) parser.add_argument('--protocolindependence', '-prot', help='Protocol Independence (false = distinguish between HTTP and HTTPS; true = treat HTTP and HTTPS equivalently)', default='false', choices=['false','true']) parser.add_argument('--caseinsensitive', '-c', help='Case Insensitive', default='false', choices=['false','true']) parser.add_argument('--enforcement', '-e', help='Enforcement Mode - Blocking or Transparent', default='blocking', choices=['blocking','transparent']) parser.add_argument('--template', '-t', choices=['Fundamental', 'Comprehensive']) parser.add_argument('--virtual', '-v', nargs='*', help='Virtual Server(s) to attach to (with full path [e.g. /Common/test])') parser.add_argument('--learningmode', '-m', choices=['automatic', 'manual', 'disabled']) args = parser.parse_args() contentTypeJsonHeader = {'Content-Type': 'application/json'} #adapted from https://devcentral.f5.com/s/articles/demystifying-icontrol-rest-6-token-based-authentication def get_auth_token(): payload = {} payload['username'] = args.user payload['password'] = passwd payload['loginProviderName'] = 'tmos' authurl = 'https://%s/mgmt/shared/authn/login' % args.bigip token = bip.post(authurl, headers=contentTypeJsonHeader, auth=(args.user, passwd), data=json.dumps(payload)).json()['token']['token'] return token def get_asm_policy_id_from_name(name): policies = bip.get('%s/asm/policies/' % (url_base)).json() for policy in policies['items']: if policy['name'] == name: id = policy['id'] return id url_base = ('https://%s/mgmt/tm' % (args.bigip)) user = args.user passwd = getpass.getpass("Password for " + user + ":") bip = requests.session() bip.verify = False requests.packages.urllib3.disable_warnings() authtoken = get_auth_token() authheader = {'X-F5-Auth-Token': authtoken} bip.headers.update(authheader) policyTemplates = bip.get('%s/asm/policy-templates/' % (url_base)).json() for policyTemplate in policyTemplates['items']: if policyTemplate['title'] == 'Fundamental' and args.template == 'Fundamental': policyTemplateId = policyTemplate['id'] if policyTemplate['title'] == 'Comprehensive' and args.template == 'Comprehensive': policyTemplateId = policyTemplate['id'] # combine two Python Dicts (our auth token and the Content-type json header) in preparation for doing POSTs postHeaders = authheader postHeaders.update(contentTypeJsonHeader) policyPayloadDict = {'name':args.policyname, 'caseInsensitive':args.caseinsensitive, 'enforcementMode':args.enforcement, 'applicationLanguage':args.language, 'protocolIndependent':args.protocolindependence} if args.template is not None: policyPayloadDict.update({'templateReference': policyTemplateId}) if args.virtual is not None: print ('Virtual(s) to add: %s' % (args.virtual)) policyPayloadDict.update({'virtualServers' : args.virtual }) newPolicyPayload = json.dumps(policyPayloadDict) addPolicy = bip.post('%s/asm/policies/' % (url_base), headers=postHeaders, data = newPolicyPayload) if addPolicy.status_code == 201: policyId = get_asm_policy_id_from_name(args.policyname) print ('Successfully Created Policy: %s - policyId: %s' % (args.policyname, policyId)) else: print ('Unsuccessful attempt to create policy: %s - Status Code: %s' % (args.policyname, addPolicy.status_code)) print ('Body: %s' % (addPolicy.content)) if args.learningmode is not None: policyBuilderPatchDict = {'learningMode': args.learningmode} updateLearning = bip.patch('%s/asm/policies/%s/policy-builder' % (url_base, policyId), headers=postHeaders, data = json.dumps(policyBuilderPatchDict)) print ('Set Learning Mode to: %s on policy: %s' % (args.learningmode, args.policyname))
Tested this on version:
13.0- dani_martinez_2Nimbostratus
Is this already developed in f5 common Python? Because I am trying and it does not work to me
- StewartT_232774Nimbostratus
Very handy script. Thank you for this!
I tweaked a tad to activate the policies if needed. I'll also be adding the ability to loop through a list of policy names/Templates to automate a large scale deployment I'm working on.
This saved me a lot of work on my own.
Hi,
I'm running v14.1 and it looks like template option is not working anymore. All created ASM policies use Fundamental template instead of the one mentioned during the policy creation. Can you confirm that the script is valid for v14 and v15 ?