Skip to content

Commit

Permalink
renamed to new naming convention.
Browse files Browse the repository at this point in the history
formatting and more documentation
  • Loading branch information
Jason McFarland committed Oct 18, 2016
1 parent f4d374a commit 51ecf8d
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 46 deletions.
2 changes: 1 addition & 1 deletion docs/enterprise-protection.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. _protection_api:

Carbon Black Protection REST API
Cb Protection API
================================

This page documents the public interfaces exposed by cbapi when communicating with a Carbon Black Enterprise
Expand Down
2 changes: 1 addition & 1 deletion docs/enterprise-response.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.. _response_api:

Carbon Black Response REST API
Cb Response API
==============================

This page documents the public interfaces exposed by cbapi when communicating with a Carbon Black Enterprise
Expand Down
98 changes: 59 additions & 39 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,69 @@
cbapi: Carbon Black API for Python
==================================

Release v\ |version|.
Release v\ |release|.

cbapi provides a straightforward interface to the Carbon Black Enterprise Protection and Enterprise Response REST APIs.
cbapi provides a straightforward interface to the Cb Protection and Response REST APIs.
This library provides a Pythonic layer to access the raw power of the REST APIs of both products, making it trivial
to do the easy stuff and handling all of the "sharp corners" behind the scenes for you. Take a look:

>>> from cbapi.response import CbEnterpriseResponseAPI, Process, Binary, Sensor
>>> c=CbEnterpriseResponseAPI()
>>> # take the first process that ran notepad.exe, download the binary and read the first two bytes
>>> c.select(Process).where('process_name:notepad.exe').first().binary.file.read(2)
'MZ'
>>> # if you want a specific ID, you can put it straight into the .select() call:
>>> binary = c.select(Binary, "24DA05ADE2A978E199875DA0D859E7EB")
>>> # isolate all sensors who ran notepad.exe
>>> sensors = set()
>>> for proc in c.select(Process).where('process_name:notepad.exe'):
... sensors.add(proc.sensor)
>>> for s in sensors:
... s.network_isolation_enabled = True
... s.save()

If you're more a Cb Enterprise Protection fellow, then you're in luck as well:

>>> from cbapi.protection.models import FileInstance
>>> from cbapi.protection import CbEnterpriseProtectionAPI
>>> p=CbEnterpriseProtectionAPI()
>>> # Select the first file instance
>>> fi = p.select(FileInstance).first()
>>> # print that computer's hostname. This automatically "joins" with the Computer API object.
>>> fi.computer.name
u'DOMAIN\\MYHOSTNAME'
>>> # change the policy ID
>>> fi.computer.policyId = 3
>>> fi.computer.save()
>>> from cbapi.response import CbEnterpriseResponseAPI, Process, Binary, Sensor
>>> #
>>> # Create our CbAPI object
>>> #
>>> c = CbEnterpriseResponseAPI()
>>> #
>>> # take the first process that ran notepad.exe, download the binary and read the first two bytes
>>> #
>>> c.select(Process).where('process_name:notepad.exe').first().binary.file.read(2)
'MZ'
>>> #
>>> # if you want a specific ID, you can put it straight into the .select() call:
>>> #
>>> binary = c.select(Binary, "24DA05ADE2A978E199875DA0D859E7EB")
>>> #
>>> # select all sensors that have ran notepad
>>> #
>>> sensors = set()
>>> for proc in c.select(Process).where('process_name:notepad.exe'):
... sensors.add(proc.sensor)
>>> #
>>> # iterate over all sensors and isolate
>>> #
>>> for s in sensors:
... s.network_isolation_enabled = True
... s.save()

If you're more a Cb Protection fellow, then you're in luck as well:

>>> from cbapi.protection.models import FileInstance
>>> from cbapi.protection import CbEnterpriseProtectionAPI
>>> #
>>> # Create our Cb Protection API object
>>> #
>>> p = CbEnterpriseProtectionAPI()
>>> #
>>> # Select the first file instance
>>> #
>>> fi = p.select(FileInstance).first()
>>> #
>>> # print that computer's hostname. This automatically "joins" with the Computer API object.
>>> #
>>> fi.computer.name
u'DOMAIN\\MYHOSTNAME'
>>> #
>>> # change the policy ID
>>> #
>>> fi.computer.policyId = 3
>>> fi.computer.save()



Major Features
--------------

- **Consistent API for both Cb Enterprise Response and Protection platforms**
We now support Carbon Black Enterprise Response and Enterprise Protection users in the same API layer. Even better,
- **Consistent API for both Cb Response and Protection platforms**
We now support Cb Enterprise Response and Protection users in the same API layer. Even better,
the object model is the same for both; if you know one API you can easily transition to the other. cbapi
hides all the differences between the two REST APIs behind a single, consistent Python-like interface.

Expand Down Expand Up @@ -76,8 +97,8 @@ The new cbapi as of version 0.9.0 enforces the use of credential files.

In order to perform any queries via the API, you will need to get the API token for your Cb user. See the documentation
on the Developer Network website on how to acquire the API token for
`Enterprise Response <http://developer.carbonblack.com/reference/enterprise-response/authentication/>`_ or
`Enterprise Protection <http://developer.carbonblack.com/reference/enterprise-protection/authentication/>`_.
`Cb Response <http://developer.carbonblack.com/reference/enterprise-response/authentication/>`_ or
`Cb Protection <http://developer.carbonblack.com/reference/enterprise-protection/authentication/>`_.

