Ejemplo n.º 1
0
def _print_status(cnt, step_cnt, msg=None):
    if cnt % step_cnt == 0:
        curr_time = time.time()
        timestamp = datetime.datetime.fromtimestamp(curr_time).strftime(
            '%H:%M:%S')
        log.info('\n[{:<6}][Current Status] {}: {}'.format(
            msg, timestamp, str(cnt)))
Ejemplo n.º 2
0
    def save_config(self, data):
        '''
        Save login config data to file

        :param data: Login data to be set
        :type data: dict
        '''
        try:
            log.debug("Saving login config data")
            if not os.path.isdir(CONFIG_DIRECTORY):
                log.info('Config directory does not exist, '
                         'creating new directory : {}'.format(
                             CONFIG_DIRECTORY))
                os.makedirs(CONFIG_DIRECTORY)

            login_cfg_data = self._set_login_config_data(data)
            if not login_cfg_data:
                return False, False

            with open(self.config_file, 'w+', encoding='utf-8') as cfg_file:
                cfg_file.write(str(json.dumps(login_cfg_data)))

            return True, self.config_file

        except Exception as save_config_err:
            log.error(save_config_err)
            return False, False
Ejemplo n.º 3
0
    def remove_curr_login_config(self, email=""):
        '''
        Remove current login config from file

        :param email: Email-id of current user
        :type email: str
        '''
        log.debug("Removing current login config data from file: {}".format(
            self.config_file))
        while True:
            user_input = input('\nThis will end your current session for {}. '
                               'Do you want to continue (Y/N)? :'.format(
                                   email))
            if user_input not in ["Y", "y", "N", "n"]:
                log.info("Please provide Y/N only")
                continue
            elif user_input in ["N", "n"]:
                return False
            else:
                break
        try:
            os.remove(self.config_file)
            log.debug("Current login config removed from file: {}".format(
                self.config_file))
            return True
        except Exception as e:
            log.debug('Error: {}. Failed to remove current login config '
                      'from path {}'.format(
                          e, self.config_file))
            raise Exception('Error: Failed to remove current login '
                            'config from path {}'.format(self.config_file))
Ejemplo n.º 4
0
def generate_cacert(cacert_info, ca_private_key):
    '''
    Generate CA Certificate

    :param cacert_info: CA certificate info
    :type cacert_info: dict

    :param ca_private_key: CA Private Key
    :type ca_private_key: RSA Private Key
    '''
    try:
        log.info("\nGenerating CA Certificate")
        ca_public_key = ca_private_key.public_key()
        subj_name_list = _create_subj_name_list(cacert_info)
        if not subj_name_list:
            return False
        issuer_name = [
            x509.NameAttribute(NameOID.COMMON_NAME, cacert_info['common_name'])
        ]
        ca_cert = _generate_cert(subject_name=subj_name_list,
                                 issuer_name=issuer_name,
                                 public_key=ca_public_key,
                                 ca_key=ca_private_key,
                                 ca=True)
        if not ca_cert:
            return False
        return ca_cert
    except Exception as err:
        log.debug("Error: {} . Cannot create CA Certificate".format(err))
Ejemplo n.º 5
0
def download_from_url(request_url):
    '''
    Download file from url

    :param request_url: Request URL to download file from
    :type request_url: str
    '''
    try:
        response = None
        while True:
            try:
                log.debug("Downloading file from url: {}".format(request_url))
                response = requests.get(url=request_url)
                response.raise_for_status()
            except requests.exceptions.SSLError:
                raise(SSLError())
            except (ConnectionError):
                log.error(NetworkError())
            except RequestException as err:
                log.error(err)

            if response:
                log.info("Node ids file downloaded successfully")
                log.debug("Response content: {}".format(response.content))
                return response.content
            else:
                log.info("Retrying...")
                time.sleep(5)

    except Exception as err:
        raise Exception(err)
Ejemplo n.º 6
0
def configure_server(vars=None):
    '''
    Set Server Config

    :param vars: `endpoint` as key - Endpoint of server to use
    :type vars: str

    :raises Exception: If there is any exception while configuring server
            KeyboardInterrupt: If there is a keyboard interrupt by user

    :return: None on Failure
    :rtype: None
    '''
    try:
        log.debug("Configure server")
        ret_status = _cli_arg_check(vars['endpoint'], '--endpoint <endpoint>')
        if not ret_status:
            return

        config = configmanager.Config(config="server")
        ret_status = config.set_server_config(vars['endpoint'])
        if not ret_status:
            log.error("Failed to save server config")
            return
        else:
            log.info("Saved new server config")

        log.info('You can now run: \npython rainmaker_admin_cli.py account '
                 'login -h (Login)')
    except KeyboardInterrupt:
        log.error("\nServer config not set")
    except Exception as e:
        log.error("Error: {}".format(e))
Ejemplo n.º 7
0
    def get_mqtthostname(self):
        '''
        Get MQTT Hostname
        '''
        try:
            backslash = '/'
            log.info("Sending request to get mqtt endpoint")
            retry_cnt = MAX_HTTP_CONNECTION_RETRIES
            path = 'admin/mqtt_host'
            request_url = constants.HOST.rstrip(backslash) + backslash + path
            log.debug("Get MQTT hostname - url: {}".format(request_url))

            while retry_cnt > 0:
                log.debug('Sending HTTP {} request - url: {} '
                          'headers: {}'.format('get', request_url,
                                               self.request_header))
                response = requests.get(url=request_url,
                                        headers=self.request_header,
                                        verify=configmanager.CERT_FILE,
                                        timeout=(5.0, 5.0))
                log.debug("Response status code received: {}".format(
                    response.status_code))
                response = json.loads(response.text)
                log.debug("Response received: {}".format(response))

                if 'mqtt_host' in response:
                    log.debug("Response mqtt hostname: {}".format(
                        response['mqtt_host']))
                    return response['mqtt_host']

                log.info("Retrying...No of retries left: {}".format(
                    str(retry_cnt - 1)))
                retry_cnt -= 1
                time.sleep(5)

            return False

        except SSLError as ssl_err:
            log.error(ssl_err)
        except NetworkError as net_err:
            log.error(net_err)
        except RequestTimeoutError as req_err:
            log.error(req_err)
        except RequestException as err:
            log.error(err)
        except Exception as req_exc_err:
            raise Exception(req_exc_err)
