marksull / fmcapi Goto Github PK
View Code? Open in Web Editor NEWA Python package designed to help users of Cisco's FMC interface with its API.
License: BSD 3-Clause "New" or "Revised" License
A Python package designed to help users of Cisco's FMC interface with its API.
License: BSD 3-Clause "New" or "Revised" License
Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
I'm trying to create a script to export all the NAT rules into a CSV, but I can't quite get it working the way I want so wondering if you had a working example that you could share?
Describe the solution you'd like
A clear and concise description of what you want to happen.
Working Example would be great, or a few pointers?
Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.
I've looked around and at the module, but can only get a list of the NAT Policies so far not the actual NAT rules. I may be missing something obvious.
Additional context
Add any other context or screenshots about the feature request here.
A question if I may, is there any reason why the following to disable an existing ACP rule isn't working, please note I'm only put the relevant few lines below for brevity.
Disabling a rule fails:
acp = AccessControlPolicy(fmc=fmc1, name=policy)
acprule = ACPRule(fmc=fmc1, acp_name=acp.name)
acprule.enabled = False
response = acprule.put()
response returns None
Deleting a rule works just fine:
acp = AccessControlPolicy(fmc=fmc1, name=policy)
acprule = ACPRule(fmc=fmc1, acp_name=acp.name)
response = acprule.delete()
Many thanks in advance,
Andy
Looking for help in updating the Mission Statement and Goals for this project. I haven't updated them for a long time but I don't want to "push" any agenda on anyone helping with this project. So, I'd like to use this "issue" ticket to generate discussion on what we should do going forward.
https://github.com/daxm/fmcapi/blob/master/docs/MissionStatement%20and%20Goals.md
I tried setting fmc.logging_level = "WARNING" but it still prints all of the "INFO" messages?
Hello!
I can't find any documentation about using fmcapi to create NetworksGroups and add another Networkgroup to that
I would like to achieve the following:
Network group : -- test-nwgrp-all
and add two network groups test-nwgrp-01 and test-nwgrp-02 to above network group.
I know I can add named and unnamed network/hosts to the network group but Would it be possible to add another network group to network group.
Thanks for all your help
I've been poking around with this module for a couple of days now and one thing I can't determine is if you have the ability to post objects in bulk?
I.E. I need to post thousands of individual Hosts, and Networks objects and doing this 1 by 1 takes hour(s).
I skimmed through the few examples but didn't notice any bulk posts, I didn't notice any in the YouTube video either, and VS Code intellisense isn't pointing me to a solution.
Anyway, I love this module. Thank you for writing and maintaining it.
When creating a prefilter rule using a dictionary as the data source, only the rule name or id and action gets set. This is because the static variable ALLOWED_FOR_KWARGS is missing from the PreFilterRules class.
To Reproduce
Steps to reproduce the behavior:
Create a PrefilterPolicy object.
Create a PrefilterRule object by passing all of required rule elements as a dictionary, example:
rule_data = {
'name': 'pf_rule_example',
'action': 'FASTPATH',
'prefilter_id': 'pf_example',
'sourceNetworks': {
'literals': [],
'objects': [
{
'type': 'NetworkGroup',
'name': 'ng-example,
}
]
},
'destinationNetworks': {
'literals': [
{
'type': 'Network',
'value': '10.0.0.0/8'
}
],
'objects': []
},
'sourceZones': {
'objects': [
{
'type': 'SecurityZone',
'name': 'sz-example',
}
]
},
}
print(PreFilterRule(fmc, **rule_data).format_data())
The result shows that only the name and action gets set.
Expected behavior
Exactly the same behaviour as ACPRules, where the ALLOWED_FOR_KWARGS variable allows all of the relevant data from the dictionary to be set in the parse_kwargs method.
this one is not working for me
hq_acprule.destination_network(action='add', name='any-ipv4')
def main():
with fmcapi.FMC(host=host, username=username, password=password, autodeploy=autodeploy) as fmc1:
hq_acprule = fmcapi.ACPRule(fmc=fmc1,
acp_name='ACP Policy',
name='Permit HQ LAN6',
action='ALLOW',
enabled=True,
)
hq_acprule.source_zone(action='add', name='inside')
#hq_acprule.
hq_acprule.logEnd = True
hq_acprule.source_network(action='add', name='any-ipv4')
hq_acprule.post()
getting this error:
INFO:root:Requesting new tokens from https://10.122.109.122/api/fmc_platform/v1/auth/generatetoken.
INFO:root:Building base to URLs.
INFO:root:Collecting version information from FMC.
INFO:root:Populating vdbVersion, sruVersion, serverVersion, and geoVersion FMC instance variables.
INFO:root:Adjusting name "ACP Policy" to "ACP_Policy" due to containing invalid characters.
INFO:root:GET success. Object with name: "ACP_Policy" and id: "005056A4-7E46-0ed3-0000-025769803796" fetched from FMC.
INFO:root:GET success. Object with name: "inside" and id: "ecb6ea9a-972c-11e9-b754-3c4dafd54627" fetched from FMC.
INFO:root:Adding "inside" to sourceZones for this ACPRule.
INFO:root:GET query for object with no name or id set. Returning full list of these object types instead.
INFO:root:GET query for object with no name or id set. Returning full list of these object types instead.
INFO:root:GET query for object with no name or id set. Returning full list of these object types instead.
ERROR:root:Error in POST operation --> 404 Client Error: Not Found for url: https://10.122.109.122/api/fmc_config/v1/domain/e276abec-e0f2-11e3-8169-6d9ed49b625f/object/fqdns?expanded=true&limit=25
ERROR:root:json_response --> {'error': {'category': 'FRAMEWORK', 'messages': [{'description': 'Invalid URL'}], 'severity': 'ERROR'}}
INFO:root:Auto deploy changes set to False. Use the Deploy button in FMC to push changes to FTDs.
Traceback (most recent call last):
File "C:/Users/T470s/AppData/Local/Programs/Python/Python37/Lib/idlelib/testFMC.py", line 44, in
main()
File "C:/Users/T470s/AppData/Local/Programs/Python/Python37/Lib/idlelib/testFMC.py", line 25, in main
hq_acprule.source_network(action='add', name='any-ipv4')
File "C:\Users\T470s\AppData\Local\Programs\Python\Python37\lib\site-packages\fmcapi\api_objects\acprule.py", line 502, in source_network
fqdns_json = FQDNS(fmc=self.fmc).get()
File "C:\Users\T470s\AppData\Local\Programs\Python\Python37\lib\site-packages\fmcapi\api_objects\apiclasstemplate.py", line 149, in get
if 'items' not in response:
TypeError: argument of type 'NoneType' is not iterable
Hi,
Is there any way to create categories in Access Policies?
Thanks,
Do you have any overrides support? I did a repo search for "overrid" and found nothing so I am guessing there is no support for it. Can you confirm if you do or do not?
TIA.
Describe the solution you'd like
Support for overrides for anything that supports override. Typical usage would be for host, network, range, fqdn, network groups, ports, and port groups when you want to use the same object name in the ACP but have the value change based on the sensor for which the ACP/object/etc is deployed to.
Describe alternatives you've considered
other than manually doing it or writing my own code no options. :(
Additional context
n/a
Hello,
I have created the Category under the ACP and trying to add the rule in that category. Not sure if this feature is supported or not
I am using below to pass the category information
acprule1 = fmcapi.AccessRules(fmc=fmc1, acp_name=namer,catagory = 'testing')
but I see in debug "section":"Default","category":"--Undefined--".
Just wondering if anyone was able to post/put rules under the category?
Thanks for your help.
INFO:root:Adjusting name 'ACP Policy' to 'ACP_Policy' due to invalid characters.
WARNING:root: GET query for ACP_Policy is not found.
WARNING:root: GET query for ACP_Policy is not found.
WARNING:root:Access Control Policy ACP_Policy not found. Cannot set up accessPolicy for AccessRules.
Wondering if there is a solution to this message. I've saw some reference to a previous issue but it didn't show a solution.
Thanks
Receiving error when attempting to add a file policy to an access rule. "'FilePolicies' object has no attribute 'type'"
I believe the issue is in the fmcapi/api_objects/policy_services/filepolicies.py file. FilePolicies are added in a very similar manner to IntrustionPolicies in that they require a type. I believe we need to update the file to use VALID_JSON_DATA = ["id", "name", "type"] just like in fmcapi/api_objects/policy_services/intrusionpolicies.py.
Are you able to test the ability to add a filepolicy to an access policy rule?
2020-09-30 20:59:13.973
GET success. Object with name: "File-Block-Policy" and id: "<policy_id>" fetched from FMC.
Information
2020-09-30 20:59:13.973
Waiting 15 seconds to allow the FMC to update the list of deployable devices.
Information
2020-09-30 20:59:28.989
Getting a list of deployable devices.
Information
2020-09-30 20:59:29.844
No devices need deployed.
Information
2020-09-30 20:59:29.845
'FilePolicies' object has no attribute 'type'
Are there any plans to use the 6.4 features to be able to get ACP rule hit counts?
Dax,
There is one suggestion for improvement I need to flag: in my case I am using your package to get Access Rules for optimization from a really busy box (23K Access Rules in a policy - this is the reason for a need to opimize).
Python/FMC/whatever just cannot handle retrieval of such a big list via .get (times out, FMC resets, etc), so I need to use ? filters in my request, for example:
https:///api/fmc_config/v1/domain//policy/accesspolicies/00A6CAE6-686A-0ed3-0000-313532636857/accessrules?limit=10
But your generic .get function, if it does not see ID or name, is using the following constuct:
url = '{}?expanded=true'.format(self.URL)
response = self.fmc.send_to_api(method='get', url=url)
So it is adding this ? and does not allow me to use filters unless I change package itself (which I did).
How about changing this function so we could add arbitrary filters/parameters to get? That will mean that this needs to be changed so it could check for a trailing ? in an self.URL and add, if needed, otherwise add &.
Thank you!
Amir
Hello Guys,
First of all, thanks for this
It will be really great to have the ability to add port literals for Access Rules just like we can with source and destination networks. Having to create port objects for access rules has left us with a lot of duplicated port objects.
Thanks.
Hello!
I can't find any documentation about using fmcapi to create NetworksGroups with 2 literal Networks.
I would like to achieve the following:
Now there is a way to create single object Network for 7.7.7.0/29 and single object Network for 8.8.8.0/29 and сombine them in one group. It is not very convenient and flexible.
When invalid credentials are used, exception rise
DEBUG:urllib3.connectionpool:https://fmcrestapisandbox.cisco.com:443 "POST /api/fmc_platform/v1/auth/generatetoken HTTP/1.1" 401 None
DEBUG:root:Response from generatetoken() post:
url: https://fmcrestapisandbox.cisco.com/api/fmc_platform/v1/auth/generatetoken
headers: {'Content-Type': 'application/json'}
response: <Response [401]>
Traceback (most recent call last):
File "ip_to_networkgroups.py", line 114, in
main(function, ip_address, network_group)
File "ip_to_networkgroups.py", line 30, in main
autodeploy=False) as fmc:
File "/usr/local/lib/python3.6/dist-packages/fmcapi/fmc.py", line 130, in enter
verify_cert=self.VERIFY_CERT,
File "/usr/local/lib/python3.6/dist-packages/fmcapi/fmc.py", line 398, in init
self.generate_tokens()
File "/usr/local/lib/python3.6/dist-packages/fmcapi/fmc.py", line 453, in generate_tokens
all_domain = json.loads(response.headers.get("DOMAINS"))
File "/usr/lib/python3.6/json/init.py", line 348, in loads
'not {!r}'.format(s.class.name))
TypeError: the JSON object must be str, bytes or bytearray, not 'NoneType'
A very small change to api_objects.py:
def get(self, **kwargs):
"""
If no self.name or self.id exists then return a full listing of all objects of this type.
Otherwise set "expanded=true" results for this specific object.
:return:
"""
logging.debug("In get() for APIClassTemplate class.")
self.parse_kwargs(**kwargs)
if 'id' in self.__dict__:
url = '{}/{}'.format(self.URL, self.id)
response = self.fmc.send_to_api(method='get', url=url)
self.parse_kwargs(**response)
logging.info('GET success. Object with name: "{}" and id: "{}" fetched from'
' FMC.'.format(self.name, self.id))
return response
elif 'name' in self.__dict__:
if self.FILTER_BY_NAME:
url = '{}?name={}&expanded=true'.format(self.URL, self.name)
else:
url = '{}?expanded=true'.format(self.URL)
response = self.fmc.send_to_api(method='get', url=url)
for item in response['items']:
if 'name' in item:
if item['name'] == self.name:
self.id = item['id']
self.parse_kwargs(**item)
logging.info('GET success. Object with name: "{}" and id: "{}" fetched from'
' FMC.'.format(self.name, self.id))
return item
else:
logging.warning('No "name" attribute associated with '
'this item to check against {}.'.format(self.name))
if 'id' not in self.__dict__:
logging.warning("\tGET query for {} is not found.\n\t\t"
"Response: {}".format(self.name, json.dumps(response)))
return response
else:
logging.info("GET query for object with no name or id set. Returning full list of these object types "
"instead.")
url = '{}?expanded=true&limit=1000'.format(self.URL)
response = self.fmc.send_to_api(method='get', url=url)
return response
The addition of &limit=1000 to the URL returns 1000 objects rather than the default of 25 which significantly increases the speed when dealing with a large policy (url = '{}?expanded=true&limit=1000'.format(self.URL)).
This small change resulted the example I'm working on taking a few mins rather than an hour+
I didn't create a pull request as you may want have this as a variable passed to get rather than hardcoded.
Thanks for this amazing work, this package helps me lot.
I am struggling with searching for the host or network using the name ( for example : test (object name) and returning the expanded details ( like Name, value, description and id)
I tried to pass the expanded = True but no luck.
It only output below information
INFO:root:GET success. Object with name: "test" and id: "0050569D-669F-0ed3-0000-146028913744" fetched from FMC.
Appreciate any guidance
Thanks
In api_objects.py for class ACPRule(APIClassTemplate): there is a following function
def destination_port(self, action, name='')
it iterated through the self.destinationPorts['objects']
However, function is giving a traceback where there is an existing rule with a literal present, but no objects - this can happen if a rule, say, has only icmp object (which is a literal), but no TCP/UDP-based ones. Function does not account for such condition.
Quick fix for me was to create "objects" key if it does not exist:
def destination_port(self, action, name=''):
logging.debug("In destination_port() for ACPRule class.")
if action == 'add':
pport_json = ProtocolPort(fmc=self.fmc)
pport_json.get(name=name)
if 'id' in pport_json.__dict__:
item = pport_json
else:
item = PortObjectGroup(fmc=self.fmc)
item.get(name=name)
if 'id' in item.__dict__:
if 'destinationPorts' in self.__dict__:
new_port = {'name': item.name, 'id': item.id, 'type': item.type}
duplicate = False
logging.debug(self.destinationPorts)
**if not 'objects' in self.destinationPorts:
self.__dict__['destinationPorts']['objects']=[]**
for obj in self.destinationPorts['objects']:
if obj['name'] == new_port['name']:
duplicate = True
break
if not duplicate:
self.destinationPorts['objects'].append(new_port)
logging.info('Adding "{}" to destinationPorts for this ACPRule.'.format(name))
else:
self.destinationPorts = {'objects': [{'name': item.name, 'id': item.id, 'type': item.type}]}
logging.info('Adding "{}" to destinationPorts for this ACPRule.'.format(name))
else:
logging.warning('Protocol Port or Protocol Port Group: "{}", not found. Cannot add to ACPRule.'.format(name))
I am not completely sure if this is the cleanest fix though.
Hello
I am trying to post/put the access rule to add the application ( eg. Facebook) instead of ports based rule.
I checked the unit test script and don't see the option for the application.
Would it be possible to add the access rule to reference the application instead of the destination port?
Thanks for your help
The error:
File "/Users/marksull/Development/Python/fmcapi/fmcapi/api_objects.py", line 173, in delete
self.parse_kwargs(**response)
TypeError: parse_kwargs() argument after ** must be a mapping, not NoneType
Caused by fmcapi.fmc.send_to_api
returning a None on the exception:
except requests.exceptions.HTTPError as err:
logging.error("Error in POST operation --> {}".format(str(err)))
logging.error("json_response -->\t{}".format(json_response))
if response:
response.close()
return None
But then fmcapi.api_objects.delete()
trying to expand the None in the response.
self.parse_kwargs(**response)
adding bulk function to the code so we can send many rules with one payload
Is your feature request related to a problem? Please describe.
I have a script to add hosts to the group. The script login, get the group, search in the response if the object is already in the group, if not add, if yes skip, finally verify. This involves several get/post/get operations.
While executing the script, if another user tries to execute the script again, it will invalidate the first user token, and the first script will lock in an endless loop until the refresh timer.
Describe the solution you'd like
If there was a successful first login, then wait a few seconds and try to log in again.
IPHost Is currently using the super default of APIClassTemplate.REQUIRED_FOR_PUT which is ['id'] but should be set to:
class IPHost(APIClassTemplate):
REQUIRED_FOR_PUT = ['id', 'name', 'value']
[**Is](url
categories.zip
)
I made a script for the creation of category in the access policy, however being beginning in python, could check if everything is good (and publish if you want)
Check with FMC 6.6 and 6.5
Best regards
I am attempting to use the fmcapi to audit an FMC environment, specifically a way to programmatically output access control policy data in to a document. Is this a feasible use case and if so could you provide a code snippet to help me along?
I have an interesting problem and I can't figure out if it's related to this module or not...I think it is...
I'm TRYING to install this module on a server that doesn't have internet access, so I ran:
pip download fmcapi -d c:\temp\fmcapi
I then transferred that folder over to the server containing the following files:
certifi-2020.6.20-py2.py3-none-any.whl
chardet-3.0.4-py2.py3-none-any.whl
DateTime-4.3-py2.py3-none-any.whl
fmcapi-20200615.0-py3-none-any.whl
idna-2.10-py2.py3-none-any.whl
ipaddress-1.0.23-py2.py3-none-any.whl
pytz-2020.1-py2.py3-none-any.whl
requests-2.24.0-py2.py3-none-any.whl
setuptools-49.2.0-py3-none-any.whl
urllib3-1.25.9-py2.py3-none-any.whl
zope.interface-5.1.0-cp38-cp38-win_amd64.whl
I then attempt to install it:
pip install --user fmcapi-20200615.0-py3-none-any.whl -f ./ --no-index
The error I get is:
Could not find a version that satisfies the requirement zope.interface (from datetime->fmcapi==20200615.0) (from version: )
No matching distribution found for zope.interface (from datetime->fmcapi==20200615.0)
The part that trips me up is a) This process works perfectly fine installing OTHER modules, e.g. requests
, tqdm
, etc. and b) the "from version:" is blank...so I'm not even sure what it's looking for here...
Hi all,
We are using FMCAPI to migrate from Checkpoint firewall, which involved bulk addition of objects to a given rule. The nature of FMCAPI is that when you "add" a destination/source network, it iterates through all FMC objects via /networkaddresses , which is quite expensive for a busy FMC with a lot of objects (but is fine). More severe issue is with token refresh -I've included a code to get token refreshed before I call something via FMCAPI , but in case of "add" operation, there are multiple GETs which you cannot control (paginated retrieval), so you get 401 errors in the middle of pagination.
Proposed fix which I have implemented on my local copy - adding a check for 401 error and refreshing token/repeating afterwards:
def send_to_api(self, method='', url='', headers='', json_data=None, more_items=[]):
---snip---
try:
while status_code == 429:
if method == 'get':
response = requests.get(url, headers=headers, verify=self.VERIFY_CERT)
elif method == 'post':
response = requests.post(url, json=json_data, headers=headers, verify=self.VERIFY_CERT)
elif method == 'put':
response = requests.put(url, json=json_data, headers=headers, verify=self.VERIFY_CERT)
elif method == 'delete':
response = requests.delete(url, headers=headers, verify=self.VERIFY_CERT)
else:
logging.error("No request method given. Returning nothing.")
return
status_code = response.status_code
if status_code == 429:
logging.warning("Too many connections to the FMC. Waiting 30 seconds and trying again.")
time.sleep(30)
if status_code == 401:
logging.warning("Token has expired. Trying to refresh.")
self.mytoken.access_token=self.mytoken.get_token()
headers = {'Content-Type': 'application/json', 'X-auth-access-token': self.mytoken.access_token}
status_code = 429
json_response = json.loads(response.text)
if status_code > 301 or 'error' in json_response:
response.raise_for_status()
Regards, Amir
Is your feature request related to a problem? Please describe.
Unable to add Manual NAT rules "after_auto" defaults to "before_auto"
We are migrating from ASA to FTD and wanted to keep the rule structure the same.
I was able to modify the manualnatrules.py by adding codes related to "section" from the accessrules.py script
I'm not a programmer so it was a lot of trial and error but it finally worked.
Just wondering if you could make that official.
Thanks, your work has been indispensable for me in building scripts for our network team and as I mentioned, I'm not a programmer, having examples is what really made the difference from other tools.
Currently ACPRule class can take in ACP name, and can list all the rules in that ACP
In this process it maps the ACP name to an ACP id first.
This issue is opened to support an ACP ID as input and get the ACP rules directly surpassing the name to ID mapping
Is your feature request related to a problem? Please describe.
I can't fine any documentation about using fmcapi to modify existing objects. I am trying to modify a network group object to add more ip addresses to it. I would also like to modify existing rules to add destination ports or destination addresses
Describe the solution you'd like
I would like update documentation with some examples of modifying objects.
I've got an HA pair and I'm trying to create a bunch of etherchannel subinterfaces. It seems that I can create them on physical interfaces.
Hi,
I am having trouble with using the acprule put operation to add src/dst and network/host. I am using below script
acprule1.name = namer
acprule1.action = "ALLOW"
acprule1.enabled = False
acprule1.sendEventsToFMC = True
acprule1.logFiles = False
acprule1.logBegin = True
acprule1.logEnd = True
acprule1.source_zone(action="add", name='inside')
acprule1.destination_zone(action="add", name='outside')
acprule1.source_network(action="add", name='test01')
acprule1.destination_network(action="add", name='test02')
acprule1.get()
acprule1.put()
I am not getting error message but the rules doesn't get updated.
INFO:root:GET success. Object with name: "Test_Firewall-Policy" and id: "0050569D-669F-0ed3-0000-146028892" fetched from FMC.
INFO:root:GET success. Object with name: "inside" and id: "7b0035c4-4f4a-11ea-9876-a67125a5a" fetched from FMC.
INFO:root:Adding "inside" to sourceZones for this AccessRules.
INFO:root:GET success. Object with name: "outside" and id: "641c654e-4f4a-11ea-a9d3-d4e4358b1" fetched from FMC.
INFO:root:Adding "outside" to destinationZones for this AccessRules.
INFO:root:Adding "test01" to sourceNetworks for this AccessRules.
INFO:root:Adding "test02" to destinationNetworks for this AccessRules.
INFO:root:GET success. Object with name: "test-rule-012" and id: "0050569D-669F-0ed3-0000-000443653" fetched from FMC.
INFO:root:PUT success. Object with name: "test-rule-012" and id: "0050569D-669F-0ed3-0000-08443653" updated in FMC.
INFO:root:Test ACPRule done.
Appreciate any help
Thanks
Good day,
I'm very newbie with python scripting. I am trying to use the FMC API to create a rule which I do succeed in. The problem I encounter is that I am trying to activate the "Log at Begining" and 'Log at End" checkbox in the rule but I cannot seem to get it working. At first I was creating the rule and it was disabled but I did manage to have it enabled. I first tried to do something like acpRule.enabled = True but it didn't work. Reading some other issues I managed to find that it actually didn't work anymore so someone suggested passing the boolean as a parameter of the put() function so I did acpRule.put(enabled=True) and that got my rule enabled. I'm trying to do the same with the logBegin and logEnd but whatever I try it doesn't seem to work. Here is a sample of my code. Note that I am doing an Excel file input for the variables because eventually I want to be able to bulk import rules.
with FMC(host=host, username=username, password=password, autodeploy=autodeploy) as fmc1:
wb = xl.load_workbook('rules.xlsx')
acpRule = AccessRules(fmc=fmc1, acp_name='My-ACP-Rule')
rule_sheet = wb['RulesCreation']
for row in range(2, rule_sheet.max_row + 1):
rule = setRuleVar()
acpRule.name = rule['name']
acpRule.action = rule['action']
acpRule.source_zone(action='add', name=rule['srcZone'])
acpRule.source_network(action='add', name=rule['srcNetwork'])
acpRule.source_port(action='add', name=rule['srcPort'])
acpRule.destination_zone(action='add', name=rule['destZone'])
acpRule.destination_network(action='add', name=rule['destNetwork'])
acpRule.destination_port(action='add', name=rule['destPort'])
acpRule.variable_set(action='set', name=rule['varSet'])
acpRule.intrusion_policy(action='set', name=rule['intruPol'])
acpRule.vlan_tags(action='add', name=rule['VlanTag'])
acpRule.post()
acpRule.get()
acpRule.put(enabled=True)
acpRule.put(logBegin=True)
acpRule.put(logEnd=True)
This is the error message I get when trying to run this script. Note it fails at the logBegin=True
Traceback (most recent call last):
File "C:/Users/MyUsername/PycharmProjects/FMC-API/CreateRules.py", line 71, in
acpRule.put(logBegin=True)
File "C:\Users\MyUsername\PycharmProjects\FMC-API\venv\lib\site-packages\fmcapi\api_objects\apiclasstemplate.py", line 306, in put
self.parse_kwargs(**response)
TypeError: parse_kwargs() argument after ** must be a mapping, not NoneType
I tried to do some acpRule.get() in between the put() but I still get the same behaviour. I don't understand why the enabled Boolean works and not the other ones.
def destination_intf(self,name):
logging.debug("In destination_intf() for ManualNatRules class.")
intf_obj = InterfaceObject(fmc=self.fmc).get()
items = intf_obj.get('items', [])
new_intf = None
for item in items:
if item["name"] == name:
new_intf = {'id': item['id'], 'type': item['type']}
break
if new_intf == None:
logging.warning('Interface Object "{}" is not found in FMC. Cannot add to destinationInterface.'.format(name))
else:
if new_intf.type == "InterfaceGroup" and len(new_intf.items) > 1:
--> self.destinationInterface = new_intf <-- missing indentation
logging.info('Interface Object "{}" added to NAT Policy.'.format(name))
Hello,
Is there a way to add an URL to an ACPRule?
Regards,
Gabor
Hello,
I love the project. I had a flawless working version from 2019 but recently upgraded to the latest. I found errors when doing a check of the package. The issue is related to the f string 3.6 feature you are now using for message formating. https://docs.python.org/3/whatsnew/3.6.html#pep-498-formatted-string-literals
Simple solution is to go to 3.6 but this server I am on I am not allowed to upgrade it.
I ran checks using: sudo python3 -m py_compile /usr/lib/python3.4/site-packages/fmcapi/fmc.py
I get errors back like:
File "/usr/lib/python3.4/site-packages/fmcapi/api_objects/policy_services/accesspolicies.py", line 35
f"action, {action}, is not a valid option. Choose from {self.DEFAULT_ACTION_OPTIONS}."
Solution: If I go through all the package files and remove the f" or f' then I no longer have issues. I might be able to append .format() to each line.
It might be good to have a check/warning about python version.
I'm trying to edit existing rules through the API. More specifically all I want to change is switching source and destination zone. I obtain them in following lines:
`acprule = ACPRule(fmc=fmc1, acp_name=acpname)
acprule.name = rule['name'] #rule has been obtained from a send_to_api function obtaining all policies in the ACP
acprule.id = rule['id']
acprule.get()
acprule.sendEventsToFMC = True
acprule.logBegin = True
acprule.intrusion_policy(action='set', name='IPS-Balanced')
acprule.source_zone(action='clear')
acprule.destination_zone(action='add', name=src_zone)
print(acprule.format_data())
acprule.put()`
The rule gets obtained just fine with all metadata in the get function. Printing the format_data also lists that all information from the obtained rule is still there, plus the changes made to the rule. However, when I then try to put the changes to the API, the format_data function called in the API changes "ALLOW" to "BLOCK". Even if I manually set the action to allow before calling the put function.
Do you have any idea how the action-attribute gets lost the moment I call the put function? I'm still quite new to python, but have some experience in programming ... so I'm not sure if it's actually the fmcapi-module or not causing this.
The output of formate_data looks like this:
Before put:
{'id': 'acp_id', 'name': 'ACL_1', 'action': 'ALLOW', 'enabled': True, 'sendEventsToFMC': True, 'logFiles': False, 'logBegin': True, 'logEnd': False, 'variableSet': {'name': 'Default-Set', 'id': 'set_id', 'type': 'VariableSet'}, 'type': 'AccessRule', 'vlanTags': {}, 'sourceNetworks': {'objects': [{'type': 'NetworkGroup', 'name': 'my_group', 'id': 'group_id'}]}, 'destinationNetworks': {'objects': [{'type': 'NetworkGroup', 'name': 'any', 'id': 'group_id'}]}, 'destinationPorts': {'objects': [{'type': 'ProtocolPortObject', 'protocol': 'UDP', 'name': 'my_port', 'id': 'port_id'}, {'type': 'ProtocolPortObject', 'protocol': 'TCP', 'name': 'my_port2', 'id': 'port_id2'}]}, 'ipsPolicy': {'name': 'IPS-Balanced', 'id': 'ips_id', 'type': 'intrusionpolicy'}, 'destinationZones': {'objects': [{'name': 'INTERNET', 'id': 'zone_id', 'type': 'SecurityZone'}]}}
After put:
{'id': 'acp_id', 'name': 'ACL_1', 'action': 'BLOCK', 'enabled': True, 'sendEventsToFMC': True, 'logFiles': False, 'logBegin': False, 'logEnd': False, 'variableSet': {'name': 'Default-Set', 'id': 'set_id', 'type': 'VariableSet'}, 'type': 'AccessRule', 'vlanTags': {}, 'sourceNetworks': {'objects': [{'type': 'NetworkGroup', 'name': 'my_group', 'id': 'group_id'}]}, 'destinationNetworks': {'objects': [{'type': 'NetworkGroup', 'name': 'any', 'id': 'group_id'}]}, 'destinationPorts': {'objects': [{'type': 'ProtocolPortObject', 'protocol': 'UDP', 'name': 'my_port', 'id': 'port_id'}, {'type': 'ProtocolPortObject', 'protocol': 'TCP', 'name': 'my_port2', 'id': 'port_id2'}]}, 'ipsPolicy': {'name': 'IPS-Balanced', 'id': 'ips_id', 'type': 'intrusionpolicy'}, 'destinationZones': {'objects': [{'name': 'INTERNET', 'id': 'zone_id', 'type': 'SecurityZone'}]}}
I would like the ability to easily add/append "comments" to the access rules for each rule change. If this functionality is available, I'm not sure how to use it at the moment.
https://github.com/daxm/fmcapi/blob/master/fmcapi/api_objects/policy_services/accessrules.py
When I batch add 200 network objects, it takes almost 10 minutes!That's not acceptable
I successfully created literals in the networkobjectgroups but that option is missing in portobjectgroups. I see a comment "Technically you can have objects OR literals" but there is no "unnamed" section. I'm just not sure if you can have literals in the portobjectgroup or you just haven't got around to coding it yet.
Thanks
When creating a rule, and trying to enable default syslog, the accessrule class is rejecting the enablesyslog bool. I made sure it was a valid json entry by comparing two rules with and without syslog enabled.
I made my code work by modifying the accessrules.py manually. I added the enableSyslog value in the VALID_JSON_DATA.
Is there another way to enable that syslog? If not, please add it to the master branch.
Thanks
Would it be possible to add an action "addgroup" to the Policy Services -> Access Rules for both destination_port
and source_port
?
Similar to what was done in #6 ?
Right now it's just:
if action == "add":
pport_json = ProtocolPortObjects(fmc=self.fmc)
pport_json.get(name=name)
if "id" in pport_json.__dict__:
item = pport_json
else:
item = PortObjectGroups(fmc=self.fmc)
item.get(name=name)
The reason I ask is because I already know if the Port i'm trying to add is a Port or a Port Group, but I have no way to say "this is a group" to avoid doing double API calls. I could speed up my processing significantly by just filtering the objects locally.
Also whenever the ProtocolPortObjects
isn't found (because it's a PortObjectGroups
), it spits out every single ProtocolPortObjects
on the FMC...which just overwhelms the console with output. Any way to turn that off?
I don't think you'd have to break backward compatibility for this request...
Hi There,
I see it is possible to perform bulk creation directly via the FMC API
Is this supported on fmcapi?
I'm back to using fmcapi after many years, good to see its still being developed :)
We are migrating from one FMC to another and as its a "downgrade" we can't use the Cisco automated migration tool. The Cisco export/import for some code is good but there are some gaps that I am trying to use fmcapi to plug.
I have used fmcapi sucessfully to create a few new objects types - for example SecurityZones and Hosts, but for some reason Networks seems to fail. Looking at your mixed code example below I should be able to call Networks and pass a name and value as subnet/cidr. Essentially the same as Hosts.
hq_lan = fmcapi.Networks(fmc=fmc1, name="hq-lan", value="10.0.0.0/24")
hq_lan.post()
all_lans = fmcapi.Networks(fmc=fmc1, name="all-lans", value="10.0.0.0/8")
all_lans.post()
hq_fmc = fmcapi.Hosts(fmc=fmc1, name="hq_fmc", value="10.0.0.10")
hq_fmc.post()
fmc_public = fmcapi.Hosts(fmc=fmc1, name="fmc_public_ip", value="100.64.0.10")
fmc_public.post()
I have tried passing it exactly as per the example and receieve a lot of errors (below).
I am running the latest fmcapi and a newish version 3.10.1 of python.
FMC is version 6.6.1.
Any help appreiated, its probably 'user error' rather than a bug, but I wasn't sure how to get in touch to be honest.
Thanks, Paul Woolnough UK
Errors:
Logging is enabled and set to INFO. Look for file "fmcapi-import-log.txt" for output.
INFO:root:Requesting new tokens from https://servername/api/fmc_platform/v1/auth/generatetoken.
Traceback (most recent call last):
File "C:\Users\AppData\Local\Programs\Python\Python310-32\lib\site-packages\urllib3\connectionpool.py", line 449, in _make_request
six.raise_from(e, None)
File "", line 3, in raise_from
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\urllib3\connectionpool.py", line 444, in _make_request
httplib_response = conn.getresponse()
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\http\client.py", line 1374, in getresponse
response.begin()
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\http\client.py", line 318, in begin
version, status, reason = self._read_status()
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\http\client.py", line 279, in _read_status
line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\socket.py", line 705, in readinto
return self._sock.recv_into(b)
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\ssl.py", line 1273, in recv_into
return self.read(nbytes, buffer)
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\ssl.py", line 1129, in read
return self._sslobj.read(len, buffer)
TimeoutError: The read operation timed out
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\requests\adapters.py", line 440, in send
resp = conn.urlopen(
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\urllib3\connectionpool.py", line 785, in urlopen
retries = retries.increment(
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\urllib3\util\retry.py", line 550, in increment
raise six.reraise(type(error), error, _stacktrace)
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\urllib3\packages\six.py", line 770, in reraise
raise value
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\urllib3\connectionpool.py", line 703, in urlopen
httplib_response = self._make_request(
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\urllib3\connectionpool.py", line 451, in _make_request
self._raise_timeout(err=e, url=url, timeout_value=read_timeout)
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\urllib3\connectionpool.py", line 340, in _raise_timeout
raise ReadTimeoutError(
urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='servername', port=443): Read timed out. (read timeout=5)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\fmcexport\static-route-objects-export-import.py", line 244, in
with fmcapi.FMC(host=host, username=username, password=password, autodeploy=False, file_logging="fmcapi-import-log.txt") as fmc1:
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\fmcapi\fmc.py", line 127, in enter
self.mytoken = Token(
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\fmcapi\fmc.py", line 360, in init
self.generate_tokens()
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\fmcapi\fmc.py", line 401, in generate_tokens
response = requests.post(
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\requests\api.py", line 117, in post
return request('post', url, data=data, json=json, **kwargs)
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\requests\sessions.py", line 529, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\requests\sessions.py", line 645, in send
r = adapter.send(request, **kwargs)
File "C:\Users\myuser\AppData\Local\Programs\Python\Python310-32\lib\site-packages\requests\adapters.py", line 532, in send
raise ReadTimeout(e, request=request)
requests.exceptions.ReadTimeout: HTTPSConnectionPool(host='servername', port=443): Read timed out. (read timeout=5)
FMCAPI version:
pip3 install fmcapi
Requirement already satisfied: fmcapi in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (20211214.0)
Requirement already satisfied: requests in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from fmcapi) (2.27.1)
Requirement already satisfied: datetime in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from fmcapi) (4.3)
Requirement already satisfied: ipaddress in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from fmcapi) (1.0.23)
Requirement already satisfied: pytz in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from datetime->fmcapi) (2021.3)
Requirement already satisfied: zope.interface in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from datetime->fmcapi) (5.4.0)
Requirement already satisfied: charset-normalizer~=2.0.0 in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from requests->fmcapi) (2.0.10)
Requirement already satisfied: idna<4,>=2.5 in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from requests->fmcapi) (3.3)
Requirement already satisfied: certifi>=2017.4.17 in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from requests->fmcapi) (2021.10.8)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from requests->fmcapi) (1.26.8)
Requirement already satisfied: setuptools in c:\users\myuser\appdata\local\programs\python\python310-32\lib\site-packages (from zope.interface->datetime->fmcapi) (58.1.0)
Hi
I am using the put and post function to update the network group which works fine but was wondering if it would be possible to use the get function and just print all object name and value information?
I am using below commands:
nwgrp_name = input ('Enter NetworkGrp:- ')
nwgrp = fmcapi.NetworkGroups(fmc=fmc1,name=nwgrp_name)
nwgrp_output= nwgrp.get()
for object1 in nwgrp_output:
obj_name1 = object1['name']
print(obj_name1)
But getting message
Traceback (most recent call last):
File "C:/Personal/GitHub/fmcapi/scripts/remove-from-nwgrp.py", line 100, in
main()
File "C:/Personal/GitHub/fmcapi/scripts/remove-from-nwgrp.py", line 73, in main
name1 = object1['value']
TypeError: string indices must be integers
Appreciate any help
Thanks
I completely forgot to move/share the pypi "location" for fmcapi with you. We should get in contact and figure out how to do this. That said, I think that if I new your pypi user I could make you a co-owner easily enough.
Hi,
Thanks for the useful package helped me get some scripts that I needed to integration do some FMC automation. Anyway I wasn't able to add NetwortGroups into a NetworkGroup.. unless I missed that option. So I made a simple addition to the api_objects.py to allow this.
api_objects.py just after the if action == 'add'
if action == 'addgroup':
netg1 = NetworkGroup(fmc=self.fmc)
response = netg1.get()
if 'items' in response:
new_net = None
for item in response['items']:
if item['name'] == name:
new_net = {'name': item['name'], 'id': item['id'], 'type': item['type']}
break
if new_net is None:
logging.warning('Network "{}" is not found in FMC. Cannot add to Ne tworkGroup.'.format(name))
else:
if 'objects' in self.__dict__:
duplicate = False
for obj in self.objects:
if obj['name'] == new_net['name']:
duplicate = True
break
if not duplicate:
self.objects.append(new_net)
logging.info('Adding "{}" to NetworkGroup.'.format(name))
else:
self.objects = [new_net]
logging.info('Adding "{}" to NetworkGroup.'.format(name))
Thanks
Chris
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.