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
def get_token_attribute(self, attribute_name, token): ''' Get User token attribute :param attribute_name: Token Attribute Name :type attribute_name: str :param token: User Token :type token: str ''' log.debug("Getting token attribute") token_payload = token.split('.')[1] if len(token_payload) % 4: token_payload += '=' * (4 - len(token_payload) % 4) log.debug("Token Payload: {}".format(token_payload)) try: str_token_payload = base64.b64decode(token_payload).decode("utf-8") log.debug("Token Playload String: {}".format(str_token_payload)) attribute_value = json.loads(str_token_payload)[attribute_name] log.debug("Attribute Value: {}".format(attribute_value)) if attribute_value is None: log.error(InvalidConfigError()) return attribute_value except Exception as err: raise Exception(err)
def save_key(key, filepath): ''' Save key to file :param key: Private Key :type key: RSA Private Key :param filepath: Destination filepath with filename :type filepath: str ''' try: log.debug("Saving Private key to file: {}".format(filepath)) key_bytes = key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.TraditionalOpenSSL, encryption_algorithm=serialization.NoEncryption()) with open(filepath, "wb+") as f: f.write(key_bytes) log.debug("Key saved to file at location: {}".format(filepath)) return True except FileError as file_err: log.debug( FileError('Error occurred while saving key to file {} ' 'error: {} \n'.format(filepath, file_err))) log.error('Error: Failed to save key in file {}'.format(filepath)) except Exception as err: log.debug( FileError('Error occurred while saving key to file {} ' 'error: {} \n'.format(filepath, err))) log.error('Error: Failed to save key in file {}'.format(filepath))
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)
def save_cert(cert, filepath): ''' Save certificate to file :param cert: Certificate :type cert: x509 Certificate :param filepath: Destination filepath with filename :type filepath: str ''' try: log.debug("Saving Certificate to file: {}".format(filepath)) cert_bytes = cert.public_bytes(encoding=serialization.Encoding.PEM, ) with open(filepath, "wb+") as f: f.write(cert_bytes) log.debug("Certificate saved to file {}".format(filepath)) return True except FileError as file_err: log.debug( FileError('Error occurred while saving cert to ' 'file {} error: {} \n'.format(filepath, file_err))) log.error('Error: Failed to save cert in file {}'.format(filepath)) except Exception as err: log.debug("Error {}. Cannot save certificate".format(err)) log.error('Error: Failed to save cert in file {}'.format(filepath))
def _fileid_check(file_id, node_count, extra_values): log.debug("Fileid check") if file_id: # Verify fileid count ret_status = verify_fileid_count(extra_values, file_id, node_count) if not ret_status: log.error( "Count: {} provided is greater than the values for fileid: {} in file: {}" .format(node_count, file_id, extra_values)) return False return True
def _check_file_type(input_file): header_str = "certs" cert_str = "BEGIN CERTIFICATE" with open(input_file, 'r', newline='\n') as inputfile: header_data = inputfile.readline() if header_str in header_data: cert_data = inputfile.readline() if cert_str in cert_data: return True log.error( "\nInput file is invalid. Please provide file containing the certificates" ) return False
def _verify_serverconfig_exists(): if not os.path.exists(SERVER_CONFIG_FILE): log.error('Server configuration is not set. Please configure using ' '<account serverconfig> CLI command') return False # If empty serverconfig file exists try: from rmaker_admin_lib.serverconfig import BASE_URL except ImportError: log.error('Server configuration is not set. ' 'Please configure using <account serverconfig> CLI command') return False return True
def _set_login_config_data(self, data): ''' Set login config data :param data: Login data to be set :type data: dict ''' try: log.debug("Setting login config data") config_data = {} config_data['idtoken'] = data['idtoken'] config_data['accesstoken'] = data['accesstoken'] config_data['refreshtoken'] = data['refreshtoken'] log.debug("Login config data set: {}".format(config_data)) return config_data except KeyError as key_err: log.error("Key Error in login config data: {}".format(key_err))
def get_new_token(self, refresh_token): """ Get new token for User Login :param refresh_token: Refresh Token of User :type refresh_token: str """ try: backslash = '/' socket.setdefaulttimeout(10) log.debug("Extending user login session") # Set HTTP Request path = 'login' request_payload = { 'user_name': self.__email, 'refreshtoken': refresh_token } request_url = constants.HOST.rstrip(backslash) + backslash + path log.debug('Sending HTTP POST Request - request url: {} ' 'request body: {}'.format(request_url, json.dumps(request_payload))) # Send HTTP POST Request log.debug('Sending HTTP {} request - url: {} data: {} ' 'headers: {}'.format('post', request_url, json.dumps(request_payload), self.request_header)) response = requests.post(url=request_url, data=json.dumps(request_payload), 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 'accesstoken' in response and 'idtoken' in response: log.debug("User session extended successfully") return response['accesstoken'], response['idtoken'] return False, 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: raise Exception(err)
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)
def set_server_config(self, endpoint): ''' Set server config endpoint :param data: Server config endpoint to be used :type data: str ''' try: backslash = '/' endpoint_to_write = "BASE_URL = '{}{}'".format(endpoint.rstrip(backslash), backslash) with open(self.config_file, 'w', encoding='utf-8') as cfg_file: cfg_file.write(endpoint_to_write) cfg_file.write('\n') return True except Exception as save_config_err: log.error(save_config_err) raise
def update_config(self, data): ''' Update current config data :param data: Config data to be updated :type data: dict ''' try: if not os.path.exists(self.config_file): log.error('Update config failed. Config file {} ' 'does not exist.'.format(self.config_file)) return False with open(self.config_file, 'w', encoding='utf-8') as cfg_file: cfg_file.write(str(json.dumps(data))) return True except Exception as save_config_err: log.error(save_config_err) raise
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
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))
def setup(self, dest=''): ''' CLI Setup ''' try: # Set Parent Parser log.debug("Setting up argparser") self.parser = argparse.ArgumentParser( description=self.description, formatter_class=self.formatter_class) log.debug("Parent parser set") # Add parent subparser parent_subparser = self._add_subparser( self.parser, title='Commands', help_text='usage: rainmaker_admin_cli.py {command} -h for ' 'additional help', dest=dest) return parent_subparser except KeyError as key_err: log.error(KeyError(str(key_err))) print(traceback.format_exc()) except AttributeError as attr_err: log.error(AttributeError(str(attr_err))) print(traceback.format_exc()) except Exception as err: log.error( CLIError('ERROR: Error occurred during ' 'CLI Setup. {}'.format(err))) print(traceback.format_exc()) return
def read_config(self): ''' Read from saved config file ''' try: log.debug("Read from config file: {}".format(self.config_file)) if not os.path.exists(self.config_file): log.debug('File not found: {}'.format(self.config_file)) return None with open(self.config_file, "r") as config_file: user_config_data = json.load(config_file) log.debug("Config data received: {}".format(user_config_data)) return user_config_data except Exception as err: log.error(FileError('Error occurred while reading config ' 'from file {}\n{}'.format( self.config_file, err))) raise
def _cli_arg_check(arg, expected_arg, err_msg=None): ''' Check if arg is given as CLI input :param arg: Input argument provided :type arg: str :param expected_arg: Expected argument :type expected_arg: str :param err_msg: Error message :type err_msg: str :return: True on Success, False on Failure :rtype: bool ''' if not arg: if err_msg: log.error("{}".format(err_msg)) else: log.error("{} is required".format(expected_arg)) return False return True
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)
def _save_nodeid_and_cert_to_file(node_id, dev_cert, dest_csv_file): ''' Save Node Id and Certificate to file :param node_id: Node Id :type node_id: str :param dev_cert: Device Certificate :type dev_cert: x509 Certificate :param dest_csv_file: Destination CSV file :type dest_csv_file: str ''' try: delimiter = "," newline = "\n" double_quote = "\"" dev_cert_bytes = dev_cert.public_bytes( encoding=serialization.Encoding.PEM, ) dev_cert_str = double_quote + dev_cert_bytes.decode('utf-8') + \ double_quote log.debug("Saving node id and cert to file: {}".format(dest_csv_file)) new_data = [node_id, dev_cert_str] data_to_write = delimiter.join(new_data) + newline dest_csv_file.write(data_to_write) log.debug("Node Id and Cert saved to file: {}".format(dest_csv_file)) log.debug("Node id and certificate saved to file successfully") return True except FileError as file_err: log.error( FileError('Error occurred while saving node id and cert to ' 'file {} error: {} \n'.format(dest_csv_file, file_err))) except Exception as err: log.error( FileError('Error occurred while saving node id and cert to ' 'file {} error: {} \n'.format(dest_csv_file, err))) raise
def get_ca_key_from_file(filename): ''' Get CA Key from file :param filename: Filename for saving CA Private Key :type filename: str ''' try: path_sep = os.sep filename = os.path.expanduser(filename.rstrip(path_sep)) log.debug("Get CA Key from file: {}".format(filename)) ca_key = None with open(filename, "rb") as key_file: ca_key = serialization.load_pem_private_key( key_file.read(), password=None, backend=default_backend()) log.debug("CA Key received.") return ca_key except FileError as file_err: log.error( FileError('Error occurred while getting key to ' 'file {} error: {} \n'.format(filename, file_err))) return except Exception as err: raise Exception(err)
def get_ca_cert_from_file(filename): ''' Get CA Certificate from file :param filename: Filename for saving CA Certificate :type filename: str ''' try: path_sep = os.sep filename = os.path.expanduser(filename.rstrip(path_sep)) log.debug("Saving CA Certificate to file: {}".format(filename)) ca_cert = None with open(filename, "rb") as crt_file: ca_cert = x509.load_pem_x509_certificate(crt_file.read(), default_backend()) log.debug("CA certificate from file received") return ca_cert except FileError as file_err: log.error( FileError('Error occurred while getting cert to ' 'file {} error: {} \n'.format(filename, file_err))) return except Exception as err: raise Exception(err)
def get_nodeid_from_file(filename): ''' Get Node Id from file :param filename: Filename containing Node Ids :type filename: str ''' try: log.debug("Getting node id from file: {}".format(filename)) delimiter = "," with open(filename) as csvfile: rows_in_file = csvfile.readlines() file_data = _check_file_format(rows_in_file) log.debug("File data received: {}".format(file_data)) nodeid_list = file_data[0].split(delimiter) log.debug("Node Ids list: {}".format(nodeid_list)) nodeid_list = _check_file_format(nodeid_list) log.debug("Node Ids received from file: {}".format(nodeid_list)) return nodeid_list except Exception as err: log.error( FileError('Error occurred while getting node ids from ' 'file {}\n{}'.format(filename, err))) raise
def __is_valid_version(self): ''' Check if API version is valid ''' backslash = '/' log.debug("Checking API Version") socket.setdefaulttimeout(10) path = 'apiversions' request_url = constants.HOST.split( constants.VERSION)[0].rstrip(backslash) + backslash + path log.debug('Sending GET HTTP Request - ' 'request url: {}'.format(request_url)) try: log.debug('Sending HTTP {} ' 'request - url: {}'.format('get', request_url)) response = requests.get(url=request_url, verify=configmanager.CERT_FILE, timeout=(5.0, 5.0)) response = json.loads(response.text) log.debug("Response received: {}".format(response)) if 'supported_versions' in response: supported_versions = response['supported_versions'] log.debug("Supported Versions: {}".format(supported_versions)) if constants.VERSION in supported_versions: log.debug("Version: {} supported".format( constants.VERSION)) return True except SSLError as ssl_err: log.error(ssl_err) return None except NetworkError as net_err: log.error(net_err) return None except RequestTimeoutError as req_err: log.error(req_err) return None except RequestException as req_exc_err: log.error(req_exc_err) return None except Exception as err: raise Exception(err) return False
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))
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)
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))
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))
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))
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))