Ejemplo n.º 8
0
def generate_devicecert(outdir, ca_cert, ca_private_key, common_name=None):
    '''
    Generate Device Certificate

    :param outdir: Output Directory
    :type outdir: str

    :param ca_cert: CA Certificate
    :type ca_cert: x509 Certificate

    :param ca_private_key: CA Private Key
    :type ca_private_key: RSA Private Key

    :param common_name: Common Name
    :type common_name: str
    '''
    try:
        log.debug("Generating device cert")

        log.debug("Generating private key")
        private_key = generate_private_key()
        if not private_key:
            return False, False
        log.debug("Private key generated")

        log.debug("Generating CSR")
        csr = generate_csr(private_key, str(common_name))
        if not csr:
            log.info("Failed to generate CSR")
            return False, False
        log.debug("CSR generated")

        dev_cert = _generate_cert(subject_name=csr.subject,
                                  issuer_name=ca_cert.subject,
                                  public_key=csr.public_key(),
                                  ca_key=ca_private_key)

        if not dev_cert:
            log.info("Certificate Not Generated")
            return False, False
        log.debug("Device certificate generated successfully")

        return dev_cert, private_key

    except Exception as err:
        raise Exception(err)
Ejemplo n.º 9
0
def get_register_device_cert_status(vars=None):
    '''
    Get Status of Device Certificate Registration Request

    :param vars: `requestid` as key - Request Id of device
                                      certificate registration request
    :type vars: str

    :raises Exception: If there is any exception while getting
                       device certificate registration status
            KeyboardInterrupt: If there is a keyboard interrupt by user

    :return: None on Failure
    :rtype: None
    '''
    try:
        log.debug("Get register device cert status")
        ret_status = _cli_arg_check(vars['requestid'],
                                    '--requestid <requestid>')
        if not ret_status:
            return

        _print_keyboard_interrupt_message()

        # Get current login session token
        # Re-login if session expired
        session = Session()
        token = session.get_access_token()
        if not token:
            log.error("Get device certificate registration request failed")
            return

        node_mfg = Node_Mfg(token)

        # Register Device Certificate
        cert_register_status = node_mfg.get_register_cert_status(
            vars['requestid'])
        log.info("Device certificate registration status: {}".format(
            cert_register_status))
        return

    except KeyboardInterrupt:
        log.error("\nRegister device certificate failed")
    except Exception as e:
        log.error("Error: {}".format(e))
Ejemplo n.º 10
0
    def get_register_cert_status(self, request_id):
        '''
        Register device certificates

        :param request_id: Request Id of device
                           certificate registration request
        :type request_id: str
        '''
        try:
            backslash = '/'
            log.info("Getting device certificate registration status")

            path = 'admin/node_certificates/register'
            query_params = {'request_id': request_id}
            request_url = constants.HOST.rstrip(backslash) + backslash + path
            log.debug("Register Certificate - url: {} params: {}".format(
                request_url, query_params))

            log.debug('Sending HTTP {} request - url: {} params: {} '
                      'headers: {}'.format('get', request_url, query_params,
                                           self.request_header))
            # Send query params in HTTP GET Request
            response = requests.get(url=request_url,
                                    params=query_params,
                                    headers=self.request_header,
                                    verify=configmanager.CERT_FILE,
                                    timeout=(5.0, 5.0))
            log.debug("Response status code received: {}".format(
                response.status_code))
            response = json.loads(response.text)
            log.debug("Response received: {}".format(response))

            log.debug("Current status: {:<3}".format(response['status']))

            return response['status']

        except SSLError as ssl_err:
            log.error(ssl_err)
        except NetworkError as net_err:
            log.error(net_err)
        except RequestTimeoutError as req_err:
            log.error(req_err)
        except Exception as req_exc_err:
            raise Exception(req_exc_err)
Ejemplo n.º 11
0
def upload_cert(upload_url, filename):
    '''
    Upload Certificate file to AWS S3 Bucket

    :param upload_url: URL to upload file to
    :type upload_url: str

    :param filename: Name of file to upload
    :type filename: str
    '''
    try:
        response = None

        log.info("Uploading certificate file: {}".format(filename))
        while True:
            try:
                headers = {'Content-type': 'application/octet-stream'}
                log.debug("Upload Certificate - url: {} filename: {}".format(
                    upload_url,
                    filename))
                with open(filename, "rb") as f:
                    response = requests.put(url=upload_url,
                                            data=f,
                                            headers=headers)
                    response.raise_for_status()

            except requests.exceptions.SSLError:
                raise(SSLError())
            except (ConnectionError):
                log.error(NetworkError())
            except RequestException as req_exc_err:
                log.error(req_exc_err)

            if response:
                log.debug("Response received: {}".format(response))
                if response.status_code != 200:
                    break
                return True
            else:
                log.info("Retrying...")
                time.sleep(5)

    except Exception as err:
        raise Exception(err)
