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)
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #4
0
 def test_gzip_bytes(self):
     gz_data = gzip_bytes(self.data)
     self.assertEqual(gunzip_bytes(gz_data), self.data)
Exemple #5
0
 def test_gunzip_bytes(self):
     self.assertEqual(gunzip_bytes(self.gz_data), self.data)
Exemple #6
0
    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)