示例#1
0
def save_random_hex_str(dest_filedir, hex_str):
    """
    Create file for random hex string and update node_info.csv

    :param dest_filedir: Destination File Directory
    :type dest_filedir: str

    :param hex_str: Random hex string to write
    :type hex_str: str

    :raises Exception: If there is any issue when writing to file

    :return: None on Success
    :rtype: None
    """
    try:
        log.debug("Writing random hex string at location: " + dest_filedir +
                  'random.info')
        with open(dest_filedir + 'random.info', 'w+') as info_file:
            info_file.write(hex_str)

        with open(dest_filedir + 'node_info.csv', 'a') as info_file:
            info_file.write('random,file,hex2bin,' + dest_filedir +
                            'random.info')
            info_file.write('\n')
    except Exception as err:
        log.error(err)
示例#2
0
def start_claim_process(mac_addr, node_platform, private_key):
    log.info("Creating session")
    curr_session = session.Session()
    header = curr_session.request_header
    try:
        # Set claim initiate data
        claim_init_data = set_claim_initiate_data(mac_addr, node_platform)

        # Perform claim initiate request
        claim_init_resp = claim_initiate(claim_init_data, header)

        # Set claim verify data
        claim_verify_data, node_info = set_claim_verify_data(
            claim_init_resp, private_key)

        # Perform claim verify request
        claim_verify_resp = claim_verify(claim_verify_data, header)

        # Get certificate from claim verify response
        node_cert = json.loads(claim_verify_resp.text)['certificate']
        print("Claim certificate received")
        log.info("Claim certificate received")

        return node_info, node_cert
    except requests.exceptions.SSLError:
        raise SSLError
    except requests.ConnectionError:
        log.error("Please check the Internet connection.")
        exit(0)
def check_status(node_object, request_id):
    status = None
    while True:
        log.debug('Checking user-node association status.')
        try:
            status = node_object.get_mapping_status(request_id)
        except Exception as mapping_status_err:
            log.error(mapping_status_err)
            return
        else:
            log.debug('User-node association status ' + status)
            if status == 'requested':
                print('Checking User Node association status - Requested\n'
                      'Retrying...')
            elif status == 'confirmed':
                print('Checking User Node association status - Confirmed')
                return
            elif status == 'timedout':
                print('Checking User Node association status - Timeout')
                return
            elif status == 'discarded':
                print('Checking User Node association status - Discarded')
                return
        time.sleep(5)
    return
示例#4
0
def claim_node(vars=None):
    """
    Claim the node connected to the given serial port
    (Get cloud credentials)

    :param vars: `port` as key - Serial Port, defaults to `None`
    :type vars: str | None

    :raises Exception: If there is an HTTP issue while claiming

    :return: None on Success
    :rtype: None
    """
    try:
        if not vars['port'] and not vars['mac'] and not vars['addr'] and not vars['platform']:
            sys.exit(vars['parser'].print_help())
        if vars['addr'] and not vars['port'] and not vars['platform']:
            sys.exit('Invalid. <port> or --platform argument is needed.')
        if vars['port']:
            if not vars['mac'] and not vars['platform']:
                claim(port=vars['port'], node_platform=vars['platform'], mac_addr=vars['mac'], flash_address=vars['addr'])
                return
        if (vars['mac'] and not vars['platform']):
            sys.exit("Invalid. --platform argument needed.")
        if (not vars['mac'] and vars['platform']):
            sys.exit("Invalid. --mac argument needed.")
        if vars['mac']:
            if not re.match(r'([0-9A-F]:?){12}', vars['mac']):
                sys.exit('Invalid MAC address.')
        claim(port=vars['port'], node_platform=vars['platform'], mac_addr=vars['mac'], flash_address=vars['addr'])
    except Exception as claim_err:
        log.error(claim_err)
        return
示例#5
0
def get_password():
    """
    Get Password as input and perform basic password validation checks.

    :raises SystemExit: If there is an issue in getting password

    :return: Password for User on Success
    :rtype: str
    """
    log.info('Doing basic password confirmation checks.')
    password_policy = '8 characters, 1 digit, 1 uppercase and 1 lowercase.'
    password_change_attempt = 0

    print('Choose a password')
    while password_change_attempt < MAX_PASSWORD_CHANGE_ATTEMPTS:
        log.debug('Password change attempt number ' +
                  str(password_change_attempt + 1))
        password = getpass.getpass('Password : '******'Password should contain at least', password_policy)
            password_change_attempt += 1
            continue
        confirm_password = getpass.getpass('Confirm Password : '******'Passwords do not match!\n'
                  'Please enter the password again ..')
        password_change_attempt += 1

    log.error('Maximum attempts to change password over. Please try again.')
    sys.exit(1)