Ejemplo n.º 12
0
def _extra_config_files_checks(outdir, extra_config, extra_values, file_id):
    log.debug("Extra config file checks")
    set_to_false = None
    if extra_config and not extra_values:
        log.info('ADDITIONAL_VALUES file must also be provided in config '
                 'alongwith ADDITIONAL_CONFIG file.')
        set_to_false = False
    if file_id and file_id in ['node_id']:
        log.info('`node_id` is the default fileid. '
                 'Any new fileid provided as input must be a key in the '
                 'ADDITIONAL_VALUES file provided in config.')
        set_to_false = False
    if file_id and file_id not in ['node_id'] and not extra_values:
        log.info(
            'Fileid provided must have corresponding values in ADDITIONAL_VALUES file in config. '
            'Please provide ADDITIONAL_VALUES file in config.')
        set_to_false = False
    '''
    if extra_values and file_id and file_id not in ['node_id'] and not extra_config:
        log.info('Fileid provided must be a config key. Please provide ADDITIONAL_CONFIG file '
                    'alongwith ADDITIONAL_VALUES file in config.')
        set_to_false = False
    '''
    if extra_config or extra_values:
        log.debug("Verifying mfg files input")
        # Verify mfg files
        verify_mfg_files(outdir, extra_config, extra_values, file_id)
    if set_to_false is False:
        return False
    return True
Ejemplo n.º 13
0
def _set_data(node_count, common_outdir):
    # Get current login session token
    # Re-login if session expired
    log.debug("Set data")
    session = Session()
    token = session.get_access_token()
    if not token:
        return None, None

    node_mfg = Node_Mfg(token)
    log.debug('Generating node ids for '
              'number of nodes: {}'.format(node_count))
    # Generate <node_count> node ids
    node_id_file_url = node_mfg.gen_node_id(node_count)
    if not node_id_file_url:
        log.error("Generate node ids failed")
        return None, None
    # Download node ids file from url
    log.info("Downloading node ids file")
    node_id_file_data = download_from_url(node_id_file_url)
    if not node_id_file_data:
        log.error("Download file from url failed")
        return None, None
    # Save node ids data received into a file
    node_ids_file = save_to_file(node_id_file_data,
                                 common_outdir,
                                 filename_prefix="node_ids")
    if not node_ids_file:
        return None, None
    log.info("Node ids file saved at location: {}".format(node_ids_file))

    # Save mqtt endpoint into a file
    endpoint = node_mfg.get_mqtthostname()
    endpoint_file = save_to_file(endpoint,
                                 common_outdir,
                                 dest_filename=MQTT_ENDPOINT_FILENAME)
    if not endpoint_file:
        return None, None
    log.info("Endpoint saved at location: {}".format(endpoint_file))
    return node_ids_file, endpoint_file
Ejemplo n.º 14
0
    def register_cert_req(self,
                          filename,
                          md5_checksum,
                          expected_resp='request_id'):
        '''
        Request to register device certificates

        :param filename: Filename of uploaded device certificates file
        :type filename: str

        :param md5_checksum: MD5 Checksum of file
        :type md5_checksum: str

        :param expected_resp: Data expected to be present in response
        :type expected_resp: str
        '''
        try:
            backslash = '/'
            log.debug("Sending request to register certificate")
            retry_cnt = MAX_HTTP_CONNECTION_RETRIES
            err_status_key = "status"

            path = 'admin/node_certificates/register'
            request_url = constants.HOST.rstrip(backslash) + backslash + path
            request_body = {'file_name': filename, 'file_md5': md5_checksum}
            log.debug('Register Certificate Request - url: {} '
                      'req_body: {}'.format(request_url, request_body))

            while retry_cnt > 0:
                try:
                    # Send HTTP POST Request
                    log.debug('Sending HTTP {} request - url: {} data: {} '
                              'headers: {}'.format('post', request_url,
                                                   json.dumps(request_body),
                                                   self.request_header))
                    response = requests.post(url=request_url,
                                             data=json.dumps(request_body),
                                             headers=self.request_header,
                                             verify=configmanager.CERT_FILE,
                                             timeout=(5.0, 5.0))
                    log.debug('Response status code received: {}'.format(
                        response.status_code))
                    response = json.loads(response.text)
                    log.debug("Response received: {}".format(response))

                    if 'status' in response:
                        log.debug("Response status: {}".format(
                            response['status']))
                        if 'success' in response['status']:
                            log.debug('Expected response {} '
                                      'received in response: {}'.format(
                                          expected_resp, response))
                            log.debug("Expected response: {}".format(
                                response[expected_resp]))
                            return response[expected_resp]
                        elif 'failure' in response['status']:
                            log.debug('Request failed: '
                                      'Response received: {}'.format(response))
                            log.error('Status: {} \n {}'.format(
                                response[err_status_key],
                                response['description']))
                            return False

                except NetworkError as net_err:
                    log.error(net_err)
                except RequestTimeoutError as req_err:
                    log.error(req_err)

                log.info("Current status: {}".format(response['status']))
                log.debug("Retrying...No of retries left: {}".format(
                    str(retry_cnt - 1)))
                retry_cnt -= 1
                time.sleep(5)

            return None

        except SSLError as ssl_err:
            log.error(ssl_err)
        except Exception as req_exc_err:
            raise Exception(req_exc_err)
