diff --git a/portalclientlib/client.py b/portalclientlib/client.py index 2f1c4d4..2a649b8 100644 --- a/portalclientlib/client.py +++ b/portalclientlib/client.py @@ -17,11 +17,18 @@ class Client(object): self.storage = kw.pop('storage') self.ipset_name = kw.pop('ipset_name') self.use_sudo = kw.pop('use_sudo', False) - + + # Default attribute values self.ip_address = kw.pop('ip_address', '127.0.0.1') self.protocol = kw.pop('protocol', 'tcp') - self.new = False + self._enabled = False + self._last_packets = 0 + self._last_activity = None + self._expires = datetime.now() + timedelta(days=1) + + self._new = False + self._commit = False # First try to get an existing client by ID self.client_id = kw.pop('client_id', None) @@ -45,13 +52,12 @@ class Client(object): if client_data: self.load_client(client_data) else: + # Creating a new client, not yet comitted. self.client_id = str(uuid4()) self.created = datetime.now() - self.enabled = False - self.last_packets = 0 - self.last_activity = None - self.expires = datetime.now() + timedelta(days=1) - self.new = True + + self._new = True + self._commit = True def load_client(self, data): @@ -66,6 +72,9 @@ class Client(object): def commit(self): + if not self._commit: + return False + self.commit_client() if self.enabled: @@ -105,11 +114,24 @@ class Client(object): ) + @property + def enabled(self): + return self._enabled + + @enabled.setter + def enabled(self, value): + if not isinstance(value, bool): + return False + + if value != self.enabled: + self._commit = True + self._enabled = value + + @property def ip_address(self): return str(self._ip_address.ip) - @ip_address.setter def ip_address(self, value): if isinstance(value, str): @@ -120,3 +142,40 @@ class Client(object): raise ValueError('Cannot set invalid value') + @property + def last_activity(self): + return self._last_activity + + @last_activity.setter + def last_activity(self, value): + if not isinstance(value, datetime): + return False + + if value != self.last_activity: + self._commit = True + self._last_activity = value + + + @property + def last_packets(self): + return self._last_packets + + @last_packets.setter + def last_packets(self, value): + if value != self.last_packets: + self._commit = True + self._last_packets = int(value) + + + @property + def expires(self): + return self._expires + + @expires.setter + def expires(self, value): + if not isinstance(value, datetime): + return False + + if value != self.expires: + self._commit = True + self._expires = value diff --git a/tools/manage_client.py b/tools/manage_client.py index 8a91be1..d905c35 100644 --- a/tools/manage_client.py +++ b/tools/manage_client.py @@ -30,8 +30,9 @@ def valid_datetime_type(arg_datetime_str): try: return datetime.strptime(arg_datetime_str, "%Y-%m-%d %H:%M") except ValueError: - msg = "Given Datetime ({0}) not valid! Expected format, 'YYYY-MM-DD HH:mm'!".format(arg_datetime_str) - raise ArgumentTypeError(msg) + msg = "Given Datetime ({0}) not valid! Expected format, 'YYYY-MM-DD HH:mm'!".format( + arg_datetime_str) + raise ArgumentTypeError(msg) parser = ArgumentParser( @@ -112,11 +113,12 @@ if args.refresh: timeout=600 ) - current_date = datetime.now() + current_time = datetime.now() for _line in proc.splitlines(): # Convert from bytestring first line = _line.decode('utf-8') + expired = False if not line.startswith('add'): continue @@ -144,40 +146,55 @@ if args.refresh: ip=client_ip, error=str(e) )) + + if args.verbose > 2: + raise + continue - if client.new: + if current_time > client.expires: + expired = True + + if client._new: if args.verbose: print('Creating new client:{ip}'.format( ip=client.ip_address )) client.enabled = True - client.commit() - if int(packets_val) != client.last_packets: - client.last_activity = current_date - client.last_packets = int(packets_val) - if args.verbose > 1: - print('Updating activity for client:{ip}'.format( + if not client.last_activity and expired: + if args.verbose: + print('Client:{ip} disabled, no activity ever logged'.format( ip=client.ip_address )) + + client.enabled = False client.commit() + # No more processing for these types of clients. + continue - # Also do a purge of clients that have no traffic for 24 hrs - if client.last_activity: - time_diff = current_date-client.last_activity + if int(packets_val) > client.last_packets: + if args.verbose > 1: + print('Client:{ip} updated'.format( + ip=client.ip_address + )) - if client.last_packets >= int(packets_val) and time_diff.days >= 1: - client.enabled = False + client.last_packets = packets_val + client.last_activity = current_time + + if client.last_activity and expired: + active_diff = current_time - client.last_activity + + if active_diff.days >= 1 and client.last_activity != current_time: if args.verbose: - print('Disabling client:{ip}'.format( + print('Client:{ip} disabled, no activity since "{last_activity}"'.format( + last_activity=client.last_activity, ip=client.ip_address )) - client.commit() - else: - if not client.enabled: - client.enabled = True - client.commit() + + client.enabled = False + + client.commit() for src_ip in args.src_ip: # Get client by IP or create a new one.