示例#6
0
def claim_initiate(claim_init_data, header):
    print("Claim initiate started")
    claim_initiate_url = CLAIM_INITIATE_URL
    try:
        # Claim Initiate Request
        log.info("Claim initiate started. Sending claim/initiate POST request")
        log.debug("Claim Initiate POST Request: url: " + claim_initiate_url +
                  "data: " + str(claim_init_data) + "headers: " + str(header) +
                  "verify: " + CERT_FILE)
        claim_initiate_response = requests.post(url=claim_initiate_url,
                                                data=claim_init_data,
                                                headers=header,
                                                verify=CERT_FILE)
        if claim_initiate_response.status_code != 200:
            log.error("Claim initiate failed.\n" +
                      claim_initiate_response.text)
            exit(0)
        print("Claim initiate done")
        log.debug("Claim Initiate POST Response: status code: " +
                  str(claim_initiate_response.status_code) +
                  " and response text: " + claim_initiate_response.text)
        log.info("Claim initiate done")
        return claim_initiate_response
    except requests.exceptions.SSLError:
        raise SSLError
    except requests.ConnectionError:
        log.error("Please check the Internet connection.")
        exit(0)
示例#7
0
    def do_GET(self):
        """
        Handle a GET request and
        writes the ESP Rainmaker Welcome HTML page(response)
        back to HTTP Client

        :raises Exception: If there is any File Handling Issue

        :return: None on Success and Failure
        :rtype: None
        """
        log.debug('Loading the welcome page after successful login.')
        self.send_response(http_client.OK)
        self.send_header('Content-type', 'text/html')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.end_headers()
        parts = urllib.parse.urlparse(self.path)
        query = _helpers.parse_unique_urlencoded(parts.query)
        self.server.query_params = query
        index_file = os.path.join(os.path.expanduser('.'), 'html/welcome.html')

        try:
            with open(index_file, 'rb') as home_page:
                self.wfile.write(home_page.read())
        except Exception as file_err:
            log.error(file_err)
            sys.exit(1)
示例#8
0
def remove_node(vars=None):
    """
    Removes the user node mapping.

    :param vars: `nodeid` as key - Node ID for the node, defaults to `None`
    :type vars: dict | None

    :raises NetworkError: If there is a network connection issue during
                          HTTP request for removing node
    :raises Exception: If there is an HTTP issue while removing node or
                       JSON format issue in HTTP response

    :return: None on Success
    :rtype: None
    """
    log.info('Removing user node mapping for node ' + vars['nodeid'])
    try:
        n = node.Node(vars['nodeid'], session.Session())
        params = n.remove_user_node_mapping()
    except Exception as remove_node_err:
        log.error(remove_node_err)
    else:
        log.debug('Removed the user node mapping successfully.')
        print('Removed node ' + vars['nodeid'] + ' successfully.')
    return
示例#9
0
def claim_verify(claim_verify_data, header):
    claim_verify_url = CLAIM_VERIFY_URL
    user_whitelist_err_msg = ('User is not allowed to claim esp32 device.'
                              ' please contact administrator')
    claim_verify_enc_data = str(claim_verify_data).replace("'", '"')
    log.debug("Claim Verify POST Request: url: " + claim_verify_url +
              "data: " + str(claim_verify_enc_data) + "headers: " +
              str(header) + "verify: " + CERT_FILE)
    claim_verify_response = requests.post(url=claim_verify_url,
                                          data=claim_verify_enc_data,
                                          headers=header,
                                          verify=CERT_FILE)
    if claim_verify_response.status_code != 200:
        claim_verify_response_json = json.loads(
            claim_verify_response.text.lower())
        if (claim_verify_response_json["description"]
                in user_whitelist_err_msg):
            log.error('Claim verification failed.\n' +
                      claim_verify_response.text)
            print('\nYour account isn\'t whitelisted for ESP32.'
                  ' Please send your registered email address to'
                  ' [email protected] for whitelisting')
        else:
            log.error('Claim verification failed.\n' +
                      claim_verify_response.text)
        exit(0)
    print("Claim verify done")
    log.debug("Claim Verify POST Response: status code: " +
              str(claim_verify_response.status_code) + " and response text: " +
              claim_verify_response.text)
    log.info("Claim verify done")
    return claim_verify_response
