glances.plugins.glances_ports   F
last analyzed

Complexity

Total Complexity 65

Size/Duplication

Total Lines 371
Duplicated Lines 12.94 %

Importance

Changes 0
Metric Value
eloc 222
dl 48
loc 371
rs 3.2
c 0
b 0
f 0
wmc 65

17 Methods

Rating   Name   Duplication   Size   Complexity  
A Plugin.get_key() 0 3 1
A ThreadScanner._port_scan_tcp() 0 27 5
F Plugin.msg_curse() 0 58 14
A ThreadScanner.stats() 0 4 1
A ThreadScanner.__init__() 0 10 1
A ThreadScanner.stopped() 0 3 1
B ThreadScanner._port_scan_icmp() 0 39 7
B ThreadScanner.run() 0 18 6
A Plugin.__init__() 0 19 1
A ThreadScanner.stop() 0 4 1
B Plugin.update() 0 25 6
A ThreadScanner._port_scan() 0 6 2
A ThreadScanner._resolv_name() 0 8 2
A ThreadScanner._web_scan() 0 16 3
B Plugin.get_ports_alert() 25 25 6
A Plugin.get_web_alert() 23 23 5
A Plugin.exit() 0 6 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like glances.plugins.glances_ports often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
#
3
# This file is part of Glances.
4
#
5
# Copyright (C) 2019 Nicolargo <[email protected]>
6
#
7
# Glances is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU Lesser General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
# Glances is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU Lesser General Public License for more details.
16
#
17
# You should have received a copy of the GNU Lesser General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19
20
"""Ports scanner plugin."""
21
22
import os
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
23
import subprocess
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
24
import threading
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
25
import socket
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
26
import time
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
27
import numbers
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
28
29
from glances.globals import WINDOWS, MACOS, BSD
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
30
from glances.ports_list import GlancesPortsList
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
31
from glances.web_list import GlancesWebList
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
32
from glances.timer import Timer, Counter
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
33
from glances.compat import bool_type
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
34
from glances.logger import logger
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
35
from glances.plugins.glances_plugin import GlancesPlugin
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
36
37
try:
38
    import requests