Ejemplo n.º 15
0
def generate_ca_cert(vars=None,
                     outdir=None,
                     common_outdir=None,
                     cli_call=True):
    '''
    Generate CA Certificate

    :param vars: `outdir` as key - Output directory
                                   to save generated CA Certificate,
                                   defaults to current directory
    :type vars: str

    :raises Exception: If there is any exception
                       while generating CA Certificate
            KeyboardInterrupt: If there is a keyboard
                               interrupt by user

    :return: None on Failure
    :rtype: None
    '''
    try:
        log.debug("Generate CA certificate")
        if not outdir:
            # Set output dirname
            outdir = _set_output_dir(vars['outdir'])
        if not common_outdir:
            # Create output directory for all common files generated
            common_outdir = _gen_common_files_dir(outdir)

        # Set CA cert and CA key filepath
        cacert_filepath = os.path.join(common_outdir, CACERT_FILENAME)
        cakey_filepath = os.path.join(common_outdir, CA_KEY_FILENAME)

        if cli_call:
            _print_keyboard_interrupt_message()
            log.info('Files generated will be stored '
                     'in directory: {}'.format(outdir))
        # Set CA cert input config menu
        cacert_cfg_menu = {
            "country_name": "Country Name (2 letter code) []:",
            "state_name": "State or Province Name (full name) []:",
            "locality_name": "Locality Name (eg, city) []:",
            "org_name": "Organization Name (eg, company) []:",
            "org_unit_name": "Organizational Unit Name (eg, section) []:",
            "common_name": "Common Name (eg, fully qualified host name) []:",
            "email_addr": "Email Address []:"
        }
        # Initialise CA cert config data
        ca_cert_cfg = {
            "country_name": "",
            "state_name": "",
            "locality_name": "",
            "org_name": "",
            "org_unit_name": "",
            "common_name": "",
            "email_addr": ""
        }
        print('\nPlease enter information which will be '
              'incorporated in your CA Certificate.\n'
              'To leave the field blank, press Enter.\n')

        # Get CA Certificate info from user
        ca_cert_cfg_values = _get_cacert_user_input(ca_cert_cfg,
                                                    cacert_cfg_menu)

        # Generate CA Private Key
        ca_private_key = generate_private_key()
        if not ca_private_key:
            log.error("Failed to generate private key")
            return
        # Save CA Private Key into a file
        ret_status = save_key(ca_private_key, cakey_filepath)
        if not ret_status:
            return
        # Generate CA Certificate
        cacert = generate_cacert(ca_cert_cfg_values, ca_private_key)
        if not cacert:
            print("Failed to generate CA certificate")
            return
        log.info('CA Certificate generated successfully '
                 'in directory: {}\n'.format(common_outdir))
        # Save CA Certificate into a file
        cacert_filepath = os.path.join(common_outdir, CACERT_FILENAME)
        ret_status = save_cert(cacert, cacert_filepath)
        if not ret_status:
            return

        if cli_call:
            log.info('You can now run: \npython rainmaker_admin_cli.py certs '
                     'devicecert generate -h '
                     '(Generate Device Certificate(s))')
        else:
            return cacert, ca_private_key

    except KeyboardInterrupt:
        log.error("\nCA Certificate Not Generated")
    except Exception as e:
        log.error("Error: {}".format(e))
Ejemplo n.º 16
0
    def get_node_id_req(self, node_cnt, expected_resp=None):
        '''
        Request to get list of node ids

        :param node_cnt: Number of node ids to get
        :type node_cnt: int

        :param expected_resp: Data expected to be present in response
        :type expected_resp: str
        '''
        try:
            backslash = '/'
            retry_cnt = MAX_HTTP_CONNECTION_RETRIES
            log.debug("Retry count set to: {}".format(retry_cnt))
            err_status_key = "status"
            err_description_key = "description"

            path = 'admin/node_ids'
            request_url = constants.HOST.rstrip(backslash) + backslash + path
            request_body = {'node_count': node_cnt}
            log.debug('Request parameters set: request_url: {} '
                      'request_body: {}'.format(request_url, request_body))

            while retry_cnt > 0:
                try:
                    log.debug("Retry Count: {}".format(retry_cnt))
                    # Send HTTP POST Request
                    log.debug('Sending HTTP {} request - url: {} data: {} '
                              'headers: {}'.format('post', request_url,
                                                   json.dumps(request_body),
                                                   self.request_header))
                    response = requests.post(url=request_url,
                                             data=json.dumps(request_body),
                                             headers=self.request_header,
                                             verify=configmanager.CERT_FILE,
                                             timeout=(5.0, 5.0))
                    log.debug('Response status code '
                              'received: {}'.format(response.status_code))
                    response = json.loads(response.text)
                    log.debug("HTTP Response received: {}".format(response))

                    if expected_resp in response:
                        log.debug('Expected response {} exists '
                                  'in response'.format(expected_resp))
                        return response[expected_resp]
                    elif err_status_key in response:
                        log.debug('Request failed: '
                                  'response received: {}'.format(response))
                        log.error("Status: {} \n{}".format(
                            response[err_status_key],
                            response[err_description_key]))
                        return None
                except NetworkError as net_err:
                    log.info(net_err)
                except RequestTimeoutError as req_err:
                    log.info(req_err)

                log.info('Retrying...No of retries left: {}'.format(
                    str(retry_cnt - 1)))
                retry_cnt -= 1
                time.sleep(5)
            return None
        except SSLError as ssl_err:
            log.error(ssl_err)
        except Exception as err:
            raise Exception(err)
