Skip to main content

Unofficial Python 3.x library for Guardicore Centra (based on API 3.0).

Project description

GuardiPy

GuardiPy is a Guardicore Centra™ API client

currently under development,
written around api v3.0,
under release 35.x,
static-declared,
for Python 3.6+,
type-hinted.

Howto

GuardiPy can be install by running the following command:

pip install GuardiPy

You can find examples as the library is developed in (the commit history of?) ./scratch_testing.py. There are two parts of the library you will primarily use:

  • GuardiPy.Centra is the connection/session object. Start here.

    • Call .execute() on this to perform actions against the API.
      • Results from .execute() are returned as a list of objects.
      • Objects can be converted to native Python dictionaries using the .convert_to_dictionary() method.
    • Call .export_to_csv() on this to fetch CSV data from the API.
      • The optional filename parameter may be used to have the CSV data written to the provided filename
  • GuardiPy.CentraObject is the directory of objects you can interact with.

    • Such as .Incident, .Asset, .VM, etc.
    • Within CentraObject there are (static) methods for performing API actions. Such as .list() to perform basic searching.
    • A CentraObject is initialized by the .execute() method, containing fields of that item. Such as the time of an incident.
  • GuardiPy.CentraObject.auxiliary_types contains type definitions that the API documentation did not give a specific section to; and thus are considered not-very-(important/complex).

Authentication

Authentication takes a hostname, username, and password.

First, create your client object, gc for example.

from GuardiPy import Centra
gc = Centra(username="me", hostname="server", password="secret")

Usage

To interact with the API, explore the Centra entities, such as CentraObject.Incident.

  • When static (ie, Incident), these entities will contain methods (ie, .list() to search) meant to be passed to Centra.execute().

    • Specifically, these return a CentraApiPayload or CentraApiExportable object.
      • The returned objects are meant to be fed directly to Centra.execute().
      • CentraApiExportable objects may also be fed directly to Centra.export_to_csv() to generate a CSV file/string.
      • Generally, you don't have to deal with the payload helper object; it's for purposes internal to the library: describing the HTTP request to make, for your given query (ie: list), of a given object type (ie: Incidents).
      • However, it can be modified on the fly if you for some reason need to do so.
  • When Centra.execute() makes your API call, it will return a list of objects from your search. These objects are instances of the class (ie, Incident()). The attributes (name, IP, timestamps, etc) are assigned to these objects.

    • This provides type hinting/autocompletion, so as you use this library, you will know what attributes are available to you**.
    • In some instances, this is undesirable. IE, if you need the JSON that makes up an object, nested entities (such as Incident.affected_assets) will return a brief description as text; instead of the JSON that makes up the affected assets in full...
    • To work around this, pass the Incident through Centra.convert_to_dictionary.
    • It, and all of it's children, will be serialized into a native Python dictionary (which can be modified if needed) before being passed to JSON.dumps().
  • When Centra.export_to_csv() makes your API call, it will return a string representation of the CSV file containing the results of your search.

    • If a filename argument is used when .export_to_csv() is called, the results of the search will also be written to the specified file.
# [ continued from above ]

from GuardiPy import CentraObject

incident_query = CentraObject.Asset.list(
    asset_id="some-uu1d-g03s-her3",  # Most can either be a string,
    label_id=["required", "labels"],  # Or list of many strings.
)

assets = gc.execute(incident_query)
print(assets)

# Soon™:
# for asset in assets:
#     asset.do_something_to_it() ...?

Output example

