def post(self): """ Receives control when the Submit button is clicked in the Notifications Card to register an email address. :return: Re-renders the page with the message of whether the email address was registered successfully or not. """ read_status_file_rc, self.container_status_dict = Common.rw_json_file( file_path=os.environ.get('container_status_path')) if read_status_file_rc: if request.form.get('add_delete_email_radio') == 'delete': self.delete_email() else: write_notify_email_file_rc = False if not Common.check_path_exists( os.environ.get('notify_emails_path')): with open(os.environ.get('notify_emails_path'), 'w+') as emfh: emfh.write(self.base_notify_emails_json_structure) read_notify_email_file_rc, self.notify_email_dict = Common.rw_json_file( file_path=os.environ.get('notify_emails_path')) if read_notify_email_file_rc: if request.form.get('app_email_register_radio') != 'ALL': app_email_list = self.notify_email_dict.get( request.form.get('app_email_register_radio')).get( 'email_list') if request.form.get( 'email_addr') not in app_email_list: app_email_list.append( request.form.get('email_addr')) write_notify_email_file_rc, write_info = Common.rw_json_file( os.environ.get('notify_emails_path'), mode='write', output_dict=self.notify_email_dict) else: write_notify_email_file_rc = True else: for app_email_dict in self.notify_email_dict.values(): if request.form.get( 'email_addr') not in app_email_dict.get( 'email_list'): app_email_dict.get('email_list').append( request.form.get('email_addr')) write_notify_email_file_rc, write_info = Common.rw_json_file( os.environ.get('notify_emails_path'), mode='write', output_dict=self.notify_email_dict) if write_notify_email_file_rc: Common.create_flash_message( "Email registered Successfully") else: Common.create_flash_message( "Error registering email. Please contact SA3 Core Automation Team." ) return redirect(url_for("container_status"))
def get(self): """ :return: Renders the html page with all substituted content needed. """ if os.environ.get('container_status_path') is None or os.environ.get( 'container_status_path') == '': container_status_app.logger.error( "Environment variable 'container_status_path' not defined.") return render_template(self.nas_production_html_template, status_file_err=True) read_json_rc, self.container_status_dict = Common.rw_json_file( file_path=os.environ.get('container_status_path')) if read_json_rc: if request.url_rule.rule == '/nas_status' or request.url_rule.rule == '/': if 'nas_production' in self.container_status_dict: if os.environ.get('notify_emails_path' ) is not None and os.environ.get( 'notify_emails_path') != '': read_email_rc, self.notify_email_dict = Common.rw_json_file( file_path=os.environ.get('notify_emails_path')) if read_email_rc and type( self.notify_email_dict) is dict: return render_template( self.nas_production_html_template, cs=self.container_status_dict.get( 'nas_production'), list_registered_emails=self.notify_email_dict) else: return render_template( self.nas_production_html_template, cs=self.container_status_dict.get( 'nas_production')) else: container_status_app.logger.error( "Environment variable 'notify_emails_path' not defined" ) return render_template( self.nas_production_html_template, cs=self.container_status_dict.get( 'nas_production')) else: return render_template(self.nas_production_html_template) return render_template(self.nas_production_html_template, cs=self.container_status_dict) else: container_status_app.logger.error( "File {} could not be read.".format( os.environ.get('container_status_path'))) return render_template(self.nas_production_html_template, status_file_err=True)
def toggle_platform_status(self): """ Called when the one of the forms containing the platform toggle switches are submitted. Contains the high level logic and then calls the appropriate put() method. :return: """ read_json_rc, self.container_status_dict = Common.rw_json_file( file_path=os.environ.get('container_status_path')) nas_production_dict = self.container_status_dict.get('nas_production') if nas_production_dict is not None and nas_production_dict.get( 'display_name') == 'NAS Automation Platform': if 'toggle_switch_form' in list(request.form.keys()): toggle_switch_names = self.create_list_of_toggle_names( nas_production_dict.get('applications').keys()) status_switch_name = nas_production_dict.get( 'display_name') + '_status_switch' additional_info_name = None app_toggle_info_tuple = (status_switch_name, additional_info_name) toggle_switch_names.append(app_toggle_info_tuple) self.put(list_o_switch_name=toggle_switch_names) if 'p2_toggle_switch_form' in list(request.form.keys()): toggle_switch_names = self.create_list_of_toggle_names( nas_production_dict.get('new_platform_apps').keys()) status_switch_name = nas_production_dict.get( 'p2_display_name') + '_status_switch' additional_info_name = None app_toggle_info_tuple = (status_switch_name, additional_info_name) toggle_switch_names.append(app_toggle_info_tuple) self.put_p2(list_o_switch_name=toggle_switch_names) return
def get(self): """ :return: Renders the html page with all substituted content needed. """ if os.environ.get('faq_data_path') is None or os.environ.get( 'faq_data_path') == '': container_status_app.logger.error( "Environment variable 'faq_data_path' not defined.") return render_template(self.nas_faq_html_template, faq_file_err=True) read_json_rc, self.faq_dict = Common.rw_json_file( file_path=os.environ.get('faq_data_path')) if read_json_rc and type(self.faq_dict) is dict: # for faq_category, faq_dicts in self.faq_dict.items(): # for faq_question, faq_content in faq_dicts.items(): # if type(faq_content) is list: # joined_multiline_content = "" # for content_string in faq_content: # joined_multiline_content = joined_multiline_content + content_string + "\r\n" # faq_dicts[faq_question] = joined_multiline_content.replace("\r\n", "<br\>") # self.faq_dict[faq_category] = faq_dicts return render_template(self.nas_faq_html_template, faq_dict=self.faq_dict) else: container_status_app.logger.error( "FAQ data in JSON file {} could not be read or could not be converted " "into a dictionary".format(os.environ.get('faq_data_path'))) return render_template(self.nas_faq_html_template, faq_file_err=True)
def send_email_notification(self): """ Called by the POST method when the "Send Email Notification" form is submitted. :return: True or false the email was sent. """ email_sent_message = "Notification email {}" read_notify_email_file_rc, self.notify_email_dict = Common.rw_json_file( file_path=os.environ.get('notify_emails_path')) if read_notify_email_file_rc: if request.form.get('from_email_addr') is None or request.form.get( 'from_email_addr') == '': send_from = self.default_from_email_addr else: send_from = request.form.get( 'from_email_addr').strip() + '@uscellular.com' if request.form.get('app_email_radio') == 'ALL': dict_of_emails = dict() for app, app_email_data in self.notify_email_dict.items(): dict_of_emails[app] = app_email_data.get('email_list') list_of_addr_to_send_to = Common.flatten_list(dict_of_emails) else: list_of_addr_to_send_to = self.notify_email_dict.get( request.form.get('app_email_radio').lower()).get( 'email_list') email = EmailServices(subject=request.form.get('email_subject'), from_address=send_from, to_address=list_of_addr_to_send_to) email_sent = email.send_email(request.form.get('email_content')) if email_sent: container_status_app.logger.info( email_sent_message.format('sent')) return True else: container_status_app.logger.error( email_sent_message.format('not sent')) return False else: container_status_app.logger.error( email_sent_message.format( 'not sent. List of registered emails could not be retrieved.' )) return False
def post(self): """ """ # if 'logout_btn' in request.form: # self.delete() # return self.login_redirect_response # # if request.cookies.get('access_token_cookie') is None: # self.redirect_to_uscc_login() # return self.login_redirect_response form = ContainerForm() if request.form.get('open_status') == 'on': self.open_container_status() else: if form.validate_on_submit(): with open(os.environ.get('container_status_path')) as csrfh: status_file_dict = json.load(csrfh) update_container_dict = status_file_dict.get( request.form.get('container_name')) update_container_dict['status'] = 'not open' update_container_dict.get('time_frame')[ 'start_date'] = request.form.get('start_date') update_container_dict.get( 'time_frame')['end_date'] = request.form.get('end_date') update_container_dict.get('poc')['name'] = request.form.get( 'poc_name') update_container_dict.get('poc')['email'] = request.form.get( 'poc_email') status_file_dict[request.form.get( 'container_name')] = update_container_dict with open(os.environ.get('container_status_path'), mode='w') as cswfh: json.dump(status_file_dict, cswfh) else: if len(form.errors) != 0: for form_field, error_message_text in form.errors.items(): Common.create_flash_message(message=form_field + ':' + error_message_text[0]) return render_template('container_status/update_container_status.html', form=form)
def put_p2(self, list_o_switch_name): """ Called by the Post method if the Status Switch button is toggled on the New Architecture tab panel. Looks at updating the container status JSON data to set the overall and each application status keys. :param list_o_switch_name: switch names from the nas_notify.html components. :return: """ if self.container_status_dict.get('nas_production') is not None: if self.container_status_dict['nas_production'].get( 'p2_overall_status') is not None: for switch_tuple in list_o_switch_name: """ For each switch tuple (i.e. (switch name, additional info) find the switch name in the request form and see if it was switch on or off and set the appropriate status string. """ if request.form.get(switch_tuple[0]) == 'on': update_status = 'ACTIVE' else: update_status = 'NOT ACTIVE' update_app_name = switch_tuple[0].split('_', 1) if update_app_name[0] == self.container_status_dict.get( 'nas_production').get('p2_display_name'): if update_status == 'ACTIVE': self.container_status_dict['nas_production'][ 'p2_overall_status'] = update_status else: self.container_status_dict['nas_production'][ 'new_platform_apps'][ update_app_name[0]]['status'] = update_status self.container_status_dict['nas_production'][ 'new_platform_apps'][update_app_name[0]][ 'additional_info'] = switch_tuple[1] update_json_rc, file_updated = Common.rw_json_file( file_path=os.environ.get('container_status_path'), mode='write', output_dict=self.container_status_dict) update_log_message = "{} update of container status JSON file. Path: {}".format( 'Successful' if update_json_rc else 'Unsuccessful', file_updated) if update_json_rc: container_status_app.logger.info(update_log_message) else: container_status_app.logger.error(update_log_message) return
def get(self): """ :return: Renders the html page with all substituted content needed. """ if os.environ.get('faq_data_path') is None or os.environ.get('faq_data_path') == '': container_status_app.logger.error("Environment variable 'faq_data_path' not defined.") return render_template(self.nas_faq_html_template, faq_file_err=True) read_json_rc, self.faq_dict = Common.rw_json_file(file_path=os.environ.get('faq_data_path')) if read_json_rc: return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict) else: container_status_app.logger.error("FAQ data file could not be read at location {}".format(os.environ.get('faq_data_path'))) return render_template(self.nas_add_faq_html_template, faq_file_err=True)
def get(self): """ :return: Renders the html page with all substituted content needed. """ read_json_rc, self.container_status_dict = Common.rw_json_file( file_path=os.environ.get('container_status_path')) if read_json_rc: if self.container_status_dict.get('nas_production') is not None and self.container_status_dict.get\ ('nas_production').get('display_name') == 'NAS Automation Platform': return render_template( self.nas_notify_html_template, nas_prod_status_data=self.container_status_dict.get( 'nas_production')) return render_template(self.nas_notify_html_template)
def delete(self): """ Called when the Delete button is pressed on the Delete FAQ form on the /nas/add/faq page. Expects that the faq_dict class instance variable has been populated by the post() method above. :return: True/False if the selected FAQ titles were deleted or not. """ faqs_deleted = False for faq_to_delete_key, faq_to_delete_value in request.form.items(): if 'FAQButton' in faq_to_delete_key: continue else: faq_delete_metadata_list = faq_to_delete_key.split(':') category_faq_dict = self.faq_dict.get(faq_delete_metadata_list[0]) if faq_to_delete_value == 'ALL': category_faq_dict.clear() container_status_app.logger.info("All FAQs in Category {} have been deleted".format(faq_delete_metadata_list[0].upper())) faqs_deleted = True else: if category_faq_dict.pop(faq_to_delete_value, None) is not None: container_status_app.logger.info("FAQ {} in Category {} has been deleted.".format( faq_to_delete_value, faq_delete_metadata_list[0].upper())) faqs_deleted = True else: container_status_app.logger.warning("FAQ {} in Category {} not found.".format( faq_to_delete_value, faq_delete_metadata_list[0].upper())) update_json_rc, file_updated = Common.rw_json_file(file_path=os.environ.get('faq_data_path'), mode='write', output_dict=self.faq_dict) if update_json_rc: container_status_app.logger.info("FAQ data file {} updated successfully.".format(os.environ.get('faq_data_path'))) else: container_status_app.logger.error("FAQ data file {} could not be updated.".format(os.environ.get('faq_data_path'))) if faqs_deleted: faqs_deleted = False if faqs_deleted: return True else: return False
def delete_email(self): """ Deletes the email address from the requested app or all apps from the form in the Notifications card :return: """ write_notify_email_file_rc = False read_notify_email_file_rc, self.notify_email_dict = Common.rw_json_file( file_path=os.environ.get('notify_emails_path')) if read_notify_email_file_rc: if request.form.get('app_email_register_radio') != 'ALL': app_email_list = self.notify_email_dict.get( request.form.get('app_email_register_radio')).get( 'email_list') if request.form.get('email_addr') in app_email_list: app_email_list.remove(request.form.get('email_addr')) write_notify_email_file_rc, write_info = Common.rw_json_file( os.environ.get('notify_emails_path'), mode='write', output_dict=self.notify_email_dict) else: write_notify_email_file_rc = True else: for app_email_dict in self.notify_email_dict.values(): if request.form.get('email_addr') in app_email_dict.get( 'email_list'): app_email_dict.get('email_list').remove( request.form.get('email_addr')) write_notify_email_file_rc, write_info = Common.rw_json_file( os.environ.get('notify_emails_path'), mode='write', output_dict=self.notify_email_dict) if write_notify_email_file_rc: Common.create_flash_message("Email Deleted Successfully") else: Common.create_flash_message( "Error deleting email. Please contact SA3 Core Automation Team." ) return
def post(self): """ Receives control when the Submit button is clicked in either of the send email forms :return: Message indicating if the email was successfully sent or not. """ if 'toggle_switch_form' in list( request.form.keys()) or 'p2_toggle_switch_form' in list( request.form.keys()): self.toggle_platform_status() else: read_json_rc, self.container_status_dict = Common.rw_json_file( file_path=os.environ.get('container_status_path')) nas_production_dict = self.container_status_dict.get( 'nas_production') if 'nas_notify_form' in list(request.form.keys()): if self.send_email_notification(): Common.create_flash_message("Email sent Successfully", category_request='info') else: Common.create_flash_message( "Error sending email. Please Contact SA3 Core Automation Team.", category_request='error') return render_template( self.nas_notify_html_template, nas_prod_status_data=self.container_status_dict.get( 'nas_production')) if 'Choose' in request.form.get('time_of_day_start'): return render_template(self.nas_notify_html_template, tods_error=True) elif 'Choose' in request.form.get('time_of_day_end'): return render_template(self.nas_notify_html_template, tode_error=True) shutil.copyfile(os.environ.get('nas_down_email_template'), self.email_template_temp_file) with open(self.email_template_temp_file, 'r+') as email_template_fh: email_template_data = email_template_fh.read() email_template_data = email_template_data.replace( '{sd}', request.form.get('outage_start_date')) email_template_data = email_template_data.replace( '{st}', "{} {}".format(request.form.get('outage_start_time'), request.form.get('time_of_day_start'))) email_template_data = email_template_data.replace( '{ed}', request.form.get('outage_end_date')) email_template_data = email_template_data.replace( '{et}', "{} {}".format(request.form.get('outage_end_time'), request.form.get('time_of_day_end'))) email_template_data = email_template_data.replace( '{why}', "{}".format(request.form.get('reason_textarea'))) if request.form.get('platform_name') == 'old_platform': apps_list = nas_production_dict.get('applications').keys() else: apps_list = nas_production_dict.get( 'new_platform_apps').keys() app_replacement_string = '' for app in apps_list: app_replacement_string = app_replacement_string + 'o {}\n'.format( app) email_template_data = email_template_data.replace( '{app}', app_replacement_string) email_template_fh.seek(0) email_template_fh.truncate() email_template_fh.write(email_template_data) read_notify_email_file_rc, self.notify_email_dict = Common.rw_json_file( file_path=os.environ.get('notify_emails_path')) if read_notify_email_file_rc: dict_of_emails = dict() for app, app_email_data in self.notify_email_dict.items(): if app_email_data.get('platform') in request.form.get( 'platform_name'): dict_of_emails[app] = app_email_data.get('email_list') email = EmailServices( subject=self.nas_down_email.get('subject').format( request.form.get('outage_start_date')), from_address=self.nas_down_email.get('from_addr'), to_address=Common.flatten_list(dict_of_emails)) with open(self.email_template_temp_file) as email_fh: email_sent = email.send_email(email_fh.read()) email_sent_message = "Outage notification email {}" if email_sent: container_status_app.logger.info( email_sent_message.format('sent')) Common.create_flash_message("Email sent Successfully", category_request='info') else: container_status_app.logger.error( email_sent_message.format('not sent')) Common.create_flash_message( "Error sending email. Please Contact SA3 Core Automation Team.", category_request='error') if read_json_rc and nas_production_dict is not None: if request.form.get('platform_name') == 'old_platform': overall_status = 'overall_status' restored_by = 'restored_by' else: overall_status = 'p2_overall_status' restored_by = 'p2_restored_by' nas_production_dict[overall_status] = 'NOT ACTIVE' nas_production_dict[restored_by] = '{} {} {} CST'.format( request.form.get('outage_end_date'), request.form.get('outage_end_time'), request.form.get('time_of_day_end')) write_json_rc, file_updated = Common.rw_json_file( file_path=os.environ.get('container_status_path'), mode='write', output_dict=self.container_status_dict) container_status_app.logger.info( "Container status JSON file updated successfully: {}". format(file_updated)) else: container_status_app.logger.error( "File path {} for container status JSON data could not be updated" .format(os.environ.get('container_status_path'))) return render_template( self.nas_notify_html_template, status_file_update_err=os.environ.get( 'container_status_path')) return render_template( self.nas_notify_html_template, nas_prod_status_data=self.container_status_dict.get( 'nas_production'))
def post(self): """ Receives control when the Submit button is clicked in the Notifications Card to register an email address. :return: Re-renders the page with the message of whether the email address was registered successfully or not. """ read_json_rc, self.faq_dict = Common.rw_json_file(file_path=os.environ.get('faq_data_path')) if read_json_rc: if 'deleteFAQButton' in request.form.keys(): if len(request.form) > 1: if self.delete(): self.backup_faq_data() reread_json_rc, self.faq_dict = Common.rw_json_file(file_path=os.environ.get('faq_data_path')) if reread_json_rc: return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict, faq_delete_rc=True) else: return render_template(self.nas_add_faq_html_template, faq_file_err=True) else: return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict, faq_delete_rc=False) else: return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict, faq_selected=False) else: if 'faq_file' in request.files: if self.process_faq_file(): self.backup_faq_data() return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict, faq_added_rc=True) else: if self.backup_faq_data(restore=True): reread_json_rc, self.faq_dict = Common.rw_json_file(os.environ.get('faq_data_path')) return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict, faq_added_rc=False) else: return render_template(self.nas_add_faq_html_template, faq_file_err=True) faq_category_dicts = self.faq_dict.get(request.form.get('faq_type_radio')) if request.form.get('faq_question') == '' and request.form.get('faq_content') == '': error_message = "Please fill in the Question and Answer form or select a file to be uploaded" Common.create_flash_message(error_message, 'error') return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict) if "\r\n" in request.form.get('faq_content'): faq_content_data = request.form.get('faq_content').split("\r\n") else: faq_content_data = request.form.get('faq_content') faq_category_dicts[request.form.get('faq_question')] = faq_content_data self.faq_dict[request.form.get('faq_type_radio')] = faq_category_dicts update_json_rc, file_updated = Common.rw_json_file(file_path=os.environ.get('faq_data_path'), mode='write', output_dict=self.faq_dict) if update_json_rc: container_status_app.logger.info("New FAQ: {} | Category: {} | Content: {}".format( request.form.get('faq_question'), request.form.get('faq_type_radio'), request.form.get('faq_content'))) self.backup_faq_data() return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict, faq_added_rc=True) else: container_status_app.logger.error("Unable to add to Category: {} | FAQ: {} | Content: {}".format( request.form.get('faq_type_radio'), request.form.get('faq_question'), request.form.get('faq_content'))) _, self.faq_dict = Common.rw_json_file(os.environ.get('faq_data_path')) return render_template(self.nas_add_faq_html_template, faq_dict=self.faq_dict, faq_added_rc=False) else: container_status_app.logger.error("Unable to read JSON file containing FAQ data at path: {}".format(os.environ.get('faq_data_path'))) return render_template(self.nas_add_faq_html_template, faq_added_rc=False)
def process_faq_file(self): """ Processes an FAQ file uploaded via the upload element on the /nas/add/faq page. :return: """ question_keywords = ['Question', 'QUESTION', 'question'] answer_keywords = ['Answer', 'answer', 'ANSWER'] file = request.files.get('faq_file') if file.filename == '': return False if file and self.allowed_file_types(file.filename): filename = secure_filename(file.filename) # file.save(os.path.join(container_status_app.config.get('UPLOAD_FOLDER'), filename)) faq_category_dicts = self.faq_dict.get(request.form.get('faq_type_radio')) current_question = None # with open(os.path.join(container_status_app.config.get('UPLOAD_FOLDER'), filename)) as faq_file_handler: # for line in faq_file_handler: for line in file: if line.decode('utf-8-sig').split(':', 1)[0] in question_keywords: faq_category_dicts[(line.decode('utf-8-sig').split(':', 1)[1]).rstrip()] = None current_question = line.decode('utf-8-sig').split(':', 1)[1].rstrip() elif line.decode('utf-8').split(':', 1)[0] in answer_keywords: if "\n" in line.decode('utf-8').split(':', 1)[1]: faq_category_dicts[current_question] = (line.decode('utf-8').split(':', 1)[1]).rstrip("\n") else: faq_category_dicts[current_question] = line.decode('utf-8').split(':', 1)[1] else: # Have to assume the current read line is part of a answer that has multiple lines for the output current_answer = faq_category_dicts.get(current_question) if not isinstance(current_answer, list): temp_list = [current_answer, line.decode('utf-8').rstrip()] faq_category_dicts[current_question] = temp_list else: current_answer.append(line.decode('utf-8').rstrip()) faq_category_dicts[current_question] = current_answer # if line.split(':', 1)[0] in question_keywords: # faq_category_dicts[(line.split(':', 1)[1]).rstrip()] = None # current_question = line.split(':', 1)[1].rstrip() # elif line.split(':', 1)[0] in answer_keywords: # if "\n" in line.split(':', 1)[1]: # faq_category_dicts[current_question] = (line.split(':', 1)[1]).rstrip("\n") # else: # faq_category_dicts[current_question] = line.split(':', 1)[1] # else: # Have to assume the current read line is part of a answer that has multiple lines for the output # current_answer = faq_category_dicts.get(current_question) # if not isinstance(current_answer, list): # temp_list = [current_answer, line.rstrip()] # faq_category_dicts[current_question] = temp_list # else: # current_answer.append(line.rstrip()) # faq_category_dicts[current_question] = current_answer self.faq_dict[request.form.get('faq_type_radio')] = faq_category_dicts update_json_rc, file_updated = Common.rw_json_file(file_path=os.environ.get('faq_data_path'), mode='write', output_dict=self.faq_dict) if update_json_rc: container_status_app.logger.info("FAQ Category: {} updated".format(request.form.get('faq_type_radio').upper())) # os.remove(os.path.join(container_status_app.config.get('UPLOAD_FOLDER'), filename)) return True else: container_status_app.logger.error("Unable to add to FAQ Category: {}".format(request.form.get('faq_type_radio').upper())) return False