Ejemplo n.º 17
0
def gen_and_save_certs(ca_cert, ca_private_key, input_filename, file_id,
                       outdir, endpoint_file, prov_type):
    '''
    Generate and save device certificate

    :param ca_cert: CA Certificate
    :type ca_cert: x509 Certificate

    :param ca_private_key: CA Private Key
    :type ca_private_key: RSA Private Key

    :param input_filename: Name of file containing Node Id's
    :type input_filename: str

    :param file_id: File Identifier
    :type file_id: str

    :param outdir: Output Directory
    :type outdir: str

    :param endpoint_file: Endpoint filename
    :type endpoint_file: str
    '''
    file_id_suffix = None
    max_filename_len = 6
    cnt = 1
    step_cnt = 100
    extra_keys = None
    extra_values_file_ptr = None

    log.debug("File Id recieved as user input: {}".format(file_id))
    try:
        # Init dir generate
        node_details_outdir, common_outdir, qrcode_outdir = _init_dir(outdir)
        # Init file generate
        dest_filename = _init_file(common_outdir)
        # Init Certs files
        dest_csv_file = _certs_files_init(dest_filename)
        # Get extra values filename
        extra_values_filename = _get_extra_values_filename()
        if extra_values_filename:
            # Get extra values file and file headers
            extra_values_file_ptr, header = _read_extra_values_file_header(
                extra_values_filename)
            # Get extra values keys if exists
            extra_keys = _get_extra_values_keys(header)
        # Create the headers for the Manufacturing CSV config file
        dest_config_filename, dest_values_filename = _mfg_files_init(
            common_outdir, extra_keys)

        curr_extra_values = None

        # Print info
        log.info("\nRandom info will be saved at location: {}".format(
            node_details_outdir))
        log.info("QR code payload will be saved at location: {}".format(
            node_details_outdir))
        log.info("QR code image(png) will be saved at location: {}".format(
            qrcode_outdir))
        log.info("\nGenerating device certificates")

        # Get Node Ids list from file
        node_id_list = get_nodeid_from_file(input_filename)
        if not node_id_list:
            print("Node ids not found in file: {}".format(input_filename))
            return False
        node_id_list = [i for i in node_id_list if i]

        # Generate and save cert for each node id
        for node_id in node_id_list:
            # Remove any spaces/newlines which may exist
            # at the start or end of the node id string
            node_id = node_id.strip()
            log.debug("Current node id: {}".format(node_id))
            # Set file id suffix
            if file_id == 'node_id':
                file_id_suffix = node_id
            # Get the values in ADDITIONAL_VALUES file
            if extra_values_filename:
                curr_extra_values = _get_curr_extra_value(
                    extra_values_file_ptr)
                # Set file id suffix
                key_value_data = list(
                    zip_longest(extra_keys, curr_extra_values))
                log.debug("Current key-value data: {}".format(key_value_data))
                for item in key_value_data:
                    if item[0] == file_id:
                        file_id_suffix = item[1]
                        log.debug(
                            "File Id suffix set to: {}".format(file_id_suffix))
                        if not file_id_suffix:
                            raise Exception(
                                '<count> provided is not equal to '
                                'number of values for fileid: {} in file: {} '.
                                format(file_id, extra_values_filename))

            # Create directory for node details for specific node id
            zeros_prefix_len = max_filename_len - len(str(cnt))
            zero_prefix_str = '0' * zeros_prefix_len
            node_id_dir_str = 'node-' + zero_prefix_str + str(
                cnt) + "-" + file_id_suffix
            node_id_dir = os.path.join(node_details_outdir, node_id_dir_str)
            if not os.path.isdir(node_id_dir):
                distutils.dir_util.mkpath(node_id_dir)
                log.debug("Directory created: {}".format(node_id_dir))

            # Set destination filename to save device certificates generated
            cert_dest_filename = _set_filename(filename_prefix='node',
                                               outdir=node_id_dir,
                                               ext=".crt")
            if not cert_dest_filename:
                return False

            # Set destination filename to save private keys
            # of certificates generated
            key_dest_filename = _set_filename(filename_prefix='node',
                                              outdir=node_id_dir,
                                              ext=".key")
            if not key_dest_filename:
                return False
            log.debug("Saving Key for Node Id: {} at location: {}".format(
                node_id, key_dest_filename))

            log.debug("Generating device certificate for node id: {}".format(
                node_id))

            # Get random info
            random_hex_str, random_str_file = _gen_random_info(node_id_dir)
            if not random_hex_str and not random_str_file:
                return

            # Print status
            _print_status(cnt,
                          step_cnt,
                          msg='Random str (used as PoP) generated')

            # Create values file for input to
            # Manufacturing Tool to generate binaries
            _create_values_file(dest_values_filename, cnt, node_id,
                                endpoint_file, cert_dest_filename,
                                key_dest_filename, random_str_file,
                                curr_extra_values)

            # Generate device certificate
            dev_cert, priv_key = generate_devicecert(outdir,
                                                     ca_cert,
                                                     ca_private_key,
                                                     common_name=node_id)
            if not dev_cert and not priv_key:
                return False
            log.debug('Saving Certificate for Node Id: {} '
                      'at location: {}'.format(node_id, cert_dest_filename))

            # Save certificate
            ret_status = save_cert(dev_cert, cert_dest_filename)
            if not ret_status:
                return False
            # Save private key
            ret_status = save_key(priv_key, key_dest_filename)
            if not ret_status:
                return False
            # Save node ids and certs together in a csv file
            # (used to upload and register the certificates)
            log.debug("Saving Node Id and Certificate to file: {}".format(
                dest_filename))
            ret_status = _save_nodeid_and_cert_to_file(node_id, dev_cert,
                                                       dest_csv_file)
            if not ret_status:
                return False
            log.debug("Number of certificates generated and saved")
            _print_status(cnt, step_cnt, msg='Certificates generated')
            # Generate QR code
            if prov_type:
                # Generate provisioning data
                # QR code image and str
                prov_status = _gen_prov_data(node_id_dir, node_id_dir_str,
                                             qrcode_outdir, random_hex_str,
                                             prov_type)
                if not prov_status:
                    return
                # Print QR code status
                _print_status(cnt,
                              step_cnt,
                              msg='QRcode payload and image generated')
            cnt += 1
        log.info("\nTotal certificates generated: {}".format(str(cnt - 1)))
        # Cleanup
        dest_csv_file.seek(0)
        dest_csv_file.close()
        if extra_values_filename:
            extra_values_file_ptr.seek(0)
            extra_values_file_ptr.close()

        log.info("Device certificates generated successfully")
        return dest_filename

    except FileError as file_err:
        log.error(file_err)
    except Exception as err:
        raise Exception(err)
