Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
134 lines (109 sloc) 6.04 KB
# -*- coding: UTF-8 -*-
import os
import sys
import yaml
import logging
import subprocess
from ftd_client.ftd_platform import FTDPlatform, FTDClient
__author__ = "Aaron Hackney "
__copyright__ = "Copyright 2019, Aaron Hackney"
__license__ = "GPL"
__version__ = "0.2"
__maintainer__ = "Aaron Hackney"
__email__ = "ahack210@gmail.com"
__status__ = "Beta"
"""This is sample code on how one might provision a freshly kicked FTD appliance. This assumes the OS has been loaded
but no one has actually signed into the box, either locally or remote.
Defaults:
Interface: The Management 0/0 interface will default to 192.168.45.45
Credentials: The default username is admin with a default password of "Admin123"
This proof of concept script will accept the EULA, change the default password fron "Admin123 to a password of our
choosing, and then change the management IP address to an IP address and gateway of our choosing. Once these steps have
been completed, other API calls can be made to begin configuriung items such as interaces, zones, policies, etc. and
the device can begin processing traffic.
This script ends by calling the change_management_ip.py script where we change the management IP address.
"""
log = logging.getLogger('ftd_config')
log.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
ch.setFormatter(formatter)
log.addHandler(ch)
# load the settings from the yaml file
with open("config.yaml", 'r') as stream:
config = yaml.safe_load(stream)
log.warning('yaml config file loaded...')
api_version = str(config['ftd_api_version'])
default_management_ip = config['intitial_provisioning']['default_management_ip']
default_password = config['intitial_provisioning']['default_password']
default_username = config['intitial_provisioning']['default_username']
if 'FTDPASS' not in os.environ:
log.error(f"Desired new password is an OS parameter vs hardcoding in the YAML file. To make this avaialbe to your "
f"script, in your bash shell: \n"
f" export FTDPASS=mynewpassword")
sys.exit()
password = os.environ['FTDPASS'] # **NOTE** New password is an OS parameter vs hardcoding in the YAML file
"""If this is an HA pair, we may be configuring the management IP address of the primary or the secondary. This script
parameter should be 'primary_ftd' or 'secondary_ftd' so that we know which IP address from the yaml file to assign to
the management interface. If no parameter is passed, we will assume that the primary_ftd management IP address should be
used. In the case of a stand-alone/non-ha device, the primary_ftd value in the yaml file will be used for the management
ip address."""
if len(sys.argv) > 1:
if sys.argv[1] == 'primary_ftd' or sys.argv[1] == 'secondary_ftd':
device_role = sys.argv[1]
else:
log.error(f"Parameter {sys.argv[1]} is invalid. The parameter shoud be either 'primary_ftd' or 'secondary_ftd':"
f"python3 provision.py primary_ftd"
f"python3 provision.py secondary_ftd")
sys.exit()
else:
device_role = 'primary_ftd'
def main():
###################################################################################################################
# Provision using default username, password, and default mangement IP adddress
ftd_client = FTDClient(api_version, default_management_ip, verify=config['verify_ssl'])
ftd_client.get_access_token(default_username, default_password) # Get an API token
if not ftd_client.token:
log.error('Auth to the box failed. Check that the yaml file has the current password. '
'(FTD default is "Admin123"')
sys.exit()
ftd_client.get_spec_json() # Load the swagger spec file
initial_provisioning(ftd_client.token, password)
###################################################################################################################
# Now we should have the username/password set so let's get a new token with the new credentials
ftd_client.token = None
ftd_client.get_access_token(default_username, password)
###################################################################################################################
# Finally let's change the management IP address. The caveat here is that the IP gets set immediately so we will
# lose connectivity to the device and will not get an API response. Since our script will hang waiting for a TCP
# response that will never come, let's handle the management IP adddress change in another script, call it as a
# sub-process, and detach from it.
change_management_ip_address(device_role)
def initial_provisioning(token, new_password, accept_eula=True):
ftd_platform = FTDPlatform(api_version, default_management_ip, verify=False)
ftd_platform.copy_token(token)
ftd_platform.get_spec_json()
initial_settings = ftd_platform.get_initial_provisioning()
initial_settings[0].acceptEULA = accept_eula
initial_settings[0].currentPassword = default_password
initial_settings[0].newPassword = new_password
ftd_platform.set_initial_provisioning(initial_settings[0])
log.warning('Initial provisioning of the FTD platfrom appears to have succeeded.')
def change_management_ip_address(role):
change_mgmt_ip = ["python", "change_management_ip.py",
api_version,
default_username,
password,
default_management_ip,
config[role]['management_ip'],
config[role]['management_mask'],
config[role]['management_gateway']]
pid = subprocess.Popen(change_mgmt_ip)
if pid:
log.debug('change_management_ip.py pid is {}'.format(pid))
log.warning('Change of the management IP address has been initiated and should be complete.')
else:
log.error('Tnere was an error running the change_management_ip.py script.')
if __name__ == "__main__":
main()
You can’t perform that action at this time.