0 ignored issues
show
introduced by Nicolas Hennion
import missing from __future__ import absolute_import
Loading history...
39
    requests_tag = True
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name requests_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
40
except ImportError as e:
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
41
    requests_tag = False
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name requests_tag does not conform to the constant naming conventions ((([A-Z_][A-Z0-9_]*)|(__.*__))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
42
    logger.warning("Missing Python Lib ({}), Ports plugin is limited to port scanning".format(e))
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (97/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by Nicolas Hennion
Use formatting in logging functions and pass the parameters as arguments
Loading history...
43
44
45
class Plugin(GlancesPlugin):
46
    """Glances ports scanner plugin."""
47
48
    def __init__(self, args=None, config=None):
49
        """Init the plugin."""
50
        super(Plugin, self).__init__(args=args,
51
                                     config=config,
52
                                     stats_init_value=[])
53
        self.args = args
54
        self.config = config
55
56
        # We want to display the stat in the curse interface
57
        self.display_curse = True
58
59
        # Init stats
60
        self.stats = GlancesPortsList(config=config, args=args).get_ports_list() + GlancesWebList(config=config, args=args).get_web_list()
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (138/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
61
62
        # Init global Timer
63
        self.timer_ports = Timer(0)
64
65
        # Global Thread running all the scans
66
        self._thread = None
67
68
    def exit(self):
69
        """Overwrite the exit method to close threads."""
70
        if self._thread is not None:
71
            self._thread.stop()
72
        # Call the father class
73
        super(Plugin, self).exit()
74
75
    @GlancesPlugin._log_result_decorator
76
    def update(self):
77
        """Update the ports list."""
78
        if self.input_method == 'local':
79
            # Only refresh:
80
            # * if there is not other scanning thread
81
            # * every refresh seconds (define in the configuration file)
82
            if self._thread is None:
83
                thread_is_running = False
84
            else:
85
                thread_is_running = self._thread.isAlive()
86
            if self.timer_ports.finished() and not thread_is_running:
87
                # Run ports scanner
88
                self._thread = ThreadScanner(self.stats)
89
                self._thread.start()
90
                # Restart timer
91
                if len(self.stats) > 0:
0 ignored issues
show
introduced by Nicolas Hennion
Do not use len(SEQUENCE) as condition value
Loading history...
92
                    self.timer_ports = Timer(self.stats[0]['refresh'])
93
                else:
94
                    self.timer_ports = Timer(0)
95
        else:
96
            # Not available in SNMP mode
97
            pass
98
99
        return self.stats
100
101
    def get_key(self):
102
        """Return the key of the list."""
103
        return 'indice'
104
105 View Code Duplication
    def get_ports_alert(self, port, header="", log=False):
0 ignored issues
show
Unused Code introduced by Nicolas Hennion
The argument log seems to be unused.
Loading history...
Duplication introduced by Nicolas Hennion
This code seems to be duplicated in your project.
Loading history...
106
        """Return the alert status relative to the port scan return value."""
107
        ret = 'OK'
108
        if port['status'] is None:
109
            ret = 'CAREFUL'
110
        elif port['status'] == 0:
111
            ret = 'CRITICAL'
112
        elif (isinstance(port['status'], (float, int)) and
113
              port['rtt_warning'] is not None and
114
              port['status'] > port['rtt_warning']):
115
            ret = 'WARNING'
116
117
        # Get stat name
118
        stat_name = self.get_stat_name(header=header)
119
120
        # Manage threshold
121
        self.manage_threshold(stat_name, ret)
122
123
        # Manage action
124
        self.manage_action(stat_name,
125
                           ret.lower(),
126
                           header,
127
                           port[self.get_key()])
128
129
        return ret
130
131 View Code Duplication
    def get_web_alert(self, web, header="", log=False):
0 ignored issues
show
Unused Code introduced by Nicolas Hennion
The argument log seems to be unused.
Loading history...
Duplication introduced by Nicolas Hennion
This code seems to be duplicated in your project.
Loading history...
132
        """Return the alert status relative to the web/url scan return value."""
133
        ret = 'OK'
134
        if web['status'] is None:
135
            ret = 'CAREFUL'
136
        elif web['status'] not in [200, 301, 302]:
137
            ret = 'CRITICAL'
138
        elif web['rtt_warning'] is not None and web['elapsed'] > web['rtt_warning']:
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (84/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
139
            ret = 'WARNING'
140
141
        # Get stat name
142
        stat_name = self.get_stat_name(header=header)
143
144
        # Manage threshold
145
        self.manage_threshold(stat_name, ret)
146
147
        # Manage action
148
        self.manage_action(stat_name,
149
                           ret.lower(),
150
                           header,
151
                           web[self.get_key()])
152
153
        return ret
154
155
    def msg_curse(self, args=None, max_width=None):
156
        """Return the dict to display in the curse interface."""
157
        # Init the return message
158
        # Only process if stats exist and display plugin enable...
159
        ret = []
160
161
        if not self.stats or args.disable_ports:
162
            return ret
163
164
        # Max size for the interface name
165
        name_max_width = max_width - 7
166
167
        # Build the string message
168
        for p in self.stats:
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name p does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
169
            if 'host' in p:
170
                if p['host'] is None:
171
                    status = 'None'
172
                elif p['status'] is None:
173
                    status = 'Scanning'
174
                elif isinstance(p['status'], bool_type) and p['status'] is True:
175
                    status = 'Open'
176
                elif p['status'] == 0:
177
                    status = 'Timeout'
178
                else:
179
                    # Convert second to ms
180
                    status = '{0:.0f}ms'.format(p['status'] * 1000.0)
181
182
                msg = '{:{width}}'.format(p['description'][0:name_max_width],
183
                                          width=name_max_width)
184
                ret.append(self.curse_add_line(msg))
185
                msg = '{:>9}'.format(status)
186
                ret.append(self.curse_add_line(msg,
187
                                               self.get_ports_alert(p,
188
                                                                    header=p['indice'] + '_rtt')))
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (98/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
189
                ret.append(self.curse_new_line())
190
            elif 'url' in p:
191
                msg = '{:{width}}'.format(p['description'][0:name_max_width],
192
                                          width=name_max_width)
193
                ret.append(self.curse_add_line(msg))
194
                if isinstance(p['status'], numbers.Number):
195
                    status = 'Code {}'.format(p['status'])
196
                elif p['status'] is None:
197
                    status = 'Scanning'
198
                else:
199
                    status = p['status']
200
                msg = '{:>9}'.format(status)
201
                ret.append(self.curse_add_line(msg,
202
                                               self.get_web_alert(p,
203
                                                                  header=p['indice'] + '_rtt')))
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (96/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
204
                ret.append(self.curse_new_line())
205
206
        # Delete the last empty line
207
        try:
208
            ret.pop()
209
        except IndexError:
210
            pass
211
212
        return ret
213
214
215
class ThreadScanner(threading.Thread):
216
    """
217
    Specific thread for the port/web scanner.
218
219
    stats is a list of dict
220
    """
221
222
    def __init__(self, stats):
223
        """Init the class."""
224
        logger.debug("ports plugin - Create thread for scan list {}".format(stats))
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (83/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by Nicolas Hennion
Use formatting in logging functions and pass the parameters as arguments
Loading history...
225
        super(ThreadScanner, self).__init__()
226
        # Event needed to stop properly the thread
227
        self._stopper = threading.Event()
228
        # The class return the stats as a list of dict
229
        self._stats = stats
230
        # Is part of Ports plugin
231
        self.plugin_name = "ports"
232
233
    def run(self):
234
        """Grab the stats.
235
236
        Infinite loop, should be stopped by calling the stop() method.
237
        """
238
        for p in self._stats:
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name p does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
239
            # End of the thread has been asked
240
            if self.stopped():
241
                break
242
            # Scan a port (ICMP or TCP)
243
            if 'port' in p:
244
                self._port_scan(p)
245
                # Had to wait between two scans
246
                # If not, result are not ok
247
                time.sleep(1)
248
            # Scan an URL
249
            elif 'url' in p and requests_tag:
250
                self._web_scan(p)
251
252
    @property
253
    def stats(self):
254
        """Stats getter."""
255
        return self._stats
256
257
    @stats.setter
258
    def stats(self, value):
259
        """Stats setter."""
260
        self._stats = value
261
262
    def stop(self, timeout=None):
0 ignored issues
show
Unused Code introduced by Nicolas Hennion
The argument timeout seems to be unused.
Loading history...
263
        """Stop the thread."""
264
        logger.debug("ports plugin - Close thread for scan list {}".format(self._stats))
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (88/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by Nicolas Hennion
Use formatting in logging functions and pass the parameters as arguments
Loading history...
265
        self._stopper.set()
266
267
    def stopped(self):
268
        """Return True is the thread is stopped."""
269
        return self._stopper.isSet()
270
271
    def _web_scan(self, web):
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This method could be written as a function/class method.

If a method does not access any attributes of the class, it could also be implemented as a function or static method. This can help improve readability. For example

class Foo:
    def some_method(self, x, y):
        return x + y;

could be written as

class Foo:
    @classmethod
    def some_method(cls, x, y):
        return x + y;
Loading history...
272
        """Scan the  Web/URL (dict) and update the status key."""
273
        try:
274
            req = requests.head(web['url'],
275
                                allow_redirects=True,
276
                                verify=web['ssl_verify'],
277
                                proxies=web['proxies'],
278
                                timeout=web['timeout'])
279
        except Exception as e:
0 ignored issues
show
Best Practice introduced by Nicolas Hennion
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by Nicolas Hennion
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
280
            logger.debug(e)
281
            web['status'] = 'Error'
282
            web['elapsed'] = 0
283
        else:
284
            web['status'] = req.status_code
285
            web['elapsed'] = req.elapsed.total_seconds()
286
        return web
287
288
    def _port_scan(self, port):
289
        """Scan the port structure (dict) and update the status key."""
290
        if int(port['port']) == 0:
0 ignored issues
show
unused-code introduced by Nicolas Hennion
Unnecessary "else" after "return"
Loading history...
291
            return self._port_scan_icmp(port)
292
        else:
293
            return self._port_scan_tcp(port)
294
295
    def _resolv_name(self, hostname):
296
        """Convert hostname to IP address."""
297
        ip = hostname
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name ip does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
298
        try:
299
            ip = socket.gethostbyname(hostname)
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name ip does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
300
        except Exception as e:
0 ignored issues
show
Best Practice introduced by Nicolas Hennion
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by Nicolas Hennion
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
301
            logger.debug("{}: Cannot convert {} to IP address ({})".format(self.plugin_name, hostname, e))
0 ignored issues
show
Coding Style introduced by Alessio Sergi
This line is too long as per the coding-style (106/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by Alessio Sergi
Use formatting in logging functions and pass the parameters as arguments
Loading history...
302
        return ip
303
304
    def _port_scan_icmp(self, port):
305
        """Scan the (ICMP) port structure (dict) and update the status key."""
306
        ret = None
307
308
        # Create the ping command
309
        # Use the system ping command because it already have the steacky bit set
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (81/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
310
        # Python can not create ICMP packet with non root right
311
        if WINDOWS:
312
            timeout_opt = '-w'
313
            count_opt = '-n'
314
        elif MACOS or BSD:
315
            timeout_opt = '-t'
316
            count_opt = '-c'
317
        else:
318
            # Linux and co...
319
            timeout_opt = '-W'
320
            count_opt = '-c'
321
        # Build the command line
322
        # Note: Only string are allowed
323
        cmd = ['ping',
324
               count_opt, '1',
325
               timeout_opt, str(self._resolv_name(port['timeout'])),
326
               self._resolv_name(port['host'])]
327
        fnull = open(os.devnull, 'w')
328
329
        try:
330
            counter = Counter()
331
            ret = subprocess.check_call(cmd, stdout=fnull, stderr=fnull, close_fds=True)
0 ignored issues
show
Coding Style introduced by Nicolas Hennion
This line is too long as per the coding-style (88/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
332
            if ret == 0:
333
                port['status'] = counter.get()
334
            else:
335
                port['status'] = False
336
        except subprocess.CalledProcessError as e:
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
337
            # Correct issue #1084: No Offline status for timeouted ports
338
            port['status'] = False
339
        except Exception as e:
0 ignored issues
show
Best Practice introduced by Nicolas Hennion
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by Nicolas Hennion
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
340
            logger.debug("{}: Error while pinging host {} ({})".format(self.plugin_name, port['host'], e))
0 ignored issues
show
Coding Style introduced by Alessio Sergi
This line is too long as per the coding-style (106/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by Alessio Sergi
Use formatting in logging functions and pass the parameters as arguments
Loading history...
341
342
        return ret
343
344
    def _port_scan_tcp(self, port):
345
        """Scan the (TCP) port structure (dict) and update the status key."""
346
        ret = None
347
348
        # Create and configure the scanning socket
349
        try:
350
            socket.setdefaulttimeout(port['timeout'])
351
            _socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
352
        except Exception as e:
0 ignored issues
show
Best Practice introduced by Nicolas Hennion
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by Nicolas Hennion
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
353
            logger.debug("{}: Error while creating scanning socket".format(self.plugin_name))
0 ignored issues
show
Coding Style introduced by Alessio Sergi
This line is too long as per the coding-style (93/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by Alessio Sergi
Use formatting in logging functions and pass the parameters as arguments
Loading history...
354
355
        # Scan port
356
        ip = self._resolv_name(port['host'])
0 ignored issues
show
Coding Style Naming introduced by Nicolas Hennion
The name ip does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
357
        counter = Counter()
358
        try:
359
            ret = _socket.connect_ex((ip, int(port['port'])))
0 ignored issues
show
introduced by Nicolas Hennion
The variable _socket does not seem to be defined for all execution paths.
Loading history...
360
        except Exception as e:
0 ignored issues
show
Best Practice introduced by Nicolas Hennion
Catching very general exceptions such as Exception is usually not recommended.

Generally, you would want to handle very specific errors in the exception handler. This ensure that you do not hide other types of errors which should be fixed.

So, unless you specifically plan to handle any error, consider adding a more specific exception.

Loading history...
Coding Style Naming introduced by Nicolas Hennion
The name e does not conform to the variable naming conventions ((([a-z][a-z0-9_]{2,30})|(_[a-z0-9_]*))$).

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
361
            logger.debug("{}: Error while scanning port {} ({})".format(self.plugin_name, port, e))
0 ignored issues
show
Coding Style introduced by Alessio Sergi
This line is too long as per the coding-style (99/80).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
introduced by Alessio Sergi
Use formatting in logging functions and pass the parameters as arguments
Loading history...
362
        else:
363
            if ret == 0:
364
                port['status'] = counter.get()
365
            else:
366
                port['status'] = False
367
        finally:
368
            _socket.close()
369
370
        return ret
371