[ Note: as of v0.1a, return types are implemented only for the Incident type (and it's children). For other types that are developed, there is a method available for converting API results to a dictionary, for easy JSON serialization. ]

Example of returned Asset object
{
    '_id': 'uuid obfuscated from here!',
    'active': True,
    'asset_id': 'uuid obfuscated from here!',
    'bios_uuid': 'uuid obfuscated from here!',
    'comments': '',
    'file_detection_rules': [],
    'first_seen': 1589471530555,
    'full_name': 'Network\\USER-NAME',
    'host_id': 'uuid obfuscated from here!',
    'host_orchestration_id': 'host-261',
    'id': 'uuid obfuscated from here!',
    'ip_addresses': ['10.1.2.3'],
    'is_on': True,
    'label_groups': [],
    'labels': [{'color_index': -1,
                'id': 'uuid obfuscated from here!',
                'key': 'vCenter host',
                'name': 'vCenter host: demo-esx2.company.local',
                'value': 'demo-esx2.company.local'},
               {'color_index': 1,
                'id': 'uuid obfuscated from here!',
                'key': 'Network',
                'name': 'Network: IT_Staff',
                'value': 'IT_Staff'},
               {'color_index': 0,
                'id': 'uuid obfuscated from here!',
                'key': 'Environment',
                'name': 'Environment: CompanyDemo',
                'value': 'CompanyDemo'},
               {'color_index': 1,
                'id': 'uuid obfuscated from here!',
                'key': 'Network',
                'name': 'Network: Vendor',
                'value': 'Vendor'},
               {'color_index': -1,
                'id': 'uuid obfuscated from here!',
                'key': 'vCenter folder',
                'name': 'vCenter folder: Something',
                'value': 'Network'}],
    'last_seen': 1601684867986,
    'mac_addresses': ['01:20:55:aa:aa:aa', 'aa:bb:cc:dd:ee:00'],
    'metadata': {'vSphere': {'host': 'demo-esx2.company.local',
                             'power_state': 'poweredOn',
                             'tools_running_status': 'guestToolsRunning',
                             'tools_version_status': 'guestToolsUnmanaged'}},
    'name': 'obfuscated string!',
    'nics': [{'cloud_network': None,
              'ip_addresses': ['10.1.5.200'],
              'is_cloud_public': False,
              'mac_address': 'aa:bb:cc:dd:ee:ff',
              'network_id': 'DemoLAN',
              'network_name': 'DemoLAN',
              'switch_id': 'vSwitch5',
              'vif_id': '0',
              'vlan_id': 0},
             {'cloud_network': None,
              'ip_addresses': [],
              'is_cloud_public': False,
              'mac_address': '11:22:33:44:55:66',
              'network_id': 'DemoLAN',
              'network_name': 'DemoLAN',
              'switch_id': 'vSwitch2',
              'vif_id': '1',
              'vlan_id': 0}],
    'orchestration_details': [{'orchestration_id': 'uuid obfuscated from here!',
                               'orchestration_name': 'DELETED',
                               'orchestration_obj_id': 'vm-12345',
                               'orchestration_type': 'vSphere',
                               'revision_id': 200609150340},
                              {'orchestration_id': 'uuid obfuscated from here!',
                               'orchestration_name': 'company demo',
                               'orchestration_obj_id': 'vm-54321',
                               'orchestration_type': 'vSphere',
                               'revision_id': 201003002040}],
    'orchestration_labels': [['vCenter host',
                              'demo-esx2.company.local'],
                             ['vCenter folder', 'Network']],
    'orchestration_labels_dict': {'vCenter folder': ['Network'],
                                  'vCenter host': ['demo-esx2.company.local']},
    'recent_domains': None,
    'replicated_labels': ['uuid obfuscated from here!',
                          'uuid obfuscated from here!',
                          'uuid obfuscated from here!'],
    'status': 'on',
    'tenant_name': 'Network',
    'vm': {'name': 'some name?',
           'orchestration_details': [{'orchestration_id': 'uuid obfuscated from here!',
                                      'orchestration_name': 'DELETED',
                                      'orchestration_obj_id': 'vm-20202020',
                                      'orchestration_type': 'vSphere',
                                      'revision_id': 200609150340},
                                     {'orchestration_id': 'uuid obfuscated from here!',
                                      'orchestration_name': 'company something',
                                      'orchestration_obj_id': 'vm-12345',
                                      'orchestration_type': 'vSphere',
                                      'revision_id': 201003002040}],
           'tenant_name': 'Network',
           'vm_id': 'uuid obfuscated from here!'},
    'vm_id': 'uuid obfuscated from here!',
    'vm_name': 'device name?'
}

Type-flexible shortcutting

GuardiPy aims for type friendliness where possible.

Most filters that take a single string are also capable of taking a list of multiple strings - such as UUIDs or IP addresses to include in a given search.

Some methods use filters where a value can be implied through many different types. Such as searching for CentraObject.Incident.list(), you are required to specify a range of time to search (from, to).

The Centra API uses Unix Epoch (in milliseconds) for date-time values. To exemplify this type flexibility, where you want/need to specify a datetime value to the API, you can provide...

  • Absolutely nothing: a default parameter is often assigned.
    • Such as searching "up until" the current UTC time:
to_time: Union[datetime, timedelta, int, str] = datetime.utcnow()
#                                             ^ default parameter value.
  • int (and str) will be assumed to be readily-formatted values in Epoch Milliseconds.
    • Such as taking a value from an API result and passing it right into another query.
    • TODO possibility: string parsing to determine such?
Incident.list(from_time=1601090930584)
#                       ^ int example.
  • datetime.timedelta will be ADDED to the current UTC time.
    • Literally, a timedelta object is added to "right now" at runtime.
    • That is to say: "right now, plus timedelta of negative seven days, will equal 1 week ago."
    • Remember: specify negative values or you will be looking into the future!
    • This allows you to lazily search for a range, such as querying "up to 3.5 days ago":
Incident.list(to_time=datetime.timedelta(days=-3, hours=-12)
  • Finally, a datetime native object...
import dateutil.parser  # v  from RFC3339 datetime string.

some_time = dateutil.parser.isoparse('2008-09-03T20:56:35.450686Z')
Incident.list(to_time=some_time)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

GuardiPy-0.5.0.tar.gz (41.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

GuardiPy-0.5.0-py3-none-any.whl (43.1 kB view details)

Uploaded Python 3

File details

Details for the file GuardiPy-0.5.0.tar.gz.

File metadata

  • Download URL: GuardiPy-0.5.0.tar.gz
  • Upload date:
  • Size: 41.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.1

File hashes

Hashes for GuardiPy-0.5.0.tar.gz
Algorithm Hash digest
SHA256 05c79ae8bcd8db51d20def29e5006c2cf754bc8f6584873e87c1a8de3a1b514f
MD5 9bfc05d01e1315c274d31b1395083217
BLAKE2b-256 4aeaee1df46e163ba2f299d049cc6d7947900c7f4f849ef178c300d1bfa75f4a

See more details on using hashes here.

File details

Details for the file GuardiPy-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: GuardiPy-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 43.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.1 importlib_metadata/4.10.0 pkginfo/1.8.2 requests/2.27.1 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.10.1

File hashes

Hashes for GuardiPy-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e8eac92c7decb60572eb1e4acfdef555d2cc00341f158c6613cef8eec35c9d37
MD5 11fd5fef8ef93622179bc8eb71ed5e44
BLAKE2b-256 6648a5a1f3c414eae59fd322cea6b79bf154c9c1825bf26b75b643f27a3581b5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page