Files
esp-rainmaker/cli/rmaker_lib/node.py
Shivani Tipnis 42ad3f89ac cli-provisioning: Fixed connectivity and import checks
Added checks and fixed error handling for poor internet connectivity

Fixed error handling checks while importing modules

Fixed mock imports in docs
2020-05-18 19:40:02 +05:30

357 lines
14 KiB
Python

# Copyright 2020 Espressif Systems (Shanghai) PTE LTD
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import requests
import json
import socket
from rmaker_lib import serverconfig, configmanager
from requests.exceptions import Timeout, ConnectionError,\
RequestException
from rmaker_lib.exceptions import NetworkError, InvalidClassInput, SSLError,\
RequestTimeoutError
from rmaker_lib.logger import log
class Node:
"""
Node class used to instantiate instances of node to perform various
node operations.
:param nodeid: Node Id of node
:type nodeid: str
:param session: :class:`rmaker_lib.session.Session`
:type session: object
"""
def __init__(self, nodeid, session):
"""
Instantiate node with nodeid and session object.
"""
log.info("Initialising node with nodeid : " + nodeid)
self.__nodeid = nodeid
self.__session = session
try:
self.__request_header = {'content-type': 'application/json',
'Authorization': session.id_token}
except AttributeError:
raise InvalidClassInput(session, 'Invalid Session Input.\
Expected: type <session object>.\
Received: ')
def get_nodeid(self):
"""
Get nodeid of device
:return: Node Id of node on Success
:rtype: str
"""
return self.__nodeid
def get_node_status(self):
"""
Get online/offline status of the node.
:raises NetworkError: If there is a network connection issue while
getting node status
:raises Exception: If there is an HTTP issue while getting node status
:return: Status of node on Success
:rtype: dict
"""
log.info("Getting online/offline status of the node : " +
self.__nodeid)
path = 'user/nodes/status'
query_parameters = 'nodeid=' + self.__nodeid
getnodestatus_url = serverconfig.HOST + path + '?' + query_parameters
try:
log.debug("Get node status request url : " + getnodestatus_url)
response = requests.get(url=getnodestatus_url,
headers=self.__request_header,
verify=configmanager.CERT_FILE)
log.debug("Get node status response : " + response.text)
response.raise_for_status()
except requests.exceptions.SSLError:
raise SSLError
except requests.exceptions.ConnectionError:
raise NetworkError
except Exception:
raise Exception(response.text)
log.info("Received node status successfully.")
return response.json()
def get_node_config(self):
"""
Get node configuration.
:raises NetworkError: If there is a network connection issue while
getting node configuration
:raises Exception: If there is an HTTP issue while getting node config
:return: Configuration of node on Success
:rtype: dict
"""
log.info("Getting node config for node : " + self.__nodeid)
path = 'user/nodes/config'
query_parameters = 'nodeid=' + self.__nodeid
getnodeconfig_url = serverconfig.HOST + path + '?' + query_parameters
try:
log.debug("Get node config request url : " + getnodeconfig_url)
response = requests.get(url=getnodeconfig_url,
headers=self.__request_header,
verify=configmanager.CERT_FILE)
log.debug("Get node config response : " + response.text)
response.raise_for_status()
except requests.exceptions.SSLError:
raise SSLError
except requests.exceptions.ConnectionError:
raise NetworkError
except Exception:
raise Exception(response.text)
log.info("Received node config successfully.")
return response.json()
def get_node_params(self):
"""
Get parameters of the node.
:raises NetworkError: If there is a network connection issue while
getting node params
:raises Exception: If there is an HTTP issue while getting node params
or JSON format issue in HTTP response
:return: Node Parameters on Success, None on Failure
:rtype: dict | None
"""
log.info("Getting parameters of the node with nodeid : " +
self.__nodeid)
path = 'user/nodes/params'
query_parameters = 'nodeid=' + self.__nodeid
getparams_url = serverconfig.HOST + path + '?' + query_parameters
try:
log.debug("Get node params request url : " + getparams_url)
response = requests.get(url=getparams_url,
headers=self.__request_header,
verify=configmanager.CERT_FILE)
log.debug("Get node params response : " + response.text)
response.raise_for_status()
except requests.exceptions.SSLError:
raise SSLError
except requests.exceptions.ConnectionError:
raise NetworkError
except Exception:
raise Exception(response.text)
response = json.loads(response.text)
if 'status' in response and response['status'] == 'failure':
return None
log.info("Received node parameters successfully.")
return response
def set_node_params(self, data):
"""
Set parameters of the node.
:param data: Parameters to be set for the node
:type data: dict
:raises NetworkError: If there is a network connection issue while
setting node params
:raises Exception: If there is an HTTP issue while setting node params
or JSON format issue in HTTP response
:return: True on Success
:rtype: bool
"""
log.info("Updating parameters of the node with nodeid : " +
self.__nodeid)
path = 'user/nodes/params'
query_parameters = 'nodeid=' + self.__nodeid
setparams_url = serverconfig.HOST + path + '?' + query_parameters
try:
log.debug("Set node params request url : " + setparams_url)
log.debug("Set node params request payload : " + json.dumps(data))
response = requests.put(url=setparams_url,
data=json.dumps(data),
headers=self.__request_header,
verify=configmanager.CERT_FILE)
log.debug("Set node params response : " + response.text)
response.raise_for_status()
except requests.exceptions.SSLError:
raise SSLError
except requests.exceptions.ConnectionError:
raise NetworkError
except Exception:
raise Exception(response.text)
log.info("Updated node parameters successfully.")
return True
def __user_node_mapping(self, secret_key, operation):
"""
Add or remove the user node mapping.
:param secret_key: The randomly generated secret key that will be
used for User-Node mapping
:type secret_key: str
:param operation: Operation to be performed, can take values
'add' or 'remove'
:type operation: str
:raises NetworkError: If there is a network connection issue
while adding user node mapping
:raises Exception: If there is an HTTP issue or JSON format issue
in HTTP response
:return: Request Id if Success, None if Failure
:rtype: str | None
"""
socket.setdefaulttimeout(10)
path = 'user/nodes/mapping'
config = configmanager.Config()
userid = config.get_user_id()
request_payload = {
'user_id': userid,
'node_id': self.__nodeid,
'secret_key': secret_key,
'operation': operation
}
request_url = serverconfig.HOST + path
try:
log.debug("User node mapping request url : " + request_url)
log.debug("User node mapping request payload : " +
str(request_payload))
response = requests.put(url=request_url,
data=json.dumps(request_payload),
headers=self.__request_header,
verify=configmanager.CERT_FILE,
timeout=(5.0, 5.0))
log.debug("User node mapping response : " + response.text)
response.raise_for_status()
except requests.exceptions.SSLError as ssl_err:
log.debug(ssl_err)
raise SSLError
except (ConnectionError, socket.timeout) as conn_err:
log.debug(conn_err)
raise NetworkError
except Timeout as time_err:
log.debug(time_err)
raise RequestTimeoutError
except RequestException as mapping_status_err:
log.debug(mapping_status_err)
raise mapping_status_err
try:
response = json.loads(response.text)
except Exception as user_node_mapping_err:
raise user_node_mapping_err
if 'request_id' in response:
return response['request_id']
return None
def add_user_node_mapping(self, secret_key):
"""
Add user node mapping.
:param secret_key: The randomly generated secret key that will be
used for User-Node mapping
:type secret_key: str
:raises NetworkError: If there is a network connection issue while
adding user node mapping
:raises Exception: If there is an HTTP issue while
adding user node mapping or
JSON format issue in HTTP response
:return: Request Id on Success, None on Failure
:rtype: str | None
"""
log.info("Adding user node mapping request with nodeid : " +
self.__nodeid)
return self.__user_node_mapping(secret_key, 'add')
def remove_user_node_mapping(self):
"""
Remove user node mapping request.
:raises NetworkError: If there is a network connection issue while
removing user node mapping
:raises Exception: If there is an HTTP issue while
removing user node mapping or
JSON format issue in HTTP response
:return: Request Id on Success, None on Failure
:rtype: str | None
"""
log.info("Removing user node mapping with nodeid : " + self.__nodeid)
secret_key = ""
return self.__user_node_mapping(secret_key, 'remove')
def get_mapping_status(self, request_id):
"""
Check status of user node mapping request.
:param requestId: Request Id
:type requestId: str
:raises NetworkError: If there is a network connection issue while
getting user node mapping status
:raises Exception: If there is an HTTP issue while getting
user node mapping status or JSON format issue
in HTTP response
:return: Request Status on Success, None on Failure
:type: str | None
"""
socket.setdefaulttimeout(10)
log.debug("Checking status of user node mapping with request_id : " +
request_id)
path = 'user/nodes/mapping'
query_parameters = "&request_id=" + request_id
request_url = serverconfig.HOST + path + '?' + query_parameters
try:
log.debug("Check user node mapping status request url : " +
request_url)
response = requests.get(url=request_url,
headers=self.__request_header,
verify=configmanager.CERT_FILE,
timeout=(5.0, 5.0))
log.debug("Check user node mapping status response : " +
response.text)
response.raise_for_status()
except requests.exceptions.SSLError as ssl_err:
log.debug(ssl_err)
raise SSLError
except (ConnectionError, socket.timeout) as conn_err:
log.debug(conn_err)
raise NetworkError
except Timeout as time_err:
log.debug(time_err)
raise RequestTimeoutError
except RequestException as mapping_status_err:
log.debug(mapping_status_err)
raise mapping_status_err
try:
response = json.loads(response.text)
except Exception as mapping_status_err:
raise mapping_status_err
if 'request_status' in response:
return response['request_status']
return None