|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# Copyright (c) 2018-2020 Red Hat, Inc.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This file is part of nmstate
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This program is free software: you can redistribute it and/or modify
|
|
Packit Service |
0535c1 |
# it under the terms of the GNU Lesser General Public License as published by
|
|
Packit Service |
0535c1 |
# the Free Software Foundation, either version 2.1 of the License, or
|
|
Packit Service |
0535c1 |
# (at your option) any later version.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# This program is distributed in the hope that it will be useful,
|
|
Packit Service |
0535c1 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
0535c1 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
0535c1 |
# GNU Lesser General Public License for more details.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
# You should have received a copy of the GNU Lesser General Public License
|
|
Packit Service |
0535c1 |
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
Packit Service |
0535c1 |
#
|
|
Packit Service |
0535c1 |
import argparse
|
|
Packit Service |
0535c1 |
import errno
|
|
Packit Service |
0535c1 |
import fnmatch
|
|
Packit Service |
0535c1 |
import json
|
|
Packit Service |
0535c1 |
import logging
|
|
Packit Service |
0535c1 |
import os
|
|
Packit Service |
0535c1 |
import subprocess
|
|
Packit Service |
0535c1 |
import sys
|
|
Packit Service |
0535c1 |
import tempfile
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
import yaml
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
import libnmstate
|
|
Packit Service |
0535c1 |
from libnmstate import PrettyState
|
|
Packit Service |
0535c1 |
from libnmstate.error import NmstateConflictError
|
|
Packit Service |
0535c1 |
from libnmstate.error import NmstatePermissionError
|
|
Packit Service |
0535c1 |
from libnmstate.error import NmstateValueError
|
|
Packit Service |
0535c1 |
from libnmstate.schema import Interface
|
|
Packit Service |
0535c1 |
from libnmstate.schema import Route
|
|
Packit Service |
0535c1 |
from libnmstate.schema import RouteRule
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def main():
|
|
Packit Service |
0535c1 |
logging.basicConfig(
|
|
Packit Service |
0535c1 |
format="%(asctime)s %(name)-12s %(levelname)-8s %(message)s",
|
|
Packit Service |
0535c1 |
level=logging.DEBUG,
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
parser = argparse.ArgumentParser()
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
subparsers = parser.add_subparsers()
|
|
Packit Service |
0535c1 |
setup_subcommand_commit(subparsers)
|
|
Packit Service |
0535c1 |
setup_subcommand_edit(subparsers)
|
|
Packit Service |
0535c1 |
setup_subcommand_rollback(subparsers)
|
|
Packit Service |
0535c1 |
setup_subcommand_set(subparsers)
|
|
Packit Service |
0535c1 |
setup_subcommand_show(subparsers)
|
|
Packit Service |
0535c1 |
setup_subcommand_version(subparsers)
|
|
Packit Service |
0535c1 |
parser.add_argument(
|
|
Packit Service |
0535c1 |
"--version", action="store_true", help="Display nmstate version"
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if len(sys.argv) == 1:
|
|
Packit Service |
0535c1 |
parser.print_usage()
|
|
Packit Service |
0535c1 |
return errno.EINVAL
|
|
Packit Service |
0535c1 |
args = parser.parse_args()
|
|
Packit Service |
0535c1 |
if args.version:
|
|
Packit Service |
0535c1 |
print(libnmstate.__version__)
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
return args.func(args)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def setup_subcommand_commit(subparsers):
|
|
Packit Service |
0535c1 |
parser_commit = subparsers.add_parser("commit", help="Commit a change")
|
|
Packit Service |
0535c1 |
parser_commit.add_argument(
|
|
Packit Service |
0535c1 |
"checkpoint", nargs="?", default=None, help="checkpoint to commit"
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_commit.set_defaults(func=commit)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def setup_subcommand_edit(subparsers):
|
|
Packit Service |
0535c1 |
parser_edit = subparsers.add_parser(
|
|
Packit Service |
0535c1 |
"edit", help="Edit network state in EDITOR"
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_edit.set_defaults(func=edit)
|
|
Packit Service |
0535c1 |
parser_edit.add_argument(
|
|
Packit Service |
0535c1 |
"--json",
|
|
Packit Service |
0535c1 |
help="Edit as JSON",
|
|
Packit Service |
0535c1 |
default=True,
|
|
Packit Service |
0535c1 |
action="store_false",
|
|
Packit Service |
0535c1 |
dest="yaml",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_edit.add_argument(
|
|
Packit Service |
0535c1 |
"only",
|
|
Packit Service |
0535c1 |
default="*",
|
|
Packit Service |
0535c1 |
nargs="?",
|
|
Packit Service |
0535c1 |
metavar=Interface.KEY,
|
|
Packit Service |
0535c1 |
help="Edit only specified interfaces (comma-separated)",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_edit.add_argument(
|
|
Packit Service |
0535c1 |
"--no-verify",
|
|
Packit Service |
0535c1 |
action="store_false",
|
|
Packit Service |
0535c1 |
dest="verify",
|
|
Packit Service |
0535c1 |
default=True,
|
|
Packit Service |
0535c1 |
help="Do not verify that the state was completely set and disable "
|
|
Packit Service |
0535c1 |
"rollback to previous state.",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_edit.add_argument(
|
|
Packit Service |
0535c1 |
"--memory-only",
|
|
Packit Service |
0535c1 |
action="store_false",
|
|
Packit Service |
0535c1 |
dest="save_to_disk",
|
|
Packit Service |
0535c1 |
default=True,
|
|
Packit Service |
0535c1 |
help="Do not make the state persistent.",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def setup_subcommand_rollback(subparsers):
|
|
Packit Service |
0535c1 |
parser_rollback = subparsers.add_parser(
|
|
Packit Service |
0535c1 |
"rollback", help="Rollback a change"
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_rollback.add_argument(
|
|
Packit Service |
0535c1 |
"checkpoint", nargs="?", default=None, help="checkpoint to roll back"
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_rollback.set_defaults(func=rollback)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def setup_subcommand_set(subparsers):
|
|
Packit Service |
0535c1 |
parser_set = subparsers.add_parser("set", help="Set network state")
|
|
Packit Service |
0535c1 |
parser_set.add_argument(
|
|
Packit Service |
0535c1 |
"file",
|
|
Packit Service |
0535c1 |
help="File containing desired state. "
|
|
Packit Service |
0535c1 |
"stdin is used when no file is specified.",
|
|
Packit Service |
0535c1 |
nargs="*",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_set.add_argument(
|
|
Packit Service |
0535c1 |
"--no-verify",
|
|
Packit Service |
0535c1 |
action="store_false",
|
|
Packit Service |
0535c1 |
dest="verify",
|
|
Packit Service |
0535c1 |
default=True,
|
|
Packit Service |
0535c1 |
help="Do not verify that the state was completely set and disable "
|
|
Packit Service |
0535c1 |
"rollback to previous state",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_set.add_argument(
|
|
Packit Service |
0535c1 |
"--no-commit",
|
|
Packit Service |
0535c1 |
action="store_false",
|
|
Packit Service |
0535c1 |
dest="commit",
|
|
Packit Service |
0535c1 |
default=True,
|
|
Packit Service |
0535c1 |
help="Do not commit new state after verification",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_set.add_argument(
|
|
Packit Service |
0535c1 |
"--timeout",
|
|
Packit Service |
0535c1 |
type=int,
|
|
Packit Service |
0535c1 |
default=60,
|
|
Packit Service |
0535c1 |
help="Timeout in seconds before reverting uncommited changes.",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_set.add_argument(
|
|
Packit Service |
0535c1 |
"--memory-only",
|
|
Packit Service |
0535c1 |
action="store_false",
|
|
Packit Service |
0535c1 |
dest="save_to_disk",
|
|
Packit Service |
0535c1 |
default=True,
|
|
Packit Service |
0535c1 |
help="Do not make the state persistent.",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_set.set_defaults(func=apply)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def setup_subcommand_show(subparsers):
|
|
Packit Service |
0535c1 |
parser_show = subparsers.add_parser("show", help="Show network state")
|
|
Packit Service |
0535c1 |
parser_show.set_defaults(func=show)
|
|
Packit Service |
0535c1 |
parser_show.add_argument(
|
|
Packit Service |
0535c1 |
"--json",
|
|
Packit Service |
0535c1 |
help="Edit as JSON",
|
|
Packit Service |
0535c1 |
default=True,
|
|
Packit Service |
0535c1 |
action="store_false",
|
|
Packit Service |
0535c1 |
dest="yaml",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_show.add_argument(
|
|
Packit Service |
0535c1 |
"only",
|
|
Packit Service |
0535c1 |
default="*",
|
|
Packit Service |
0535c1 |
nargs="?",
|
|
Packit Service |
0535c1 |
metavar=Interface.KEY,
|
|
Packit Service |
0535c1 |
help="Show only specified interfaces (comma-separated)",
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def setup_subcommand_version(subparsers):
|
|
Packit Service |
0535c1 |
parser_version = subparsers.add_parser(
|
|
Packit Service |
0535c1 |
"version", help="Display nmstate version"
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
parser_version.set_defaults(func=version)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def version(args):
|
|
Packit Service |
0535c1 |
print(libnmstate.__version__)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def commit(args):
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
0535c1 |
libnmstate.commit(checkpoint=args.checkpoint)
|
|
Packit Service |
0535c1 |
except NmstateValueError as e:
|
|
Packit Service |
0535c1 |
print("ERROR committing change: {}\n".format(str(e)))
|
|
Packit Service |
0535c1 |
return os.EX_DATAERR
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def edit(args):
|
|
Packit Service |
0535c1 |
state = _filter_state(libnmstate.show(), args.only)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if not state[Interface.KEY]:
|
|
Packit Service |
0535c1 |
sys.stderr.write("ERROR: No such interface\n")
|
|
Packit Service |
0535c1 |
return os.EX_USAGE
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
pretty_state = PrettyState(state)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if args.yaml:
|
|
Packit Service |
0535c1 |
suffix = ".yaml"
|
|
Packit Service |
0535c1 |
txtstate = pretty_state.yaml
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
suffix = ".json"
|
|
Packit Service |
0535c1 |
txtstate = pretty_state.json
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
new_state = _get_edited_state(txtstate, suffix, args.yaml)
|
|
Packit Service |
0535c1 |
if not new_state:
|
|
Packit Service |
0535c1 |
return os.EX_DATAERR
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
print("Applying the following state: ")
|
|
Packit Service |
0535c1 |
print_state(new_state, use_yaml=args.yaml)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
libnmstate.apply(
|
|
Packit Service |
0535c1 |
new_state, verify_change=args.verify, save_to_disk=args.save_to_disk
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def rollback(args):
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
0535c1 |
libnmstate.rollback(checkpoint=args.checkpoint)
|
|
Packit Service |
0535c1 |
except NmstateValueError as e:
|
|
Packit Service |
0535c1 |
print("ERROR rolling back change: {}\n".format(str(e)))
|
|
Packit Service |
0535c1 |
return os.EX_DATAERR
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def show(args):
|
|
Packit Service |
0535c1 |
state = _filter_state(libnmstate.show(), args.only)
|
|
Packit Service |
0535c1 |
print_state(state, use_yaml=args.yaml)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def apply(args):
|
|
Packit Service |
0535c1 |
if args.file:
|
|
Packit Service |
0535c1 |
for statefile in args.file:
|
|
Packit Service |
0535c1 |
if statefile == "-" and not os.path.isfile(statefile):
|
|
Packit Service |
0535c1 |
statedata = sys.stdin.read()
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
with open(statefile) as statefile:
|
|
Packit Service |
0535c1 |
statedata = statefile.read()
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
ret = apply_state(
|
|
Packit Service |
0535c1 |
statedata,
|
|
Packit Service |
0535c1 |
args.verify,
|
|
Packit Service |
0535c1 |
args.commit,
|
|
Packit Service |
0535c1 |
args.timeout,
|
|
Packit Service |
0535c1 |
args.save_to_disk,
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
if ret:
|
|
Packit Service |
0535c1 |
return ret
|
|
Packit Service |
0535c1 |
elif not sys.stdin.isatty():
|
|
Packit Service |
0535c1 |
statedata = sys.stdin.read()
|
|
Packit Service |
0535c1 |
return apply_state(
|
|
Packit Service |
0535c1 |
statedata,
|
|
Packit Service |
0535c1 |
args.verify,
|
|
Packit Service |
0535c1 |
args.commit,
|
|
Packit Service |
0535c1 |
args.timeout,
|
|
Packit Service |
0535c1 |
args.save_to_disk,
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
sys.stderr.write("ERROR: No state specified\n")
|
|
Packit Service |
0535c1 |
return 1
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def apply_state(statedata, verify_change, commit, timeout, save_to_disk):
|
|
Packit Service |
0535c1 |
use_yaml = False
|
|
Packit Service |
0535c1 |
# JSON dictionaries start with a curly brace
|
|
Packit Service |
0535c1 |
if statedata[0] == "{":
|
|
Packit Service |
0535c1 |
state = json.loads(statedata)
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
state = yaml.load(statedata, Loader=yaml.SafeLoader)
|
|
Packit Service |
0535c1 |
use_yaml = True
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
0535c1 |
checkpoint = libnmstate.apply(
|
|
Packit Service |
0535c1 |
state,
|
|
Packit Service |
0535c1 |
verify_change=verify_change,
|
|
Packit Service |
0535c1 |
commit=commit,
|
|
Packit Service |
0535c1 |
rollback_timeout=timeout,
|
|
Packit Service |
0535c1 |
save_to_disk=save_to_disk,
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
except NmstatePermissionError as e:
|
|
Packit Service |
0535c1 |
sys.stderr.write("ERROR: Missing permissions:{}\n".format(str(e)))
|
|
Packit Service |
0535c1 |
return os.EX_NOPERM
|
|
Packit Service |
0535c1 |
except NmstateConflictError:
|
|
Packit Service |
0535c1 |
sys.stderr.write(
|
|
Packit Service |
0535c1 |
"ERROR: State editing already in progress.\n"
|
|
Packit Service |
0535c1 |
"Commit, roll back or wait before retrying.\n"
|
|
Packit Service |
0535c1 |
)
|
|
Packit Service |
0535c1 |
return os.EX_UNAVAILABLE
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
print("Desired state applied: ")
|
|
Packit Service |
0535c1 |
print_state(state, use_yaml=use_yaml)
|
|
Packit Service |
0535c1 |
if checkpoint:
|
|
Packit Service |
0535c1 |
print("Checkpoint: {}".format(checkpoint))
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _filter_state(state, whitelist):
|
|
Packit Service |
0535c1 |
if whitelist != "*":
|
|
Packit Service |
0535c1 |
patterns = [p for p in whitelist.split(",")]
|
|
Packit Service |
0535c1 |
state[Interface.KEY] = _filter_interfaces(state, patterns)
|
|
Packit Service |
0535c1 |
state[Route.KEY] = _filter_routes(state, patterns)
|
|
Packit Service |
0535c1 |
state[RouteRule.KEY] = _filter_route_rule(state)
|
|
Packit Service |
0535c1 |
return state
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _filter_interfaces(state, patterns):
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
return the states for all interfaces from `state` that match at least one
|
|
Packit Service |
0535c1 |
of the provided patterns.
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
showinterfaces = []
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
for interface in state[Interface.KEY]:
|
|
Packit Service |
0535c1 |
for pattern in patterns:
|
|
Packit Service |
0535c1 |
if fnmatch.fnmatch(interface["name"], pattern):
|
|
Packit Service |
0535c1 |
showinterfaces.append(interface)
|
|
Packit Service |
0535c1 |
break
|
|
Packit Service |
0535c1 |
return showinterfaces
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _get_edited_state(txtstate, suffix, use_yaml):
|
|
Packit Service |
0535c1 |
while True:
|
|
Packit Service |
0535c1 |
txtstate = _run_editor(txtstate, suffix)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if txtstate is None:
|
|
Packit Service |
0535c1 |
return None
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
new_state, error = _parse_state(txtstate, use_yaml)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if error:
|
|
Packit Service |
0535c1 |
if not _try_edit_again(error):
|
|
Packit Service |
0535c1 |
return None
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
return new_state
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _run_editor(txtstate, suffix):
|
|
Packit Service |
0535c1 |
editor = os.environ.get("EDITOR", "vi")
|
|
Packit Service |
0535c1 |
with tempfile.NamedTemporaryFile(
|
|
Packit Service |
0535c1 |
suffix=suffix, prefix="nmstate-"
|
|
Packit Service |
0535c1 |
) as statefile:
|
|
Packit Service |
0535c1 |
statefile.write(txtstate.encode("utf-8"))
|
|
Packit Service |
0535c1 |
statefile.flush()
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
0535c1 |
subprocess.check_call([editor, statefile.name])
|
|
Packit Service |
0535c1 |
statefile.seek(0)
|
|
Packit Service |
0535c1 |
return statefile.read()
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
except subprocess.CalledProcessError:
|
|
Packit Service |
0535c1 |
sys.stderr.write("Error running editor, aborting...\n")
|
|
Packit Service |
0535c1 |
return None
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _parse_state(txtstate, parse_yaml):
|
|
Packit Service |
0535c1 |
error = ""
|
|
Packit Service |
0535c1 |
state = {}
|
|
Packit Service |
0535c1 |
if parse_yaml:
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
0535c1 |
state = yaml.load(txtstate, Loader=yaml.SafeLoader)
|
|
Packit Service |
0535c1 |
except yaml.parser.ParserError as e:
|
|
Packit Service |
0535c1 |
error = "Invalid YAML syntax: %s\n" % e
|
|
Packit Service |
0535c1 |
except yaml.parser.ScannerError as e:
|
|
Packit Service |
0535c1 |
error = "Invalid YAML syntax: %s\n" % e
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
try:
|
|
Packit Service |
0535c1 |
state = json.loads(txtstate)
|
|
Packit Service |
0535c1 |
except ValueError as e:
|
|
Packit Service |
0535c1 |
error = "Invalid JSON syntax: %s\n" % e
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
if not error and Interface.KEY not in state:
|
|
Packit Service |
0535c1 |
# Allow editing routes only.
|
|
Packit Service |
0535c1 |
state[Interface.KEY] = []
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
return state, error
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _try_edit_again(error):
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
Print error and ask for user feedback. Return True, if the state should be
|
|
Packit Service |
0535c1 |
edited again and False otherwise.
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
sys.stderr.write("ERROR: " + error)
|
|
Packit Service |
0535c1 |
response = ""
|
|
Packit Service |
0535c1 |
while response not in ("y", "n"):
|
|
Packit Service |
0535c1 |
response = input(
|
|
Packit Service |
0535c1 |
"Try again? [y,n]:\n"
|
|
Packit Service |
0535c1 |
"y - yes, start editor again\n"
|
|
Packit Service |
0535c1 |
"n - no, throw away my changes\n"
|
|
Packit Service |
0535c1 |
"> "
|
|
Packit Service |
0535c1 |
).lower()
|
|
Packit Service |
0535c1 |
if response == "n":
|
|
Packit Service |
0535c1 |
return False
|
|
Packit Service |
0535c1 |
return True
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def print_state(state, use_yaml=False):
|
|
Packit Service |
0535c1 |
state = PrettyState(state)
|
|
Packit Service |
0535c1 |
if use_yaml:
|
|
Packit Service |
0535c1 |
sys.stdout.write(state.yaml)
|
|
Packit Service |
0535c1 |
else:
|
|
Packit Service |
0535c1 |
print(state.json)
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _filter_routes(state, patterns):
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
return the states for all routes from `state` that match at least one
|
|
Packit Service |
0535c1 |
of the provided patterns.
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
routes = {Route.CONFIG: [], Route.RUNNING: []}
|
|
Packit Service |
0535c1 |
for route_type in (Route.RUNNING, Route.CONFIG):
|
|
Packit Service |
0535c1 |
for route in state.get(Route.KEY, {}).get(route_type, []):
|
|
Packit Service |
0535c1 |
for pattern in patterns:
|
|
Packit Service |
0535c1 |
if fnmatch.fnmatch(route[Route.NEXT_HOP_INTERFACE], pattern):
|
|
Packit Service |
0535c1 |
routes[route_type].append(route)
|
|
Packit Service |
0535c1 |
return routes
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
|
|
Packit Service |
0535c1 |
def _filter_route_rule(state):
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
return the rules for state's route rule that match the table_id of the
|
|
Packit Service |
0535c1 |
filtered route of state by interface
|
|
Packit Service |
0535c1 |
"""
|
|
Packit Service |
0535c1 |
route_rules = {RouteRule.CONFIG: []}
|
|
Packit Service |
0535c1 |
table_ids = []
|
|
Packit Service |
0535c1 |
for routes in {Route.CONFIG: [], Route.RUNNING: []}:
|
|
Packit Service |
0535c1 |
for route in state.get(Route.KEY, {}).get(routes, []):
|
|
Packit Service |
0535c1 |
if route.get(Route.TABLE_ID) not in table_ids:
|
|
Packit Service |
0535c1 |
table_ids.append(route.get(Route.TABLE_ID))
|
|
Packit Service |
0535c1 |
for rule in state.get(RouteRule.KEY, {}).get(RouteRule.CONFIG, []):
|
|
Packit Service |
0535c1 |
if rule.get(RouteRule.ROUTE_TABLE) in table_ids:
|
|
Packit Service |
0535c1 |
route_rules[RouteRule.CONFIG].append(rule)
|
|
Packit Service |
0535c1 |
return route_rules
|