Once you acquire your API token, place it in one of the default credentials file locations:

Expand Down Expand Up @@ -136,8 +157,8 @@ legacy scripts cannot run under Python 3.
Once cbapi 1.0.0 is released, the old :py:mod:`cbapi.legacy.CbApi` will be deprecated and removed entirely no earlier
than January 2017.
New scripts should use the :py:mod:`cbapi.response.rest_api.CbEnterpriseResponseAPI`
(for Carbon Black Enterprise Response) and :py:mod:`cbapi.protection.rest_api.CbEnterpriseProtectionAPI`
(for Carbon Black Enterprise Protection / former Bit9 Parity) API entry points.
(for Cb Response) and :py:mod:`cbapi.protection.rest_api.CbEnterpriseProtectionAPI`
(for Cb Protection) API entry points.


Forwards Compatibility
Expand All @@ -147,7 +168,8 @@ Forwards Compatibility
will be documented in the changelog. The API will be frozen as of version 1.0; afterward, any changes in the 1.x version branch
will be additions/bug fixes only. Breaking changes to the API will increment the major version number (2.x).

Contents:
Full Documentation
------------------

.. toctree::
:maxdepth: 2
Expand All @@ -156,8 +178,6 @@ Contents:
enterprise-protection
exceptions



Indices and tables
==================

Expand Down
56 changes: 51 additions & 5 deletions src/cbapi/response/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ def _query_implementation(cls, cb):

@property
def binary(self):
"""
Joins this attribute with the :class:`.Binary` object associated with this Banned Hash object
"""
return self._join(Binary, "md5hash")

def _update_object(self):
Expand Down Expand Up @@ -208,13 +211,32 @@ def _search(self, cls, min_score=None, max_score=None):
min_score, max_score))

def search_processes(self, min_score=None, max_score=None):
"""
Perform a *Process* search within this feed that satisfies min_score and max_score
:param min_score: minimum feed score
:param max_score: maximum feed score
:return: Returns a :py:class:`response.rest_api.Query` object with the appropriate search parameters for processes
:rtype: :py:class:`response.rest_api.Query`
"""
return self._search(Process, min_score, max_score)

def search_binaries(self, min_score=None, max_score=None):
"""
Perform a *Binary* search within this feed that satisfies min_score and max_score
:param min_score: minimum feed score
:param max_score: maximum feed score
:return: Returns a :py:class:`response.rest_api.Query` object within the appropriate search parameters for binaries
:rtype: :py:class:`response.rest_api.Query`
"""
return self._search(Binary, min_score, max_score)

@property
def actions(self):
"""
:return: Returns all :class:`.FeedAction` objects associated with this feed
:rtype: :py:class:`response.rest_api.Query`
"""
return self._cb.select(FeedAction).where("group_id:{0}".format(int(self._model_unique_id)))

@property
Expand Down Expand Up @@ -341,7 +363,13 @@ def _query_implementation(cls, cb):
@property
def group(self):
"""
Returns the sensor's group id. This attribute can also be set.
:getter:
Returns the sensor's group id.
:setter:
Allows access to set the sensor's group id
"""
return self._join(SensorGroup, "group_id")

Expand All @@ -360,7 +388,6 @@ def dns_name(self):
def hostname(self):
"""
Returns the hostname associated with this sensor object. This is the same as 'computer_name'
:return:
"""
return getattr(self, 'computer_name', None)

Expand Down Expand Up @@ -446,6 +473,7 @@ def lr_session(self):
:return: Live Response session object
:rtype: :py:class:`cbapi.live_response_api.LiveResponseSession`
:raises ApiError: if there is an error establishing a Live Response session for this Sensor
"""
if not getattr(self, "supports_cblr", False):
raise ApiError("Sensor does not support Cb Live Response")
Expand Down Expand Up @@ -566,7 +594,13 @@ def _query(self):
@property
def query(self):
"""
Returns the query associated with this watchlist. This attribute can also be set.
:getter:
Returns the query associated with this watchlist.
:setter:
Allows access to set the query associated with this watchlist
"""
queryparams = [(k, v) for k, v in self._query if k == "q" or k.startswith("cb.q.")]
queryparts = []
Expand Down Expand Up @@ -606,6 +640,12 @@ def query(self, new_query):

@property
def facets(self):
"""
Returns facets from the search associated with the watchlist query
:return: dictionary of facets as keys
:rtype: dict
"""
facets = {}
for k, v in self._query:
if k.startswith("cb.fq."):
Expand All @@ -614,6 +654,12 @@ def facets(self):
return facets

def search(self):
"""
Creates a search based on the watchlist's search parameter
:return: a `Process` :py:class:`.response.rest_api.Query` or Binary :py:class:`.response.rest_api.Query`
:rtype: :py:class:`.response.rest_api.Query`
"""
search_query = getattr(self, "search_query", "")
index_type = getattr(self, "index_type", "events")

Expand Down Expand Up @@ -1568,7 +1614,7 @@ def find_file_writes(self, filename):
@property
def binary(self):
"""
Joins this attribute with the Binary object associated with this Process object
Joins this attribute with the :class:`.Binary` object associated with this Process object
:example:
Expand Down Expand Up @@ -1621,7 +1667,7 @@ def cmdline(self):
@property
def sensor(self):
"""
Joins this attribute with the Sensor object associated with this Process object
Joins this attribute with the :class:`.Sensor` object associated with this Process object
:example:
Expand Down

0 comments on commit 51ecf8d

Please sign in to comment.