Completed
Push — master ( 4d2b48...8fd865 )
by Björn
16s queued 12s
created

gvm.protocols.gmp.Gmp.determine_supported_gmp()   B

Complexity

Conditions 6

Size

Total Lines 23
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 17
nop 1
dl 0
loc 23
rs 8.6166
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2019-2020 Greenbone Networks GmbH
3
#
4
# SPDX-License-Identifier: GPL-3.0-or-later
5
#
6
# This program is free software: you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation, either version 3 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
19
"""
20
Module for communication with gvmd
21
"""
22
from typing import Any, Optional, Callable, Union
23
24
from gvm.errors import GvmError
25
26
from gvm.protocols.base import GvmProtocol, GvmConnection
27
28
from gvm.protocols.gmpv7 import Gmp as Gmpv7
29
from gvm.protocols.gmpv8 import Gmp as Gmpv8
30
from gvm.protocols.gmpv9 import Gmp as Gmpv9
31
from gvm.protocols.gmpv208 import Gmp as Gmpv208
32
from gvm.protocols.gmpv214 import Gmp as Gmpv214
33
34
from gvm.transforms import EtreeCheckCommandTransform
35
36
from gvm.xml import XmlCommand
37
38
SUPPORTED_GMP_VERSIONS = Union[  # pylint: disable=invalid-name
39
    Gmpv7, Gmpv8, Gmpv9, Gmpv208, Gmpv214
40
]
41
42
43
class Gmp(GvmProtocol):
44
    """Dynamically select supported GMP protocol of the remote manager daemon.
45
46
    Must be used as a `Context Manager
47
    <https://docs.python.org/3/reference/datamodel.html#context-managers>`_
48
49
    Example:
50
51
        .. code-block:: python
52
53
            from gvm.protocols.gmp import Gmp
54
55
            with Gmp(connection) as gmp:
56
                # gmp can be an instance of gvm.protocols.gmpv7.Gmp,
57
                # gvm.protocols.gmpv8.Gmp or gvm.protocols.gmpv9.Gmp depending
58
                # on the supported GMP version of the remote manager daemon
59
                resp = gmp.get_tasks()
60
61
    Attributes:
62
        connection: Connection to use to talk with the remote daemon. See
63
            :mod:`gvm.connections` for possible connection types.
64
        transform: Optional transform `callable`_ to convert response data.
65
            After each request the callable gets passed the plain response data
66
            which can be used to check the data and/or conversion into different
67
            representations like a xml dom.
68
69
            See :mod:`gvm.transforms` for existing transforms.
70
71
    .. _callable:
72
        https://docs.python.org/3/library/functions.html#callable
73
    """
74
75
    def __init__(
76
        self,
77
        connection: GvmConnection,
78
        *,
79
        transform: Optional[Callable[[str], Any]] = None
80
    ):
81
        super().__init__(connection, transform=EtreeCheckCommandTransform())
82
        self._gmp_transform = transform
83
84
    def determine_remote_gmp_version(self) -> str:
85
        """Determine the supported GMP version of the remote daemon"""
86
        self.connect()
87
        resp = self._send_xml_command(XmlCommand("get_version"))
88
        self.disconnect()
89
90
        version_el = resp.find('version')
91
        if version_el is None:
92
            raise GvmError(
93
                'Invalid response from manager daemon while requesting the '
94
                'version information.'
95
            )
96
97
        return version_el.text
98
99
    def determine_supported_gmp(self) -> SUPPORTED_GMP_VERSIONS:
100
        """Determine supported GMP version of the remote daemon and return a
101
        corresponding Gmp class instance
102
        """
103
        version = self.determine_remote_gmp_version()
104
        major_version = int(version.split('.')[0])
105
        if major_version == 7:
106
            gmp_class = Gmpv7
107
        elif major_version == 8:
108
            gmp_class = Gmpv8
109
        elif major_version == 9:
110
            gmp_class = Gmpv9
111
        elif major_version == 20:
112
            gmp_class = Gmpv208
113
        elif major_version >= 21:
114
            gmp_class = Gmpv214
115
        else:
116
            raise GvmError(
117
                'Remote manager daemon uses an unsupported version of GMP. '
118
                'The GMP version was {}.'.format(version)
119
            )
120
121
        return gmp_class(self._connection, transform=self._gmp_transform)
122
123
    def __enter__(self):
124
        gmp = self.determine_supported_gmp()
125
126
        gmp.connect()
127
128
        return gmp
129