Skip to content

Commit 6ab1c51

Browse files
authored
[minigraph] Consume golden_config_db.json while loading minigraph (sonic-net#2140)
What I did This PR is for supporting consume golden_config_db.json while loading minigraph. User can put the golden_config_db.json with minigraph file to override configDB after reload minigraph. The golden_config_db.json looks just like a config_db.json and it will be placed on /etc/sonic/golden_config_db.json. How I did it Add code config override-config-table command to let it consume golden_config_db.json How to verify it Add UT tests and run.
1 parent c37a957 commit 6ab1c51

7 files changed

+729
-2
lines changed

config/main.py

+69-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
from collections import OrderedDict
1717
from generic_config_updater.generic_updater import GenericUpdater, ConfigFormat
18-
from minigraph import parse_device_desc_xml
18+
from minigraph import parse_device_desc_xml, minigraph_encoder
1919
from natsort import natsorted
2020
from portconfig import get_child_ports
2121
from socket import AF_INET, AF_INET6
@@ -27,7 +27,7 @@
2727
from utilities_common.intf_filter import parse_interface_in_filter
2828
from utilities_common import bgp_util
2929
import utilities_common.cli as clicommon
30-
from utilities_common.general import load_db_config
30+
from utilities_common.general import load_db_config, load_module_from_source
3131

3232
from .utils import log
3333

@@ -71,6 +71,7 @@
7171
DEFAULT_CONFIG_YANG_FILE = '/etc/sonic/config_yang.json'
7272
NAMESPACE_PREFIX = 'asic'
7373
INTF_KEY = "interfaces"
74+
DEFAULT_GOLDEN_CONFIG_DB_FILE = '/etc/sonic/golden_config_db.json'
7475

7576
INIT_CFG_FILE = '/etc/sonic/init_cfg.json'
7677

@@ -99,6 +100,9 @@
99100
QUEUE_RANGE = click.IntRange(min=0, max=255)
100101
GRE_TYPE_RANGE = click.IntRange(min=0, max=65535)
101102

103+
# Load sonic-cfggen from source since /usr/local/bin/sonic-cfggen does not have .py extension.
104+
sonic_cfggen = load_module_from_source('sonic_cfggen', '/usr/local/bin/sonic-cfggen')
105+
102106
#
103107
# Helper functions
104108
#
@@ -1619,6 +1623,10 @@ def load_minigraph(db, no_service_restart):
16191623
cfggen_namespace_option = " -n {}".format(namespace)
16201624
clicommon.run_command(db_migrator + ' -o set_version' + cfggen_namespace_option)
16211625

1626+
# Load golden_config_db.json
1627+
if os.path.isfile(DEFAULT_GOLDEN_CONFIG_DB_FILE):
1628+
override_config_by(DEFAULT_GOLDEN_CONFIG_DB_FILE)
1629+
16221630
# We first run "systemctl reset-failed" to remove the "failed"
16231631
# status from all services before we attempt to restart them
16241632
if not no_service_restart:
@@ -1667,6 +1675,65 @@ def load_port_config(config_db, port_config_path):
16671675
port_name), display_cmd=True)
16681676
return
16691677

