Code Monkey home page Code Monkey logo

fmcapi's People

Contributors

aegiacometti avatar amrithanagarajan avatar amrnagar avatar baaptm avatar chris-guthrie avatar cisco7507 avatar dalamanster avatar daxm avatar dependabot[bot] avatar jmattatall avatar jummo avatar kell4now avatar manofcolombia avatar marksull avatar marksullcisco avatar mcclem avatar msd101 avatar mysticryuujin avatar niconori avatar outlawww avatar parkerbrother1 avatar ravdup09 avatar rsp2k avatar shaktikshri avatar svalgaard avatar tejasvi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fmcapi's Issues

Docmentation: List All NAT Rules

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.

ACP rule disable

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

Adding network group to another network group

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

Bulk Posts?

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.

ALLOWED_FOR_KWARGS missing in policy_services.prefilterrules module

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.

access-control-policy for source and destination is not working

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

Support for overrides

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

adding acprule and using category

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.

Seeing this: INFO:root:Adjusting name "ACP Policy" to "ACP_Policy" due to containing invalid characters

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

"Type" error when calling FilePolicies for an access rule.

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'

APIClassTemplate(object) .get function issue

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

Add Destination/Source Ports literals to Access Rules

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.

Creating NetworkGroups

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.

Add an escape method/message for invalid credentials

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'

Increase the limit of returned items to 1000

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.

Host or network get operation not displaying expanded information

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

destinationPorts can contain both literals and objects

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.

Adding accessrule based on application instead of destination port

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

Issuing delete() on non-existent UUID results in traceback

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)

endless loop when 2 requests happens

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 REQUIRED_FOR_PUT needs to be updated

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']

Add categories in access policy

[**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

Audit documentation use case

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?

zope.interface version

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...

Timing/race condition with API Token refresh

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

"after_auto" Manual NAT rules

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.

ACPRule class support to search by acp_id

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

Documentation To Modify Existing objects

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.

acprule put() to add additional Zones and network/host not working

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

FMC ACP Rule Boolean Parameters

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.

Indentation error in api_objects.py

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))

Python3.4, pip3 install fmcapi -U, f string causing errors

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.

ACPRule.put() action not passing through well

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'}]}}

literals in portobjectgroups

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

In accessrules.py, enableSyslog is not part of the VALID_JSON_DATA

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

addgroup: destination_port and source_port

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...

Bulk Creation

Hi There,

I see it is possible to perform bulk creation directly via the FMC API

Is this supported on fmcapi?

Unable to add network objects?

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)

printing only object name and value of network-group using for loop

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

Moving/Sharing PyPI of fmcapi

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.

Adding NetworkGroups to a NetworkGroup isn't supported.

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.