def save_devices_in_db(device_serials_list, net_id): error = [] try: network = Network.query.get(net_id) except (ProgrammingError, OperationalError) as e: error_log = str(e) log_msg = "Database error on Add Devices: {}".format(error_log) send_wr_log(log_msg) return jsonify("Database error!") for device_serial in device_serials_list: dev_name = device_serial.replace("-", "") network_id = network.id device = Device.query.filter_by(serial=device_serial).first() if device: error.append( "Device with {} serial is already registered in {}".format( device.serial, device.network.name)) continue device = Device(dev_name, device_serial, network_id) db.session.add(device) log_msg = "User: {} - Device Name: {}, Device Serial: {} is saved in DB".format( current_user.username, dev_name, device_serial) send_wr_log(log_msg) db.session.commit() if error: return jsonify(error) return jsonify("success")
def rename_devices(): result = [] if request.method == 'POST': rename_devices_json = request.get_json() device_name = rename_devices_json["device_name"] device_list = rename_devices_json["device_list"] for device in device_list: # db_device = Device.query.filter_by(serial=device['serial']).first() db_device = Device.query.get(device['id']) meraki_net_id = db_device.network.meraki_id serial = db_device.serial try: rename_response = rename_device_v0(meraki_net_id, serial, device_name) result.append("{} with model {} is renamed to {}".format( db_device.name, rename_response['model'], device_name)) log_msg = "User: {} - Device: {} is renamed as {}".format( current_user.username, db_device.name, device_name) db_device.name = device_name db_device.devmodel = rename_response['model'] db.session.add(db_device) send_wr_log(log_msg) except ConnectionError: log_msg = "User: {} - Meraki response error while renaming device: {}.".format( current_user.username, device['name']) send_wr_log(log_msg) result.append( "Meraki response error while renaming device: {}".format( device['name'])) db.session.commit() return jsonify(result)
def admin_groups(): form = GroupForm(request.form, meta={'csrf': False}) #form.set_choices() choice_form = ChoiceForm(request.form) choice_form.set_choices() if request.method == 'POST': if form.validate_on_submit(): error = None #new_group_name = request.data.decode("utf-8") #new_group_name = new_group_name.strip() new_group_name = form.new_group_name.data.strip() if len(new_group_name) < 4: error = "Group name must be 4 characters long at least!" return jsonify(error) if Group.query.filter_by(name=new_group_name).first(): error = "Exists!" return jsonify(error) new_group = Group(new_group_name) db.session.add(new_group) db.session.commit() log_msg = "User: {} - Group: {} is created.".format(current_user.username, new_group.name) send_wr_log(log_msg) return_data = [(group.id, group.name) for group in Group.query.all()] return jsonify(return_data) else: return jsonify(form.errors['new_group_name']), 400 return render_template('groups.html', form=form, choice_form=choice_form)
def replace_previous_appliance(meraki_net_id): result = [] meraki_devices = get_network_devices(meraki_net_id) if meraki_devices: for device in meraki_devices: if '450' in device['model'] or '600' in device[ 'model'] or '250' in device['model']: # MX250, MX450 and MX600 models are critical devices; so skip removing process continue try: remove_result = remove_network_device(meraki_net_id, device['serial']) except: remove_result = False result.append( "Meraki Server Error while removing device {}".format( device['serial'])) if remove_result: db_device = Device.query.filter_by(name=device['name']).first() if db_device: db_device.committed = False result.append('Device {} is removed from network'.format( device['serial'])) log_msg = "User: {} - Device {} is removed from " \ "network id: {}".format(current_user.username, device['serial'], meraki_net_id) send_wr_log(log_msg) return result
def logout(): log_msg = "User logged out: {}".format(current_user.username) send_wr_log(log_msg) # change user alt id for login_required behaviour user = current_user user.alt_id = get_random_alt_id() db.session.add(user) db.session.commit() # (flask_login) clear session logout_user() flash('You are logged out.') return redirect(url_for('users.login'))
def delete_groups(): result = [] if request.method == 'POST': groups_to_be_deleted = request.get_json() for group in groups_to_be_deleted: db_group = Group.query.filter_by(name=group['name']).first() db.session.delete(db_group) log_msg = "User: {} - Group: {} is removed.".format( current_user.username, db_group.name) send_wr_log(log_msg) result.append("Group: {} is removed".format(group['name'])) try: db.session.commit() except: return jsonify("Database error!") return jsonify(result)
def negate_user_admin_access(): if request.method == 'POST': users_to_be_negated = request.get_json() for user in users_to_be_negated: if user['name'] == current_user.username: return jsonify("Cannot modify current user") db_user = User.query.filter_by(username=user['name']).first() # group = Group.query.filter_by(name='administrators').first() db_user.admin = not db_user.admin # db_user.groups.append(group) if db_user.admin else db_user.groups.remove(group) db.session.add(db_user) log_msg = "User: {} - {}'s admin status is {}".format( current_user.username, db_user.username, db_user.admin) send_wr_log(log_msg) try: db.session.commit() except: return jsonify("Database error!") return jsonify("success")
def tag_group(): result = [] if request.method == 'POST': group_tag_list = request.get_json() group_list = group_tag_list[0] tag_list = group_tag_list[-1] for group_id in group_list: group = Group.query.get(int(group_id)) for tag_id in tag_list: tag = Tag.query.get(int(tag_id)) group.tags.append(tag) log_msg = "User: {} - Group: {} is associated with tag: {}.".format( current_user.username, group.name, tag.name) send_wr_log(log_msg) db.session.add(group) try: db.session.commit() except: return jsonify("Database error!") return jsonify(result)
def reboot_admin_devices(): result = [] if request.method == 'POST': reboot_devices_json = request.get_json() for device in reboot_devices_json: response = reboot_device(device['serial']) if response == "success": log_msg = "User: {} - Device: {} is rebooted.".format( current_user.username, device['serial']) send_wr_log(log_msg) result.append("Device: {} is rebooted!".format( device['serial'])) else: log_msg = "User: {} - Meraki response error while rebooting device: {}.".format( current_user.username, device['serial']) send_wr_log(log_msg) result.append( "Meraki response error while rebooting device: {}".format( device['serial'])) return jsonify(result)
def add_user(): result = [] if request.method == 'POST': user_group_list = request.get_json() user_list = user_group_list[0] group_list = user_group_list[-1] for user_id in user_list: user = User.query.get(int(user_id)) for grp_id in group_list: group = Group.query.get(int(grp_id)) user.groups.append(group) log_msg = "User: {} - {} is made member of group: {}".format( current_user.username, user.username, group.name) send_wr_log(log_msg) db.session.add(user) try: db.session.commit() except: return jsonify("Database error!") return jsonify(result)
def load_templates_to_db(): if Template.query.first(): template_age = datetime.datetime.now() - Template.query.first().reg_date template_age_days = template_age.days else: template_age_days = 100 # first time retrieving for template if template_age_days > 7: # If templates in db are older than a week, then drop templates table and retrieve again try: templates = get_templates() # returns dictionary Template.query.delete() for template in templates.items(): db_row = Template(*template) db.session.add(db_row) db.session.commit() except ConnectionError: error = "Meraki Server Bad Response" log_msg = "User: {} - {} while loading templates into db.".format(current_user.username, error) send_wr_log(log_msg) return error
def load_networks_to_db(): if Network.query.first(): network_age = datetime.datetime.now() - Network.query.first().reg_date network_age_days = network_age.days else: network_age_days = 100 # first time retrieving for template if network_age_days > 200: # If templates in db are older than a week, then drop templates table and retrieve again try: networks = get_networks() # returns dictionary list Network.query.delete() for network in networks: db_row = Network(**network) db.session.add(db_row) db.session.commit() return "Networks are saved in db" except ConnectionError: error = "Meraki Server Bad Response" log_msg = "User: {} - {} while loading networks into db.".format(current_user.username, error) send_wr_log(log_msg) return error
def delete_networks(): result = [] if request.method == 'POST': networks_to_be_deleted = request.get_json() for network in networks_to_be_deleted: db_network = Network.query.filter_by(name=network['name']).first() related_devices = Device.query.filter_by(network_id=db_network.id) if related_devices: for device in related_devices: if device.committed: result.append( "Device: {} from Network: {} cannot be deleted; " "it is committed!".format(device.name, db_network.name)) else: db.session.delete(device) log_msg = "User: {} - Device: {} from Network: {} is deleted.".format( current_user.username, device.name, db_network.name) send_wr_log(log_msg) result.append( "Device: {} from Network: {} is deleted!".format( device.name, db_network.name)) if db_network.committed: result.append( "Network: {} cannot be deleted; it is committed!".format( db_network.name)) else: db.session.delete(db_network) log_msg = "User: {} - Network: {} is deleted.".format( current_user.username, db_network.name) send_wr_log(log_msg) result.append("Network: {} is deleted!".format( db_network.name)) try: db.session.commit() except: return jsonify("Database error!") return jsonify(result)
def reset_groups(): result = [] if request.method == 'POST': groups_to_be_reset = request.get_json() for group in groups_to_be_reset: db_group = Group.query.filter_by(name=group['name']).first() # db_group.users.clear() # user relations are to be deleted in users section db_group.tags.clear() db_group.networks.clear() db.session.add(db_group) log_msg = "User: {} - Group: {} tag and network relations are reset.".format( current_user.username, db_group.name) send_wr_log(log_msg) result.append( "Group: {} tag and network relations are reset.\n" "Please \'Update Networks\' in Networks page.".format( group['name'])) try: db.session.commit() except: return jsonify("Database error!") return jsonify(result)
def reboot_devices(): result = [] if request.method == 'POST': reboot_devices_json = request.get_json() for device in reboot_devices_json: current_time = datetime.datetime.now() db_device = Device.query.get(device['id']) # check if device is rebooted in an hour; if so do not allow it to be rebooted if db_device.rebooted: time_since_last_reboot = current_time - db_device.rebooted if time_since_last_reboot.seconds < 3600: result.append("Device: {} was already rebooted!".format( device['serial'])) continue else: db_device.rebooted = current_time db.session.add(db_device) db.session.commit() else: db_device.rebooted = current_time db.session.add(db_device) db.session.commit() response = reboot_device(device['serial']) if response == "success": log_msg = "User: {} - Device: {} is rebooted.".format( current_user.username, device['serial']) send_wr_log(log_msg) result.append("Device: {} is rebooted!".format( device['serial'])) else: log_msg = "User: {} - Meraki response error while rebooting device: {}.".format( current_user.username, device['serial']) send_wr_log(log_msg) result.append( "Meraki response error while rebooting device: {}".format( device['serial'])) return jsonify(result)
def admin_groups(): form = GroupForm(request.form) form.set_choices() if request.method == 'POST': error = None new_group_name = request.data.decode("utf-8") new_group_name = new_group_name.strip() if len(new_group_name) < 4: error = "Group name must be 4 characters long at least!" return jsonify(error) if Group.query.filter_by(name=new_group_name).first(): error = "Exists!" return jsonify(error) new_group = Group(new_group_name) db.session.add(new_group) db.session.commit() log_msg = "User: {} - Group: {} is created.".format(current_user.username, new_group.name) send_wr_log(log_msg) return_data = [(group.id, group.name) for group in Group.query.all()] return jsonify(return_data) return render_template('groups.html', form=form)
def add_devices(): error = None form = AddDevicesForm(request.form) form.set_choices() form.serial_nos.data = "" if request.method == 'POST': form_dict = request.get_json() net_id = form_dict['network'] devices = form_dict['devices'] device_serials_list = devices.strip().upper().replace(" ", "").replace( "*", "-").split("\n") while '' in device_serials_list: device_serials_list.remove('') # remove blank items error = save_devices_in_db(device_serials_list, int(net_id)) log_msg = "User: {} - Saving devices in DB: {}".format( current_user.username, error) send_wr_log(log_msg) return error return render_template('add_devices.html', current_user=current_user, form=form, error=error)
def reset_membership(): result = [] if request.method == 'POST': users_to_be_reset = request.get_json() if users_to_be_reset: for user in users_to_be_reset: if user['name'] == current_user.username: return jsonify("Cannot modify current user") db_user = User.query.filter_by(username=user['name']).first() db_user.groups.clear() db.session.add(db_user) result.append( "User: {} group membership has been reset!".format( db_user.username)) log_msg = "User: {} - Group membership for user {} is reset.".format( current_user.username, db_user.username) send_wr_log(log_msg) try: db.session.commit() result.append("DB Write is successful!") except: return jsonify("Database error!") return jsonify(result)
def delete_devices(): result = [] if request.method == 'POST': devices_to_be_deleted = request.get_json() for device in devices_to_be_deleted: db_device = Device.query.filter_by(name=device['name']).first() network_name = db_device.network if db_device.committed: result.append("Device: {} in Network: {} cannot be deleted; " "it is committed!".format( device['name'], network_name)) else: db.session.delete(db_device) log_msg = "User: {} - Device: {} is removed from Network: {}.".format( current_user.username, device['name'], network_name) send_wr_log(log_msg) result.append("Device: {} is removed from Network: {}!".format( device['name'], network_name)) try: db.session.commit() except: return jsonify("Database error!") return jsonify(result)
def commit_networks(): result = [] if request.method == 'POST': networks_to_be_commit = request.get_json() for network in networks_to_be_commit: db_network = Network.query.filter_by(name=network['name']).first() if db_network.committed: result.append("{} is already committed.".format( db_network.name)) continue network_dict = { 'name': db_network.name, 'productTypes': [db_network.type], 'tags': [tag.name for tag in db_network.tags] } try: # check if network is to be copied from an existing one if db_network.source_network: network_dict[ 'copyFromNetworkId'] = db_network.copied_from.meraki_id # commit to cloud create_net_res = create_network(network_dict) # api call rate limit time.sleep(0.1) log_msg = "User: {} - Network: {} is created on Meraki Cloud.".format( current_user.username, db_network.name) send_wr_log(log_msg) # write new network meraki id to db db_network.meraki_id = create_net_res['id'] db.session.add(db_network) # bind template if db_network.template: template_meraki_id = db_network.template.meraki_id bind_template(db_network.meraki_id, template_meraki_id) log_msg = "User: {} - Network: {} is bound to" \ " template {} on Meraki Cloud.".format(current_user.username, db_network.name, db_network.template.name) send_wr_log(log_msg) result.append("Network: {} committed to Meraki Cloud".format( db_network.name)) db_network.committed = True except ConnectionError: result.append("Meraki Response Error for Network: {}".format( db_network.name)) log_msg = "User: {} - Meraki Response Error for Network: {}".format( current_user.username, db_network.name) send_wr_log(log_msg) db_network.committed = False db.session.commit() return jsonify(result)
def admin_update_devices_table(): t1 = time.time() log_msg = "User: {} - Updating devices table is started.".format(current_user.username) send_wr_log(log_msg) try: load_devices_to_db() except Exception as e: error = str(e) log_msg = "User: {} - {} while updating devices table.".format(current_user.username, error) send_wr_log(log_msg) return error t2 = time.time() log_msg = "User: {} - Updating devices table is ended in {} seconds.".format(current_user.username, t2 - t1) send_wr_log(log_msg) return "success"
def copy_switch(): if request.method == 'POST': switch_dict = request.get_json() dest_switch_list = [switch_dict['newSwitch']] response = clone_switch(switch_dict['sourceSwitch'], dest_switch_list) if 'errors' in response: log_msg = "User: {} - Error while cloning the switch {} to {}: {}." \ "".format(current_user.username, switch_dict['sourceSwitch'], dest_switch_list, response['errors']) send_wr_log(log_msg) return jsonify(response['errors']) elif 'sourceSerial' in response: log_msg = "User: {} - Cloned the switch {} to {} successfully." \ "".format(current_user.username, switch_dict['sourceSwitch'], dest_switch_list) send_wr_log(log_msg) return jsonify("Cloned Successfully!") else: log_msg = "User: {} - Server error while cloning the switch {} to {}: {}." \ "".format(current_user.username, switch_dict['sourceSwitch'], dest_switch_list, response) send_wr_log(log_msg) return jsonify("Server Error!")
def logout(): log_msg = "User logged out: {}".format(current_user.username) send_wr_log(log_msg) logout_user() # (flask_login) clear session flash('You are logged out.') return redirect(url_for('users.login'))
def login(): form = LoginForm(request.form) error = None if request.method == 'POST': if form.validate_on_submit(): # user = User.query.filter_by(username=request.form['username']).first() input_username = request.form['username'][:128] password = request.form['password'][:256] # if user is not None and bcrypt.check_password_hash(user.password, request.form['password']): username = input_username.split('@')[0] # making some orderings so as to accept both DOMAIN\USER, USER at login ad_domain = os.environ['USERDNSDOMAIN'].lower().split(".")[0] username = username.split("\\")[-1] ldap_username = ad_domain + "\\" + username # ldap login try: ldap_login_user = User.ldap_login(ldap_username, password) if ldap_login_user: log_msg = "Authentication Success against LDAP: {}".format( ldap_username) send_wr_log(log_msg) # verify if the user exists in DB and besides if DB is working!! try: user = User.query.filter_by(username=username).first() except (ProgrammingError, OperationalError) as e: error = str(e) log_msg = "Database error on login: {}".format(error) send_wr_log(log_msg) return render_template('login.html', form=form, error=error) if not user: email_suffix = ad_domain + ".com" email = username + "@" + email_suffix try: name, surname = username.split('.') except ValueError: name = username surname = 'service_user' password = '******' users_exist = User.query.all() # first user who logs in is going to be admin if users_exist: user = User(username, password, email, name, surname) else: user = User(username, password, email, name, surname, admin=True, operator=True) db.session.add(user) db.session.commit() if not user.alt_id: user.alt_id = get_random_alt_id() db.session.add(user) db.session.commit() login_user(user, remember=False) # (flask_login) session created log_msg = "User logged in: {}".format( current_user.username) send_wr_log(log_msg) if current_user.operator: return redirect(url_for('operator.new_network')) elif current_user.admin: return redirect(url_for('admin.admin_users')) else: return render_template('403.html', title='403'), 403 except INVALID_CREDENTIALS: error = 'Invalid Credentials. Please try again.' log_msg = "Authentication Failure: {}: {}".format( ldap_username, error) send_wr_log(log_msg) except SERVER_DOWN: error = 'Authentication Server Unreachable' send_wr_log("Login attempt: {}".format(error)) return render_template('login.html', form=form, error=error, current_user=False)
def commit_devices(): result = [] if request.method == 'POST': devices_to_be_commit = request.get_json() meraki_net_id_list = [] dev_serial_list = [] for i, device in enumerate(devices_to_be_commit): # db_device = Device.query.filter_by(serial=device['serial']).first() db_device = Device.query.get(device['id']) if db_device.committed: result.append("{} is already committed.".format( db_device.name)) continue # check if there is a mismatch in network ids of devices meraki_net_id_list.append(db_device.network.meraki_id) if i > 0: if meraki_net_id_list[i] != meraki_net_id_list[i - 1]: return jsonify( "Error, there is mismatch between network ids") dev_serial_list.append(device['serial']) if devices_to_be_commit and meraki_net_id_list: db_device = Device.query.get(devices_to_be_commit[-1]['id']) # to be used for appliance, only one appliance is allowed to be committed in a go else: return jsonify(result) try: # there should not exist two appliance device in an appliance network; check and modify: appliance_replaced = "" if db_device.network.type == 'appliance' and dev_serial_list: dev_serial_list = [db_device.serial] appliance_replaced = replace_previous_appliance( meraki_net_id_list[0]) if appliance_replaced: result.extend( appliance_replaced ) # logged in the function itself (replace_previous_appliance) # bind devices to network on cloud response = claim_network_devices(meraki_net_id_list[0], dev_serial_list) if response == "success": result.append("Devices are claimed and bound to network") log_msg = "User: {} - Devices: {} are claimed and " \ "bound to network: {} on Meraki Cloud.".format(current_user.username, ", ".join(dev_serial_list), db_device.network.name) send_wr_log(log_msg) # check if it is an appliance and there exists a related switch network, if so # update trusted dhcp server with the mac address of the appliance if db_device.network.type == 'appliance': new_device = get_device(dev_serial_list[-1]) # wait some time until the device can be fetched from meraki cloud for _ in range(5): if new_device == '404': time.sleep(2) new_device = get_device(dev_serial_list[-1]) else: break appliance_net = Network.query.filter_by( meraki_id=meraki_net_id_list[0]).first() app_net_name = appliance_net.name # Custom Naming Convention: switch network is named with same prefix # (seperated by a dash) as that of the appliance network which resides in the same location. prefix = app_net_name.split("-")[0] switch_name = prefix + "-Switch" switch_network = Network.query.filter_by( name=switch_name).first() if switch_network: try: update_result = update_switch_trusted_dhcp( switch_network.meraki_id, new_device['mac']) log_msg = "User: {} - Committed Updating Trusted DHCP" \ " to {} on Switch Network {} with " \ "result: {}".format(current_user.username, new_device['mac'], switch_name, str(update_result)) send_wr_log(log_msg) result.append( 'Updated Trusted DHCP on switch network {} as ' 'MAC Address: {}').format( switch_name, new_device['mac']) except: result.append("Meraki Server Error while updating " "trusted dhcp on Network {}".format( switch_name)) log_msg = "User: {} - Meraki Server Error while updating " \ "trusted dhcp on Network {}".format(current_user.username, switch_name) send_wr_log(log_msg) else: result.append( "Switch network {} is not found! " "Set Trusted DHCP Mac Address manually!".format( switch_name)) else: log_msg = "User: {} - Error for claiming devices: {}: {}".format( current_user.username, ", ".join(dev_serial_list), response['errors']) send_wr_log(log_msg) result.extend(response['errors']) # rename devices and get the model name from response and then update the table. for device in devices_to_be_commit: # db_device = Device.query.filter_by(serial=device['serial']).first() db_device = Device.query.get(device['id']) meraki_net_id = db_device.network.meraki_id rename_response = rename_device_v0(meraki_net_id, device['serial'], device['name']) db_device.devmodel = rename_response['model'] db_device.committed = True db.session.add(db_device) # api call rate limit time.sleep(0.2) db.session.commit() except ConnectionError: log_msg = "User: {} - Meraki Response Error while claiming devices: {}".format( current_user.username, ", ".join(dev_serial_list)) send_wr_log(log_msg) result.append("Meraki Response Error") return jsonify(result)
def new_network(): error = None # beginning of "on page load" ##### templates_names = [] try: templates_db = Template.query.all() except (ProgrammingError, OperationalError) as e: error_log = str(e) log_msg = "Database error on (Get) New Network: {}".format(error_log) send_wr_log(log_msg) return jsonify("Database error!") for template in templates_db: templates_names.append(template.name) form = NewNetworkForm(request.form) form.net_template.choices = list(templates_names) form.set_choices() ##### # end of "on page load" block if request.method == 'POST': net_will_be_copied = False error = None net_name = form.net_name.data net_name = net_name.strip() # validation on serverside if net_name == "": return jsonify("Enter a unique network name!") net_type = form.net_type.data user_id = current_user.id # ensure that network name does not already exist in db try: network = Network.query.filter_by(name=net_name).first() except (ProgrammingError, OperationalError) as e: error_log = str(e) log_msg = "Database error on (Post) New Network: {}".format( error_log) send_wr_log(log_msg) return jsonify("Database error!") if network: error = "Network already exists, try another unique name" # return render_template('home.html', form=form, error=error) log_msg = "User: {} - Network Name: {} - {}".format( current_user.username, network.name, error) send_wr_log(log_msg) return jsonify(error) if net_type == 'appliance': template = Template.query.filter_by( name=form.net_template.data).first() bound_template = template.meraki_id network = Network(net_name, net_type, user_id, bound_template=bound_template) log_msg = "User: {} - Network {} is being saved in DB" \ " with binding to template: {}".format(current_user.username, network.name, template.name) send_wr_log(log_msg) else: network_copy_source = Network.query.get(int(form.net_to_copy.data)) source_network = network_copy_source.id # it is not bound template, actually. network = Network(net_name, net_type, user_id, source_network=source_network) log_msg = "User: {} - Network {} is being saved in DB" \ " being copied from the Network: {}".format(current_user.username, network.name, network_copy_source.name) send_wr_log(log_msg) network.net_tags = "" for tag_id in form.net_tag_mselect.data: tag = Tag.query.get(int(tag_id)) network.tags.append(tag) network.net_tags += tag.name + " " # build network group relation according to selected tags for group in tag.groups: network.groups.append(group) # location specific tag for name seperated with dash; # eg. for network name AB11-Firewall, then new tag will be AB11 if "-" in net_name: specific_tag_name = net_name.split("-")[0] specific_tag = Tag.query.filter_by(name=specific_tag_name).first() if not specific_tag: new_network_tag = Tag(specific_tag_name) db.session.add(new_network_tag) db.session.commit() network.tags.append(new_network_tag) else: network.tags.append(specific_tag) db.session.add(network) db.session.commit() log_msg = "User: {} - Network: {} is saved in DB with success".format( current_user.username, network.name) send_wr_log(log_msg) return jsonify(error) return render_template('new_network.html', current_user=current_user, form=form, error=error)
def update_admin_networks_table(): ''' If the network exists in db, updates the network row with new values; clears and rebuilds: - tags table, - networks-tags relations, - group-networks relations else, adds new network to networks table. :return: 200 ''' t1 = time.time() log_msg = "User: {} - Started updating networks table".format(current_user.username) send_wr_log(log_msg) try: meraki_networks = get_networks() templates = get_templates() except ConnectionError: error = "Meraki Server Bad Response" log_msg = "User: {} - {} while updating networks table.".format(current_user.username, error) send_wr_log(log_msg) return error for key, value in templates.items(): template = Template.query.filter_by(meraki_id=value).first() if template: template.update(key, value) else: template = Template(key, value) db.session.add(template) db.session.commit() # update templates table db_networks = Network.query.all() # cleaning non-existent networks from db table for network in db_networks: network_exists = False for m_network in meraki_networks: if m_network['meraki_id'] == network.meraki_id: network_exists = True break if not network_exists: log_msg = "User: {} - Network: {} with {} id does not exist on cloud; " \ "being deleted from db.".format(current_user.username, network.name, network.meraki_id) send_wr_log(log_msg) network.tags.clear() network.groups.clear() for device in network.devices: log_msg = "User: {} - Deleting device: {} related with network: {} " \ "from DB".format(current_user.username, device.serial, network.name) send_wr_log(log_msg) db.session.delete(device) db.session.delete(network) # networks from meraki cloud for network in meraki_networks: db_network = Network.query.filter_by(meraki_id=network['meraki_id']).first() # update if the network exists if db_network: db_network.update(**network) # update the existing network in db consistent with cloud # update tags table and build their relation with networks if network['net_tags']: db_network.tags.clear() for tag in network['net_tags'].split(" "): db_tag = Tag.query.filter_by(name=tag).first() if db_tag: db_network.tags.append(db_tag) else: new_tag = Tag(tag) db.session.add(new_tag) db_network.tags.append(new_tag) else: db_network = Network(**network) # there is a new network on cloud, and save it in db db.session.add(db_network) db_network.committed = True # db is synced with cloud db.session.commit() # build group network relation according to tag bindings to both networks and groups db_groups = Group.query.all() for db_group in db_groups: db_grp_tags = db_group.tags if db_grp_tags: for db_network in db_networks: db_net_tags = db_network.tags for db_net_tag in db_net_tags: if db_net_tag in db_group.tags: db_group.networks.append(db_network) break else: if db_network in db_group.networks: db_group.networks.remove(db_network) db.session.add(db_group) db.session.commit() # cleaning duplicate networks if not existing in cloud # sq = Network.query.with_entities(Network.name).group_by(Network.name).having(func.count(Network.name) > 1).subquery() # duplicates = Network.query.filter(Network.name == sq.c.name).order_by(Network.name).all() # if duplicates: # for network in duplicates: # result = get_network(network.meraki_id) # if result == 404: # network.groups.clear() # network.tags.clear() # if network.devices: # for device in network.devices: # db.session.delete(device) # db.session.delete(network) # db.session.commit() t2 = time.time() log_msg = "User: {} - Updating networks table is completed in {} seconds.".format(current_user.username, t2 - t1) send_wr_log(log_msg) return "success"