diff --git a/fastprod_backend/fastprod/api.py b/fastprod_backend/fastprod/api.py index 27de321..a45e19b 100644 --- a/fastprod_backend/fastprod/api.py +++ b/fastprod_backend/fastprod/api.py @@ -1,8 +1,8 @@ from flask import Flask,jsonify,request,abort, make_response from werkzeug.exceptions import HTTPException from nornir import InitNornir - - +import os +from werkzeug.utils import secure_filename import json ALLOWED_EXTENSIONS = {'conf'} @@ -11,15 +11,18 @@ UPLOAD_FOLDER = 'fastprod/upload_files/' def init_nornir(): app.config['nr'] = InitNornir(config_file="fastprod/inventory/config.yaml") - app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER + + def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS app = Flask(__name__) +app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER + from services.devices import ( get_inventory, add_device,get_device_by_name,delete_device,get_device_interfaces,get_device_interfaces_ip,get_device_technical_info) -from services.config import (get_config_by_device) +from services.config import (get_config_by_device,run_config_from_file_by_device) from services.tasks import (run_show_commands_by_device,run_config_commands_by_device) init_nornir() @@ -80,6 +83,14 @@ def get_config(device_name): config = get_config_by_device(device) return jsonify(interfaces_ip=config) if request.method == 'POST': + if request.files.to_dict(flat=False).get('config_file'): + file = request.files['config_file'] + if not allowed_file(file.filename): + abort(make_response(jsonify(message="file extension not allowed"), 403)) + filename = secure_filename(file.filename) + file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename)) + result = run_config_from_file_by_device(device,file_path=os.path.join(app.config['UPLOAD_FOLDER'], filename)) + return jsonify(result=result) if request.get_json().get('mode') == 'enable': commands = request.get_json().get('commands') result = run_show_commands_by_device(device, commands=commands) @@ -90,7 +101,6 @@ def get_config(device_name): return jsonify(result=result, commands=commands) - @app.errorhandler(HTTPException) def handle_exception(e): """Return JSON instead of HTML for HTTP errors.""" diff --git a/fastprod_backend/fastprod/services/config.py b/fastprod_backend/fastprod/services/config.py index 1539d14..af0b07b 100644 --- a/fastprod_backend/fastprod/services/config.py +++ b/fastprod_backend/fastprod/services/config.py @@ -2,6 +2,8 @@ from api import app from nornir_napalm.plugins.tasks import napalm_get, napalm_configure, napalm_cli from nornir.core.task import Task, Result from nornir_utils.plugins.functions import print_result +from nornir_netmiko.tasks import netmiko_send_config, netmiko_send_command, netmiko_save_config,netmiko_commit + def get_config_by_device(device): nr = app.config.get('nr') @@ -12,7 +14,6 @@ def get_config_by_device(device): def run_config_from_file_by_device(device=None, file_path=None): nr = app.config.get('nr') if device and file_path: - result = nr.filter(device_name=device.get('name')).run(task=netmiko_send_config, - config_file=file_path) + result = nr.filter(device_name=device.get('name')).run(task=netmiko_send_config,config_file=file_path) print_result(result) return result[device.get('name')].changed \ No newline at end of file diff --git a/fastprod_backend/fastprod/upload_files/R1-CPE-BAT-A_loopback.conf b/fastprod_backend/fastprod/upload_files/R1-CPE-BAT-A_loopback.conf new file mode 100644 index 0000000..c3807db --- /dev/null +++ b/fastprod_backend/fastprod/upload_files/R1-CPE-BAT-A_loopback.conf @@ -0,0 +1,3 @@ +interface loopback 10 +ip add 10.10.10.10 255.255.255.255 +description created from config file uploaded from postman diff --git a/fastprod_backend/nornir.log b/fastprod_backend/nornir.log index b254326..7055b09 100644 --- a/fastprod_backend/nornir.log +++ b/fastprod_backend/nornir.log @@ -51,3 +51,5 @@ Traceback (most recent call last): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ TypeError: expected string or bytes-like object, got 'list' +2025-11-27 13:16:50,900 - nornir.core - INFO - run() - Running task 'netmiko_send_config' with args {'config_file': 'fastprod/upload_files/R1-CPE-BAT-A_loopback.conf'} on 1 hosts +2025-11-27 13:18:50,146 - nornir.core - INFO - run() - Running task 'netmiko_send_config' with args {'config_file': 'fastprod/upload_files/R1-CPE-BAT-A_loopback.conf'} on 1 hosts