Skip to content

Commit

Permalink
[minigraph] Consume golden_config_db.json while loading minigraph (#2140
Browse files Browse the repository at this point in the history
)

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.
  • Loading branch information
wen587 authored May 9, 2022
1 parent c37a957 commit 6ab1c51
Show file tree
Hide file tree
Showing 7 changed files with 729 additions and 2 deletions.
71 changes: 69 additions & 2 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

from collections import OrderedDict
from generic_config_updater.generic_updater import GenericUpdater, ConfigFormat
from minigraph import parse_device_desc_xml
from minigraph import parse_device_desc_xml, minigraph_encoder
from natsort import natsorted
from portconfig import get_child_ports
from socket import AF_INET, AF_INET6
Expand All @@ -27,7 +27,7 @@
from utilities_common.intf_filter import parse_interface_in_filter
from utilities_common import bgp_util
import utilities_common.cli as clicommon
from utilities_common.general import load_db_config
from utilities_common.general import load_db_config, load_module_from_source

from .utils import log

Expand Down Expand Up @@ -71,6 +71,7 @@
DEFAULT_CONFIG_YANG_FILE = '/etc/sonic/config_yang.json'
NAMESPACE_PREFIX = 'asic'
INTF_KEY = "interfaces"
DEFAULT_GOLDEN_CONFIG_DB_FILE = '/etc/sonic/golden_config_db.json'

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

Expand Down Expand Up @@ -99,6 +100,9 @@
QUEUE_RANGE = click.IntRange(min=0, max=255)
GRE_TYPE_RANGE = click.IntRange(min=0, max=65535)

# Load sonic-cfggen from source since /usr/local/bin/sonic-cfggen does not have .py extension.
sonic_cfggen = load_module_from_source('sonic_cfggen', '/usr/local/bin/sonic-cfggen')

#
# Helper functions
#
Expand Down Expand Up @@ -1619,6 +1623,10 @@ def load_minigraph(db, no_service_restart):
cfggen_namespace_option = " -n {}".format(namespace)
clicommon.run_command(db_migrator + ' -o set_version' + cfggen_namespace_option)

# Load golden_config_db.json
if os.path.isfile(DEFAULT_GOLDEN_CONFIG_DB_FILE):
override_config_by(DEFAULT_GOLDEN_CONFIG_DB_FILE)

# We first run "systemctl reset-failed" to remove the "failed"
# status from all services before we attempt to restart them
if not no_service_restart:
Expand Down Expand Up @@ -1667,6 +1675,65 @@ def load_port_config(config_db, port_config_path):
port_name), display_cmd=True)
return


def override_config_by(golden_config_path):
# Override configDB with golden config
clicommon.run_command('config override-config-table {}'.format(
golden_config_path), display_cmd=True)
return


#
# 'override-config-table' command ('config override-config-table ...')
#
@config.command('override-config-table')
@click.argument('input-config-db', required=True)
@click.option(
'--dry-run', is_flag=True, default=False,
help='test out the command without affecting config state'
)
@clicommon.pass_db
def override_config_table(db, input_config_db, dry_run):
"""Override current configDB with input config."""

try:
# Load golden config json
config_input = read_json_file(input_config_db)
except Exception as e:
click.secho("Bad format: json file broken. {}".format(str(e)),
fg='magenta')
sys.exit(1)

# Validate if the input is dict
if not isinstance(config_input, dict):
click.secho("Bad format: input_config_db is not a dict",
fg='magenta')
sys.exit(1)

config_db = db.cfgdb

if dry_run:
# Read config from configDB
current_config = config_db.get_config()
# Serialize to the same format as json input
sonic_cfggen.FormatConverter.to_serialized(current_config)
# Override current config with golden config
for table in config_input:
current_config[table] = config_input[table]
print(json.dumps(current_config, sort_keys=True,
indent=4, cls=minigraph_encoder))
else:
# Deserialized golden config to DB recognized format
sonic_cfggen.FormatConverter.to_deserialized(config_input)
# Delete table from DB then mod_config to apply golden config
click.echo("Removing configDB overriden table first ...")
for table in config_input:
config_db.delete_table(table)
click.echo("Overriding input config to configDB ...")
data = sonic_cfggen.FormatConverter.output_to_db(config_input)
config_db.mod_config(data)
click.echo("Overriding completed. No service is restarted.")

