|
|
47b589 |
From d0bfae4171f0d280241949a928654c84e63ed006 Mon Sep 17 00:00:00 2001
|
|
|
47b589 |
From: Gris Ge <fge@redhat.com>
|
|
|
47b589 |
Date: Mon, 29 Jun 2020 22:30:03 +0800
|
|
|
47b589 |
Subject: [PATCH] pretty state: Dumping state in the sorted order with priority
|
|
|
47b589 |
|
|
|
47b589 |
For OVS bond port, we would like the `name` been shown before other
|
|
|
47b589 |
properties.
|
|
|
47b589 |
|
|
|
47b589 |
To achieve that, we sort the dict keys and honoring the priority list which
|
|
|
47b589 |
means keys in `PRIORITY_LIST` will be shown before others.
|
|
|
47b589 |
|
|
|
47b589 |
Currently the `PRIORITY_LIST` is:
|
|
|
47b589 |
`("name", "type", "state", "enabled", "dns", "route-rules", "routes",
|
|
|
47b589 |
"interfaces")`
|
|
|
47b589 |
|
|
|
47b589 |
Test cases added.
|
|
|
47b589 |
|
|
|
47b589 |
Signed-off-by: Gris Ge <fge@redhat.com>
|
|
|
47b589 |
Signed-off-by: Till Maas <till@redhat.com>
|
|
|
47b589 |
---
|
|
|
47b589 |
libnmstate/prettystate.py | 94 ++++++++++++++++++---------------------
|
|
|
47b589 |
1 file changed, 43 insertions(+), 51 deletions(-)
|
|
|
47b589 |
|
|
|
47b589 |
diff --git a/libnmstate/prettystate.py b/libnmstate/prettystate.py
|
|
|
47b589 |
index da57618..10e22d6 100644
|
|
|
47b589 |
--- a/libnmstate/prettystate.py
|
|
|
47b589 |
+++ b/libnmstate/prettystate.py
|
|
|
47b589 |
@@ -1,5 +1,5 @@
|
|
|
47b589 |
#
|
|
|
47b589 |
-# Copyright (c) 2018-2019 Red Hat, Inc.
|
|
|
47b589 |
+# Copyright (c) 2018-2020 Red Hat, Inc.
|
|
|
47b589 |
#
|
|
|
47b589 |
# This file is part of nmstate
|
|
|
47b589 |
#
|
|
|
47b589 |
@@ -17,15 +17,29 @@
|
|
|
47b589 |
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
47b589 |
#
|
|
|
47b589 |
|
|
|
47b589 |
-from collections import OrderedDict
|
|
|
47b589 |
+from collections.abc import Mapping
|
|
|
47b589 |
+from collections.abc import Sequence
|
|
|
47b589 |
from copy import deepcopy
|
|
|
47b589 |
import difflib
|
|
|
47b589 |
import json
|
|
|
47b589 |
-from operator import itemgetter
|
|
|
47b589 |
|
|
|
47b589 |
import yaml
|
|
|
47b589 |
|
|
|
47b589 |
-from libnmstate.schema import Constants
|
|
|
47b589 |
+from .schema import DNS
|
|
|
47b589 |
+from .schema import Route
|
|
|
47b589 |
+from .schema import RouteRule
|
|
|
47b589 |
+from .schema import Interface
|
|
|
47b589 |
+
|
|
|
47b589 |
+PRIORITY_LIST = (
|
|
|
47b589 |
+ "name",
|
|
|
47b589 |
+ "type",
|
|
|
47b589 |
+ "state",
|
|
|
47b589 |
+ "enabled",
|
|
|
47b589 |
+ DNS.KEY,
|
|
|
47b589 |
+ RouteRule.KEY,
|
|
|
47b589 |
+ Route.KEY,
|
|
|
47b589 |
+ Interface.KEY,
|
|
|
47b589 |
+)
|
|
|
47b589 |
|
|
|
47b589 |
|
|
|
47b589 |
def format_desired_current_state_diff(desired_state, current_state):
|
|
|
47b589 |
@@ -57,8 +71,8 @@ def format_desired_current_state_diff(desired_state, current_state):
|
|
|
47b589 |
|
|
|
47b589 |
class PrettyState:
|
|
|
47b589 |
def __init__(self, state):
|
|
|
47b589 |
- yaml.add_representer(OrderedDict, represent_ordereddict)
|
|
|
47b589 |
- self.state = order_state(deepcopy(state))
|
|
|
47b589 |
+ yaml.add_representer(dict, represent_dict)
|
|
|
47b589 |
+ self.state = _sort_with_priority(state)
|
|
|
47b589 |
|
|
|
47b589 |
@property
|
|
|
47b589 |
def yaml(self):
|
|
|
47b589 |
@@ -71,35 +85,18 @@ class PrettyState:
|
|
|
47b589 |
return json.dumps(self.state, indent=4, separators=(",", ": "))
|
|
|
47b589 |
|
|
|
47b589 |
|
|
|
47b589 |
-def represent_ordereddict(dumper, data):
|
|
|
47b589 |
+def represent_dict(dumper, data):
|
|
|
47b589 |
+ """
|
|
|
47b589 |
+ Represent dictionary with insert order
|
|
|
47b589 |
"""
|
|
|
47b589 |
- Represent OrderedDict as regular dictionary
|
|
|
47b589 |
-
|
|
|
47b589 |
- Source: https://stackoverflow.com/questions/16782112/can-pyyaml-dump-dict-items-in-non-alphabetical-order
|
|
|
47b589 |
- """ # noqa: E501
|
|
|
47b589 |
value = []
|
|
|
47b589 |
|
|
|
47b589 |
for item_key, item_value in data.items():
|
|
|
47b589 |
node_key = dumper.represent_data(item_key)
|
|
|
47b589 |
node_value = dumper.represent_data(item_value)
|
|
|
47b589 |
-
|
|
|
47b589 |
value.append((node_key, node_value))
|
|
|
47b589 |
|
|
|
47b589 |
- return yaml.nodes.MappingNode(u"tag:yaml.org,2002:map", value)
|
|
|
47b589 |
-
|
|
|
47b589 |
-
|
|
|
47b589 |
-def order_state(state):
|
|
|
47b589 |
- iface_states = state.pop(Constants.INTERFACES, None)
|
|
|
47b589 |
-
|
|
|
47b589 |
- state = order_iface_state(state)
|
|
|
47b589 |
-
|
|
|
47b589 |
- if iface_states is not None:
|
|
|
47b589 |
- state[Constants.INTERFACES] = [
|
|
|
47b589 |
- order_iface_state(iface_state)
|
|
|
47b589 |
- for iface_state in sorted(iface_states, key=itemgetter("name"))
|
|
|
47b589 |
- ]
|
|
|
47b589 |
-
|
|
|
47b589 |
- return state
|
|
|
47b589 |
+ return yaml.nodes.MappingNode("tag:yaml.org,2002:map", value)
|
|
|
47b589 |
|
|
|
47b589 |
|
|
|
47b589 |
def represent_unicode(_, data):
|
|
|
47b589 |
@@ -112,30 +109,25 @@ def represent_unicode(_, data):
|
|
|
47b589 |
"""
|
|
|
47b589 |
|
|
|
47b589 |
return yaml.ScalarNode(
|
|
|
47b589 |
- tag=u"tag:yaml.org,2002:str", value=data.encode("utf-8")
|
|
|
47b589 |
+ tag="tag:yaml.org,2002:str", value=data.encode("utf-8")
|
|
|
47b589 |
)
|
|
|
47b589 |
|
|
|
47b589 |
|
|
|
47b589 |
-def order_iface_state(iface_state):
|
|
|
47b589 |
- ordered_state = OrderedDict()
|
|
|
47b589 |
-
|
|
|
47b589 |
- for setting in ("name", "type", "state"):
|
|
|
47b589 |
- try:
|
|
|
47b589 |
- ordered_state[setting] = iface_state.pop(setting)
|
|
|
47b589 |
- except KeyError:
|
|
|
47b589 |
- pass
|
|
|
47b589 |
-
|
|
|
47b589 |
- for key, value in order_dict(iface_state).items():
|
|
|
47b589 |
- ordered_state[key] = value
|
|
|
47b589 |
-
|
|
|
47b589 |
- return ordered_state
|
|
|
47b589 |
-
|
|
|
47b589 |
-
|
|
|
47b589 |
-def order_dict(dict_):
|
|
|
47b589 |
- ordered_dict = OrderedDict()
|
|
|
47b589 |
- for key, value in sorted(dict_.items()):
|
|
|
47b589 |
- if isinstance(value, dict):
|
|
|
47b589 |
- value = order_dict(value)
|
|
|
47b589 |
- ordered_dict[key] = value
|
|
|
47b589 |
-
|
|
|
47b589 |
- return ordered_dict
|
|
|
47b589 |
+def _sort_with_priority(data):
|
|
|
47b589 |
+ if isinstance(data, Sequence) and not isinstance(data, str):
|
|
|
47b589 |
+ return [_sort_with_priority(item) for item in data]
|
|
|
47b589 |
+ elif isinstance(data, Mapping):
|
|
|
47b589 |
+ new_data = {}
|
|
|
47b589 |
+ for key in sorted(data.keys(), key=_sort_with_priority_key_func):
|
|
|
47b589 |
+ new_data[key] = _sort_with_priority(data[key])
|
|
|
47b589 |
+ return new_data
|
|
|
47b589 |
+ else:
|
|
|
47b589 |
+ return deepcopy(data)
|
|
|
47b589 |
+
|
|
|
47b589 |
+
|
|
|
47b589 |
+def _sort_with_priority_key_func(key):
|
|
|
47b589 |
+ try:
|
|
|
47b589 |
+ priority = PRIORITY_LIST.index(key)
|
|
|
47b589 |
+ except ValueError:
|
|
|
47b589 |
+ priority = len(PRIORITY_LIST)
|
|
|
47b589 |
+ return (priority, key)
|
|
|
47b589 |
--
|
|
|
47b589 |
2.27.0
|
|
|
47b589 |
|