Completed
Pull Request — master (#277)
by Gleyberson
01:29
created

kytos.utils.client.NAppsClient.upload_napp()   A

Complexity

Conditions 2

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2.0811

Importance

Changes 0
Metric Value
cc 2
eloc 14
nop 3
dl 0
loc 19
rs 9.7
c 0
b 0
f 0
ccs 8
cts 11
cp 0.7272
crap 2.0811
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 1
        if config is None:
29 1
            config = KytosConfig().config
30 1
        self._config = config
31
32 1
    @staticmethod
33
    def make_request(endpoint, **kwargs):
34
        """Send a request to server."""
35 1
        data = kwargs.get('json', [])
36 1
        package = kwargs.get('package', None)
37 1
        method = kwargs.get('method', 'GET')
38
39 1
        function = getattr(requests, method.lower())
40
41 1
        try:
42 1
            if package:
43 1
                response = function(endpoint, data=data,
44
                                    files={'file': package})
45
            else:
46 1
                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 1
        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 1
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps', '')
60 1
        res = self.make_request(endpoint)
61
62 1
        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 1
        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 1
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps',
72
                                username, name, '')
73 1
        res = self.make_request(endpoint)
74 1
        if res.status_code == 404:  # We need to know if NApp is not found
75
            return None
76 1
        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 1
        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 1
        if napps is None:
92 1
            napps = []
93 1
            api = self._config.get('kytos', 'api')
94 1
            endpoint = os.path.join(api, 'api', 'kytos', 'core', 'reload',
95
                                    'all')
96 1
            response = self.make_request(endpoint)
97
98 1
        for napp in napps:
99 1
            api = self._config.get('kytos', 'api')
100 1
            endpoint = os.path.join(api, 'api', 'kytos', 'core', 'reload',
101
                                    napp[0], napp[1])
102 1
            response = self.make_request(endpoint)
103
104 1
        if response.status_code != 200:
105
            raise KytosException('Error reloading the napp: Module not founded'
106
                                 ' or could not be imported')
107
108 1
        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 1
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps', '')
114 1
        metadata['token'] = self._config.get('auth', 'token')
115 1
        response = self.make_request(endpoint, json=metadata, package=package,
116
                                     method="POST")
117 1
        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 1
        username = metadata.get('username', metadata.get('author'))
126 1
        name = metadata.get('name')
127
128 1
        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 1
        api = self._config.get('napps', 'api')
139 1
        endpoint = os.path.join(api, 'napps', username, napp, '')
140 1
        content = {'token': self._config.get('auth', 'token')}
141 1
        response = self.make_request(endpoint, json=content, method='DELETE')
142 1
        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 1
        endpoint = os.path.join(self._config.get('napps', 'api'), 'users', '')
159 1
        res = self.make_request(endpoint, method='POST', json=user_dict)
160
161
        return res.content.decode('utf-8')
162