1678+
1679+
def override_config_by(golden_config_path):
1680+
# Override configDB with golden config
1681+
clicommon.run_command('config override-config-table {}'.format(
1682+
golden_config_path), display_cmd=True)
1683+
return
1684+
1685+
1686+
#
1687+
# 'override-config-table' command ('config override-config-table ...')
1688+
#
1689+
@config.command('override-config-table')
1690+
@click.argument('input-config-db', required=True)
1691+
@click.option(
1692+
'--dry-run', is_flag=True, default=False,
1693+
help='test out the command without affecting config state'
1694+
)
1695+
@clicommon.pass_db
1696+
def override_config_table(db, input_config_db, dry_run):
1697+
"""Override current configDB with input config."""
1698+
1699+
try:
1700+
# Load golden config json
1701+
config_input = read_json_file(input_config_db)
1702+
except Exception as e:
1703+
click.secho("Bad format: json file broken. {}".format(str(e)),
1704+
fg='magenta')
1705+
sys.exit(1)
1706+
1707+
# Validate if the input is dict
1708+
if not isinstance(config_input, dict):
1709+
click.secho("Bad format: input_config_db is not a dict",
1710+
fg='magenta')
1711+
sys.exit(1)
1712+
1713+
config_db = db.cfgdb
1714+
1715+
if dry_run:
1716+
# Read config from configDB
1717+
current_config = config_db.get_config()
1718+
# Serialize to the same format as json input
1719+
sonic_cfggen.FormatConverter.to_serialized(current_config)
1720+
# Override current config with golden config
1721+
for table in config_input:
1722+
current_config[table] = config_input[table]
1723+
print(json.dumps(current_config, sort_keys=True,
1724+
indent=4, cls=minigraph_encoder))
1725+
else:
1726+
# Deserialized golden config to DB recognized format
1727+
sonic_cfggen.FormatConverter.to_deserialized(config_input)
1728+
# Delete table from DB then mod_config to apply golden config
1729+
click.echo("Removing configDB overriden table first ...")
1730+
for table in config_input:
1731+
config_db.delete_table(table)
1732+
click.echo("Overriding input config to configDB ...")
1733+
data = sonic_cfggen.FormatConverter.output_to_db(config_input)
1734+
config_db.mod_config(data)
1735+
click.echo("Overriding completed. No service is restarted.")
1736+
16701737
#
16711738
# 'hostname' command
16721739
#
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
{
2+
"running_config": {
3+
"ACL_TABLE": {
4+
"DATAACL": {
5+
"policy_desc": "DATAACL",
6+
"ports": [
7+
"Ethernet4"
8+
],
9+
"stage": "ingress",
10+
"type": "L3"
11+
},
12+
"NTP_ACL": {
13+
"policy_desc": "NTP_ACL",
14+
"services": [
15+
"NTP"
16+
],
17+
"stage": "ingress",
18+
"type": "CTRLPLANE"
19+
}
20+
},
21+
"AUTO_TECHSUPPORT_FEATURE": {
22+
"bgp": {
23+
"rate_limit_interval": "600",
24+
"state": "enabled"
25+
},
26+
"database": {
27+
"rate_limit_interval": "600",
28+
"state": "enabled"
29+
}
30+
},
31+
"PORT": {
32+
"Ethernet4": {
33+
"admin_status": "up",
34+
"alias": "fortyGigE0/4",
35+
"description": "Servers0:eth0",
36+
"index": "1",
37+
"lanes": "29,30,31,32",
38+
"mtu": "9100",
39+
"pfc_asym": "off",
40+
"speed": "40000",
41+
"tpid": "0x8100"
42+
},
43+
"Ethernet8": {
44+
"admin_status": "up",
45+
"alias": "fortyGigE0/8",
46+
"description": "Servers1:eth0",
47+
"index": "2",
48+
"lanes": "33,34,35,36",
49+
"mtu": "9100",
50+
"pfc_asym": "off",
51+
"speed": "40000",
52+
"tpid": "0x8100"
53+
}
54+
}
55+
},
56+
"golden_config": {
57+
58+
},
59+
"expected_config": {
60+
"ACL_TABLE": {
61+
"DATAACL": {
62+
"policy_desc": "DATAACL",
63+
"ports": [
64+
"Ethernet4"
65+
],
66+
"stage": "ingress",
67+
"type": "L3"
68+
},
69+
"NTP_ACL": {
70+
"policy_desc": "NTP_ACL",
71+
"services": [
72+
"NTP"
73+
],
74+
"stage": "ingress",
75+
"type": "CTRLPLANE"
76+
}
77+
},
78+
"AUTO_TECHSUPPORT_FEATURE": {
79+
"bgp": {
80+
"rate_limit_interval": "600",
81+
"state": "enabled"
82+
},
83+
"database": {
84+
"rate_limit_interval": "600",
85+
"state": "enabled"
86+
}
87+
},
88+
"PORT": {
89+
"Ethernet4": {
90+
"admin_status": "up",
91+
"alias": "fortyGigE0/4",
92+
"description": "Servers0:eth0",
93+
"index": "1",
94+
"lanes": "29,30,31,32",
95+
"mtu": "9100",
96+
"pfc_asym": "off",
97+
"speed": "40000",
98+
"tpid": "0x8100"
99+
},
100+
"Ethernet8": {
101+
"admin_status": "up",
102+
"alias": "fortyGigE0/8",
103+
"description": "Servers1:eth0",
104+
"index": "2",
105+
"lanes": "33,34,35,36",
106+
"mtu": "9100",
107+
"pfc_asym": "off",
108+
"speed": "40000",
109+
"tpid": "0x8100"
110+
}
111+
}
112+
}
113+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
{
2+
"running_config": {
3+
"ACL_TABLE": {
4+
"DATAACL": {
5+
"policy_desc": "DATAACL",
6+
"ports": [
7+
"Ethernet4"
8+
],
9+
"stage": "ingress",
10+
"type": "L3"
11+
},
12+
"NTP_ACL": {
13+
"policy_desc": "NTP_ACL",
14+
"services": [
15+
"NTP"
16+
],
17+
"stage": "ingress",
18+
"type": "CTRLPLANE"
19+
}
20+
},
21+
"AUTO_TECHSUPPORT_FEATURE": {
22+
"bgp": {
23+
"rate_limit_interval": "600",
24+
"state": "enabled"
25+
},
26+
"database": {
27+
"rate_limit_interval": "600",
28+
"state": "enabled"
29+
}
30+
},
31+
"PORT": {
32+
"Ethernet4": {
33+
"admin_status": "up",
34+
"alias": "fortyGigE0/4",
35+
"description": "Servers0:eth0",
36+
"index": "1",
37+
"lanes": "29,30,31,32",
38+
"mtu": "9100",
39+
"pfc_asym": "off",
40+
"speed": "40000",
41+
"tpid": "0x8100"
42+
},
43+
"Ethernet8": {
44+
"admin_status": "up",
45+
"alias": "fortyGigE0/8",
46+
"description": "Servers1:eth0",
47+
"index": "2",
48+
"lanes": "33,34,35,36",
49+
"mtu": "9100",
50+
"pfc_asym": "off",
51+
"speed": "40000",
52+
"tpid": "0x8100"
53+
}
54+
}
55+
},
56+
"golden_config": {
57+
"ACL_TABLE": {
58+
"EVERFLOWV6": {
59+
"policy_desc": "EVERFLOWV6",
60+
"ports": [
61+
"Ethernet12"
62+
],
63+
"stage": "ingress",
64+
"type": "MIRRORV6"
65+
}
66+
},
67+
"AUTO_TECHSUPPORT_FEATURE": {
68+
"bgp": {
69+
"state": "disabled"
70+
},
71+
"database": {
72+
"state": "disabled"
73+
}
74+
},
75+
"PORT": {
76+
"Ethernet12": {
77+
"admin_status": "up",
78+
"alias": "fortyGigE0/12",
79+
"description": "Servers2:eth0",
80+
"index": "3",
81+
"lanes": "37,38,39,40",
82+
"mtu": "9100",
83+
"pfc_asym": "off",
84+
"speed": "40000",
85+
"tpid": "0x8100"
86+
}
87+
}
88+
},
89+
"expected_config": {
90+
"ACL_TABLE": {
91+
"EVERFLOWV6": {
92+
"policy_desc": "EVERFLOWV6",
93+
"ports": [
94+
"Ethernet12"
95+
],
96+
"stage": "ingress",
97+
"type": "MIRRORV6"
98+
}
99+
},
100+
"AUTO_TECHSUPPORT_FEATURE": {
101+
"bgp": {
102+
"state": "disabled"
103+
},
104+
"database": {
105+
"state": "disabled"
106+
}
107+
},
108+
"PORT": {
109+
"Ethernet12": {
110+
"admin_status": "up",
111+
"alias": "fortyGigE0/12",
112+
"description": "Servers2:eth0",
113+
"index": "3",
114+
"lanes": "37,38,39,40",
115+
"mtu": "9100",
116+
"pfc_asym": "off",
117+
"speed": "40000",
118+
"tpid": "0x8100"
119+
}
120+
}
121+
}
122+
}

0 commit comments

Comments
 (0)