示例#10
0
def flash_nvs_partition_bin(port, bin_to_flash, address):
    """
    Flash binary onto node

    :param port: Serial Port
    :type port: str

    :param bin_to_flash: Filname of binary to flash
    :type bin_to_flash: str

    :raises Exception: If there is any issue when flashing binary onto node

    :return: None on Success
    :rtype: None
    """
    try:
        if not port:
            sys.exit(
                "If you want to write the claim data to flash, please provide the <port> argument."
            )
        print("Flashing binary onto node")
        log.info("Flashing binary onto node")
        command = ['--port', port, 'write_flash', address, bin_to_flash]
        esptool.main(command)
    except Exception as err:
        log.error(err)
        sys.exit(1)
示例#11
0
def set_params(vars=None):
    """
    Set parameters of the node.

    :param vars:
        `nodeid` as key - Node ID for the node,\n
        `data` as key - JSON data containing parameters to be set `or`\n
        `filepath` as key - Path of the JSON file containing parameters
                            to be set,\n
        defaults to `None`
    :type vars: dict | None

    :raises Exception: If there is an HTTP issue while setting params or
                       JSON format issue in HTTP response

    :return: None on Success
    :rtype: None
    """
    log.info('Setting params of the node with nodeid : ' + vars['nodeid'])
    data = vars['data']
    filepath = vars['filepath']

    if data is not None:
        log.debug('Setting node parameters using JSON data.')
        # Trimming white spaces except the ones between two strings
        data = re.sub(
            r"(?<![a-z]|[A-Z])\s(?![a-z]|[A-Z])|\
            (?<=[a-z]|[A-Z])\s(?![a-z]|[A-Z])|\
                (?<![a-z]|[A-Z])\s(?=[a-z]|[A-Z])", "", data)
        try:
            log.debug('JSON data : ' + data)
            data = json.loads(data)
        except Exception:
            raise InvalidJSONError
            return

    elif filepath is not None:
        log.debug('Setting node parameters using JSON file.')
        file = Path(filepath)
        if not file.exists():
            log.error('File %s does not exist!' % file.name)
            return
        with open(file) as fh:
            try:
                data = json.load(fh)
                log.debug('JSON filename :' + file.name)
            except Exception:
                raise InvalidJSONError
                return

    try:
        n = node.Node(vars['nodeid'], session.Session())
        status = n.set_node_params(data)
    except Exception as set_params_err:
        log.error(set_params_err)
    else:
        print('Node state updated successfully.')
    return
示例#12
0
def remove_shared_nodes(vars=None):
    """
    Remove shared nodes
    
    :param vars: `nodes` as key - Node Id for the node
    :type vars: dict

    :param vars: `email` as key - Email address of the user
    :type vars: dict

    :raises Exception: If there is an issue
                       while removing shared nodes

    :return: None on Success
    :rtype: None
    """
    try:
        log.debug("Removing shared nodes")

        # Remove any spaces if exist
        node_ids = vars['nodes'].strip()

        # Check user input format
        ret_status = _check_user_input(node_ids)

        # Get email-id
        email_id = vars['email']
        log.debug("Email-id set to: {}".format(email_id))

        # Create API data dictionary
        api_data = {}
        api_data['nodes'] = node_ids
        api_data['email'] = email_id
        n = node.Node(None, session.Session())
        log.debug("API data set to: {}".format(api_data))

        # API call to remove the shared nodes
        node_json_resp = n.remove_shared_nodes(api_data)
        log.debug("Remove shared nodes response: {}".format(node_json_resp))

    except Exception as get_node_status_err:
        log.error(get_node_status_err)
    else:
        try:
            log.debug("Displaying status")
            # Display result
            if not isinstance(node_json_resp, dict):
                print(node_json_resp)
            else:
                _display_status(node_json_resp)
        except AttributeError as err:
            log.debug("Error: {}".format(err))
            _display_json(node_json_resp)

    log.debug("Removing shared nodes successful")

    return