#
# 'hostname' command
#
Expand Down
113 changes: 113 additions & 0 deletions tests/config_override_input/empty_input.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
{
"running_config": {
"ACL_TABLE": {
"DATAACL": {
"policy_desc": "DATAACL",
"ports": [
"Ethernet4"
],
"stage": "ingress",
"type": "L3"
},
"NTP_ACL": {
"policy_desc": "NTP_ACL",
"services": [
"NTP"
],
"stage": "ingress",
"type": "CTRLPLANE"
}
},
"AUTO_TECHSUPPORT_FEATURE": {
"bgp": {
"rate_limit_interval": "600",
"state": "enabled"
},
"database": {
"rate_limit_interval": "600",
"state": "enabled"
}
},
"PORT": {
"Ethernet4": {
"admin_status": "up",
"alias": "fortyGigE0/4",
"description": "Servers0:eth0",
"index": "1",
"lanes": "29,30,31,32",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
},
"Ethernet8": {
"admin_status": "up",
"alias": "fortyGigE0/8",
"description": "Servers1:eth0",
"index": "2",
"lanes": "33,34,35,36",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
}
}
},
"golden_config": {

},
"expected_config": {
"ACL_TABLE": {
"DATAACL": {
"policy_desc": "DATAACL",
"ports": [
"Ethernet4"
],
"stage": "ingress",
"type": "L3"
},
"NTP_ACL": {
"policy_desc": "NTP_ACL",
"services": [
"NTP"
],
"stage": "ingress",
"type": "CTRLPLANE"
}
},
"AUTO_TECHSUPPORT_FEATURE": {
"bgp": {
"rate_limit_interval": "600",
"state": "enabled"
},
"database": {
"rate_limit_interval": "600",
"state": "enabled"
}
},
"PORT": {
"Ethernet4": {
"admin_status": "up",
"alias": "fortyGigE0/4",
"description": "Servers0:eth0",
"index": "1",
"lanes": "29,30,31,32",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
},
"Ethernet8": {
"admin_status": "up",
"alias": "fortyGigE0/8",
"description": "Servers1:eth0",
"index": "2",
"lanes": "33,34,35,36",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
}
}
}
}
122 changes: 122 additions & 0 deletions tests/config_override_input/full_config_override.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
{
"running_config": {
"ACL_TABLE": {
"DATAACL": {
"policy_desc": "DATAACL",
"ports": [
"Ethernet4"
],
"stage": "ingress",
"type": "L3"
},
"NTP_ACL": {
"policy_desc": "NTP_ACL",
"services": [
"NTP"
],
"stage": "ingress",
"type": "CTRLPLANE"
}
},
"AUTO_TECHSUPPORT_FEATURE": {
"bgp": {
"rate_limit_interval": "600",
"state": "enabled"
},
"database": {
"rate_limit_interval": "600",
"state": "enabled"
}
},
"PORT": {
"Ethernet4": {
"admin_status": "up",
"alias": "fortyGigE0/4",
"description": "Servers0:eth0",
"index": "1",
"lanes": "29,30,31,32",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
},
"Ethernet8": {
"admin_status": "up",
"alias": "fortyGigE0/8",
"description": "Servers1:eth0",
"index": "2",
"lanes": "33,34,35,36",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
}
}
},
"golden_config": {
"ACL_TABLE": {
"EVERFLOWV6": {
"policy_desc": "EVERFLOWV6",
"ports": [
"Ethernet12"
],
"stage": "ingress",
"type": "MIRRORV6"
}
},
"AUTO_TECHSUPPORT_FEATURE": {
"bgp": {
"state": "disabled"
},
"database": {
"state": "disabled"
}
},
"PORT": {
"Ethernet12": {
"admin_status": "up",
"alias": "fortyGigE0/12",
"description": "Servers2:eth0",
"index": "3",
"lanes": "37,38,39,40",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
}
}
},
"expected_config": {
"ACL_TABLE": {
"EVERFLOWV6": {
"policy_desc": "EVERFLOWV6",
"ports": [
"Ethernet12"
],
"stage": "ingress",
"type": "MIRRORV6"
}
},
"AUTO_TECHSUPPORT_FEATURE": {
"bgp": {
"state": "disabled"
},
"database": {
"state": "disabled"
}
},
"PORT": {
"Ethernet12": {
"admin_status": "up",
"alias": "fortyGigE0/12",
"description": "Servers2:eth0",
"index": "3",
"lanes": "37,38,39,40",
"mtu": "9100",
"pfc_asym": "off",
"speed": "40000",
"tpid": "0x8100"
}
}
}
}
Loading

0 comments on commit 6ab1c51

Please sign in to comment.