f5-common-python icon indicating copy to clipboard operation
f5-common-python copied to clipboard

Why is ASM Violations collection not available?

Open sonicblind opened this issue 7 years ago • 6 comments

Hi,

I am wondering how can I get a collection of all ASM violations?

To me, the fact that I am able to fetch them via this REST call: https://<hostname>/mgmt/tm/asm/violations/ should be a proof that the F5 API does support this collection.

Why is it then not implemented in f5-common-python? And why is it also missing in ASM namespace in official user guide (page 71)?

I don't understand why is it missing in the ASM namespace, and also not implemented in f5-common-sdk when the API is able to deliver the data for violations?

What am I missing here?

Thanks in advance for any ideas.

Cheers, Martin

sonicblind avatar Jul 25 '18 21:07 sonicblind

In case somebody would be interested in the same topic, I managed to fix this for myself by extending the f5-common-python.

Under ./f5/bigip/tm/asm/ I created a new file violations.py as a new module for ASM violations. I used existing module attack_types.py as a template for violations.py.

Then, I altered the existing init.py and made only two simple additions:

  • imported Violations_s from violations
  • appended Violations_s to self._meta_data['allowed_lazy_attributes'] of init method

Works like a charm.

sonicblind avatar Jul 30 '18 09:07 sonicblind

others will still need this functionality. Feel free to post your code here and I will write tests for it so it can be merged for everyone.

jasonrahm avatar Jul 30 '18 14:07 jasonrahm

Under f5/bigip/tm/asm/ I created a new file called violations.py with this following content. It is basically a copy of attack_types.py from the same directory, I only replaced the necessary names etc.

from f5.bigip.resource import AsmResource
from f5.bigip.resource import Collection
from f5.sdk_exception import UnsupportedOperation

class Violations_s(Collection):
    """BIG-IP ASM Violations collection."""
    def __init__(self, asm):
        super(Violations_s, self).__init__(asm)
        self._meta_data['object_has_stats'] = False
        self._meta_data['allowed_lazy_attributes'] = [Violation]
        self._meta_data['attribute_registry'] = {
            'tm:asm:violations:violationstate': Violation
		}

class Violation(AsmResource):
    """BIG-IP ASM Violation resource"""
    def __init__(self, violations_s):
        super(Violation, self).__init__(violations_s)
        self._meta_data['required_json_kind'] = 'tm:asm:violations:violationstate'

    def create(self, **kwargs):
        """Create is not supported for Violation resource
                :raises: UnsupportedOperation
        """
        raise UnsupportedOperation(
            "%s does not support the create method" % self.__class__.__name__
        )

    def delete(self, **kwargs):
        """Delete is not supported for Violation resource
                :raises: UnsupportedOperation
        """
        raise UnsupportedOperation(
            "%s does not support the delete method" % self.__class__.__name__
        )

    def modify(self, **kwargs):
        """Modify is not supported for Violation resource
                :raises: UnsupportedOperation
        """
        raise UnsupportedOperation(
            "%s does not support the modify method" % self.__class__.__name__
	)

Then I altered the code of f5/bigip/tm/asm/__init__.py. I added only two lines, the last import statement and the last item in self._meta_data['allowed_lazy_attributes']:

from f5.bigip.resource import OrganizingCollection
from f5.bigip.tm.asm.attack_types import Attack_Types_s
from f5.bigip.tm.asm.file_transfer import File_Transfer
from f5.bigip.tm.asm.policies import Policies_s
from f5.bigip.tm.asm.policy_templates import Policy_Templates_s
from f5.bigip.tm.asm.signature_sets import Signature_Sets_s
from f5.bigip.tm.asm.signature_statuses import Signature_Statuses_s
from f5.bigip.tm.asm.signature_systems import Signature_Systems_s
from f5.bigip.tm.asm.signature_update import Signature_Update
from f5.bigip.tm.asm.signatures import Signatures_s
from f5.bigip.tm.asm.tasks import Tasks
from f5.bigip.tm.asm.violations import Violations_s

class Asm(OrganizingCollection):
    """BIG-IP® Application Security Manager (ASM) organizing collection."""

    def __init__(self, tm):
        super(Asm, self).__init__(tm)
        self._meta_data['allowed_lazy_attributes'] = [
            Attack_Types_s,
            File_Transfer,
            Policies_s,
            Policy_Templates_s,
            Signature_Sets_s,
            Signature_Statuses_s,
            Signature_Systems_s,
            Signature_Update,
            Signatures_s,
            Tasks,
	    Violations_s,
        ]

sonicblind avatar Jul 31 '18 11:07 sonicblind

And here is a simple script which shows how to achieve the same, but without touching the official modules of f5-common-python.


from f5.bigip import ManagementRoot

from f5.sdk_exception import UnsupportedOperation
from f5.bigip.resource import AsmResource
from f5.bigip.resource import Collection

class Violations_s(Collection):
	def __init__(self, asm):
		super(Violations_s, self).__init__(asm)
		self._meta_data['object_has_stats'] = False
		self._meta_data['allowed_lazy_attributes'] = [Violation]
		self._meta_data['attribute_registry'] = {
			'tm:asm:violations:violationstate': Violation
		}
		
class Violation(AsmResource):
	def __init__(self, violations_s):
		super(Violation, self).__init__(violations_s)
		self._meta_data['required_json_kind'] = 'tm:asm:violations:violationstate'

	def create(self, **kwargs):
		raise UnsupportedOperation(f"{self.__class__.__name__} does not support the create method")

	def delete(self, **kwargs):
		raise UnsupportedOperation(f"{self.__class__.__name__} does not support the delete method")

	def modify(self, **kwargs):
		raise UnsupportedOperation(f"{self.__class__.__name__} does not support the modify method")
		
		
mgmt = ManagementRoot(hostname, username, password)

# Get collection of attack types - this is available in f5-common-python
attacks = mgmt.tm.asm.attack_types_s.get_collection(requests_params={'params': '$top=5&$select=id,name'})
for attack in attacks:
	print(attack.id, attack.name)

# Now add violations to available API calls
mgmt.tm.asm._meta_data['allowed_lazy_attributes'].append(Violations_s)

# Get collection of violations - this isn't available in f5-common-python
# But is now since we manually added the functionality
violations = mgmt.tm.asm.violations_s.get_collection(requests_params={'params': '$top=5&$select=id,name'})
for violation in violations:
	print(violation.id, violation.name)

sonicblind avatar Jul 31 '18 12:07 sonicblind

@sonicblind I would suggest opening a pull request and tests for this, so you can author it? If you are external to F5 we would need you to sign a document (last I check we did that anyway) but it would be great if you coded this and submitted PR.

wojtek0806 avatar Aug 08 '18 09:08 wojtek0806

@wojtek0806

I already wrote additional code to enable me to retrieve 'tm:asm:events:requests:requeststate'. This was also not part of the existing distribution.

But I have never done a contribution to GitHub. Don't know how this all works. If you are willing to guide me through, I'll be happy to help.

sonicblind avatar Aug 16 '18 14:08 sonicblind