示例#13
0
def _load_source(name, path):
    try:
        from importlib.machinery import SourceFileLoader
        return SourceFileLoader(name, path).load_module()
    except ImportError:
        # importlib.machinery doesn't exists in Python 2 so we will use imp (deprecated in Python 3)
        import imp
        return imp.load_source(name, path)
    except Exception as load_source_err:
        log.error(load_source_err)
        sys.exit(1)
示例#14
0
def logout(vars=None):
    """
    Logout of the current session.

    :raises Exception: If there is any issue in logout for user

    :return: None on Success and Failure
    :rtype: None
    """
    log.info('Logging out current logged-in user')

    # Removing the creds stored locally
    log.debug("Removing creds stored locally, invalidating token")
    config = configmanager.Config()
    
    # Get email-id of current logged-in user
    email_id = config.get_token_attribute('email')
    log.info('Logging out user: {}'.format(email_id))

    # Ask user for ending current session   
    # Get user input
    input_resp = config.get_input_to_end_session(email_id)
    if not input_resp:
        return
    
    # Call Logout API
    try:
        curr_session = session.Session()
        status_resp = curr_session.logout()
        log.debug("Logout API successful")
    except Exception as logout_err:
        log.error(logout_err)
        return

    # Check API status in response
    if 'status' in status_resp and status_resp['status'] == 'failure':
        print("Logout from ESP RainMaker Failed. Exiting.")
        print("[{}]:{}".format(status_resp['error_code'], status_resp['description']))
        return   
    
    # Remove current login creds
    ret_val = config.remove_curr_login_creds()
    if ret_val is None:
        print("Logout from ESP RainMaker Failed. Exiting.")
        return
    
    # Logout is successful
    print("Logged out from ESP RainMaker")
    log.debug('Logout Successful')
    log.debug("Local creds removed successfully")
    
    return
示例#15
0
def login(vars=None):
    """
    First time login of the user.

    :param vars: `email` as key - Email address of the user, defaults to `None`
    :type vars: dict

    :raises Exception: If there is any issue in login for user

    :return: None on Success and Failure
    :rtype: None
    """
    log.info('Signing in the user. Username  ' + str(vars['email']))
    config = configmanager.Config()
    
    # Set email-id
    email_id = vars['email']
    log.info('Logging in user: {}'.format(email_id))
    
    # Check user current creds exist
    resp_filename = config.check_user_creds_exists()
    
    # If current creds exist, ask user for ending current session
    if resp_filename:      
        
        # Get email-id of current logged-in user
        curr_email_id = config.get_token_attribute('email')
        log.info('Logging out user: {}'.format(curr_email_id))
        
        # Get user input
        input_resp = config.get_input_to_end_session(curr_email_id)
        if not input_resp:
            return
        
        # Remove current login creds
        ret_val = config.remove_curr_login_creds(curr_creds_file=resp_filename)
        if ret_val is None:
            print("Failed to end previous login session. Exiting.")
            return
    else:
        log.debug("Current login creds not found at path: {}".format(resp_filename))

    if vars['email'] is None:
        browser_login()
        return
    try:
        u = user.User(vars['email'])
        u.login()
        print('Login Successful')
    except Exception as login_err:
        log.error(login_err)
示例#16
0
def claim_node(vars=None):
    """
    Claim the node connected to the given serial port
    (Get cloud credentials)

    :param vars: `port` as key - Serial Port, defaults to `None`
    :type vars: str | None

    :raises Exception: If there is an HTTP issue while claiming

    :return: None on Success
    :rtype: None
    """
    try:
        claim(vars['port'])
    except Exception as claim_err:
        log.error(claim_err)
        return
示例#17
0
def get_node_status(vars=None):
    """
    Shows the online/offline status of the node.

    :param vars: `nodeid` as key - Node ID for the node, defaults to `None`
    :type vars: dict | None

    :raises Exception: If there is an HTTP issue while getting node status

    :return: None on Success
    :rtype: None
    """
    try:
        n = node.Node(vars['nodeid'], session.Session())
        node_status = n.get_node_status()
    except Exception as get_node_status_err:
        log.error(get_node_status_err)
    else:
        print(json.dumps(node_status, indent=4))
    return
