Files
esp-rainmaker/cli/rmaker_lib/node.py
Shivani Tipnis 647ab47ebf ota: Fix OTA Upgrade error messages and ota service checks handling
Fixed message handling for OTA failure if no internet connectivity

Fixed config check for ota service support before uploading image
2020-06-06 00:35:16 +05:30

381 lines
15 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 Timeout as time_err:
log.debug(time_err)
raise RequestTimeoutError
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
"""
socket.setdefaulttimeout(10)
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,
timeout=(5.0, 5.0))
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 Timeout as time_err:
log.debug(time_err)
raise RequestTimeoutError
except RequestException as get_nodes_config_err:
log.debug(get_nodes_config_err)
raise get_nodes_config_err
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
"""
socket.setdefaulttimeout(10)
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,
timeout=(5.0, 5.0))
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 Timeout as time_err:
log.debug(time_err)
raise RequestTimeoutError
except RequestException as get_nodes_params_err:
log.debug(get_nodes_params_err)
raise get_nodes_params_err
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
"""
socket.setdefaulttimeout(10)
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))
log.debug("Set node params request header : " + json.dumps(self.request_header))
response = requests.put(url=setparams_url,
data=json.dumps(data),
headers=self.request_header,
verify=configmanager.CERT_FILE,
timeout=(5.0, 5.0))
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 Timeout as time_err:
log.debug(time_err)
raise RequestTimeoutError
except RequestException as set_nodes_params_err:
log.debug(set_nodes_params_err)
raise set_nodes_params_err
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