Passed
Pull Request — master (#186)
by Jaspar
12:57
created

Gmp.determine_remote_gmp_version()   A

Complexity

Conditions 2

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
nop 1
dl 0
loc 15
rs 9.95
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# Copyright (C) 2019 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
32
from gvm.transforms import EtreeCheckCommandTransform
33
34
from gvm.xml import XmlCommand
35
36
SupportedGmpVersion = Union[Gmpv7, Gmpv8, Gmpv9]
37
38
39
class Gmp(GvmProtocol):
40
    """Dynamically select supported GMP protocol of the remote manager daemon.
41
42
    Must be used as a `Context Manager
43
    <https://docs.python.org/3/reference/datamodel.html#context-managers>`_
44
45
    Example:
46
47
        .. code-block:: python
48
49
            from gvm.protocols.gmp import Gmp
50
51
            with Gmp(connection) as gmp:
52
                # gmp can be an instance of gvm.protocols.gmpv7.Gmp,
53
                # gvm.protocols.gmpv8.Gmp or gvm.protocols.gmpv9.Gmp depending
54
                # on the supported GMP version of the remote manager daemon
55
                resp = gmp.get_tasks()
56
57
    Attributes:
58
        connection: Connection to use to talk with the remote daemon. See
59
            :mod:`gvm.connections` for possible connection types.
60
        transform: Optional transform `callable`_ to convert response data.
61
            After each request the callable gets passed the plain response data
62
            which can be used to check the data and/or conversion into different
63
            representations like a xml dom.
64
65
            See :mod:`gvm.transforms` for existing transforms.
66
67
    .. _callable:
68
        https://docs.python.org/3/library/functions.html#callable
69
    """
70
71
    def __init__(
72
        self,
73
        connection: GvmConnection,
74
        *,
75
        transform: Optional[Callable[[str], Any]] = None
76
    ):
77
        super().__init__(connection, transform=EtreeCheckCommandTransform())
78
        self._gmp_transform = transform
79
80
    def determine_remote_gmp_version(self) -> str:
81
        """ Determine the supported GMP version of the remote deamon
82
        """
83
        self.connect()
84
        resp = self._send_xml_command(XmlCommand("get_version"))
85
        self.disconnect()
86
87
        version_el = resp.find('version')
88
        if version_el is None:
89
            raise GvmError(
90
                'Invalid response from manager daemon while requesting the '
91
                'version information.'
92
            )
93
94
        return version_el.text
95
96
    def determine_supported_gmp(self) -> SupportedGmpVersion:
97
        """ Determine supported GMP version of the remote deamon and return a
98
            corresponding Gmp class instance
99
        """
100
        version = self.determine_remote_gmp_version()
101
        major_version = int(version[0])
102
        if major_version == 7:
103
            gmp_class = Gmpv7
104
        elif major_version == 8:
105
            gmp_class = Gmpv8
106
        elif major_version >= 9:
107
            gmp_class = Gmpv9
108
        else:
109
            raise GvmError(
110
                'Remote manager daemon uses an unsupported version of GMP. '
111
                'The GMP version was {}.'.format(version)
112
            )
113
114
        return gmp_class(self._connection, transform=self._gmp_transform)
115
116
    def __enter__(self):
117
        gmp = self.determine_supported_gmp()
118
119
        gmp.connect()
120
121
        return gmp
122