Ejemplo n.º 18
0
def generate_device_cert(vars=None):
    '''
    Generate Device Certificate

    :param vars: `count` as key - Number of Node Ids
                                  for generating certificates
    :type vars: str

    :param vars: `fileid` as key - File Identifier
    :type vars: str

    :param vars: `cacertfile` as key - Name of file containing CA Certificate
    :type vars: str

    :param vars: `cakeyfile` as key - Name of file containing CA Private Key
    :type vars: str

    :param vars: `outdir` as key - Output directory to save
                                   generated Device Certificate,
                                   defaults to current directory
    :type vars: str

    :raises Exception: If there is any exception while generating
                       Device Certificate(s)
            KeyboardInterrupt: If there is a keyboard interrupt by user

    :return: None on Failure
    :rtype: None
    '''
    try:
        log.debug("Generate device certificates")
        node_count = int(vars['count'])
        ret_status = _cli_arg_check(node_count,
                                    '--count <count>',
                                    err_msg='<count> must be > 0')
        if not ret_status:
            return

        # Init
        file_id = vars['fileid']
        if len(file_id) == 0:
            file_id = None
        prov_type = None
        if vars['prov']:
            prov_type = vars['prov']

        # Set output dirname
        outdir = _set_output_dir(vars['outdir'])

        # Extra config files checks
        extra_config = get_param_from_config('ADDITIONAL_CONFIG')
        extra_values = get_param_from_config('ADDITIONAL_VALUES')
        ret_status = _extra_config_files_checks(outdir, extra_config,
                                                extra_values, file_id)
        if not ret_status:
            return

        # Fileid checks
        ret_status = _fileid_check(file_id, node_count, extra_values)
        if not ret_status:
            return

        # Set default file id
        if not file_id:
            file_id = 'node_id'

        # Create output directory for all common files generated
        common_outdir = _gen_common_files_dir(outdir)

        # Generate CA Cert and CA Key
        ca_cert_filepath = vars['cacertfile']
        ca_key_filepath = vars['cakeyfile']
        log.debug("CA Cert filename input: {}".format(ca_cert_filepath))
        log.debug("CA Key filename input: {}".format(ca_key_filepath))
        if not ca_cert_filepath and not ca_key_filepath:
            ca_cert, ca_private_key = generate_ca_cert(
                vars=vars,
                outdir=outdir,
                common_outdir=common_outdir,
                cli_call=False)
        if ca_cert_filepath and not ca_key_filepath:
            raise Exception("CA key file is not provided")
        if ca_key_filepath and not ca_cert_filepath:
            raise Exception("CA cert file is not provided")

        _print_keyboard_interrupt_message()
        log.info('Files generated will be stored '
                 'in directory: {}'.format(outdir))
        # Get and save CA Certificate from file
        if len(ca_cert_filepath) != 0:
            ca_cert = _get_and_save_ca_cert_from_input(common_outdir,
                                                       ca_cert_filepath)

        # Get and save CA Private Key from file
        if len(ca_key_filepath) != 0:
            ca_private_key = _get_and_save_ca_key_from_input(
                common_outdir, ca_key_filepath)
        # Set data
        node_ids_file, endpoint_file = _set_data(node_count, common_outdir)
        if not node_ids_file and not endpoint_file:
            raise Exception("")
        # Generate Device Cert and save into file
        certs_dest_filename = gen_and_save_certs(ca_cert, ca_private_key,
                                                 node_ids_file, file_id,
                                                 outdir, endpoint_file,
                                                 prov_type)
        if not certs_dest_filename:
            log.error("Generate device certificate failed")
            return
        log.info('\nNode Ids and device certificates saved at '
                 'location: {}'.format(certs_dest_filename))
        # Generate binaries
        log.info("\nGenerating binaries for the device certficates generated")
        gen_cert_bin(outdir, file_id)
        log.info('\nYou can now run: \npython rainmaker_admin_cli.py certs '
                 'devicecert register --inputfile {} '
                 '(Register Generated Device Certificate(s))'.format(
                     certs_dest_filename))

    except KeyboardInterrupt:
        log.error("\nGenerate device certificate failed")
    except Exception as err:
        log.error("Generate device certificate failed")
        if len(str(err)) > 0:
            log.error("Error: {}".format(err))
Ejemplo n.º 19
0
    def get_cert_upload_url(self, cert_filename):
        '''
        Get URL to upload device certificates

        :param cert_filename: Filename having certifcates
        :type cert_filename: str
        '''
        try:
            backslash = '/'
            log.info("Get URL for uploading certificates file")
            retry_cnt = MAX_HTTP_CONNECTION_RETRIES
            expected_key_in_resp = "url"
            err_status_key = "status"

            path = 'admin/node_certificates/register'
            query_params = {'file_name': cert_filename}
            request_url = constants.HOST.rstrip(backslash) + backslash + path

            log.debug('Sending request to get URL '
                      'for uploading certificates file '
                      '- url: {} params: {}'.format(request_url, query_params))

            while retry_cnt > 0:
                try:
                    log.debug('Sending HTTP {} request - url: {} params: {} '
                              'headers: {}'.format('get', request_url,
                                                   query_params,
                                                   self.request_header))
                    # Send query params in HTTP GET Request
                    response = requests.get(url=request_url,
                                            params=query_params,
                                            headers=self.request_header,
                                            verify=configmanager.CERT_FILE,
                                            timeout=(5.0, 5.0))
                    log.debug("Response status code received: {}".format(
                        response.status_code))
                    response = json.loads(response.text)
                    log.debug("Response received: {}".format(response))

                    if expected_key_in_resp in response:
                        log.debug('Expected key: {} present in '
                                  'response: {}'.format(
                                      expected_key_in_resp, response))
                        log.info('URL for uploading certificates file '
                                 'received successfully')
                        log.debug("URL received: {}".format(
                            response[expected_key_in_resp]))
                        return response[expected_key_in_resp]
                    elif err_status_key in response:
                        log.debug('Request failed: response '
                                  'received: {}'.format(response))
                        log.error("Status: {} \n {}".format(
                            response[err_status_key], response['description']))
                        return None

                except NetworkError as net_err:
                    log.error(net_err)
                except RequestTimeoutError as req_err:
                    log.error(req_err)

                log.info('Retrying...No of retries '
                         'left: {}'.format(str(retry_cnt - 1)))
                retry_cnt -= 1
                time.sleep(5)

            return None

        except SSLError as ssl_err:
            log.error(ssl_err)
        except Exception as req_exc_err:
            raise Exception(req_exc_err)