示例#18
0
def get_user_details(vars=None):
    """
    Get details of current logged-in user
    """
    try:
        # Get user details
        log.debug('Getting details of current logged-in user')
        curr_session = session.Session()
        user_info = curr_session.get_user_details()
        log.debug("User details received")
    except Exception as err:
        log.error(err)
    else:
        # Print API response output
        for key, val in user_info.items():
            if key == "user_name":
                key = key + " (email)"
            title = key.replace("_", " ").title()
            print("{}: {}".format(title, val))
    return
示例#19
0
def get_params(vars=None):
    """
    Get parameters of the node.

    :param vars: `nodeid` as key - Node ID for the node, defaults to `None`
    :type vars: dict | None

    :raises Exception: If there is an HTTP issue while getting params or
                       JSON format issue in HTTP response

    :return: None on Success
    :rtype: None
    """
    try:
        n = node.Node(vars['nodeid'], session.Session())
        params = n.get_node_params()
    except SSLError:
        log.error(SSLError())
    except NetworkError as conn_err:
        print(conn_err)
        log.warn(conn_err)
    except Exception as get_params_err:
        log.error(get_params_err)
    else:
        if params is None:
            log.error('Node status not updated.')
            return
        else:
            print(json.dumps(params, indent=4))
    return params
示例#20
0
def signup(vars=None):
    """
    User signup to the ESP Rainmaker.

    :param vars: `email` as key - Email address of the user, defaults to `None`
    :type vars: dict

    :raises Exception: If there is any issue in signup for user

    :return: None on Success
    :rtype: None
    """
    log.info('Signing up the user ' + vars['email'])
    u = user.User(vars['email'])
    password = get_password()
    try:
        status = u.signup_request(password)
    except Exception as signup_err:
        log.error(signup_err)
    else:
        if status is True:
            verification_code = input('Enter verification code sent on your'
                                      'Email.\n Verification Code : ')
            try:
                status = u.signup(verification_code)
            except Exception as signup_err:
                log.error(signup_err)
                return
            print('Signup Successful\n'
                  'Please login to continue with ESP Rainmaker CLI')
        else:
            log.error('Signup failed. Please try again.')
    return
示例#21
0
    def set_config(self, data, config_file=CONFIG_FILE):
        """
        Set the configuration file.

        :params data: Config Data to write to file
        :type data: dict

        :params config_file: Config filename to write config data to
        :type data: str

        :raises OSError: If there is an OS issue while creating new directory
                         for config file
        :raises Exception: If there is a File Handling error while saving
                           config to file

        :return: None on Success and Failure
        :rtype: None
        """
        log.info("Configuring config file.")
        file_dir = Path(path.expanduser(HOME_DIRECTORY + CONFIG_DIRECTORY))
        file = Path(path.expanduser(HOME_DIRECTORY) + config_file)
        if not file.exists():
            try:
                if not file_dir.exists():
                    log.debug('Config directory does not exist,'
                              'creating new directory.')
                    os.makedirs(
                        path.expanduser(HOME_DIRECTORY) + CONFIG_DIRECTORY)
            except OSError as set_config_err:
                log.error(set_config_err)
                if set_config_err.errno != errno.EEXIST:
                    raise set_config_err
        try:
            with open(path.join(path.expanduser(HOME_DIRECTORY), config_file),
                      'w') as config_file:
                json.dump(data, config_file)
        except Exception as set_config_err:
            raise set_config_err
        log.info("Configured config file successfully.")
示例#22
0
def get_tokens(code):
    """
    Get access token and set the config file after successful browser login.

    :raises Exception: If there is an HTTP issue in getting access token
    :raises SystemExit: If Exception is raised

    :return: None on Success and Failure
    :rtype: None
    """
    log.info('Getting access tokens using authorization code.')
    client_id = serverconfig.CLIENT_ID
    request_data = 'grant_type=authorization_code&client_id=' + client_id +\
                   '&code=' + code + '&redirect_uri=' +\
                   serverconfig.REDIRECT_URL

    request_header = {'content-type': 'application/x-www-form-urlencoded'}
    try:
        response = requests.post(url=serverconfig.TOKEN_URL,
                                 data=request_data,
                                 headers=request_header,
                                 verify=configmanager.CERT_FILE)
        response.raise_for_status()
    except requests.exceptions.SSLError:
        raise SSLError
    except requests.exceptions.ConnectionError:
        raise NetworkError
    except Exception as get_token_err:
        log.error(get_token_err)
        sys.exit(1)
    else:
        config_data = {}
        result = response.json()
        config_data['idtoken'] = result['id_token']
        config_data['refreshtoken'] = result['refresh_token']
        config_data['accesstoken'] = result['access_token']
        log.debug('Received access tokens using authorization code.')
        configmanager.Config().set_config(config_data)
    return
