File: client.py

package info (click to toggle)
kytos-utils 2019.2-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 396 kB
  • sloc: python: 1,310; sh: 15; makefile: 3
file content (161 lines) | stat: -rw-r--r-- 5,415 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
"""REST communication with NApps Server."""
# This file is part of kytos-utils.
#
# Copyright (c) 2016 by Kytos Team.
#
# Authors:
#    Beraldo Leal <beraldo AT ncc DOT unesp DOT br>

import json
import logging
import os
import sys

import requests

from kytos.utils.config import KytosConfig
from kytos.utils.decorators import kytos_auth
from kytos.utils.exceptions import KytosException

LOG = logging.getLogger(__name__)


class CommonClient:
    """Generic class used to make request the NApps server."""

    def __init__(self, config=None):
        """Set Kytos config."""
        if config is None:
            config = KytosConfig().config
        self._config = config

    @staticmethod
    def make_request(endpoint, **kwargs):
        """Send a request to server."""
        data = kwargs.get('json', [])
        package = kwargs.get('package', None)
        method = kwargs.get('method', 'GET')

        function = getattr(requests, method.lower())

        try:
            if package:
                response = function(endpoint, data=data,
                                    files={'file': package})
            else:
                response = function(endpoint, json=data)
        except requests.exceptions.ConnectionError:
            LOG.error("Couldn't connect to NApps server %s.", endpoint)
            sys.exit(1)

        return response


class NAppsClient(CommonClient):
    """Client for the NApps Server."""

    def get_napps(self):
        """Get all NApps from the server."""
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps', '')
        res = self.make_request(endpoint)

        if res.status_code != 200:
            msg = 'Error getting NApps from server (%s) - %s'
            LOG.error(msg, res.status_code, res.reason)
            sys.exit(1)

        return json.loads(res.content.decode('utf-8'))['napps']

    def get_napp(self, username, name):
        """Return napp metadata or None if not found."""
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps',
                                username, name, '')
        res = self.make_request(endpoint)
        if res.status_code == 404:  # We need to know if NApp is not found
            return None
        if res.status_code != 200:
            msg = 'Error getting %s/%s from server: (%d) - %s'
            raise KytosException(msg % (username, name, res.status_code,
                                        res.reason))
        return json.loads(res.content)

    def reload_napps(self, napps=None):
        """Reload a specific NApp or all Napps.

        Args:
            napp (list): NApp list to be reload.
        Raises:
            requests.HTTPError: When there's a server error.

        """
        if napps is None:
            napps = []
            api = self._config.get('kytos', 'api')
            endpoint = os.path.join(api, 'api', 'kytos', 'core', 'reload',
                                    'all')
            response = self.make_request(endpoint)

        for napp in napps:
            api = self._config.get('kytos', 'api')
            endpoint = os.path.join(api, 'api', 'kytos', 'core', 'reload',
                                    napp[0], napp[1])
            response = self.make_request(endpoint)

        if response.status_code != 200:
            raise KytosException('Error reloading the napp: Module not founded'
                                 ' or could not be imported')

        return response.content

    @kytos_auth
    def upload_napp(self, metadata, package):
        """Upload the napp from the current directory to the napps server."""
        endpoint = os.path.join(self._config.get('napps', 'api'), 'napps', '')
        metadata['token'] = self._config.get('auth', 'token')
        response = self.make_request(endpoint, json=metadata, package=package,
                                     method="POST")
        if response.status_code != 201:
            KytosConfig().clear_token()
            LOG.error("%s: %s - %s", response.status_code, response.reason,
                      response.content.decode('utf-8'))
            sys.exit(1)

        # WARNING: this will change in future versions, when 'author' will get
        # removed.
        username = metadata.get('username', metadata.get('author'))
        name = metadata.get('name')

        print("SUCCESS: NApp {}/{} uploaded.".format(username, name))

    @kytos_auth
    def delete(self, username, napp):
        """Delete a NApp.

        Raises:
            requests.HTTPError: If 400 <= status < 600.

        """
        api = self._config.get('napps', 'api')
        endpoint = os.path.join(api, 'napps', username, napp, '')
        content = {'token': self._config.get('auth', 'token')}
        response = self.make_request(endpoint, json=content, method='DELETE')
        response.raise_for_status()


class UsersClient(CommonClient):
    """Client for the NApps Server."""

    def register(self, user_dict):
        """Send an user_dict to NApps server using POST request.

        Args:
            user_dict(dict): Dictionary with user attributes.

        Returns:
            result(string): Return the response of Napps server.

        """
        endpoint = os.path.join(self._config.get('napps', 'api'), 'users', '')
        res = self.make_request(endpoint, method='POST', json=user_dict)

        return res.content.decode('utf-8')