def test_generate(self): inst = self._get_instance(CheckPointPusher) _append_file(self.log_path, LOG_DATA.encode('latin_1')) HEADER = ('srcaddr,dstaddr,srcport,dstport,protocol,' 'bytes_in,bytes_out,start,end') LINES = [ ('192.0.2.2,198.51.100.1,47006,80,6,' '200,100,1464898147,1464898147'), ('192.0.2.3,198.51.100.2,49152,443,17,' '300,200,1464898207,1464898207'), ] for dt, expected_lines, file_name in ( ( datetime(2016, 6, 2, 20, 19, 0), [HEADER, LINES[0]], '20160602200000_20160602201900.csv.gz', ), ( datetime(2016, 6, 2, 20, 21, 0), [HEADER, LINES[1]], '20160602201000_20160602202100.csv.gz', ), ): patch_path = 'ona_service.check_point_pusher.create_dirs' with patch(patch_path, autospec=True) as mock_create_dirs: inst.execute(dt) mock_create_dirs.assert_called_once_with(inst.input_dir) with io.open(join(inst.input_dir, file_name), 'rb') as infile: data = gunzip_bytes(infile.read()) self.assertEqual(data.decode('utf-8').splitlines(), expected_lines)
def test_execute_multiline(self): output = {} def send_file(data_type, path, now, suffix=None): with io.open(path, 'rb') as infile: output[index] = infile.read() self.inst.api.send_file.side_effect = send_file # There are two entries here, but we only know the first has ended once # we see the second. index = 0 _append_file(self.log_path, LOG_DATA_MULTILINE) _append_file(self.log_path, LOG_DATA_MULTILINE) self.inst.execute(now=self.now) actual = gunzip_bytes(output[index]).splitlines() expected = [ '_time,Computer,TargetUserName,EventCode,ComputerAddress', '1463831340,computer.obsrvbl.local,ACCOUNT241,4624,192.168.0.100', ] self.assertEqual(actual, expected) self.assertEqual(self.inst.api.send_file.call_count, 1) self.assertEqual(self.inst.log_node.parsed_data, []) # No additional calls if there were no additional writes index = 1 self.inst.execute(now=self.now) self.assertEqual(self.inst.api.send_file.call_count, 1) self.assertEqual(actual, expected) # Two more writes signal the end of the second and third entries, but # one is skipped index = 2 _append_file(self.log_path, LOG_DATA_MULTILINE.replace('ACCOUNT241', 'USER$')) _append_file(self.log_path, LOG_DATA_MULTILINE) self.inst.execute(now=self.now) actual = gunzip_bytes(output[index]).splitlines() expected = [ '_time,Computer,TargetUserName,EventCode,ComputerAddress', '1463831340,computer.obsrvbl.local,ACCOUNT241,4624,192.168.0.100', ] self.assertEqual(actual, expected) self.assertEqual(self.inst.api.send_file.call_count, 2)
def test_execute_oneline(self): output = {} def send_file(data_type, path, now, suffix=None): with io.open(path, 'rb') as infile: output[index] = infile.read() self.inst.api.send_file.side_effect = send_file index = 0 _append_file(self.log_path, LOG_DATA_ONELINE) self.inst.execute(now=self.now) actual = gunzip_bytes(output[0]).splitlines() expected = [ '_time,Computer,TargetUserName,EventCode,ComputerAddress', '1482256140,wk242.obsrvbl.local,Account242,4624,192.0.2.2', ] self.assertEqual(actual, expected) self.assertEqual(self.inst.api.send_file.call_count, 1) self.assertEqual(self.inst.log_node.parsed_data, []) # No additional calls if there were no additional writes self.inst.execute(now=self.now) self.assertEqual(self.inst.api.send_file.call_count, 1)
def test_gzip_bytes(self): gz_data = gzip_bytes(self.data) self.assertEqual(gunzip_bytes(gz_data), self.data)
def test_gunzip_bytes(self): self.assertEqual(gunzip_bytes(self.gz_data), self.data)
def test_exceute(self, mock_post): # Intercept the ISE API calls def _post(url, data=None, json=None, **kwargs): resp = Response() resp.status_code = 200 # All calls require the same headers and certificates self.assertEqual(kwargs['headers'], self.expected_headers) self.assertEqual( kwargs['cert'], (self.client_cert, self.client_key) ) self.assertEqual(kwargs['verify'], self.ca_cert) if url.startswith('https://localhost:8910/pxgrid/control'): # Control requests use a static password self.assertEqual(kwargs['auth'], ('ona-node', 'ona-password')) # Account activation if url.endswith('/AccountActivate'): expected_input = {} output_json = {'accountState': 'ENABLED'} # Service lookup elif url.endswith('/ServiceLookup'): expected_input = {'name': 'com.cisco.ise.session'} output_json = { 'services': [ { 'nodeName': 'service-node', 'properties': { 'restBaseUrl': 'https://localhost:8241' }, }, ] } # Secret request if url.endswith('/AccessSecret'): expected_input = {'peerNodeName': 'service-node'} output_json = {'secret': 'service-node-secret'} # The peer node answers the Get Sessions requests elif url == ('https://localhost:8241/getSessions'): # The peer node uses the secret for authorization self.assertEqual( kwargs['auth'], ('ona-node', 'service-node-secret') ) expected_input = { 'startTimestamp': (self.now + TICK_DELTA).isoformat() } output_json = { 'sessions': [ # Wrong state { 'state': 'DISCONNECTED', 'timestamp': '2019-01-29T12:34:01.100-06:00', }, # No IP addresses { 'state': 'AUTHENTICATED', 'timestamp': '2019-01-29T12:34:01.100-06:00', }, # No adUserDomainName { 'state': 'AUTHENTICATED', 'ipAddresses': ['192.0.2.0', '192.0.2.1'], 'timestamp': '2019-01-29T12:34:01.100-06:00', 'adNormalizedUser': '******', }, # Valid { 'state': 'AUTHENTICATED', 'ipAddresses': ['192.0.2.0', '192.0.2.1'], 'timestamp': '2019-01-29T12:34:01.100-06:00', 'adNormalizedUser': '******', 'adUserDomainName': u'some-domain\ufffd\ufffd', }, # Valid { 'state': 'AUTHENTICATED', 'ipAddresses': ['192.0.2.0', '192.0.2.1'], 'timestamp': '2019-01-29T12:34:01.100-06:00', 'adNormalizedUser': '******', 'adUserDomainName': u'some-domain\ufffd\ufffd', }, ] } self.assertEqual(kwargs['headers'], self.expected_headers) else: resp.status_code = 404 self.assertEqual(json, expected_input) resp._content = dumps(output_json).encode('utf-8') return resp mock_post.side_effect = _post # Intercept the file upload output = {} def send_file(data_type, path, now, suffix=None): with io.open(path, 'rb') as infile: output[index] = infile.read() return {'remote_path': 'file:///tmp/ise_data.csv.gz'} # Get an IsePoller instance inst = self._get_instance( OBSRVBL_ISE_NODE_NAME='ona-node', OBSRVBL_ISE_PASSWORD='******', ) inst.api.send_file.side_effect = send_file # Do the deed index = 0 inst.execute(now=self.now) actual = gunzip_bytes(output[index]).splitlines() expected = [ ','.join(OUTPUT_FIELDNAMES), '1548786841,,some-user,,192.0.2.0,some-domain', ] self.assertEqual(actual, expected) self.assertEqual(inst.api.send_file.call_count, 1) self.assertEqual(inst.api.send_signal.call_count, 1)