Passed
Push — master ( 79cc3a...1e4540 )
by Beraldo
01:32
created

NAppsClient.reload_napps()   B

Complexity

Conditions 4

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
c 0
b 0
f 0
dl 0
loc 27
rs 8.5806
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
import json
10
import logging
11
import os
12
import sys
13
14
import requests
15
16
from kytos.utils.config import KytosConfig
17
from kytos.utils.decorators import kytos_auth
18
from kytos.utils.exceptions import KytosException
19
20
LOG = logging.getLogger(__name__)
21
22
23
class CommonClient:
24
    """Generic class used to make request the Napss server."""
25
26
    def __init__(self, config=None):
27
        """Set Kytos config."""
28
        if config is None:
29
            config = KytosConfig().config
30
        self._config = config
31
32
    @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
class NAppsClient(CommonClient):
55
    """Client for the NApps Server."""
56
57
    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
    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
        elif res.status_code != 200:
77
            raise KytosException('Error getting %s/%s from server: (%d) - %s',
78
                                 username, name, res.status_code, res.reason)
79
        return json.loads(res.content)
80
81
    def reload_napps(self, napps=None):
82
        """Reload a specific NApp or all Napps.
83
84
        Args:
85
            napp (list): NApp list to be reload.
86
        Raises:
87
            requests.HTTPError: When there's a server error.
88
89
        """
90
        if napps is None:
91
            napps = []
92
            api = self._config.get('kytos', 'api')
93
            endpoint = os.path.join(api, 'api', 'kytos', 'core', 'reload',
94
                                    'all')
95
            response = self.make_request(endpoint)
96
97
        for napp in napps:
98
            api = self._config.get('kytos', 'api')
99
            endpoint = os.path.join(api, 'api', 'kytos', 'core', 'reload',
100
                                    napp[0], napp[1])
101
            response = self.make_request(endpoint)
102
103
        if response.status_code != 200:
104
            raise KytosException('Error reloading the napp: Module not founded'
105
                                 ' or could not be imported')
106
107
        return response.content
108
109
    @kytos_auth
110
    def upload_napp(self, metadata, package):
111
        """Upload the napp from the current directory to the napps server."""
112
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps', '')
113
        metadata['token'] = self._config.get('auth', 'token')
114
        request = self.make_request(endpoint, json=metadata, package=package,
115
                                    method="POST")
116
        if request.status_code != 201:
117
            KytosConfig().clear_token()
118
            LOG.error("%s: %s", request.status_code, request.reason)
119
            sys.exit(1)
120
121
        # WARNING: this will change in future versions, when 'author' will get
122
        # removed.
123
        username = metadata.get('username', metadata.get('author'))
124
        name = metadata.get('name')
125
126
        print("SUCCESS: NApp {}/{} uploaded.".format(username, name))
127
128
    @kytos_auth
129
    def delete(self, username, napp):
130
        """Delete a NApp.
131
132
        Raises:
133
            requests.HTTPError: If 400 <= status < 600.
134
135
        """
136
        api = self._config.get('napps', 'api')
137
        endpoint = os.path.join(api, 'napps', username, napp, '')
138
        content = {'token': self._config.get('auth', 'token')}
139
        response = self.make_request(endpoint, json=content, method='DELETE')
140
        response.raise_for_status()
141
142
143
class UsersClient(CommonClient):
144
    """Client for the NApps Server."""
145
146
    def register(self, user_dict):
147
        """Send an user_dict to NApps server using POST request.
148
149
        Args:
150
            user_dict(dict): Dictionary with user attributes.
151
152
        Returns:
153
            result(string): Return the response of Napps server.
154
155
        """
156
        endpoint = os.path.join(self._config.get('napps', 'api'), 'users', '')
157
        res = self.make_request(endpoint, method='POST', json=user_dict)
158
159
        return res.content.decode('utf-8')
160