示例#23
0
def list_shared_nodes(vars=None):
    """
    List shared nodes
    
    :param vars: `node` as key - Node Id for the node
                 (if provided)
    :type vars: dict

    :raises Exception: If there is an issue
                       while getting shared nodes

    :return: None on Success
    :rtype: None
    """
    try:
        log.debug("Get shared nodes")

        n = node.Node(vars['node'], session.Session())
        log.debug("Node id received from user: {}".format(vars['node']))

        # API
        node_json_resp = n.get_shared_nodes()
        log.debug("Get shared nodes response: {}".format(node_json_resp))

    except Exception as get_node_status_err:
        log.error(get_node_status_err)
    else:
        try:
            # Display result
            log.debug("Displaying status")
            _display_status(node_json_resp)
        except AttributeError as err:
            log.debug("Error: {}".format(err))
            _display_json(node_json_resp)

    log.debug("Get shared nodes successful")

    return
示例#24
0
def login(vars=None):
    """
    First time login of the user.

    :param vars: `email` as key - Email address of the user, defaults to `None`
    :type vars: dict

    :raises Exception: If there is any issue in login for user

    :return: None on Success
    :rtype: None
    """
    log.info('Signing in the user. Username  ' + str(vars['email']))
    if vars['email'] is None:
        browser_login()
        return
    u = user.User(vars['email'])
    try:
        u.login()
    except Exception as login_err:
        log.error(login_err)
    else:
        print('Login Successful')
示例#25
0
def get_nodes(vars=None):
    """
    List all nodes associated with the user.

    :param vars: No Parameters passed, defaults to `None`
    :type vars: dict | None

    :raises Exception: If there is an HTTP issue while getting nodes

    :return: None on Success
    :rtype: None
    """
    try:
        s = session.Session()
        nodes = s.get_nodes()
    except Exception as get_nodes_err:
        log.error(get_nodes_err)
    else:
        if len(nodes.keys()) == 0:
            print('User is not associated with any nodes.')
            return
        for key in nodes.keys():
            print(nodes[key].get_nodeid())
    return
示例#26
0
def flash_bin_onto_node(port, esptool, bin_to_flash):
    """
    Flash binary onto node

    :param port: Serial Port
    :type port: str

    :param esptool: esptool module
    :type esptool: module

    :param bin_to_flash: Filname of binary to flash
    :type bin_to_flash: str

    :raises Exception: If there is any issue when flashing binary onto node

    :return: None on Success
    :rtype: None
    """
    try:
        command = ['--port', port, 'write_flash', '0x340000', bin_to_flash]
        esptool.main(command)
    except Exception as err:
        log.error(err)
        sys.exit(1)
示例#27
0
def get_mqtt_host(vars=None):
    """
    Returns MQTT Host endpoint

    :param vars: No Parameters passed, defaults to `None`
    :type vars: dict | None

    :raises NetworkError: If there is a network connection issue while
                          getting MQTT Host endpoint
    :raises Exception: If there is an HTTP issue while getting
                       MQTT Host endpoint or JSON format issue in HTTP response

    :return: MQTT Host endpoint
    :rtype: str
    """
    log.info("Getting MQTT Host endpoint.")
    path = 'mqtt_host'
    request_url = serverconfig.HOST.split(serverconfig.VERSION)[0] + path
    try:
        log.debug("Get MQTT Host request url : " + request_url)
        response = requests.get(url=request_url,
                                verify=configmanager.CERT_FILE)
        log.debug("Get MQTT Host resonse : " + response.text)
        response.raise_for_status()
    except requests.exceptions.SSLError:
        raise SSLError
    except requests.ConnectionError:
        raise NetworkError
        return
    except Exception as mqtt_host_err:
        log.error(mqtt_host_err)
        return
    try:
        response = json.loads(response.text)
    except Exception as json_decode_err:
        log.error(json_decode_err)
    if 'mqtt_host' in response:
        log.info("Received MQTT Host endpoint successfully.")
        print(response['mqtt_host'])
    else:
        log.error("MQTT Host does not exists.")
    return response['mqtt_host']
