Source code for tenable.dl

'''
Product Downloads
=================

.. autoclass:: Downloads
    :members:
'''
from tenable.base.platform import APIPlatform
from box import BoxList
from io import BytesIO
import os, warnings

[docs]class Downloads(APIPlatform): ''' The Downloads object is the primary interaction point for users to interface with Downloads API via the pyTenable library. All of the API endpoint classes that have been written will be grafted onto this class. Args: api_token (str, optional): The user's API access key for Tenable Vulnerability Management If an access key isn't specified, then the library will attempt to read the environment variable ``TDL_API_TOKEN`` to acquire the key. retries (int, optional): The number of retries to make before failing a request. The default is ``5``. backoff (float, optional): If a 429 response is returned, how much do we want to backoff if the response didn't send a Retry-After header. The default backoff is ``1`` second. vendor (str, optional): The vendor name for the User-Agent string. product (str, optional): The product name for the User-Agent string. build (str, optional): The version or build identifier for the User-Agent string. timeout (int, optional): The connection timeout parameter informing the library how long to wait in seconds for a stalled response before terminating the connection. If unspecified, the default is 120 seconds. Examples: Basic Example: >>> from tenable.dl import Downloads >>> dl = Downloads(api_token='API_TOKEN') Example with proper identification: >>> dl = Downloads('API_TOKEN', >>> vendor='Company Name', >>> product='My Awesome Widget', >>> build='1.0.0') Example with proper identification leveraging environment variables for access and secret keys: >>> dl = Downloads( >>> vendor='Company Name', product='Widget', build='1.0.0') ''' _box = True _env_base = 'TDL' _url = 'https://www.tenable.com' _base_path = 'downloads/api/v2' def __init__(self, api_token=None, **kwargs): if not api_token: api_token = os.getenv('{}_API_TOKEN'.format(self._env_base)) kwargs['api_token'] = api_token super().__init__(**kwargs) def _authenticate(self, **kwargs): ''' Authentication method for Downloads API ''' if not kwargs.get('api_token'): warnings.warn('Starting an unauthenticated session') self._log.warning('Starting an unauthenticated session.') else: self._session.headers.update({ 'Authorization': 'Bearer {token}'.format( token=kwargs.get('api_token') ) })
[docs] def list(self): ''' Lists the available content pages. :devportal:`API Endpoint Documentation <get_pages>` Returns: :obj:`list`: The list of page resources. Examples: >>> pages = dl.list() >>> for page in pages: ... pprint(page) ''' return self.get('pages', box=BoxList)
[docs] def details(self, page): ''' Retrieves the specific download items for the page requested. :devportal:`API Endpoint Documentation <get_pages-slug>` Args: page (str): The name of the page to request. Returns: :obj:`dict`: The page details. Examples: >>> details = dl.details('nessus') ''' return self.get('pages/{}'.format(page))
[docs] def download(self, page, package, fobj=None): ''' Retrieves the requested package and downloads the file. :devportal:`API Endpoint Documentation <get_pages-slug-files-file>` Args: page (str): The name of the page package (str): The package filename fobj (FileObject, optional): The file-like object to write the package to. If nothing is specified, then a BytesIO object will be used. Returns: :obj:`FileObject`: The binary package Examples: >>> with open('Nessus-latest.x86_64.rpm', 'wb') as pkgfile: ... dl.download('nessus', ... 'Nessus-8.3.0-es7.x86_64.rpm', pkgfile) ''' if not fobj: fobj = BytesIO() resp = self.get( 'pages/{}/files/{}'.format(page, package), stream=True, box=False) # Lets stream the file into the file-like object... for chunk in resp.iter_content(chunk_size=1024): if chunk: fobj.write(chunk) fobj.seek(0) resp.close() # Lastly lets return the FileObject to the caller. return fobj