From 2d2fc87d0838ec9e36758e73675c9cbbff3d91bc Mon Sep 17 00:00:00 2001 From: Emanuela Mitreva Date: Thu, 26 Jan 2023 20:52:30 +0200 Subject: [PATCH] Using packaging for python3.7+ --- examples/response/partition_operations.py | 7 ++- setup.py | 3 +- src/cbapi/protection/models.py | 24 ++++++----- src/cbapi/protection/rest_api.py | 8 +++- src/cbapi/response/models.py | 52 ++++++++++++----------- src/cbapi/response/query.py | 8 +++- src/cbapi/response/rest_api.py | 12 ++++-- 7 files changed, 69 insertions(+), 45 deletions(-) diff --git a/examples/response/partition_operations.py b/examples/response/partition_operations.py index 07a87bad..bd896907 100755 --- a/examples/response/partition_operations.py +++ b/examples/response/partition_operations.py @@ -1,5 +1,8 @@ import sys -from distutils.version import LooseVersion +if sys.version_info <= (3, 6): + from distutils.version import LooseVersion as parse +else: + from packaging.version import parse from cbapi.response.models import StoragePartition from cbapi.example_helpers import build_cli_parser, get_cb_response_object @@ -73,7 +76,7 @@ def main(): args = parser.parse_args() cb = get_cb_response_object(args) - if cb.cb_server_version < LooseVersion("6.1.0"): + if cb.cb_server_version < parse("6.1.0"): parser.error("This script can only work with server versions >= 6.1.0; {0} is running {1}" .format(cb.url, cb.cb_server_version)) return 1 diff --git a/setup.py b/setup.py index 42503e25..d9a5a598 100644 --- a/setup.py +++ b/setup.py @@ -37,7 +37,8 @@ install_requires.extend(['simplejson', 'total-ordering', 'ordereddict']) if sys.version_info < (3, 0): install_requires.extend(['futures']) - +if sys.version_info > (3, 6): + install_requires.extend(['packaging']) setup( name='cbapi', version='1.7.9', diff --git a/src/cbapi/protection/models.py b/src/cbapi/protection/models.py index 1e282d33..5b982767 100644 --- a/src/cbapi/protection/models.py +++ b/src/cbapi/protection/models.py @@ -3,7 +3,11 @@ from ..oldmodels import BaseModel, immutable, MutableModel from ..models import MutableBaseModel, CreatableModelMixin, NewBaseModel from contextlib import closing -from distutils.version import LooseVersion +import sys +if sys.version_info <= (3, 6): + from distutils.version import LooseVersion as parse +else: + from packaging.version import parse from zipfile import ZipFile import cbapi.six as six @@ -146,7 +150,7 @@ class DriftReport(NewBaseModel): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") class DriftReportContents(NewBaseModel): @@ -154,7 +158,7 @@ class DriftReportContents(NewBaseModel): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") class Event(NewBaseModel): @@ -280,7 +284,7 @@ class GrantedUserPolicyPermission(NewBaseModel): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") @immutable @@ -374,7 +378,7 @@ class PublisherCertificate(NewBaseModel): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") class ScriptRule(MutableBaseModel): @@ -382,7 +386,7 @@ class ScriptRule(MutableBaseModel): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") @immutable @@ -413,7 +417,7 @@ class TrustedDirectory(MutableBaseModel): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") class TrustedUser(MutableBaseModel, CreatableModelMixin): @@ -422,7 +426,7 @@ class TrustedUser(MutableBaseModel, CreatableModelMixin): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") class User(MutableBaseModel, CreatableModelMixin): @@ -431,7 +435,7 @@ class User(MutableBaseModel, CreatableModelMixin): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") class UserGroup(MutableBaseModel, CreatableModelMixin): @@ -440,4 +444,4 @@ class UserGroup(MutableBaseModel, CreatableModelMixin): @classmethod def _minimum_server_version(cls): - return LooseVersion("8.0") + return parse("8.0") diff --git a/src/cbapi/protection/rest_api.py b/src/cbapi/protection/rest_api.py index 3ee1f166..628c0016 100644 --- a/src/cbapi/protection/rest_api.py +++ b/src/cbapi/protection/rest_api.py @@ -1,7 +1,11 @@ from ..utils import convert_query_params from ..query import PaginatedQuery from ..errors import UnauthorizedError, ApiError -from distutils.version import LooseVersion +import sys +if sys.version_info <= (3, 6): + from distutils.version import LooseVersion as parse +else: + from packaging.version import parse from cbapi.connection import BaseAPI @@ -32,7 +36,7 @@ def __init__(self, *args, **kwargs): log.debug('Connected to Cb server version %s at %s' % (self._server_info['ParityServerVersion'], self.session.server)) - self.cb_server_version = LooseVersion(self._server_info['ParityServerVersion']) + self.cb_server_version = parse(self._server_info['ParityServerVersion']) def _perform_query(self, cls, **kwargs): if hasattr(cls, "_query_implementation"): diff --git a/src/cbapi/response/models.py b/src/cbapi/response/models.py index 535d385e..0f177f13 100755 --- a/src/cbapi/response/models.py +++ b/src/cbapi/response/models.py @@ -3,7 +3,11 @@ import copy import json -from distutils.version import LooseVersion +import sys +if sys.version_info <= (3, 6): + from distutils.version import LooseVersion as parse +else: + from packaging.version import parse from collections import namedtuple, defaultdict import base64 from datetime import datetime, timedelta @@ -656,7 +660,7 @@ def __init__(self, *args, **kwargs): def _query_implementation(cls, cb): # ** Disable the paginated query implementation for now ** - # if cb.cb_server_version >= LooseVersion("5.2.0"): + # if cb.cb_server_version >= parse("5.2.0"): # return SensorPaginatedQuery(cls, cb) # else: # return SensorQuery(cls, cb) @@ -869,7 +873,7 @@ def _update_object(self): if "event_log_flush_time" in self._dirty_attributes and self._info.get("event_log_flush_time", None) is not None: - if self._cb.cb_server_version > LooseVersion("6.0.0"): + if self._cb.cb_server_version > parse("6.0.0"): # since the date/time stamp just needs to be far in the future, we just fake a GMT timezone. try: self._info["event_log_flush_time"] = self.event_log_flush_time.strftime("%a, %d %b %Y %H:%M:%S GMT") @@ -1070,7 +1074,7 @@ def _retrieve_cb_info(self): return info def _update_object(self): - if self._cb.cb_server_version < LooseVersion("6.1.0") or self._info.get("id", None) is None: + if self._cb.cb_server_version < parse("6.1.0") or self._info.get("id", None) is None: # only include IDs of the teams and not the entire dictionary # - applies to Cb Response server < 6.0 as well as Cb Response servers >= 6.0 where the user hasn't # been created yet. @@ -1394,7 +1398,7 @@ class ThreatReport(MutableBaseModel): @classmethod def _query_implementation(cls, cb): - if cb.cb_server_version >= LooseVersion('5.1.0'): + if cb.cb_server_version >= parse('5.1.0'): return ThreatReportQuery(cls, cb) else: return Query(cls, cb) @@ -1524,7 +1528,7 @@ def group_by(self, field_name): :return: Query object :rtype: :py:class:`ProcessQuery` """ - if self._cb.cb_server_version >= LooseVersion('6.0.0'): + if self._cb.cb_server_version >= parse('6.0.0'): nq = self._clone() nq._default_args["cb.group"] = field_name return nq @@ -1573,7 +1577,7 @@ def min_last_update(self, v): :return: Query object :rtype: :py:class:`ProcessQuery` """ - if self._cb.cb_server_version >= LooseVersion('6.0.0'): + if self._cb.cb_server_version >= parse('6.0.0'): nq = self._clone() try: v = v.strftime("%Y-%m-%dT%H:%M:%SZ") @@ -1599,7 +1603,7 @@ def min_last_server_update(self, v): :return: Query object :rtype: :py:class:`ProcessQuery` """ - if self._cb.cb_server_version >= LooseVersion('6.0.0'): + if self._cb.cb_server_version >= parse('6.0.0'): nq = self._clone() try: v = v.strftime("%Y-%m-%dT%H:%M:%SZ") @@ -1625,7 +1629,7 @@ def max_last_update(self, v): :return: Query object :rtype: :py:class:`ProcessQuery` """ - if self._cb.cb_server_version >= LooseVersion('6.0.0'): + if self._cb.cb_server_version >= parse('6.0.0'): nq = self._clone() try: v = v.strftime("%Y-%m-%dT%H:%M:%SZ") @@ -1651,7 +1655,7 @@ def max_last_server_update(self, v): :return: Query object :rtype: :py:class:`ProcessQuery` """ - if self._cb.cb_server_version >= LooseVersion('6.0.0'): + if self._cb.cb_server_version >= parse('6.0.0'): nq = self._clone() try: v = v.strftime("%Y-%m-%dT%H:%M:%SZ") @@ -2285,7 +2289,7 @@ def parse_guid(self, procguid): # new 5.x process IDs are hex strings with optional segment IDs. if len(procguid) == 45: return procguid[:36], int(procguid[38:], 16) - elif len(procguid) == 49 and self._cb.cb_server_version >= LooseVersion('6.0.0'): + elif len(procguid) == 49 and self._cb.cb_server_version >= parse('6.0.0'): return procguid[:36], int(procguid[38:], 16) else: return None, None @@ -2309,7 +2313,7 @@ def __init__(self, cb, procguid, segment=None, max_children=15, initial_data=Non self.__children_info = None self.__sibling_info = None - if cb.cb_server_version < LooseVersion('6.0.0'): + if cb.cb_server_version < parse('6.0.0'): self._default_segment = 1 else: self._default_segment = 0 @@ -2322,7 +2326,7 @@ def __init__(self, cb, procguid, segment=None, max_children=15, initial_data=Non if len(procguid) == 45: self.id = procguid[:36] self.current_segment = int(procguid[38:], 16) - elif len(procguid) == 49 and cb.cb_server_version >= LooseVersion('6.0.0'): + elif len(procguid) == 49 and cb.cb_server_version >= parse('6.0.0'): self.id = procguid[:36] self.current_segment = int(procguid[38:], 16) else: @@ -2339,14 +2343,14 @@ def __init__(self, cb, procguid, segment=None, max_children=15, initial_data=Non self._process_summary_api = 'v1' - if cb.cb_server_version >= LooseVersion('6.0.0'): + if cb.cb_server_version >= parse('6.0.0'): self._process_summary_api = 'v2' self._process_event_api = 'v4' self._event_parser = ProcessV4Parser(self) - elif cb.cb_server_version >= LooseVersion('5.2.0'): + elif cb.cb_server_version >= parse('5.2.0'): self._process_event_api = 'v3' self._event_parser = ProcessV3Parser(self) - elif cb.cb_server_version >= LooseVersion('5.1.0'): + elif cb.cb_server_version >= parse('5.1.0'): # CbER 5.1.0 introduced an extended event API self._process_event_api = 'v2' self._event_parser = ProcessV2Parser(self) @@ -2755,7 +2759,7 @@ def all_events_segment(self): def get_segments(self): if not self._segments: - if self._cb.cb_server_version < LooseVersion('6.0.0'): + if self._cb.cb_server_version < parse('6.0.0'): log.debug("using process_id search for cb response server < 6.0") segment_query = Query(Process, self._cb, query="process_id:{0}".format(self.id)).sort("") proclist = sorted([res["segment_id"] for res in segment_query._search()]) @@ -3066,7 +3070,7 @@ def require_all_events(self): self.all_events_loaded = True def all_childprocs(self): - if self._cb.cb_server_version < LooseVersion('6.0.0'): + if self._cb.cb_server_version < parse('6.0.0'): self.get_segments() segments = self._segments @@ -3088,7 +3092,7 @@ def all_childprocs(self): i += 1 def all_modloads(self): - if self._cb.cb_server_version < LooseVersion('6.0.0'): + if self._cb.cb_server_version < parse('6.0.0'): self.get_segments() segments = self._segments @@ -3110,7 +3114,7 @@ def all_modloads(self): i += 1 def all_filemods(self): - if self._cb.cb_server_version < LooseVersion('6.0.0'): + if self._cb.cb_server_version < parse('6.0.0'): self.get_segments() segments = self._segments @@ -3132,7 +3136,7 @@ def all_filemods(self): i += 1 def all_processblocks(self): - if self._cb.cb_server_version < LooseVersion('6.0.0'): + if self._cb.cb_server_version < parse('6.0.0'): self.get_segments() segments = self._segments @@ -3154,7 +3158,7 @@ def all_processblocks(self): i += 1 def all_regmods(self): - if self._cb.cb_server_version < LooseVersion('6.0.0'): + if self._cb.cb_server_version < parse('6.0.0'): self.get_segments() segments = self._segments @@ -3176,7 +3180,7 @@ def all_regmods(self): i += 1 def all_crossprocs(self): - if self._cb.cb_server_version < LooseVersion('6.0.0'): + if self._cb.cb_server_version < parse('6.0.0'): self.get_segments() segments = self._segments @@ -3198,7 +3202,7 @@ def all_crossprocs(self): i += 1 def all_netconns(self): - if self._cb.cb_server_version < LooseVersion('6.0.0'): + if self._cb.cb_server_version < parse('6.0.0'): self.get_segments() segments = self._segments diff --git a/src/cbapi/response/query.py b/src/cbapi/response/query.py index 9d96a629..e02b11df 100644 --- a/src/cbapi/response/query.py +++ b/src/cbapi/response/query.py @@ -1,7 +1,11 @@ from ..utils import convert_query_params from ..query import PaginatedQuery from cbapi.six.moves import urllib -from distutils.version import LooseVersion +import sys +if sys.version_info <= (3, 6): + from distutils.version import LooseVersion as parse +else: + from packaging.version import parse from ..errors import ApiError import copy @@ -56,7 +60,7 @@ def __init__(self, doc_class, cb, query=None, raw_query=None): # FIX: Cb Response server version 5.1.0-3 throws an exception after returning HTTP 504 when facet=false in the # HTTP request. Work around this by only setting facet=false on 5.1.1 and above server versions. - if self._cb.cb_server_version >= LooseVersion('5.1.1'): + if self._cb.cb_server_version >= parse('5.1.1'): self._default_args["facet"] = "false" def _clone(self): diff --git a/src/cbapi/response/rest_api.py b/src/cbapi/response/rest_api.py index 8407bb7a..e172ab90 100644 --- a/src/cbapi/response/rest_api.py +++ b/src/cbapi/response/rest_api.py @@ -4,7 +4,11 @@ from cbapi.six.moves import urllib -from distutils.version import LooseVersion +import sys +if sys.version_info <= (3, 6): + from distutils.version import LooseVersion as parse +else: + from packaging.version import parse from ..connection import BaseAPI from .models import Process, Binary, Watchlist, Investigation, Alert, ThreatReport, StoragePartition from ..errors import UnauthorizedError, ApiError, ClientError @@ -44,13 +48,13 @@ def __init__(self, *args, **kwargs): raise UnauthorizedError(uri=self.url, message="Invalid API token for server {0:s}.".format(self.url)) log.debug('Connected to Cb server version %s at %s' % (self.server_info['version'], self.session.server)) - self.cb_server_version = LooseVersion(self.server_info['version']) - if self.cb_server_version < LooseVersion('5.0'): + self.cb_server_version = parse(self.server_info['version']) + if self.cb_server_version < parse('5.0'): raise ApiError("CbEnterpriseResponseAPI only supports Cb servers version >= 5.0.0") self._has_legacy_partitions = False try: - if self.cb_server_version >= LooseVersion('6.0'): + if self.cb_server_version >= parse('6.0'): legacy_partitions = [p for p in self.select(StoragePartition) if p.info.get("isLegacy", False)] if legacy_partitions: self._has_legacy_partitions = True