示例#28
0
def forgot_password(vars=None):
    """
    Forgot password request to reset the password.

    :param vars: `email` as key - Email address of the user, defaults to `None`
    :type vars: dict

    :raises Exception: If there is an HTTP issue while
                       changing password for user

    :return: None on Success and Failure
    :rtype: None
    """
    log.info('Changing user password. Username ' + vars['email'])
    u = user.User(vars['email'])
    status = False
    try:
        status = u.forgot_password()
    except Exception as forgot_pwd_err:
        log.error(forgot_pwd_err)
    else:
        verification_code = input('Enter verification code sent on your Email.'
                                  '\n Verification Code : ')
        password = get_password()
        if status is True:
            try:
                log.debug('Received verification code on email ' +
                          vars['email'])
                status = u.forgot_password(password, verification_code)
            except Exception as forgot_pwd_err:
                log.error(forgot_pwd_err)
            else:
                print('Password changed successfully.'
                      'Please login with the new password.')
        else:
            log.error('Failed to reset password. Please try again.')
    return
示例#29
0
def ota_upgrade(vars=None):
    """
    Upload OTA Firmware Image
    and
    Set image url returned in response as node params
    """
    try:
        node_id = vars['nodeid']
        img_file_path = vars['otaimagepath']
        if os.path.isabs(img_file_path) is False:
            img_file_path = os.path.join(os.getcwd(), img_file_path)
        img_name = img_file_path.split('/')[-1].split('.bin')[0]
        with open(img_file_path, 'rb') as f:
            fw_img_bytes = f.read()
        base64_fw_img = base64.b64encode(fw_img_bytes).decode('ascii')

        retries = MAX_HTTP_CONNECTION_RETRIES
        node_object = None
        status = None
        response = None
        service_name = None
        service_obj = None
        service_config = None
        node_params = None
        param_url_to_set = None
        curr_session = None
        while retries > 0:
            try:
                # If session is expired then to initialise the new session
                # internet connection is required.
                if not curr_session:
                    curr_session = session.Session()
                if not node_object:
                    node_object = node.Node(node_id, curr_session)
                    log.info("Creating service object...")
                if not service_obj:
                    service_obj = service.Service()
                    log.info("Checking service " + service.OTA_SERVICE_TYPE + " in node config...")
                    print("Checking " + service.OTA_SERVICE_TYPE + " in node config...")
                if not service_config and not service_name:
                    service_config, service_name = service_obj.verify_service_exists(node_object, service.OTA_SERVICE_TYPE)
                    if not service_config:
                        log.error(service.OTA_SERVICE_TYPE + " not found.")
                        break
                    log.info("Checking service " + service.OTA_SERVICE_TYPE + " in config...Success")
                    log.debug("Service config received: " + str(service_config) +
                              " Service name received: " + str(service_name))
                    print("Uploading OTA Firmware Image...This may take time...")
                    log.info("Uploading OTA Firmware Image...This may take time...")
                if not status and not response:
                    # Upload OTA Firwmare Image
                    status, response = service_obj.upload_ota_image(node_object, img_name, base64_fw_img)
                    if status:
                        break
            except SSLError:
                log.error(SSLError())
                break
            except (NetworkError, RequestTimeoutError) as conn_err:
                print(conn_err)
                log.warn(conn_err)
            except Exception as node_init_err:
                log.error(node_init_err)
                break
            time.sleep(5)
            retries -= 1
            if retries:
                print("Retries left:", retries)
                log.info("Retries left: " + str(retries))

        if node_object is None:
            log.error('Initialising new session...Failed\n')
            return

        if not status or not 'success' in status:
            print("\n")
            log.error("OTA Upgrade...Failed")
            log.debug('OTA Upgrade...Failed '
                      'status: ' + str(status) + ' response: ' + str(response))
            return

        log.info('Upload OTA Firmware Image Request...Success')
        log.debug("Upload OTA Firmware Image Request - Status: " + json.dumps(status) +
                  " Response: " + json.dumps(response))


        retries = MAX_HTTP_CONNECTION_RETRIES
        ota_start_status = None
        node_params = None
        service_read_params = None
        service_write_params = None
        ota_status = None

        while retries > 0:
            try:
                if 'image_url' in response:
                    param_url_to_set = response["image_url"]

                    if not service_read_params and not service_write_params:
                        log.info("Getting service params from node config")
                        service_read_params, service_write_params = service_obj.get_service_params(service_config)
                        log.debug("Service params received with read properties: " + str(service_read_params) +
                                  " Service params received with write properties: " + str(service_write_params))
                        log.info("Getting node params...")
                    if not node_params:
                        node_params = node_object.get_node_params()
                        log.debug("Node params received: " + json.dumps(node_params))
                        print("Setting the OTA URL parameter...")

                    if not ota_start_status:
                        ota_start_status = service_obj.start_ota(node_object, node_params, service_name,
                                                        service_write_params, param_url_to_set)
                        log.debug("OTA status received: " + str(ota_start_status))
                        if not ota_start_status:
                            log.error("Failed to start OTA service...Exiting...")
                            break
                        print("Getting OTA Status...")
                    if not ota_status:
                        ota_status = service_obj.check_ota_status(node_object, service_name, service_read_params)
                        break
            except SSLError:
                log.error(SSLError())
                break
            except (NetworkError, RequestTimeoutError) as conn_err:
                print(conn_err)
                log.warn(conn_err)
            except Exception as node_init_err:
                log.error(node_init_err)
                break
            time.sleep(5)
            retries -= 1
            if retries:
                print("Retries left:", retries)
                log.info("Retries left: " + str(retries))

        if ota_status in [None, False]:
            log.error("OTA Upgrade...Failed")
            log.debug('OTA Upgrade...Failed '
                      'ota_status: ' + str(ota_status))
    except KeyError as key_err:
        log.error("Key Error: " + str(key_err))
    except Exception as ota_err:
        log.error(ota_err)
    return
