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')
|