Ejemplo n.º 20
0
def register_device_cert(vars=None):
    '''
    Register Uploaded Device Certificate

    :param vars: `inputfile` as key - Name of file containing
                                      node ids and device certificates
    :type vars: str

    :raises Exception: If there is any exception while
                       registering Device Certificate(s)
            KeyboardInterrupt: If there is a keyboard interrupt by user

    :return: None on Failure
    :rtype: None
    '''
    try:
        log.debug("Register device certificate")
        ret_status = _cli_arg_check(vars['inputfile'],
                                    '--inputfile <csvfilename>')
        if not ret_status:
            return

        is_valid_type = _check_file_type(vars['inputfile'])
        if not is_valid_type:
            return

        _print_keyboard_interrupt_message()

        # Get current login session token
        # Re-login if session expired
        session = Session()
        curr_email_id = session.get_curr_user_creds()
        token = session.get_access_token()
        if not token:
            log.error("Register device certificate failed")
            return

        # Get filename from input path
        basefilename = os.path.basename(vars['inputfile'])
        node_mfg = Node_Mfg(token)
        # Get URL to upload Device Certificate to
        cert_upload_url = node_mfg.get_cert_upload_url(basefilename)
        if not cert_upload_url:
            log.error("Upload Device Certificate Failed.")
            return

        # Upload Device Certificate file to S3 Bucket
        cert_upload = upload_cert(cert_upload_url, vars['inputfile'])
        if not cert_upload:
            log.error("Failed to upload Device Certificates")
            return
        else:
            log.info("Device certificate uploaded")

        # Get MD5 Checksum for input file
        md5_checksum = _get_md5_checksum(vars['inputfile'])

        # Register Device Certificate
        request_id = node_mfg.register_cert_req(basefilename, md5_checksum)
        if not request_id:
            log.error("Request to register device certificate failed")
            return
        else:
            log.info('Request to register device certificate is successful\n')
            log.info('Certificate registration will take some time\n'
                     'You will receive the status on '
                     'your email-id: {}'.format(curr_email_id))

        log.info(
            '\nYou can also run following command to check status: \n'
            'python rainmaker_admin_cli.py certs devicecert getcertstatus '
            '--requestid {} '
            '(Get Device Certificate Registration '
            'Status)'.format(request_id))

    except KeyboardInterrupt:
        log.error("\nRegister device certificate failed")
    except Exception as e:
        log.error("Error: {}".format(e))
Ejemplo n.º 21
0
    def login(self, password=None):
        """
        Login to user with given password

        :param password: Password of User
        :type password: str
        """
        try:
            backslash = '/'
            socket.setdefaulttimeout(10)
            expected_resp = ["idtoken", "accesstoken", "refreshtoken"]
            # Get password from user
            if password is None:
                log.debug("Get password from user")
                password = getpass.getpass("Password:"******"Password received")

            # Set HTTP Request
            path = 'login/'
            login_info = {'user_name': self.__email, 'password': password}

            login_url = constants.HOST.rstrip(backslash) + backslash + path

            log.debug('Sending HTTP POST Request - login url:{} '
                      'request body: {}'.format(login_url,
                                                json.dumps(login_info)))

            # Send HTTP POST Request
            log.debug('Sending HTTP {} request - url: {} data: {} '
                      'headers: {}'.format('post', login_url,
                                           json.dumps(login_info),
                                           self.request_header))

            response = requests.post(url=login_url,
                                     data=json.dumps(login_info),
                                     headers=self.request_header,
                                     verify=configmanager.CERT_FILE,
                                     timeout=(5.0, 5.0))

            response = json.loads(response.text)

            log.debug("Response received: {}".format(response))

            # Check response
            if 'status' in response:
                log.debug("Response status: {}".format(response['status']))
                if 'success' in response['status']:
                    for item in expected_resp:
                        if item not in response:
                            log.error('Expected response {} not found in '
                                      'response: {}'.format(item, response))
                            return False
                        else:
                            log.debug('Expected response {} received in '
                                      'response: {}'.format(item, response))

                    return response
                elif 'failure' in response['status']:
                    log.info(response['description'])
                    return False
                else:
                    log.debug(
                        "Login API HTTP status not in success/failure. Response received: {}"
                        .format(response))
                    return False

        except SSLError as ssl_err:
            log.error(ssl_err)
        except NetworkError as net_err:
            log.error(net_err)
        except RequestTimeoutError as req_err:
            log.error(req_err)
        except RequestException as req_exc_err:
            log.error(req_exc_err)
        except Exception as err:
            log.error(err)
Ejemplo n.º 22
0
def login(vars=None):
    '''
    User login

    :param vars: `email` as key - Email of user to login
    :type vars: str

    :raises Exception: If there is any exception while logging in
            KeyboardInterrupt: If there is a keyboard interrupt by user

    :return: None on Failure
    :rtype: None
    '''
    try:
        log.debug("Login command")
        ret_server_status = _verify_serverconfig_exists()
        if not ret_server_status:
            return

        ret_status = _cli_arg_check(vars['email'], '--email <emailid>')
        if not ret_status:
            return

        _print_keyboard_interrupt_message()

        # Get current user email-id
        session = Session()
        curr_email_id = session.get_curr_user_creds()

        # Remove current login config if exists
        config = configmanager.Config()
        # Current email creds exist
        if curr_email_id:
            ret_status = config.remove_curr_login_config(email=curr_email_id)
            if not ret_status:
                return

        # User login
        user = User(vars['email'])
        # Login API call
        user_login_data = user.login()
        if not user_login_data:
            log.error("Login failed.")
            return
        else:
            log.info("Login successful")

        # Save new user login config
        ret_status, cfg_file = config.save_config(user_login_data)
        if not ret_status:
            log.error('Failed to save login config '
                      'to file {}'.format(cfg_file))
            return
        else:
            log.info("Saved new login config in file: {}".format(cfg_file))

        log.info('\nYou can now run: \npython rainmaker_admin_cli.py certs '
                 'cacert generate -h (Generate CA Certificate)'
                 '\n\tor\npython rainmaker_admin_cli.py certs devicecert '
                 'generate -h (Generate Device Certificate(s))')
    except KeyboardInterrupt:
        log.error("\nLogin Failed")
    except Exception as e:
        log.error("Error: {}".format(e))
