def main(): # Get command line arguments parser = argparse.ArgumentParser(description="Update User-ID by adding or removing a user-to-ip mapping") parser.add_argument('-v', '--verbose', action='count', help="Verbose (-vv for extra verbose)") parser.add_argument('-q', '--quiet', action='store_true', help="No output") # Palo Alto Networks related arguments fw_group = parser.add_argument_group('Palo Alto Networks Device') fw_group.add_argument('hostname', help="Hostname of Firewall") fw_group.add_argument('username', help="Username for Firewall") fw_group.add_argument('password', help="Password for Firewall") fw_group.add_argument('action', help="The action of the user. Must be 'login' or 'logout'.") fw_group.add_argument('user', help="The username of the user") fw_group.add_argument('ip', help="The IP address of the user") args = parser.parse_args() ### Set up logger # Logging Levels # WARNING is 30 # INFO is 20 # DEBUG is 10 if args.verbose is None: args.verbose = 0 if not args.quiet: logging_level = 20 - (args.verbose * 10) if logging_level <= logging.DEBUG: logging_format = '%(levelname)s:%(name)s:%(message)s' else: logging_format = '%(message)s' logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). device = PanDevice.create_from_device(args.hostname, args.username, args.password, classify_exceptions=True) logging.debug("Detecting type of device") # Panorama does not have a userid API, so exit. # You can use the userid API on a firewall with the Panorama 'target' # parameter by creating a Panorama object first, then create a # Firewall object with the 'panorama' and 'serial' variables populated. if issubclass(type(device), Panorama): logging.error("Connected to a Panorama, but user-id API is not possible on Panorama. Exiting.") sys.exit(1) if args.action == "login": logging.debug("Login user %s at IP %s" % (args.user, args.ip)) device.userid.login(args.user, args.ip) elif args.action == "logout": logging.debug("Logout user %s at IP %s" % (args.user, args.ip)) device.userid.logout(args.user, args.ip) else: raise StandardError("Unknown action: %s. Must be 'login' or 'logout'." % args.action) logging.debug("Done")
def main(): # Get command line arguments parser = argparse.ArgumentParser(description="Tag an IP address on a Palo Alto Networks Next generation Firewall") parser.add_argument('-v', '--verbose', action='count', help="Verbose (-vv for extra verbose)") parser.add_argument('-q', '--quiet', action='store_true', help="No output") parser.add_argument('-u', '--unregister', action='store_true', help="Remove the tags (default is register)") parser.add_argument('-c', '--clear', action='store_true', help="Clear all tags. ip and tags arguments are ignored") # Palo Alto Networks related arguments fw_group = parser.add_argument_group('Palo Alto Networks Device') fw_group.add_argument('hostname', help="Hostname of Firewall") fw_group.add_argument('username', help="Username for Firewall") fw_group.add_argument('password', help="Password for Firewall") fw_group.add_argument('ip', help="The IP address that should be tagged") fw_group.add_argument('tags', help="Comma delimited tags. eg. linux,apache,server") args = parser.parse_args() ### Set up logger # Logging Levels # WARNING is 30 # INFO is 20 # DEBUG is 10 if args.verbose is None: args.verbose = 0 if not args.quiet: logging_level = 20 - (args.verbose * 10) if logging_level <= logging.DEBUG: logging_format = '%(levelname)s:%(name)s:%(message)s' else: logging_format = '%(message)s' logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). device = PanDevice.create_from_device(args.hostname, args.username, args.password, ) # Panorama does not have a userid API, so exit. # You can use the userid API on a firewall with the Panorama 'target' # parameter by creating a Panorama object first, then create a # Firewall object with the 'panorama' and 'serial' variables populated. if issubclass(type(device), Panorama): logging.error("Connected to a Panorama, but user-id API is not possible on Panorama. Exiting.") sys.exit(1) if args.clear: device.userid.clear_all_registered_ip() sys.exit(0) if args.unregister: device.userid.unregister(args.ip, args.tags.split(',')) else: device.userid.register(args.ip, args.tags.split(','))
def get_dev_type(pan_addr): global username, password while True: try: pan_device = PanDevice(pan_addr, username, password) if pan_device.refresh_system_info().platform.lower() in [ 'panorama', 'm-100', 'm-200', 'm-500', 'm-600' ]: print('\n\n...Auto-detected device type as Panorama...\n') return 'pano' else: print('\n\n...Auto-detected device type as a firewall...\n') return 'fw' except errors.PanURLError as e: if 'invalid credential' in str(e).lower(): print( '\n\nYour user credentials are invalid, try again...\n\n') username, password = get_creds() else: print('\n\nUnable to connect to device...\n\n') exit()
def main(): # Get command line arguments parser = argparse.ArgumentParser( description= "Upgrade a Palo Alto Networks Firewall or Panorama to the specified version" ) parser.add_argument('-v', '--verbose', action='count', help="Verbose (-vv for extra verbose)") parser.add_argument('-q', '--quiet', action='store_true', help="No output") parser.add_argument( '-n', '--dryrun', action='store_true', help="Print what would happen, but don't perform upgrades") # Palo Alto Networks related arguments fw_group = parser.add_argument_group('Palo Alto Networks Device') fw_group.add_argument('hostname', help="Hostname of Firewall or Panorama") fw_group.add_argument('username', help="Username for Firewall or Panorama") fw_group.add_argument('password', help="Password for Firewall or Panorama") fw_group.add_argument( 'version', help="The target PAN-OS/Panorama version (eg. 7.0.0 or latest)") args = parser.parse_args() ### Set up logger # Logging Levels # WARNING is 30 # INFO is 20 # DEBUG is 10 if args.verbose is None: args.verbose = 0 if not args.quiet: logging_level = 20 - (args.verbose * 10) if logging_level <= logging.DEBUG: logging_format = '%(levelname)s:%(name)s:%(message)s' else: logging_format = '%(message)s' logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). # This is important to know what version to upgrade to next. device = PanDevice.create_from_device( args.hostname, args.username, args.password, ) # Perform the upgrades in sequence with reboots between each upgrade device.software.upgrade_to_version(args.version, args.dryrun)
def main(): argument_spec = dict( ip_address=dict(required=True), username=dict(default='admin'), password=dict(no_log=True), api_key=dict(no_log=True), cmd=dict(required=True), cmd_is_xml=dict(default=False, type='bool'), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') auth = [module.params[x] for x in ('ip_address', 'username', 'password', 'api_key')] cmd = module.params['cmd'] cmd_is_xml = module.params['cmd_is_xml'] # Create the device with the appropriate pandevice type try: dev = PanDevice.create_from_device(*auth) except PanDeviceError as e: module.fail_json(msg='Failed to connect: {0}'.format(e)) changed = False xml_output = [] try: xml_output = dev.op(cmd, xml=True, cmd_xml=(not cmd_is_xml)) changed = True except PanDeviceError: if cmd_is_xml: e = get_exception() module.fail_json( msg='Failed to run XML command : {0} : {1}'.format(cmd, e)) tokens = cmd.split() tokens[-1] = '"{0}"'.format(tokens[-1]) cmd2 = ' '.join(tokens) try: xml_output = dev.op(cmd2, xml=True) changed = True except PanDeviceError: e = get_exception() module.fail_json(msg='Failed to run command : {0} : {1}'.format( cmd2, e)) obj_dict = xmltodict.parse(xml_output) json_output = json.dumps(obj_dict) module.exit_json(changed=changed, msg="Done", stdout=json_output, stdout_xml=xml_output)
def cli(hostname, username, password): """ PanDevice demo script. """ try: device = PanDevice.create_from_device(hostname, api_username=username, api_password=password) configure_network(device) configure_policy(device) device.commit(sync=True) except PanDeviceError as e: click.echo('PanDeviceError: {}'.format(e))
def main(): # Get command line arguments parser = argparse.ArgumentParser(description="Upgrade a Palo Alto Networks Firewall or Panorama to the specified version") parser.add_argument('-v', '--verbose', action='count', help="Verbose (-vv for extra verbose)") parser.add_argument('-q', '--quiet', action='store_true', help="No output") parser.add_argument('-n', '--dryrun', action='store_true', help="Print what would happen, but don't perform upgrades") # Palo Alto Networks related arguments fw_group = parser.add_argument_group('Palo Alto Networks Device') fw_group.add_argument('hostname', help="Hostname of Firewall or Panorama") fw_group.add_argument('username', help="Username for Firewall or Panorama") fw_group.add_argument('password', help="Password for Firewall or Panorama") fw_group.add_argument('version', help="The target PAN-OS/Panorama version (eg. 7.0.0 or latest)") args = parser.parse_args() ### Set up logger # Logging Levels # WARNING is 30 # INFO is 20 # DEBUG is 10 if args.verbose is None: args.verbose = 0 if not args.quiet: logging_level = 20 - (args.verbose * 10) if logging_level <= logging.DEBUG: logging_format = '%(levelname)s:%(name)s:%(message)s' else: logging_format = '%(message)s' logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). # This is important to know what version to upgrade to next. device = PanDevice.create_from_device(args.hostname, args.username, args.password, ) # Perform the upgrades in sequence with reboots between each upgrade device.software.upgrade_to_version(args.version, args.dryrun)
def get_pandevice(self, firewall): if firewall: firewall_config = self.config['firewall'].get(firewall) else: firewall_config = self.config['firewall'].get('default') # no need to duplicate config validation because pandevice is verbose enough device = None try: device = PanDevice.create_from_device( hostname=firewall_config.get('host'), api_username=firewall_config.get('api_username'), api_password=firewall_config.get('api_password'), api_key=firewall_config.get('api_key'), port=firewall_config.get('port'), ) except PanDeviceError as e: raise Exception( "Failed to connect to firewall {} with pandevice error {}".format(firewall_config, e) ) return device
def main(): # Get command line arguments parser = argparse.ArgumentParser( description= "Tag an IP address on a Palo Alto Networks Next generation Firewall") parser.add_argument('-v', '--verbose', action='count', help="Verbose (-vv for extra verbose)") parser.add_argument('-q', '--quiet', action='store_true', help="No output") parser.add_argument( '-r', '--register', help= "Tags to register to an IP, for multiple tags use commas eg. linux,apache,server" ) parser.add_argument( '-u', '--unregister', help= "Tags to remove from an an IP, for multiple tags use commas eg. linux,apache,server" ) parser.add_argument('-l', '--list', action='store_true', help="List all tags for an IP") parser.add_argument('-c', '--clear', action='store_true', help="Clear all tags for all IP") # Palo Alto Networks related arguments fw_group = parser.add_argument_group('Palo Alto Networks Device') fw_group.add_argument('hostname', help="Hostname of Firewall") fw_group.add_argument('username', help="Username for Firewall") fw_group.add_argument('password', help="Password for Firewall") fw_group.add_argument('ip', help="The IP address to tag/untag/list") args = parser.parse_args() ### Set up logger # Logging Levels # WARNING is 30 # INFO is 20 # DEBUG is 10 if args.verbose is None: args.verbose = 0 if not args.quiet: logging_level = 20 - (args.verbose * 10) if logging_level <= logging.DEBUG: logging_format = '%(levelname)s:%(name)s:%(message)s' else: logging_format = '%(message)s' logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). device = PanDevice.create_from_device( args.hostname, args.username, args.password, ) # Panorama does not have a userid API, so exit. # You can use the userid API on a firewall with the Panorama 'target' # parameter by creating a Panorama object first, then create a # Firewall object with the 'panorama' and 'serial' variables populated. if issubclass(type(device), Panorama): logging.error( "Connected to a Panorama, but user-id API is not possible on Panorama. Exiting." ) sys.exit(1) if args.clear: device.userid.clear_registered_ip() if args.list: all_tags_by_ip = device.userid.get_registered_ip() try: # Print the tags for the requested IP logging.info(all_tags_by_ip[args.ip]) except KeyError: # There were no tags for that IP logging.info("No tags for IP: %s" % args.ip) if args.unregister: device.userid.unregister(args.ip, args.unregister.split(',')) if args.register: device.userid.register(args.ip, args.register.split(','))
def get_pandevice_parent(self, module): """Builds the pandevice object tree, returning the parent object. If pandevice is not installed, then module.fail_json() will be invoked. Arguments: * module(AnsibleModule): the ansible module. Returns: * The parent pandevice object based on the spec given to get_connection(). """ # Sanity check. if not HAS_PANDEVICE: module.fail_json(msg='Missing required library "pandevice".') d, host_arg = None, None if module.params['provider'] and module.params['provider']['host']: d = module.params['provider'] host_arg = 'host' elif module.params['ip_address'] is not None: d = module.params host_arg = 'ip_address' else: module.fail_json(msg='New or classic provider params are required.') # Create the connection object. try: self.device = PanDevice.create_from_device( d[host_arg], d['username'], d['password'], d['api_key']) except PanDeviceError as e: module.fail_json(msg='Failed connection: {0}'.format(e)) parent = self.device not_found = '{0} "{1}" is not present.' if hasattr(self.device, 'refresh_devices'): # Panorama connection. # Error if Panorama is not supported. if self.panorama_error is not None: module.fail_json(msg=self.panorama_error) # Spec: template stack. if self.template_stack is not None: name = module.params[self.template_stack] stacks = TemplateStack.refreshall(parent) for ts in stacks: if ts.name == name: parent = ts break else: module.fail_json(msg=not_found.format( 'Template stack', name, )) # Spec: template. if self.template is not None: name = module.params[self.template] templates = Template.refreshall(parent) for t in templates: if t.name == name: parent = t break else: module.fail_json(msg=not_found.format( 'Template', name, )) # Spec: vsys importable. if self.vsys_importable is not None: name = module.params[self.vsys_importable] if name is not None: vo = Vsys(name) parent.add(vo) parent = vo # Spec: vsys_dg or device_group. dg_name = self.vsys_dg or self.device_group if dg_name is not None: name = module.params[dg_name] if name not in (None, 'shared'): groups = DeviceGroup.refreshall(parent) for dg in groups: if dg.name == name: parent = dg break else: module.fail_json(msg=not_found.format( 'Device group', name, )) # Spec: rulebase. if self.rulebase is not None: if module.params[self.rulebase] in (None, 'pre-rulebase'): rb = PreRulebase() parent.add(rb) parent = rb elif module.params[self.rulebase] == 'post-rulebase': rb = PostRulebase() parent.add(rb) parent = rb else: module.fail_json(msg=not_found.format( 'Rulebase', module.params[self.rulebase])) else: # Firewall connection. # Error if firewalls are not supported. if self.firewall_error is not None: module.fail_json(msg=self.firewall_error) # Spec: vsys or vsys_dg or vsys_importable. vsys_name = self.vsys_dg or self.vsys or self.vsys_importable if vsys_name is not None: self.con.vsys = module.params[vsys_name] # Spec: rulebase. if self.rulebase is not None: rb = Rulebase() parent.add(rb) parent = rb # Done. return parent
def main(): argument_spec = dict(ip_address=dict(required=True), username=dict(default='admin'), password=dict(no_log=True), api_key=dict(no_log=True), state=dict(default='present', choices=['present', 'absent']), admin_username=dict(default='admin'), authentication_profile=dict(), web_client_cert_only=dict(type='bool'), superuser=dict(type='bool'), superuser_read_only=dict(type='bool'), panorama_admin=dict(type='bool'), device_admin=dict(type='bool'), device_admin_read_only=dict(type='bool'), vsys=dict(type='list'), vsys_read_only=dict(type='list'), ssh_public_key=dict(), role_profile=dict(), admin_password=dict(no_log=True), password_profile=dict(no_log=False), commit=dict(type='bool', default=True)) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') # Get PAN-OS auth info. auth = [ module.params[x] for x in ['ip_address', 'username', 'password', 'api_key'] ] # Open the connection to the PAN-OS device. con = PanDevice.create_from_device(*auth) # Get administrator object spec. spec_params = [ 'authentication_profile', 'web_client_cert_only', 'superuser', 'superuser_read_only', 'panorama_admin', 'device_admin', 'device_admin_read_only', 'vsys', 'vsys_read_only', 'ssh_public_key', 'role_profile', 'password_profile', ] params = dict((k, module.params[k]) for k in spec_params) params['name'] = module.params['admin_username'] password = module.params['admin_password'] # Get other params. state = module.params['state'] commit = module.params['commit'] # Get the current administrators. admins = Administrator.refreshall(con, add=False) obj = Administrator(**params) con.add(obj) # Set "password_hash" by requesting a password hash. if password is not None: try: obj.password_hash = con.request_password_hash(password) except PanDeviceError as e: module.fail_json(msg='Failed to get phash: {0}'.format(e)) # Perform the requested action. changed = False if state == 'present': for x in admins: if obj.name == x.name: # If user did not specify a password, keep the current one. if obj.password_hash is None and x.password_hash: obj.password_hash = x.password_hash # Don't use .equal() here because we don't want pandevice to # try and do smart things with the password_hash field. if obj.element_str() != x.element_str(): try: obj.apply() except PanDeviceError as e: module.fail_json(msg='Failed apply: {0}'.format(e)) else: changed = True break else: try: obj.create() except PanDeviceError as e: module.fail_json(msg='Failed create: {0}'.format(e)) else: changed = True elif state == 'absent': if obj.name in [x.name for x in admins]: try: obj.delete() except PanDeviceError as e: module.fail_json(msg='Failed delete: {0}'.format(e)) else: changed = True # Commit if appropriate. if changed and commit: try: con.commit(sync=True) except PanDeviceError as e: module.fail_json(msg='Failed commit: {0}'.format(e)) # Done. module.exit_json(changed=changed, msg='done')
def main(): # Get command line arguments parser = argparse.ArgumentParser( description="Update User-ID by adding or removing a user-to-ip mapping" ) parser.add_argument('-v', '--verbose', action='count', help="Verbose (-vv for extra verbose)") parser.add_argument('-q', '--quiet', action='store_true', help="No output") # Palo Alto Networks related arguments fw_group = parser.add_argument_group('Palo Alto Networks Device') fw_group.add_argument('hostname', help="Hostname of Firewall") fw_group.add_argument('username', help="Username for Firewall") fw_group.add_argument('password', help="Password for Firewall") fw_group.add_argument( 'action', help="The action of the user. Must be 'login' or 'logout'.") fw_group.add_argument('user', help="The username of the user") fw_group.add_argument('ip', help="The IP address of the user") args = parser.parse_args() ### Set up logger # Logging Levels # WARNING is 30 # INFO is 20 # DEBUG is 10 if args.verbose is None: args.verbose = 0 if not args.quiet: logging_level = 20 - (args.verbose * 10) if logging_level <= logging.DEBUG: logging_format = '%(levelname)s:%(name)s:%(message)s' else: logging_format = '%(message)s' logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). device = PanDevice.create_from_device( args.hostname, args.username, args.password, ) logging.debug("Detecting type of device") # Panorama does not have a userid API, so exit. # You can use the userid API on a firewall with the Panorama 'target' # parameter by creating a Panorama object first, then create a # Firewall object with the 'panorama' and 'serial' variables populated. if issubclass(type(device), Panorama): logging.error( "Connected to a Panorama, but user-id API is not possible on Panorama. Exiting." ) sys.exit(1) if args.action == "login": logging.debug("Login user %s at IP %s" % (args.user, args.ip)) device.userid.login(args.user, args.ip) elif args.action == "logout": logging.debug("Logout user %s at IP %s" % (args.user, args.ip)) device.userid.logout(args.user, args.ip) else: raise StandardError( "Unknown action: %s. Must be 'login' or 'logout'." % args.action) logging.debug("Done")
def run_module(): module_args = dict(ip_address=dict(required=True), username=dict(default='admin'), password=dict(no_log=True)) result = dict(changed=False, packet_loss='', message='') module = AnsibleModule(argument_spec=module_args, #support_check_mode=False ) if not HAS_LIB: module.fail_json( msg='Missing required libraries: pandevice, netmiko, xmltodict') try: device = PanDevice.create_from_device(module.params['ip_address'], module.params['username'], module.params['password']) except PanDeviceError as e: module.fail_json(msg=e.message) auth = { 'device_type': 'paloalto_panos', 'ip': module.params['ip_address'], 'username': module.params['username'], 'password': module.params['password'] } try: conn = ConnectHandler(**auth) except (NetMikoTimeoutException, NetMikoAuthenticationException) as e: module.fail_json(msg=e) route_table_dict = xmltodict.parse( device.op('show routing route', xml=True))['response']['result'] route_interface_dict = xmltodict.parse( device.op('show routing interface', xml=True))['response']['result'] nexthops = [] nexthop_interfaces = [] if 'entry' in route_table_dict: for entry in route_table_dict['entry']: if ('A' in entry['flags'] and not 'C' in entry['flags'] and not 'H' in entry['flags'] and entry['nexthop'] != 'discard' and not entry['nexthop'] in nexthops): nexthops.append(entry['nexthop']) nexthop_interfaces.append(entry['interface']) interface_ip_map_dict = {} if 'interface' in route_interface_dict: for interface in route_interface_dict['interface']: if 'address' in interface: interface_ip_map_dict[interface['name']] = interface['address'] else: interface_ip_map_dict[interface['name']] = '' nexthop_interface_ips = [] for nexthop_int in nexthop_interfaces: for int_name, int_ip in interface_ip_map_dict.items(): if nexthop_int == int_name: nexthop_int = int_ip nexthop_interface_ips.append(nexthop_int[:-3]) break packet_loss_dict = {} for nexthop, source in list(zip(nexthops, nexthop_interface_ips)): if source: cmd = 'ping source {} count 2 host {}'.format(source, nexthop) raw_text_ping = conn.send_command( cmd, expect_string=r'(unknown)|(syntax)|(bind)|(\d{1,3})%').strip( 'ping\n') re_packet_loss = re.search(r'(\d{1,3})%', raw_text_ping) if re_packet_loss: packet_loss_dict[nexthop] = re_packet_loss.group(0) result['packet_loss'] = json.dumps(packet_loss_dict) result['message'] = 'Done' result['changed'] = True conn.disconnect() module.exit_json(**result)
def main(): # Get command line arguments parser = argparse.ArgumentParser(description="Tag an IP address on a Palo Alto Networks Next generation Firewall") parser.add_argument('-v', '--verbose', action='count', help="Verbose (-vv for extra verbose)") parser.add_argument('-q', '--quiet', action='store_true', help="No output") parser.add_argument('-r', '--register', help="Tags to register to an IP, for multiple tags use commas eg. linux,apache,server") parser.add_argument('-u', '--unregister', help="Tags to remove from an an IP, for multiple tags use commas eg. linux,apache,server") parser.add_argument('-l', '--list', action='store_true', help="List all tags for an IP") parser.add_argument('-c', '--clear', action='store_true', help="Clear all tags for all IP") # Palo Alto Networks related arguments fw_group = parser.add_argument_group('Palo Alto Networks Device') fw_group.add_argument('hostname', help="Hostname of Firewall") fw_group.add_argument('username', help="Username for Firewall") fw_group.add_argument('password', help="Password for Firewall") fw_group.add_argument('ip', help="The IP address to tag/untag/list") args = parser.parse_args() ### Set up logger # Logging Levels # WARNING is 30 # INFO is 20 # DEBUG is 10 if args.verbose is None: args.verbose = 0 if not args.quiet: logging_level = 20 - (args.verbose * 10) if logging_level <= logging.DEBUG: logging_format = '%(levelname)s:%(name)s:%(message)s' else: logging_format = '%(message)s' logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). device = PanDevice.create_from_device(args.hostname, args.username, args.password, ) # Panorama does not have a userid API, so exit. # You can use the userid API on a firewall with the Panorama 'target' # parameter by creating a Panorama object first, then create a # Firewall object with the 'panorama' and 'serial' variables populated. if issubclass(type(device), Panorama): logging.error("Connected to a Panorama, but user-id API is not possible on Panorama. Exiting.") sys.exit(1) if args.clear: device.userid.clear_registered_ip() if args.list: all_tags_by_ip = device.userid.get_registered_ip() try: # Print the tags for the requested IP logging.info(all_tags_by_ip[args.ip]) except KeyError: # There were no tags for that IP logging.info("No tags for IP: %s" % args.ip) if args.unregister: device.userid.unregister(args.ip, args.unregister.split(',')) if args.register: device.userid.register(args.ip, args.register.split(','))
def main(): """ Simple command-line program for shutting down virtual machines on a system. """ args = GetArgs() if args.password: password = args.password else: password = getpass.getpass( prompt='Enter password for host %s and user %s: ' % (args.host, args.user)) context = ssl._create_unverified_context() host = args.host user = args.user password = args.password port = int(args.port) vm = args.vmname # Set # of CPU cores and memory based on the model. if args.model == "50": vcpu = 2 memory = 5632 elif args.model == "100": vcpu = 2 memory = 6656 elif args.model == "300": vcpu = 4 memory = 9216 elif args.model == "500": vcpu = 8 memory = 16384 elif args.model == "700": vcpu = 16 memory = 57344 # PAN-OS info: pan_hostname = args.pan_host pan_username = args.pan_user pan_password = args.pan_pass auth_code = args.auth_code api_key = args.api_key service_instance = get_service_instance(host, user, password, port, context) vmobj = get_vm(service_instance, vm) if vmobj: # Create PAN-OS device am make sure connection can be created. Wait for 5 minutes timeout = time.time() + 60 * 5 # 5 min from now ready = False while time.time() < timeout: try: device = PanDevice.create_from_device( pan_hostname, api_username=pan_username, api_password=pan_password) except PanDeviceError as msg: print("PAN-OS is not ready trying again!") time.sleep(5) pass else: print("PAN-OS device connection created!") ready = True break if ready: # Make sure PAN-OS is ready to accept commands. wait for 5 minutes timeout = time.time() + 60 * 5 if wait_for_panos(device, timeout): # De active the current license. apply_api_key(device, api_key) deactivate_license(device) shutdown_vm(vmobj) change_vcpu(vmobj, vcpu) change_memory(vmobj, memory) poweron_vm(vmobj) timeout = time.time() + 60 * 5 # Make sure PAN-OS is ready to accept commands. wait for 5 minutes if wait_for_panos(device, timeout): activate_license(device, auth_code) print("Model upgraded to %s successfully!" % args.model) else: exit(1)
def main(): argument_spec = dict( ip_address=dict(required=True), username=dict(default='admin'), password=dict(no_log=True), api_key=dict(no_log=True), rule_name=dict(required=True), source_zone=dict(type='list', default=['any']), source_ip=dict(type='list', default=["any"]), source_user=dict(type='list', default=['any']), hip_profiles=dict(type='list', default=['any']), destination_zone=dict(type='list', default=['any']), destination_ip=dict(type='list', default=["any"]), application=dict(type='list', default=['any']), service=dict(type='list', default=['application-default']), category=dict(type='list', default=['any']), action=dict(default='allow', choices=[ 'allow', 'deny', 'drop', 'reset-client', 'reset-server', 'reset-both' ]), log_setting=dict(), log_start=dict(type='bool', default=False), log_end=dict(type='bool', default=True), description=dict(default=''), rule_type=dict(default='universal', choices=['universal', 'intrazone', 'interzone']), tag_name=dict(type='list'), negate_source=dict(type='bool', default=False), negate_destination=dict(type='bool', default=False), disabled=dict(type='bool', default=False), schedule=dict(), icmp_unreachable=dict(type='bool'), disable_server_response_inspection=dict(type='bool', default=False), group_profile=dict(), antivirus=dict(), spyware=dict(), vulnerability=dict(), url_filtering=dict(), file_blocking=dict(), wildfire_analysis=dict(), data_filtering=dict(), target=dict(type='list'), negate_target=dict(type='bool', default=False), location=dict(choices=['top', 'bottom', 'before', 'after']), existing_rule=dict(), devicegroup=dict(), rulebase=dict(default='pre-rulebase', choices=['pre-rulebase', 'post-rulebase']), vsys=dict(default='vsys1'), state=dict(choices=['present', 'absent']), operation=dict(default='add', choices=['add', 'update', 'delete', 'find']), commit=dict(type='bool', default=True)) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') elif not hasattr(SecurityRule, 'move'): module.fail_json(msg='Python library pandevice needs to be updated.') # Get the firewall / panorama auth. auth = ( module.params['ip_address'], module.params['username'], module.params['password'], module.params['api_key'], ) # Set the SecurityRule object params rule_spec = { 'name': module.params['rule_name'], 'fromzone': module.params['source_zone'], 'tozone': module.params['destination_zone'], 'source': module.params['source_ip'], 'source_user': module.params['source_user'], 'hip_profiles': module.params['hip_profiles'], 'destination': module.params['destination_ip'], 'application': module.params['application'], 'service': module.params['service'], 'category': module.params['category'], 'action': module.params['action'], 'log_setting': module.params['log_setting'], 'log_start': module.params['log_start'], 'log_end': module.params['log_end'], 'description': module.params['description'], 'type': module.params['rule_type'], 'tag': module.params['tag_name'], 'negate_source': module.params['negate_source'], 'negate_destination': module.params['negate_destination'], 'disabled': module.params['disabled'], 'schedule': module.params['schedule'], 'icmp_unreachable': module.params['icmp_unreachable'], 'disable_server_response_inspection': module.params['disable_server_response_inspection'], 'group': module.params['group_profile'], 'virus': module.params['antivirus'], 'spyware': module.params['spyware'], 'vulnerability': module.params['vulnerability'], 'url_filtering': module.params['url_filtering'], 'file_blocking': module.params['file_blocking'], 'wildfire_analysis': module.params['wildfire_analysis'], 'data_filtering': module.params['data_filtering'], } # Get other info location = module.params['location'] existing_rule = module.params['existing_rule'] devicegroup = module.params['devicegroup'] rulebase = module.params['rulebase'] vsys = module.params['vsys'] state = module.params['state'] operation = module.params['operation'] commit = module.params['commit'] # Sanity check the location / existing_rule params. if location in ('before', 'after') and not existing_rule: module.fail_json( msg= "'existing_rule' must be specified if location is 'before' or 'after'." ) # Open the connection to the PAN-OS device device = None try: device = PanDevice.create_from_device(*auth) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Add some additional rule params if device is Panorama if isinstance(device, Panorama): rule_spec['target'] = module.params['target'] rule_spec['negate_target'] = module.params['negate_target'] # Set the attachment point for the RuleBase object parent = device if isinstance(parent, Firewall): if vsys is not None: vsys_list = Vsys.refreshall(parent) parent = get_vsys(vsys, vsys_list) if parent is None: module.fail_json(msg='VSYS not found: {0}'.format(vsys)) parent = parent.add(Rulebase()) elif isinstance(parent, Panorama): if devicegroup == 'shared': devicegroup = None if devicegroup is not None: parent = parent.add(Rulebase()) else: parent = get_devicegroup(parent, devicegroup) if parent is None: module.fail_json( msg='Device group not found: {0}'.format(devicegroup)) if rulebase == 'pre-rulebase': parent = parent.add(PreRulebase()) elif rulebase == 'post-rulebase': parent = parent.add(PostRulebase()) # Now that we have the rulebase let's grab its security rules rules = SecurityRule.refreshall(parent) # Create new rule object from the params and add to rulebase new_rule = SecurityRule(**rule_spec) parent.add(new_rule) # Which action shall we take on the rule object? changed = False if state == 'present': match = find_rule(rules, new_rule) if match: # Change an existing rule if not match.equal(new_rule): try: if not module.check_mode: new_rule.apply() except PanDeviceError as e: module.fail_json( msg='Failed "present" apply: {0}'.format(e)) else: changed = True else: # Add a new rule try: if not module.check_mode: new_rule.create() except PanDeviceError as e: module.fail_json(msg='Failed "present" apply: {0}'.format(e)) else: changed = True # Move the rule if location is defined if location: try: if not module.check_mode: new_rule.move(location, existing_rule) except PanDeviceError as e: if '{0}'.format(e) not in ACCEPTABLE_MOVE_ERRORS: module.fail_json(msg='Failed move: {0}'.format(e)) else: changed = True elif state == 'absent': match = find_rule(rules, new_rule) if match: # Delete an existing rule try: if not module.check_mode: new_rule.delete() except PanDeviceError as e: module.fail_json(msg='Failed "absent" delete: {0}'.format(e)) else: changed = True elif operation == "find": # Search for the rule match = find_rule(rules, new_rule) # If found, format and return the result if match: module.exit_json(stdout_lines=match.about(), msg='Rule matched') else: module.fail_json( msg='Rule \'%s\' not found. Is the name correct?' % new_rule.name) elif operation == "delete": # Search for the object match = find_rule(rules, new_rule) if match is None: module.fail_json( msg='Rule \'%s\' not found. Is the name correct?' % new_rule.name) try: if not module.check_mode: new_rule.delete() except PanDeviceError as e: module.fail_json(msg='Failed "delete" delete: {0}'.format(e)) else: changed = True elif operation == "add": # Search for the rule. Fail if found. match = find_rule(rules, new_rule) if match: module.fail_json( msg= 'Rule \'%s\' already exists. Use operation: \'update\' to change it.' % new_rule.name) try: if not module.check_mode: new_rule.create() except PanDeviceError as e: module.fail_json(msg='Failed "add" create: {0}'.format(e)) else: changed = True if location: try: if not module.check_mode: new_rule.move(location, existing_rule) except PanDeviceError as e: if '{0}'.format(e) not in ACCEPTABLE_MOVE_ERRORS: module.fail_json(msg='Failed move: {0}'.format(e)) elif operation == 'update': # Search for the rule. Update if found. match = find_rule(rulebase, new_rule.name) if not match: module.fail_json( msg= 'Rule \'%s\' does not exist. Use operation: \'add\' to add it.' % new_rule.name) try: if not module.check_mode: new_rule.apply() except PanDeviceError as e: module.fail_json(msg='Failed "update" apply: {0}'.format(e)) else: changed = True if location: try: if not module.check_mode: new_rule.move(location, existing_rule) except PanDeviceError as e: if '{0}'.format(e) not in ACCEPTABLE_MOVE_ERRORS: module.fail_json(msg='Failed move: {0}'.format(e)) # Optional commit. # FIXME: Commits should be done using the separate commit module if changed and commit: try: device.commit(sync=True) except PanDeviceError as e: module.fail_json(msg='Failed commit: {0}'.format(e)) module.exit_json(changed=changed, msg='Done')
def main(): argument_spec = dict( ip_address=dict(required=True), password=dict(no_log=True), username=dict(default='admin'), api_key=dict(no_log=True), operation=dict(default='add', choices=['add', 'update', 'delete']), state=dict(choices=['present', 'absent']), if_name=dict(required=True), mode=dict(default='layer3', choices=[ 'layer3', 'layer2', 'virtual-wire', 'tap', 'ha', 'decrypt-mirror', 'aggregate-group' ]), ip=dict(type='list'), ipv6_enabled=dict(), management_profile=dict(), mtu=dict(), adjust_tcp_mss=dict(), netflow_profile=dict(), lldp_enabled=dict(), lldp_profile=dict(), netflow_profile_l2=dict(), link_speed=dict(), link_duplex=dict(), link_state=dict(), aggregate_group=dict(), comment=dict(), ipv4_mss_adjust=dict(), ipv6_mss_adjust=dict(), enable_dhcp=dict(type='bool', default=True), create_default_route=dict(type='bool', default=False), create_dhcp_default_route=dict(type='bool', default=False), dhcp_default_route_metric=dict(), dhcp_default_route=dict(type='str', default="no"), zone_name=dict(required=True), vr_name=dict(default='default'), vsys_dg=dict(default='vsys1'), commit=dict(type='bool', default=True), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') # Get the firewall / panorama auth. auth = [ module.params[x] for x in ('ip_address', 'username', 'password', 'api_key') ] # Get the object params. spec = { 'name': module.params['if_name'], 'mode': module.params['mode'], 'ip': module.params['ip'], 'ipv6_enabled': module.params['ipv6_enabled'], 'management_profile': module.params['management_profile'], 'mtu': module.params['mtu'], 'adjust_tcp_mss': module.params['adjust_tcp_mss'], 'netflow_profile': module.params['netflow_profile'], 'lldp_enabled': module.params['lldp_enabled'], 'lldp_profile': module.params['lldp_profile'], 'netflow_profile_l2': module.params['netflow_profile_l2'], 'link_speed': module.params['link_speed'], 'link_duplex': module.params['link_duplex'], 'link_state': module.params['link_state'], 'aggregate_group': module.params['aggregate_group'], 'comment': module.params['comment'], 'ipv4_mss_adjust': module.params['ipv4_mss_adjust'], 'ipv6_mss_adjust': module.params['ipv6_mss_adjust'], 'enable_dhcp': module.params['enable_dhcp'] or None, 'create_dhcp_default_route': module.params['create_default_route'] or None, 'dhcp_default_route_metric': module.params['dhcp_default_route_metric'], } # Get other info. enable_dhcp = module.params['enable_dhcp'] operation = module.params['operation'] state = module.params['state'] zone_name = module.params['zone_name'] vr_name = module.params['vr_name'] vsys_dg = module.params['vsys_dg'] commit = module.params['commit'] dhcp_default_route = module.params['dhcp_default_route'] management_profile = module.params['management_profile'] if_name = module.params['if_name'] dhcpe = ( '<entry name="%s"><layer3><dhcp-client><enable>yes</enable><create-default-route>%s</create-default-route>' '</dhcp-client><interface-management-profile>%s</interface-management-profile></layer3></entry>' % (if_name, dhcp_default_route, management_profile)) dhcpx = ( "/config/devices/entry[@name='localhost.localdomain']/network/interface/ethernet/entry[@name='%s']" % (if_name)) # Open the connection to the PANOS device. con = PanDevice.create_from_device(*auth) # Set vsys if firewall, device group if panorama. if hasattr(con, 'refresh_devices'): # Panorama # Normally we want to set the device group here, but there are no # interfaces on Panorama. So if we're given a Panorama device, then # error out. ''' groups = panorama.DeviceGroup.refreshall(con, add=False) for parent in groups: if parent.name == vsys_dg: con.add(parent) break else: module.fail_json(msg="'{0}' device group is not present".format(vsys_dg)) ''' module.fail_json(msg="Ethernet interfaces don't exist on Panorama") else: # Firewall # Normally we should set the vsys here, but since interfaces are # vsys importables, we'll use organize_into_vsys() to help find and # cleanup when the interface is imported into an undesired vsys. # con.vsys = vsys_dg pass # Retrieve the current config. try: interfaces = EthernetInterface.refreshall(con, add=False, name_only=True) zones = Zone.refreshall(con) routers = VirtualRouter.refreshall(con) vsys_list = Vsys.refreshall(con) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Build the object based on the user spec. eth = EthernetInterface(**spec) con.add(eth) # Which action should we take on the interface? changed = False if state == 'present': if eth.name in [x.name for x in interfaces]: i = EthernetInterface(eth.name) con.add(i) try: i.refresh() except PanDeviceError as e: module.fail_json(msg='Failed "present" refresh: {0}'.format(e)) if not i.equal(eth, compare_children=False): eth.extend(i.children) try: eth.apply() changed = True except PanDeviceError as e: module.fail_json( msg='Failed "present" apply: {0}'.format(e)) else: try: eth.create() changed = True except PanDeviceError as e: module.fail_json(msg='Failed "present" create: {0}'.format(e)) try: changed |= set_zone(con, eth, zone_name, zones) changed |= set_virtual_router(con, eth, vr_name, routers) if enable_dhcp is True: con.xapi.edit(xpath=dhcpx, element=dhcpe) except PanDeviceError as e: module.fail_json(msg='Failed zone/vr assignment: {0}'.format(e)) elif state == 'absent': try: changed |= set_zone(con, eth, None, zones) changed |= set_virtual_router(con, eth, None, routers) except PanDeviceError as e: module.fail_json( msg='Failed "absent" zone/vr cleanup: {0}'.format(e)) changed = True if eth.name in [x.name for x in interfaces]: try: eth.delete() changed = True except PanDeviceError as e: module.fail_json(msg='Failed "absent" delete: {0}'.format(e)) elif operation == 'delete': if eth.name not in [x.name for x in interfaces]: module.fail_json( msg='Interface {0} does not exist, and thus cannot be deleted'. format(eth.name)) try: con.organize_into_vsys() set_zone(con, eth, None, zones) set_virtual_router(con, eth, None, routers) eth.delete() changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) elif operation == 'add': if eth.name in [x.name for x in interfaces]: module.fail_json( msg='Interface {0} is already present; use operation "update"'. format(eth.name)) con.vsys = vsys_dg # Create the interface. try: eth.create() set_zone(con, eth, zone_name, zones) set_virtual_router(con, eth, vr_name, routers) changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) elif operation == 'update': if eth.name not in [x.name for x in interfaces]: module.fail_json( msg= 'Interface {0} is not present; use operation "add" to create it' .format(eth.name)) # If the interface is in the wrong vsys, remove it from the old vsys. try: con.organize_into_vsys() except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) if eth.vsys != vsys_dg: try: eth.delete_import() except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Move the ethernet object to the correct vsys. for vsys in vsys_list: if vsys.name == vsys_dg: vsys.add(eth) break else: module.fail_json(msg='Vsys {0} does not exist'.format(vsys)) # Update the interface. try: eth.apply() set_zone(con, eth, zone_name, zones) set_virtual_router(con, eth, vr_name, routers) changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) else: module.fail_json(msg="Unsupported operation '{0}'".format(operation)) # Commit if we were asked to do so. if changed and commit: try: con.commit(sync=True, exceptions=True) except PanDeviceError: e = get_exception() module.fail_json(msg='Performed {0} but commit failed: {1}'.format( operation, e.message)) # Done! module.exit_json(changed=changed, msg='okey dokey')
def main(): # Get command line arguments parser = argparse.ArgumentParser( description= "Tag an IP address on a Palo Alto Networks Next generation Firewall") parser.add_argument('-v', '--verbose', action='count', help="Verbose (-vv for extra verbose)") parser.add_argument('-q', '--quiet', action='store_true', help="No output") parser.add_argument('-u', '--unregister', action='store_true', help="Remove the tags (default is register)") parser.add_argument( '-c', '--clear', action='store_true', help="Clear all tags. ip and tags arguments are ignored") # Palo Alto Networks related arguments fw_group = parser.add_argument_group('Palo Alto Networks Device') fw_group.add_argument('hostname', help="Hostname of Firewall") fw_group.add_argument('username', help="Username for Firewall") fw_group.add_argument('password', help="Password for Firewall") fw_group.add_argument('ip', help="The IP address that should be tagged") fw_group.add_argument( 'tags', help="Comma delimited tags. eg. linux,apache,server") args = parser.parse_args() ### Set up logger # Logging Levels # WARNING is 30 # INFO is 20 # DEBUG is 10 if args.verbose is None: args.verbose = 0 if not args.quiet: logging_level = 20 - (args.verbose * 10) if logging_level <= logging.DEBUG: logging_format = '%(levelname)s:%(name)s:%(message)s' else: logging_format = '%(message)s' logging.basicConfig(format=logging_format, level=logging_level) # Connect to the device and determine its type (Firewall or Panorama). device = PanDevice.create_from_device( args.hostname, args.username, args.password, ) # Panorama does not have a userid API, so exit. # You can use the userid API on a firewall with the Panorama 'target' # parameter by creating a Panorama object first, then create a # Firewall object with the 'panorama' and 'serial' variables populated. if issubclass(type(device), Panorama): logging.error( "Connected to a Panorama, but user-id API is not possible on Panorama. Exiting." ) sys.exit(1) if args.clear: device.userid.clear_all_registered_ip() sys.exit(0) if args.unregister: device.userid.unregister(args.ip, args.tags.split(',')) else: device.userid.register(args.ip, args.tags.split(','))
def main(): argument_spec = dict( ip_address=dict(required=True), password=dict(no_log=True), username=dict(default='admin'), api_key=dict(no_log=True), operation=dict(default='add', choices=['add', 'update', 'delete']), state=dict(choices=['present', 'absent']), if_name=dict(required=True), ip=dict(type='list'), ipv6_enabled=dict(), management_profile=dict(), mtu=dict(), netflow_profile=dict(), comment=dict(), zone_name=dict(required=True), vr_name=dict(default='default'), vsys_dg=dict(default='vsys1'), commit=dict(type='bool', default=True), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') # Get the firewall / panorama auth. auth = [ module.params[x] for x in ('ip_address', 'username', 'password', 'api_key') ] # Get the object params. spec = { 'name': module.params['if_name'], 'ip': module.params['ip'], 'ipv6_enabled': module.params['ipv6_enabled'], 'management_profile': module.params['management_profile'], 'mtu': module.params['mtu'], 'netflow_profile': module.params['netflow_profile'], 'comment': module.params['comment'], } # Get other info. operation = module.params['operation'] state = module.params['state'] zone_name = module.params['zone_name'] vr_name = module.params['vr_name'] vsys_dg = module.params['vsys_dg'] commit = module.params['commit'] if_name = module.params['if_name'] # Open the connection to the PANOS device. con = PanDevice.create_from_device(*auth) # Set vsys if firewall, device group if panorama. if hasattr(con, 'refresh_devices'): # Panorama # Normally we want to set the device group here, but there are no # interfaces on Panorama. So if we're given a Panorama device, then # error out. ''' groups = panorama.DeviceGroup.refreshall(con, add=False) for parent in groups: if parent.name == vsys_dg: con.add(parent) break else: module.fail_json(msg="'{0}' device group is not present".format(vsys_dg)) ''' module.fail_json(msg="Ethernet interfaces don't exist on Panorama") else: # Firewall # Normally we should set the vsys here, but since interfaces are # vsys importables, we'll use organize_into_vsys() to help find and # cleanup when the interface is imported into an undesired vsys. # con.vsys = vsys_dg pass # Retrieve the current config. try: interfaces = TunnelInterface.refreshall(con, add=False, name_only=True) zones = Zone.refreshall(con) routers = VirtualRouter.refreshall(con) vsys_list = Vsys.refreshall(con) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Build the object based on the user spec. tun = TunnelInterface(**spec) con.add(tun) # Which action should we take on the interface? changed = False if state == 'present': if tun.name in [x.name for x in interfaces]: i = TunnelInterface(tun.name) con.add(i) try: i.refresh() except PanDeviceError as e: module.fail_json(msg='Failed "present" refresh: {0}'.format(e)) if not i.equal(tun, compare_children=False): tun.extend(i.children) try: tun.apply() changed = True except PanDeviceError as e: module.fail_json( msg='Failed "present" apply: {0}'.format(e)) else: try: tun.create() changed = True except PanDeviceError as e: module.fail_json(msg='Failed "present" create: {0}'.format(e)) try: changed |= set_zone(con, tun, zone_name, zones) changed |= set_virtual_router(con, tun, vr_name, routers) except PanDeviceError as e: module.fail_json(msg='Failed zone/vr assignment: {0}'.format(e)) elif state == 'absent': try: changed |= set_zone(con, tun, None, zones) changed |= set_virtual_router(con, tun, None, routers) except PanDeviceError as e: module.fail_json( msg='Failed "absent" zone/vr cleanup: {0}'.format(e)) changed = True if tun.name in [x.name for x in interfaces]: try: tun.delete() changed = True except PanDeviceError as e: module.fail_json(msg='Failed "absent" delete: {0}'.format(e)) elif operation == 'delete': if tun.name not in [x.name for x in interfaces]: module.fail_json( msg='Interface {0} does not exist, and thus cannot be deleted'. format(tun.name)) try: con.organize_into_vsys() set_zone(con, tun, None, zones) set_virtual_router(con, tun, None, routers) tun.delete() changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) elif operation == 'add': if tun.name in [x.name for x in interfaces]: module.fail_json( msg='Interface {0} is already present; use operation "update"'. format(tun.name)) con.vsys = vsys_dg # Create the interface. try: tun.create() set_zone(con, tun, zone_name, zones) set_virtual_router(con, tun, vr_name, routers) changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) elif operation == 'update': if tun.name not in [x.name for x in interfaces]: module.fail_json( msg= 'Interface {0} is not present; use operation "add" to create it' .format(tun.name)) # If the interface is in the wrong vsys, remove it from the old vsys. try: con.organize_into_vsys() except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) if tun.vsys != vsys_dg: try: tun.delete_import() except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Move the ethernet object to the correct vsys. for vsys in vsys_list: if vsys.name == vsys_dg: vsys.add(tun) break else: module.fail_json(msg='Vsys {0} does not exist'.format(vsys)) # Update the interface. try: tun.apply() set_zone(con, tun, zone_name, zones) set_virtual_router(con, tun, vr_name, routers) changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) else: module.fail_json(msg="Unsupported operation '{0}'".format(operation)) # Commit if we were asked to do so. if changed and commit: try: con.commit(sync=True) except PanDeviceError: e = get_exception() module.fail_json(msg='Performed {0} but commit failed: {1}'.format( operation, e.message)) # Done! module.exit_json(changed=changed, msg='okey dokey')
def delete_from_device(palo: PanDevice, expired: list): results = [] for cert in expired: results.append(palo.remove_by_name(cert['@name'])) return expired
def main(): argument_spec = dict(ip_address=dict(required=True), username=dict(default='admin'), password=dict(default='admin', no_log=True), api_key=dict(no_log=True), serialnum=dict(required=True), devicegroup=dict(), templatestack=dict(), state=dict(default='present')) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, mutually_exclusive=[['api_key', 'password']]) if not HAS_LIB: module.fail_json( msg='pan-python and pandevice are required for this module') serialnum = module.params["serialnum"] devicegroup = module.params['devicegroup'] templatestack = module.params['templatestack'] state = module.params['state'] # Get the authentication params auth = ( module.params['ip_address'], module.params['username'], module.params['password'], module.params['api_key'], ) # Open the connection to the PAN-OS device device = None try: device = PanDevice.create_from_device(*auth) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Ensure we're not connected to a firewall if isinstance(device, Firewall): module.fail_json( msg='This module is only supported on Panorama instances') # Set our change flag changed = False # Add to Panorama if not already connected fw = get_firewall(device, serialnum) if fw is None and state == 'present' and not module.check_mode: fw = Firewall(serial=serialnum) device.add(fw) fw.create() changed = True # Process the DeviceGroup if devicegroup: dg = get_devicegroup(device, devicegroup) if dg is None: module.fail_json( msg="DeviceGroup not found: {0}".format(devicegroup)) elif dg.find( fw.serial, Firewall ) is None and state == 'present' and not module.check_mode: dg.add(fw) fw.create() changed = True elif dg.find(fw.serial, Firewall) and state == 'absent' and not module.check_mode: dg.remove(dg.find(fw.serial)) dg.apply() changed = True # Add to the Template Stack if templatestack: ts = get_templatestack(device, templatestack) if ts is None: module.fail_json( msg="TemplateStack not found: {0}".format(templatestack)) else: listify(ts) if fw.serial not in ts.devices and state == 'present' and not module.check_mode: ts.devices.append(serialnum) ts.create() changed = True elif fw.serial in ts.devices and state == 'absent' and not module.check_mode: ts.devices.remove(fw.serial) ts.apply() changed = True # Remove from Panorama if (device.find(fw.serial, Firewall)) and (state == 'absent'): device.remove(fw) device.apply() changed = True module.exit_json(changed=changed)
def get_pandevice_parent(self, module): """Builds the pandevice object tree, returning the parent object. If pandevice is not installed, then module.fail_json() will be invoked. Arguments: * module(AnsibleModule): the ansible module. Returns: * The parent pandevice object based on the spec given to get_connection(). """ # Sanity check. if not HAS_PANDEVICE: module.fail_json(msg='Missing required library "pandevice".') # Verify pandevice minimum version. if self.min_pandevice_version is not None: pdv = tuple(int(x) for x in pandevice.__version__.split('.')) if pdv < self.min_pandevice_version: module.fail_json(msg=_MIN_VERSION_ERROR.format( 'pandevice', pandevice.__version__, _vstr(self.min_pandevice_version))) d, host_arg = None, None if module.params['provider'] and module.params['provider']['host']: d = module.params['provider'] host_arg = 'host' elif module.params['ip_address'] is not None: d = module.params host_arg = 'ip_address' else: module.fail_json( msg='New or classic provider params are required.') # Create the connection object. try: self.device = PanDevice.create_from_device(d[host_arg], d['username'], d['password'], d['api_key'], d['port']) except PanDeviceError as e: module.fail_json(msg='Failed connection: {0}'.format(e)) # Verify PAN-OS minimum version. if self.min_panos_version is not None: if self.device._version_info < self.min_panos_version: module.fail_json(msg=_MIN_VERSION_ERROR.format( 'PAN-OS', _vstr(self.device._version_info), _vstr(self.min_panos_version))) parent = self.device not_found = '{0} "{1}" is not present.' pano_mia_param = 'Param "{0}" is required for Panorama but not specified.' ts_error = 'Specify either the template or the template stack{0}.' if hasattr(self.device, 'refresh_devices'): # Panorama connection. # Error if Panorama is not supported. if self.panorama_error is not None: module.fail_json(msg=self.panorama_error) # Spec: template stack. tmpl_required = False added_template = False if self.template_stack is not None: name = module.params[self.template_stack] if name is not None: stacks = TemplateStack.refreshall(parent, name_only=True) for ts in stacks: if ts.name == name: parent = ts added_template = True break else: module.fail_json(msg=not_found.format( 'Template stack', name, )) elif self.template is not None: tmpl_required = True else: module.fail_json( msg=pano_mia_param.format(self.template_stack)) # Spec: template. if self.template is not None: name = module.params[self.template] if name is not None: if added_template: module.fail_json(msg=ts_error.format(', not both')) templates = Template.refreshall(parent, name_only=True) for t in templates: if t.name == name: parent = t break else: module.fail_json(msg=not_found.format( 'Template', name, )) elif tmpl_required: module.fail_json(msg=ts_error.format('')) else: module.fail_json(msg=pano_mia_param.format(self.template)) # Spec: vsys importable. vsys_name = self.vsys_importable or self.vsys if vsys_name is not None: name = module.params[vsys_name] if name not in (None, 'shared'): vo = Vsys(name) parent.add(vo) parent = vo # Spec: vsys_dg or device_group. dg_name = self.vsys_dg or self.device_group if dg_name is not None: name = module.params[dg_name] if name not in (None, 'shared'): groups = DeviceGroup.refreshall(parent, name_only=True) for dg in groups: if dg.name == name: parent = dg break else: module.fail_json(msg=not_found.format( 'Device group', name, )) # Spec: rulebase. if self.rulebase is not None: if module.params[self.rulebase] in (None, 'pre-rulebase'): rb = PreRulebase() parent.add(rb) parent = rb elif module.params[self.rulebase] == 'rulebase': rb = Rulebase() parent.add(rb) parent = rb elif module.params[self.rulebase] == 'post-rulebase': rb = PostRulebase() parent.add(rb) parent = rb else: module.fail_json(msg=not_found.format( 'Rulebase', module.params[self.rulebase])) else: # Firewall connection. # Error if firewalls are not supported. if self.firewall_error is not None: module.fail_json(msg=self.firewall_error) # Spec: vsys or vsys_dg or vsys_importable. vsys_name = self.vsys_dg or self.vsys or self.vsys_importable if vsys_name is not None: self.device.vsys = module.params[vsys_name] # Spec: rulebase. if self.rulebase is not None: rb = Rulebase() parent.add(rb) parent = rb # Done. return parent
def main(): argument_spec = dict( ip_address=dict(required=True), username=dict(default='admin'), password=dict(no_log=True), api_key=dict(no_log=True), state=dict(default='present', choices=['present', 'absent']), panorama_template=dict(), name=dict(required=True), ping=dict(type='bool'), telnet=dict(type='bool'), ssh=dict(type='bool'), http=dict(type='bool'), http_ocsp=dict(type='bool'), https=dict(type='bool'), snmp=dict(type='bool'), response_pages=dict(type='bool'), userid_service=dict(type='bool'), userid_syslog_listener_ssl=dict(type='bool'), userid_syslog_listener_udp=dict(type='bool'), permitted_ip=dict(type='list'), commit=dict(type='bool', default=True), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') auth = [ module.params[x] for x in ('ip_address', 'username', 'password', 'api_key') ] state = module.params['state'] panorama_template = module.params['panorama_template'] obj = ManagementProfile(*[ module.params[x] for x in ('name', 'ping', 'telnet', 'ssh', 'http', 'http_ocsp', 'https', 'snmp', 'response_pages', 'userid_service', 'userid_syslog_listener_ssl', 'userid_syslog_listener_udp', 'permitted_ip') ]) commit = module.params['commit'] # Create the device with the appropriate pandevice type dev = PanDevice.create_from_device(*auth) # Object tree initialization and parent selection. parent = dev if hasattr(dev, 'refresh_devices'): # This is Panorama. if not panorama_template: module.fail_json( msg="'panorama_template' is required for Panorama") ts = Template.refreshall(dev) for x in ts: if x.name == panorama_template: parent = x break else: module.fail_json( msg='template "{0}" not found'.format(panorama_template)) # Check current status. try: cur_list = ManagementProfile.refreshall(parent) except PanDeviceError: e = get_exception() module.fail_json(msg='Failed refreshall: {0}'.format(e.message)) parent.add(obj) # Determine what function to use based on the desired state. func = None changed = False if state == 'present': for x in cur_list: if x.name == obj.name: if not x.equal(obj, compare_children=False): for child in x.children: obj.add(child) func = 'apply' break else: func = 'create' else: for x in cur_list: if x.name == obj.name: func = 'delete' break # Perform create / apply / delete, if needed. if func is not None: try: getattr(obj, func)() except PanDeviceError: e = get_exception() module.fail_json(msg='Failed {0}: {1}'.format(func, e.message)) changed = True # Perform commit if requested. if commit: try: dev.commit() except PanDeviceError: e = get_exception() module.fail_json(msg='Failed commit: {0}'.format(e.message)) # Done module.exit_json(changed=changed, msg="Done")
def main(): argument_spec = dict( ip_address=dict(required=True), username=dict(default='admin'), password=dict(required=True, no_log=True), api_key=dict(no_log=True), operation=dict(choices=['add', 'update', 'delete', 'find', 'disable']), state=dict(default='present', choices=['present', 'absent']), rule_name=dict(required=True), description=dict(), nat_type=dict(default='ipv4', choices=['ipv4', 'nat64', 'nptv6']), tag_name=dict(), source_zone=dict(type='list'), source_ip=dict(type='list', default=['any']), destination_zone=dict(), destination_ip=dict(type='list', default=['any']), service=dict(default='any'), to_interface=dict(default='any'), snat_type=dict( choices=['static-ip', 'dynamic-ip-and-port', 'dynamic-ip']), snat_address_type=dict( choices=['interface-address', 'translated-address'], default='interface-address'), snat_static_address=dict(), snat_dynamic_address=dict(type='list'), snat_interface=dict(), snat_interface_address=dict(), snat_bidirectional=dict(type='bool', default=False), dnat_address=dict(), dnat_port=dict(), devicegroup=dict(default='shared'), rulebase=dict(default='pre-rulebase', choices=['pre-rulebase', 'post-rulebase']), vsys=dict(default='vsys1'), location=dict(default='bottom', choices=['top', 'bottom', 'before', 'after']), existing_rule=dict(), commit=dict(type='bool', default=True)) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') elif not hasattr(NatRule, 'move'): module.fail_json(msg='Python library pandevice needs to be updated.') # Get firewall / Panorama auth. auth = [ module.params[x] for x in ('ip_address', 'username', 'password', 'api_key') ] # Get object params. rule_name = module.params['rule_name'] description = module.params['description'] tag_name = module.params['tag_name'] source_zone = module.params['source_zone'] source_ip = module.params['source_ip'] destination_zone = module.params['destination_zone'] destination_ip = module.params['destination_ip'] service = module.params['service'] to_interface = module.params['to_interface'] nat_type = module.params['nat_type'] snat_type = module.params['snat_type'] snat_address_type = module.params['snat_address_type'] snat_static_address = module.params['snat_static_address'] snat_dynamic_address = module.params['snat_dynamic_address'] snat_interface = module.params['snat_interface'] snat_interface_address = module.params['snat_interface_address'] snat_bidirectional = module.params['snat_bidirectional'] dnat_address = module.params['dnat_address'] dnat_port = module.params['dnat_port'] # Get other info. operation = module.params['operation'] state = module.params['state'] devicegroup = module.params['devicegroup'] vsys = module.params['vsys'] commit = module.params['commit'] location = module.params['location'] existing_rule = module.params['existing_rule'] # Sanity check the location / existing_rule params. if location in ('before', 'after') and not existing_rule: module.fail_json( msg= "'existing_rule' must be specified if location is 'before' or 'after'." ) # Create the device with the appropriate pandevice type con = PanDevice.create_from_device(*auth) # Set vsys if firewall, device group if Panorama, and set the rulebase. parent = con if hasattr(con, 'refresh_devices'): # Panorama if devicegroup not in (None, 'shared'): dev_group = get_devicegroup(con, devicegroup) if not dev_group: module.fail_json( msg= '\'%s\' device group not found in Panorama. Is the name correct?' % devicegroup) parent = dev_group if module.params['rulebase'] in (None, 'pre-rulebase'): rulebase = PreRulebase() parent.add(rulebase) parent = rulebase elif module.params['rulebase'] == 'post-rulebase': rulebase = PostRulebase() parent.add(rulebase) parent = rulebase else: # Firewall parent.vsys = vsys rulebase = Rulebase() parent.add(rulebase) parent = rulebase # Get the current NAT rules. try: rules = NatRule.refreshall(parent) except PanDeviceError as e: module.fail_json(msg='Failed NAT refreshall: {0}'.format(e)) # Create the desired rule. new_rule = create_nat_rule(rule_name=rule_name, description=description, tag_name=tag_name, source_zone=source_zone, destination_zone=destination_zone, source_ip=source_ip, destination_ip=destination_ip, service=service, to_interface=to_interface, nat_type=nat_type, snat_type=snat_type, snat_address_type=snat_address_type, snat_static_address=snat_static_address, snat_dynamic_address=snat_dynamic_address, snat_interface=snat_interface, snat_interface_address=snat_interface_address, snat_bidirectional=snat_bidirectional, dnat_address=dnat_address, dnat_port=dnat_port) if not new_rule: module.fail_json(msg='Incorrect NAT rule params specified; quitting') parent.add(new_rule) # Perform the desired operation. changed = False do_move = False if state == 'present': match = find_rule(rules, new_rule) if match is not None: if not match.equal(new_rule): try: new_rule.apply() except PanDeviceError as e: module.fail_json( msg='Failed "present" apply: {0}'.format(e)) else: changed = True do_move = True else: try: new_rule.create() except PanDeviceError as e: module.fail_json(msg='Failed "present" create: {0}'.format(e)) else: changed = True do_move = True elif state == 'absent': match = find_rule(rules, new_rule) if match is not None: try: new_rule.delete() except PanDeviceError as e: module.fail_json(msg='Failed "absent" delete: {0}'.format(e)) else: changed = True elif operation == "find": # Search for the rule match = find_rule(rules, new_rule) # If found, format and return the result if match: match_dict = xmltodict.parse(match.element_str()) module.exit_json(stdout_lines=json.dumps(match_dict, indent=2), msg='Rule matched') else: module.fail_json( msg='Rule \'%s\' not found. Is the name correct?' % rule_name) elif operation == "delete": # Search for the object match = find_rule(rules, new_rule) if match is None: module.fail_json( msg='Rule \'%s\' not found. Is the name correct?' % rule_name) try: new_rule.delete() except PanDeviceError as e: module.fail_json(msg='Failed "delete" delete: {0}'.format(e)) else: changed = True elif operation == "add": # Look for required parameters if not source_zone or not destination_zone or not nat_type: module.fail_json( msg= 'Missing parameter. Required: source_zone, destination_zone, nat_type' ) # Search for the rule. Fail if found. match = find_rule(rules, new_rule) if match: module.fail_json( msg= 'Rule \'%s\' already exists. Use operation: \'update\' to change it.' % rule_name) try: new_rule.create() except PanDeviceError as e: module.fail_json(msg='Failed "add" create: {0}'.format(e)) else: changed = True do_move = True elif operation == 'update': # Search for the rule. Update if found. match = find_rule(rulebase, rule_name) if not match: module.fail_json( msg= 'Rule \'%s\' does not exist. Use operation: \'add\' to add it.' % rule_name) try: new_rule.apply() except PanDeviceError as e: module.fail_json(msg='Failed "update" apply: {0}'.format(e)) else: changed = True do_move = True elif operation == 'disable': # Search for the rule, disable if found. match = find_rule(rules, new_rule) if not match: module.fail_json(msg='Rule \'%s\' does not exist.' % rule_name) if not match.disabled: match.disabled = True try: match.update('disabled') except PanDeviceError as e: module.fail_json(msg='Failed "disabled": {0}'.format(e)) else: changed = True # Optional move. if do_move: try: new_rule.move(location, existing_rule) except PanDeviceError as e: if '{0}'.format(e) not in ACCEPTABLE_MOVE_ERRORS: module.fail_json(msg='Failed move: {0}'.format(e)) else: changed = True # Optional commit. if changed and commit: try: con.commit(sync=True) except PanDeviceError as e: module.fail_json(msg='Failed commit: {0}'.format(e)) module.exit_json(changed=changed, msg='Done')
def main(): argument_spec = dict(ip_address=dict(required=True), password=dict(no_log=True), username=dict(default='admin'), api_key=dict(no_log=True), zone=dict(required=True), mode=dict(choices=[ 'tap', 'virtual-wire', 'layer2', 'layer3', 'external' ], default='layer3'), interface=dict(type='list'), zone_profile=dict(), log_setting=dict(), enable_userid=dict(type='bool', default=False), include_acl=dict(type='list'), exclude_acl=dict(type='list'), vsys=dict(default='vsys1'), template=dict(), state=dict(choices=['present', 'absent'], default='present')) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') # Get the firewall / panorama auth. auth = ( module.params['ip_address'], module.params['username'], module.params['password'], module.params['api_key'], ) # Set the Zone object params zone_spec = { 'name': module.params['zone'], 'mode': module.params['mode'], 'interface': module.params['interface'], 'zone_profile': module.params['zone_profile'], 'log_setting': module.params['log_setting'], 'enable_user_identification': module.params['enable_userid'], 'include_acl': module.params['include_acl'], 'exclude_acl': module.params['exclude_acl'] } # Get other info vsys = module.params['vsys'] template = module.params['template'] state = module.params['state'] # Open the connection to the PAN-OS device device = None try: device = PanDevice.create_from_device(*auth) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Set the attachment point for the Zone object parent = None if isinstance(device, Firewall): parent = device elif isinstance(device, Panorama): if template is not None: template_list = Template.refreshall(device) parent = get_template(template, template_list) if parent is None: module.fail_json( msg='Template not found: {0}'.format(template)) else: module.fail_json( msg= 'A template parameter is required when device type is Panorama' ) if vsys is not None: v = Vsys(vsys) parent.add(v) parent = v # Retrieve the current list of zones try: zones = Zone.refreshall(parent) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Build the zone and attach to the parent new_zone = Zone(**zone_spec) parent.add(new_zone) # Which action shall we take on the Zone object? changed = False if state == 'present': match = find_zone(zones, new_zone) if match: # Change an existing zone if not match.equal(new_zone): try: if not module.check_mode: new_zone.create() except PanDeviceError as e: module.fail_json( msg='Failed "present" create: {0}'.format(e)) else: changed = True else: # Add a new zone try: if not module.check_mode: new_zone.apply() except PanDeviceError as e: module.fail_json(msg='Failed "present" apply: {0}'.format(e)) else: changed = True elif state == 'absent': match = find_zone(zones, new_zone) if match: # Delete an existing zone try: if not module.check_mode: new_zone.delete() except PanDeviceError as e: module.fail_json(msg='Failed "absent" delete: {0}'.format(e)) else: changed = True # Done! module.exit_json(changed=changed, msg='Done')
def get_pandevice_parent(self, module, timeout=0): """Builds the pandevice object tree, returning the parent object. If pandevice is not installed, then module.fail_json() will be invoked. Arguments: * module(AnsibleModule): the ansible module. * timeout(int): Number of seconds to retry opening the connection to PAN-OS. Returns: * The parent pandevice object based on the spec given to get_connection(). """ # Sanity check. if not HAS_PANDEVICE: module.fail_json(msg='Missing required library "pandevice".') # Verify pandevice minimum version. if self.min_pandevice_version is not None: pdv = tuple(int(x) for x in pandevice.__version__.split('.')) if pdv < self.min_pandevice_version: module.fail_json(msg=_MIN_VERSION_ERROR.format( 'pandevice', pandevice.__version__, _vstr(self.min_pandevice_version))) pan_device_auth, serial_number = None, None if module.params['provider'] and module.params['provider'][ 'ip_address']: pan_device_auth = ( module.params['provider']['ip_address'], module.params['provider']['username'], module.params['provider']['password'], module.params['provider']['api_key'], module.params['provider']['port'], ) serial_number = module.params['provider']['serial_number'] elif module.params.get('ip_address', None) is not None: pan_device_auth = ( module.params['ip_address'], module.params['username'], module.params['password'], module.params['api_key'], module.params['port'], ) msg = 'Classic provider params are deprecated; use "provider" instead' module.deprecate(msg, '2.12') else: module.fail_json(msg='Provider params are required.') # Create the connection object. if not isinstance(timeout, int): raise ValueError('Timeout must be an int') elif timeout < 0: raise ValueError('Timeout must greater than or equal to 0') end_time = time.time() + timeout while True: try: self.device = PanDevice.create_from_device(*pan_device_auth) except PanDeviceError as e: if timeout == 0: module.fail_json(msg='Failed connection: {0}'.format(e)) elif time.time() >= end_time: module.fail_json(msg='Connection timeout: {0}'.format(e)) else: break # Verify PAN-OS minimum version. if self.min_panos_version is not None: if self.device._version_info < self.min_panos_version: module.fail_json(msg=_MIN_VERSION_ERROR.format( 'PAN-OS', _vstr(self.device._version_info), _vstr(self.min_panos_version))) # Optional: Firewall via Panorama connectivity specified. if hasattr(self.device, 'refresh_devices') and serial_number: fw = Firewall(serial=serial_number) self.device.add(fw) self.device = fw parent = self.device no_shared = 'Scope "shared" is not allowed' not_found = '{0} "{1}" is not present.' pano_mia_param = 'Param "{0}" is required for Panorama but not specified.' ts_error = 'Specify either the template or the template stack{0}.' if hasattr(self.device, 'refresh_devices'): # Panorama connection. templated = False # Error if Panorama is not supported. if self.panorama_error is not None: module.fail_json(msg=self.panorama_error) # Spec: template stack. tmpl_required = False added_template = False if self.template_stack is not None: name = module.params[self.template_stack] if name is not None: templated = True stacks = TemplateStack.refreshall(parent, name_only=True) for ts in stacks: if ts.name == name: parent = ts added_template = True break else: module.fail_json(msg=not_found.format( 'Template stack', name, )) elif self.template is not None: tmpl_required = True else: module.fail_json( msg=pano_mia_param.format(self.template_stack)) # Spec: template. if self.template is not None: name = module.params[self.template] if name is not None: templated = True if added_template: module.fail_json(msg=ts_error.format(', not both')) templates = Template.refreshall(parent, name_only=True) for t in templates: if t.name == name: parent = t break else: module.fail_json(msg=not_found.format( 'Template', name, )) elif tmpl_required: module.fail_json(msg=ts_error.format('')) elif not added_template: module.fail_json(msg=pano_mia_param.format(self.template)) # Spec: vsys_dg or device_group. dg_name = self.vsys_dg or self.device_group if dg_name is not None: name = module.params[dg_name] if name not in (None, 'shared'): groups = DeviceGroup.refreshall(parent, name_only=True) for dg in groups: if dg.name == name: parent = dg break else: module.fail_json(msg=not_found.format( 'Device group', name, )) elif self.error_on_shared: module.fail_json(msg=no_shared) # Spec: vsys importable. vsys_name = self.vsys_importable or self.vsys or self.vsys_shared if dg_name is None and templated and vsys_name is not None: name = module.params[vsys_name] if name not in (None, 'shared'): vo = Vsys(name) parent.add(vo) parent = vo # Spec: rulebase. if self.rulebase is not None: if module.params[self.rulebase] in (None, 'pre-rulebase'): rb = PreRulebase() parent.add(rb) parent = rb elif module.params[self.rulebase] == 'rulebase': rb = Rulebase() parent.add(rb) parent = rb elif module.params[self.rulebase] == 'post-rulebase': rb = PostRulebase() parent.add(rb) parent = rb else: module.fail_json(msg=not_found.format( 'Rulebase', module.params[self.rulebase])) else: # Firewall connection. # Error if firewalls are not supported. if self.firewall_error is not None: module.fail_json(msg=self.firewall_error) # Spec: vsys or vsys_dg or vsys_importable. vsys_name = self.vsys_dg or self.vsys or self.vsys_importable or self.vsys_shared if vsys_name is not None: parent.vsys = module.params[vsys_name] if parent.vsys == 'shared' and self.error_on_shared: module.fail_json(msg=no_shared) # Spec: rulebase. if self.rulebase is not None: rb = Rulebase() parent.add(rb) parent = rb # Done. return parent
def main(): argument_spec = dict( ip_address=dict(required=True), password=dict(no_log=True), username=dict(default='admin'), api_key=dict(no_log=True), operation=dict(required=True, choices=['add', 'update', 'delete', 'find']), addressobject=dict(default=None), addressgroup=dict(default=None), serviceobject=dict(default=None), servicegroup=dict(default=None), address=dict(default=None), address_type=dict(default='ip-netmask', choices=['ip-netmask', 'ip-range', 'fqdn']), static_value=dict(type='list', default=None), dynamic_value=dict(default=None), protocol=dict(default=None, choices=['tcp', 'udp']), source_port=dict(default=None), destination_port=dict(default=None), services=dict(type='list', default=None), description=dict(default=None), tag_name=dict(default=None), color=dict(default=None, choices=[ 'red', 'green', 'blue', 'yellow', 'copper', 'orange', 'purple', 'gray', 'light green', 'cyan', 'light gray', 'blue gray', 'lime', 'black', 'gold', 'brown' ]), vsys=dict(default='vsys1'), devicegroup=dict(default=None), commit=dict(type='bool', default=False), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_one_of=[['api_key', 'password']], mutually_exclusive=[[ 'addressobject', 'addressgroup', 'serviceobject', 'servicegroup', 'tag_name' ]]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') ip_address = module.params["ip_address"] password = module.params["password"] username = module.params['username'] api_key = module.params['api_key'] operation = module.params['operation'] addressobject = module.params['addressobject'] addressgroup = module.params['addressgroup'] serviceobject = module.params['serviceobject'] servicegroup = module.params['servicegroup'] address = module.params['address'] address_type = module.params['address_type'] static_value = module.params['static_value'] dynamic_value = module.params['dynamic_value'] protocol = module.params['protocol'] source_port = module.params['source_port'] destination_port = module.params['destination_port'] services = module.params['services'] description = module.params['description'] tag_name = module.params['tag_name'] color = module.params['color'] vsys = module.params['vsys'] devicegroup = module.params['devicegroup'] commit = module.params['commit'] # Create the device with the appropriate pandevice type device = PanDevice.create_from_device(ip_address, username, password, api_key=api_key) # If Panorama, validate the devicegroup dev_group = None if hasattr(device, 'refresh_devices'): # Panorama: set the device group. if devicegroup == 'shared': # Device group of None is "shared" scope for Panorama. devicegroup = None if devicegroup is not None: dev_group = get_devicegroup(device, devicegroup) if dev_group: device.add(dev_group) else: module.fail_json( msg= '\'%s\' device group not found in Panorama. Is the name correct?' % devicegroup) else: # Firewall: set the targetted vsys. device.vsys = vsys # What type of object are we talking about? if addressobject: obj_name = addressobject obj_type = objects.AddressObject elif addressgroup: obj_name = addressgroup obj_type = objects.AddressGroup elif serviceobject: obj_name = serviceobject obj_type = objects.ServiceObject elif servicegroup: obj_name = servicegroup obj_type = objects.ServiceGroup elif tag_name: obj_name = tag_name obj_type = objects.Tag else: module.fail_json(msg='No object type defined!') # Which operation shall we perform on the object? msg = None if operation == "find": # Search for the object match = find_object(device, dev_group, obj_name, obj_type) # If found, format and return the result if match: match_dict = xmltodict.parse(match.element_str()) module.exit_json(stdout_lines=json.dumps(match_dict, indent=2), msg='Object matched') else: module.fail_json( msg='Object \'%s\' not found. Is the name correct?' % obj_name) elif operation == "delete": # Search for the object match = find_object(device, dev_group, obj_name, obj_type) # If found, delete it if match: try: match.delete() except PanXapiError: exc = get_exception() module.fail_json(msg=exc.message) msg = "Object '{0}' successfully deleted".format(obj_name) else: module.fail_json( msg='Object \'%s\' not found. Is the name correct?' % obj_name) elif operation == "add": # Search for the object. Fail if found. match = find_object(device, dev_group, obj_name, obj_type) if match: module.fail_json( msg= 'Object \'%s\' already exists. Use operation: \'update\' to change it.' % obj_name) else: try: new_object = create_object(addressobject=addressobject, addressgroup=addressgroup, serviceobject=serviceobject, servicegroup=servicegroup, address=address, address_type=address_type, static_value=static_value, dynamic_value=dynamic_value, protocol=protocol, source_port=source_port, destination_port=destination_port, services=services, description=description, tag_name=tag_name, color=color) changed = add_object(device, dev_group, new_object) except PanXapiError: exc = get_exception() module.fail_json(msg=exc.message) msg = "Object '{0}' successfully added".format(obj_name) elif operation == "update": # Search for the object. Update if found. match = find_object(device, dev_group, obj_name, obj_type) if match: try: new_object = create_object(addressobject=addressobject, addressgroup=addressgroup, serviceobject=serviceobject, servicegroup=servicegroup, address=address, address_type=address_type, static_value=static_value, dynamic_value=dynamic_value, protocol=protocol, source_port=source_port, destination_port=destination_port, services=services, description=description, tag_name=tag_name, color=color) changed = add_object(device, dev_group, new_object) except PanXapiError: exc = get_exception() module.fail_json(msg=exc.message) msg = "Object '{0}' successfully updated.".format(obj_name) else: module.fail_json( msg= 'Object \'%s\' does not exist. Use operation: \'add\' to add it.' % obj_name) # Optional: commit the change. if commit: try: device.commit(sync=True) except PanDeviceError as e: module.fail_json(msg='Failed to commit: {0}'.format(e)) # Done. module.exit_json(changed=True, msg=msg)