diff options
-rw-r--r-- | python/vyos/remote.py | 26 | ||||
-rwxr-xr-x | src/helpers/vyos-load-config.py | 90 |
2 files changed, 112 insertions, 4 deletions
diff --git a/python/vyos/remote.py b/python/vyos/remote.py index 49936ec08..f8a21f068 100644 --- a/python/vyos/remote.py +++ b/python/vyos/remote.py @@ -121,16 +121,34 @@ def get_remote_config(remote_file): if request['protocol'] in ('scp', 'sftp'): check_and_add_host_key(request['host']) + redirect_opt = '' + + if request['protocol'] in ('http', 'https'): + redirect_opt = '-L' + # Try header first, and look for 'OK' or 'Moved' codes: + curl_cmd = 'curl {0} -q -I {1}'.format(redirect_opt, remote_file) + try: + curl_output = subprocess.check_output(curl_cmd, shell=True, + universal_newlines=True) + except subprocess.CalledProcessError: + sys.exit(1) + + return_vals = re.findall(r'^HTTP\/\d+\.?\d\s+(\d+)\s+(.*)$', + curl_output, re.MULTILINE) + for val in return_vals: + if int(val[0]) not in [200, 301, 302]: + print('HTTP error: {0} {1}'.format(*val)) + sys.exit(1) + if request['user'] and not request['passwd']: curl_cmd = 'curl -# -u {0} {1}'.format(request['user'], remote_file) else: - curl_cmd = 'curl -# {0}'.format(remote_file) + curl_cmd = 'curl {0} -# {1}'.format(redirect_opt, remote_file) - config_file = None try: config_file = subprocess.check_output(curl_cmd, shell=True, universal_newlines=True) - except subprocess.CalledProcessError as err: - print("Called process error: {}.".format(err)) + except subprocess.CalledProcessError: + config_file = None return config_file diff --git a/src/helpers/vyos-load-config.py b/src/helpers/vyos-load-config.py new file mode 100755 index 000000000..4e6d67efa --- /dev/null +++ b/src/helpers/vyos-load-config.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2019 VyOS maintainers and contributors +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 or later as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +# + +"""Load config file from within config session. +Config file specified by URI or path (without scheme prefix). +Example: load https://somewhere.net/some.config + or + load /tmp/some.config +""" + +import sys +import tempfile +import vyos.defaults +import vyos.remote +from vyos.config import Config, VyOSError +from vyos.migrator import Migrator, MigratorError + +system_config_file = 'config.boot' + +class LoadConfig(Config): + """A subclass for calling 'loadFile'. + This does not belong in config.py, and only has a single caller. + """ + def load_config(self, file_path): + cmd = [self._cli_shell_api, 'loadFile', file_path] + self._run(cmd) + +if len(sys.argv) > 1: + file_name = sys.argv[1] +else: + file_name = system_config_file + +configdir = vyos.defaults.directories['config'] + +protocols = ['scp', 'sftp', 'http', 'https', 'ftp', 'tftp'] + +if any(x in file_name for x in protocols): + config_file = vyos.remote.get_remote_config(file_name) + if not config_file: + sys.exit("No config file by that name.") +else: + canonical_path = '{0}/{1}'.format(configdir, file_name) + try: + with open(canonical_path, 'r') as f: + config_file = f.read() + except OSError as err1: + try: + with open(file_name, 'r') as f: + config_file = f.read() + except OSError as err2: + sys.exit('{0}\n{1}'.format(err1, err2)) + +config = LoadConfig() + +print("Loading configuration from '{}'".format(file_name)) + +with tempfile.NamedTemporaryFile() as fp: + with open(fp.name, 'w') as fd: + fd.write(config_file) + + migration = Migrator(fp.name) + try: + migration.run() + except MigratorError as err: + sys.exit('{}'.format(err)) + + try: + config.load_config(fp.name) + except VyOSError as err: + sys.exit('{}'.format(err)) + +if config.session_changed(): + print("Load complete. Use 'commit' to make changes effective.") +else: + print("No configuration changes to commit.") |