Ejemplo n.º 23
0
 def get_access_token(self):
     '''
     Get Access Token
     '''
     try:
         log.debug("Getting access token")
         config = Config()
         config_data = config.read_config()
         if not config_data:
             log.info("User is not logged in. Please login to continue")
             log.debug('User config data not found. '
                       'Please login to continue')
             return False
         log.debug("Config data: {}".format(config_data))
         if 'accesstoken' not in config_data:
             log.error('Access Token not found in current login '
                       'config data from '
                       'file: {}'.format(config.config_file))
             return False
         access_token = config_data['accesstoken']
         if not self.__is_valid_token(access_token):
             log.info('Previous Session expired. Initialising new session')
             id_token = config_data['idtoken']
             email_id = self.get_token_attribute('email', id_token)
             log.debug("Email Id: {}".format(email_id))
             if not email_id:
                 log.debug("Failed to get email attribute from payload.")
                 return False
             valid_ver_status = self.__is_valid_version()
             if valid_ver_status is False:
                 log.error(InvalidApiVersionError())
                 return False
             elif valid_ver_status is None:
                 return False
             refresh_token = config_data['refreshtoken']
             user = User(email_id)
             access_token, id_token = user.get_new_token(refresh_token)
             log.debug('New config data received - access token: {} '
                       'id token: {}'.format(access_token, id_token))
             if not access_token and not id_token:
                 log.debug("Error getting new user token")
                 log.info(
                     "Previous Session expired. Cannot extend session. Please login to continue"
                 )
                 return False
             new_config = {}
             key_text = str('accesstoken')
             new_config[key_text] = access_token
             key_text = str('idtoken')
             new_config[key_text] = id_token
             key_text = str('refreshtoken')
             new_config[key_text] = refresh_token
             log.debug("New config data: {}".format(new_config))
             ret_status = config.update_config(new_config)
             log.debug("Config data update status: {}".format(ret_status))
             if not ret_status:
                 log.debug("Failed to update config.")
                 return False
             log.debug('Previous Session expired. New session initialised.')
         log.debug("Current Session is valid")
         return access_token
     except Exception as err:
         log.debug("Error while getting access token")
         return False
Ejemplo n.º 24
0
def _print_keyboard_interrupt_message():
    log.info("Press Ctrl-C to abort")
Ejemplo n.º 25
0
    def gen_node_id(self, node_count):
        '''
        Generate list of node ids

        :param node_cnt: Number of node ids to get
        :type node_cnt: int
        '''
        try:
            backslash = '/'
            req_id = None
            log.info("Sending request for generating node ids: {}".format(
                node_count))
            expected_resp = 'request_id'
            log.debug('Sending request for node ids for number of nodes: {}. '
                      'Expected response: {}'.format(node_count,
                                                     expected_resp))
            req_id = self.get_node_id_req(node_count,
                                          expected_resp=expected_resp)
            if not req_id:
                log.debug(
                    "Expected response: {} not found.".format(expected_resp))
                return False
            log.info('Request for generating '
                     'node ids: {} is successful'.format(node_count))

            retry_cnt = MAX_HTTP_CONNECTION_RETRIES
            expected_key_in_resp = "url"

            path = 'admin/node_ids'
            query_params = {'request_id': req_id}
            request_url = constants.HOST.rstrip(backslash) + backslash + path

            log.debug('Sending GET HTTP Request - request url: {} '
                      'query params: {}'.format(request_url, query_params))

            log.info('Sending request for getting {} '
                     'for node ids file'.format(expected_key_in_resp))

            while retry_cnt > 0:
                try:
                    log.debug('Sending HTTP {} request - url: {} params: {} '
                              'headers: {}'.format('get', request_url,
                                                   query_params,
                                                   self.request_header))
                    # Send query params in HTTP GET Request
                    response = requests.get(url=request_url,
                                            params=query_params,
                                            headers=self.request_header,
                                            verify=configmanager.CERT_FILE,
                                            timeout=(5.0, 5.0))
                    log.debug("Response status code received: {}".format(
                        response.status_code))
                    response = json.loads(response.text)
                    log.debug("Response received: {}".format(response))

                    curr_time = time.time()
                    timestamp = datetime.datetime.fromtimestamp(
                        curr_time).strftime('%H:%M:%S')
                    log.info("[{:<6}] Current status: {:<3}".format(
                        timestamp, response['status']))
                    if 'success' in response['status']:
                        log.debug("Response status: {}".format(
                            response['status']))
                        if expected_key_in_resp not in response:
                            raise InvalidJSONError
                        log.info("Node ids file url received successfully")
                        log.debug("URL received: {}".format(
                            response[expected_key_in_resp]))
                        return response[expected_key_in_resp]
                    elif 'in_progress' in response['status']:
                        time.sleep(5)
                        continue
                    elif 'failure' in response['status']:
                        log.debug('Request failed: response '
                                  'received: {}'.format(response))
                        log.error("Status: {} \n {}".format(
                            response['status'], response['description']))
                        return None

                except NetworkError as net_err:
                    log.error(net_err)
                except RequestTimeoutError as req_err:
                    log.error(req_err)

                log.info('Retrying...No of retries left: {}'.format(
                    str(retry_cnt - 1)))
                retry_cnt -= 1
                time.sleep(5)

            return None

        except InvalidJSONError as json_err:
            log.error(json_err)
        except SSLError as ssl_err:
            log.error(ssl_err)
        except Exception as err:
            raise Exception(err)