示例#30
0
def browser_login():
    """
    Opens browser with login url using Httpd Server.

    :raises Exception: If there is an HTTP issue while
                       logging in through browser

    :return: None on Success and Failure
    :rtype: None
    """
    log.info('Logging in through browser')
    server_instance = None
    for attempt in range(10):
        try:
            port = get_free_port()
            server_instance = HttpdServer(('localhost', port),
                                          HttpdRequestHandler)
            # Added timeout to handle keyboard interrupts for browser login.
            server_instance.timeout = 0.5
            break
        except socket.error as err:
            log.warn('Error %s. Port %s is not available.'
                     'Trying with next port.', err, port)

    if server_instance is None:
        log.error('Error: Could not launch local webserver.'
                  'Use --email option instead.')
        return

    url = serverconfig.LOGIN_URL + str(port) +\
        '&host_url=' + serverconfig.HOST + 'login' +\
        '&github_url=' + serverconfig.EXTERNAL_LOGIN_URL +\
        str(port)

    print('Opening browser window for login...')
    open_status = webbrowser.open(url)
    if open_status is False:
        log.error('Failed to open login page. Please try again.')
        return
    else:
        print('Use the browser for login. Press ctrl+C to abort.')
    log.debug('Web browser opened. Waiting for user login.')
    try:
        while True:
            server_instance.handle_request()
            if 'error' in server_instance.query_params:
                log.error('Authentication Error: "%s". Description: "%s" ' +
                          server_instance.query_params['error'] +
                          server_instance.query_params.ge('error_description'))
                return
            if 'code' in server_instance.query_params:
                log.debug('Login successful. Received authorization code.')
                code = server_instance.query_params['code']
                get_tokens(code)
                print('Login successful')
                return

            if 'id_token' in server_instance.query_params and \
                    'refresh_token' in server_instance.query_params:
                log.debug('Login successful.'
                          'Received idtoken and refresh token.')
                config_data = {}
                config_data['idtoken'] = server_instance.query_params[
                                                                'id_token'
                                                                ]
                config_data['refreshtoken'] = server_instance.query_params[
                                                                'refresh_token'
                                                                ]
                config_data['accesstoken'] = server_instance.query_params[
                                                                'access_token'
                                                                ]
                configmanager.Config().set_config(config_data)
                print('Login successful')
                return
    except Exception as browser_login_err:
        log.error(browser_login_err)