Passed
Push — master ( e3bfee...4746ec )
by Humberto
02:01
created

kytos/utils/client.py (1 issue)

Severity
1
"""REST communication with NApps Server."""
2
# This file is part of kytos-utils.
3
#
4
# Copyright (c) 2016 by Kytos Team.
5
#
6
# Authors:
7
#    Beraldo Leal <beraldo AT ncc DOT unesp DOT br>
8
9 1
import json
10 1
import logging
11 1
import os
12 1
import sys
13
14 1
import requests
15
16 1
from kytos.utils.config import KytosConfig
17 1
from kytos.utils.decorators import kytos_auth
18 1
from kytos.utils.exceptions import KytosException
19
20 1
LOG = logging.getLogger(__name__)
21
22
23 1
class CommonClient:
24
    """Generic class used to make request the NApps server."""
25
26 1
    def __init__(self, config=None):
27
        """Set Kytos config."""
28
        if config is None:
29
            config = KytosConfig().config
30
        self._config = config
31
32 1
    @staticmethod
33
    def make_request(endpoint, **kwargs):
34
        """Send a request to server."""
35
        data = kwargs.get('json', [])
36
        package = kwargs.get('package', None)
37
        method = kwargs.get('method', 'GET')
38
39
        function = getattr(requests, method.lower())
40
41
        try:
42
            if package:
43
                response = function(endpoint, data=data,
44
                                    files={'file': package})
45
            else:
46
                response = function(endpoint, json=data)
47
        except requests.exceptions.ConnectionError:
48
            LOG.error("Couldn't connect to NApps server %s.", endpoint)
49
            sys.exit(1)
50
51
        return response
52
53
54 1
class NAppsClient(CommonClient):
55
    """Client for the NApps Server."""
56
57 1
    def get_napps(self):
58
        """Get all NApps from the server."""
59
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps', '')
60
        res = self.make_request(endpoint)
61
62
        if res.status_code != 200:
63
            msg = 'Error getting NApps from server (%s) - %s'
64
            LOG.error(msg, res.status_code, res.reason)
65
            sys.exit(1)
66
67
        return json.loads(res.content.decode('utf-8'))['napps']
68
69 1
    def get_napp(self, username, name):
70
        """Return napp metadata or None if not found."""
71
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps',
72
                                username, name, '')
73
        res = self.make_request(endpoint)
74
        if res.status_code == 404:  # We need to know if NApp is not found
75
            return None
76
        if res.status_code != 200:
77
            msg = 'Error getting %s/%s from server: (%d) - %s'
78
            raise KytosException(msg % (username, name, res.status_code,
79
                                        res.reason))
80
        return json.loads(res.content)
81
82 1
    def reload_napps(self, napps=None):
83
        """Reload a specific NApp or all Napps.
84
85
        Args:
86
            napp (list): NApp list to be reload.
87
        Raises:
88
            requests.HTTPError: When there's a server error.
89
90
        """
91
        if napps is None:
92
            napps = []
93
            api = self._config.get('kytos', 'api')
94
            endpoint = os.path.join(api, 'api', 'kytos', 'core', 'reload',
95
                                    'all')
96
            response = self.make_request(endpoint)
97
98
        for napp in napps:
99
            api = self._config.get('kytos', 'api')
100
            endpoint = os.path.join(api, 'api', 'kytos', 'core', 'reload',
101
                                    napp[0], napp[1])
102
            response = self.make_request(endpoint)
103
104
        if response.status_code != 200:
0 ignored issues
show
The variable response does not seem to be defined in case napps is None on line 91 is False. Are you sure this can never be the case?
Loading history...
105
            raise KytosException('Error reloading the napp: Module not founded'
106
                                 ' or could not be imported')
107
108
        return response.content
109
110 1
    @kytos_auth
111
    def upload_napp(self, metadata, package):
112
        """Upload the napp from the current directory to the napps server."""
113
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps', '')
114
        metadata['token'] = self._config.get('auth', 'token')
115
        response = self.make_request(endpoint, json=metadata, package=package,
116
                                     method="POST")
117
        if response.status_code != 201:
118
            KytosConfig().clear_token()
119
            LOG.error("%s: %s - %s", response.status_code, response.reason,
120
                      response.content.decode('utf-8'))
121
            sys.exit(1)
122
123
        # WARNING: this will change in future versions, when 'author' will get
124
        # removed.
125
        username = metadata.get('username', metadata.get('author'))
126
        name = metadata.get('name')
127
128
        print("SUCCESS: NApp {}/{} uploaded.".format(username, name))
129
130 1
    @kytos_auth
131
    def delete(self, username, napp):
132
        """Delete a NApp.
133
134
        Raises:
135
            requests.HTTPError: If 400 <= status < 600.
136
137
        """
138
        api = self._config.get('napps', 'api')
139
        endpoint = os.path.join(api, 'napps', username, napp, '')
140
        content = {'token': self._config.get('auth', 'token')}
141
        response = self.make_request(endpoint, json=content, method='DELETE')
142
        response.raise_for_status()
143
144
145 1
class UsersClient(CommonClient):
146
    """Client for the NApps Server."""
147
148 1
    def register(self, user_dict):
149
        """Send an user_dict to NApps server using POST request.
150
151
        Args:
152
            user_dict(dict): Dictionary with user attributes.
153
154
        Returns:
155
            result(string): Return the response of Napps server.
156
157
        """
158
        endpoint = os.path.join(self._config.get('napps', 'api'), 'users', '')
159
        res = self.make_request(endpoint, method='POST', json=user_dict)
160
161
        return res.content.decode('utf-8')
162