diff --git a/config/main.py b/config/main.py index ed071c6887..389714dcae 100755 --- a/config/main.py +++ b/config/main.py @@ -6,6 +6,8 @@ import json import subprocess import netaddr +import logging +import logging.handlers import re import syslog @@ -789,6 +791,86 @@ def del_vlan_member(ctx, vid, interface_name): db.set_entry('VLAN_MEMBER', (vlan_name, interface_name), None) + +def vrf_add_management_vrf(): + """Enable management vrf""" + + config_db = ConfigDBConnector() + config_db.connect() + entry = config_db.get_entry('MGMT_VRF_CONFIG', "vrf_global") + if entry and entry['mgmtVrfEnabled'] == 'true' : + click.echo("ManagementVRF is already Enabled.") + return None + config_db.mod_entry('MGMT_VRF_CONFIG',"vrf_global",{"mgmtVrfEnabled": "true"}) + cmd="service ntp stop" + os.system (cmd) + cmd="systemctl restart interfaces-config" + os.system (cmd) + cmd="service ntp start" + os.system (cmd) + + +def vrf_delete_management_vrf(): + """Disable management vrf""" + + config_db = ConfigDBConnector() + config_db.connect() + entry = config_db.get_entry('MGMT_VRF_CONFIG', "vrf_global") + if not entry or entry['mgmtVrfEnabled'] == 'false' : + click.echo("ManagementVRF is already Disabled.") + return None + config_db.mod_entry('MGMT_VRF_CONFIG',"vrf_global",{"mgmtVrfEnabled": "false"}) + cmd="service ntp stop" + os.system (cmd) + cmd="systemctl restart interfaces-config" + os.system (cmd) + cmd="service ntp start" + os.system (cmd) + + +# +# 'vrf' group ('config vrf ...') +# + +@config.group('vrf') +def vrf(): + """VRF-related configuration tasks""" + pass + + +@vrf.command('add') +@click.argument('vrfname', metavar='. Type mgmt for management VRF', required=True) +@click.pass_context +def vrf_add (ctx, vrfname): + """VRF ADD""" + if vrfname == 'mgmt' or vrfname == 'management': + vrf_add_management_vrf() + else: + click.echo("Creation of data vrf={} is not yet supported".format(vrfname)) + + +@vrf.command('del') +@click.argument('vrfname', metavar='. Type mgmt for management VRF', required=False) +@click.pass_context +def vrf_del (ctx, vrfname): + """VRF Delete""" + if vrfname == 'mgmt' or vrfname == 'management': + vrf_delete_management_vrf() + else: + click.echo("Deletion of data vrf={} is not yet supported".format(vrfname)) + + +@config.command('clear_mgmt') +@click.pass_context +def clear_mgmt(ctx): + MGMT_TABLE_NAMES = [ + 'MGMT_INTERFACE', + 'MGMT_VRF_CONFIG'] + config_db = ConfigDBConnector() + config_db.connect() + for mgmt_table in MGMT_TABLE_NAMES: + config_db.delete_table(mgmt_table) + # # 'bgp' group ('config bgp ...') # @@ -925,6 +1007,14 @@ def speed(ctx, interface_name, interface_speed, verbose): command += " -vv" run_command(command, display_cmd=verbose) +def _get_all_mgmtinterface_keys(): + """Returns list of strings containing mgmt interface keys + """ + config_db = ConfigDBConnector() + config_db.connect() + return config_db.get_table('MGMT_INTERFACE').keys() + + # # 'ip' subgroup ('config interface ip ...') # @@ -942,8 +1032,9 @@ def ip(ctx): @ip.command() @click.argument('interface_name', metavar='', required=True) @click.argument("ip_addr", metavar="", required=True) +@click.argument('gw', metavar='', required=False) @click.pass_context -def add(ctx, interface_name, ip_addr): +def add(ctx, interface_name, ip_addr, gw): """Add an IP address towards the interface""" config_db = ctx.obj["config_db"] if get_interface_naming_mode() == "alias": @@ -956,6 +1047,32 @@ def add(ctx, interface_name, ip_addr): if interface_name.startswith("Ethernet"): config_db.set_entry("INTERFACE", (interface_name, ip_addr), {"NULL": "NULL"}) config_db.set_entry("INTERFACE", interface_name, {"NULL": "NULL"}) + elif interface_name == 'eth0': + + # Configuring more than 1 IPv4 or more than 1 IPv6 address fails. + # Allow only one IPv4 and only one IPv6 address to be configured for IPv6. + # If a row already exist, overwrite it (by doing delete and add). + mgmtintf_key_list = _get_all_mgmtinterface_keys() + + for key in mgmtintf_key_list: + # For loop runs for max 2 rows, once for IPv4 and once for IPv6. + if ':' in ip_addr and ':' in key[1]: + # If user has configured IPv6 address and the already available row is also IPv6, delete it here. + config_db.set_entry("MGMT_INTERFACE", ("eth0", key[1]), None) + elif ':' not in ip_addr and ':' not in key[1]: + # If user has configured IPv4 address and the already available row is also IPv6, delete it here. + config_db.set_entry("MGMT_INTERFACE", ("eth0", key[1]), None) + + # Set the new row with new value + if not gw: + config_db.set_entry("MGMT_INTERFACE", (interface_name, ip_addr), {"NULL": "NULL"}) + else: + config_db.set_entry("MGMT_INTERFACE", (interface_name, ip_addr), {"gwaddr": gw}) + cmd="systemctl restart interfaces-config" + os.system (cmd) + cmd="systemctl restart ntp-config" + os.system (cmd) + elif interface_name.startswith("PortChannel"): config_db.set_entry("PORTCHANNEL_INTERFACE", (interface_name, ip_addr), {"NULL": "NULL"}) config_db.set_entry("PORTCHANNEL_INTERFACE", interface_name, {"NULL": "NULL"}) @@ -991,6 +1108,12 @@ def remove(ctx, interface_name, ip_addr): if interface_name.startswith("Ethernet"): config_db.set_entry("INTERFACE", (interface_name, ip_addr), None) if_table = "INTERFACE" + elif interface_name == 'eth0': + config_db.set_entry("MGMT_INTERFACE", (interface_name, ip_addr), None) + cmd="systemctl restart interfaces-config" + os.system (cmd) + cmd="systemctl restart ntp-config" + os.system (cmd) elif interface_name.startswith("PortChannel"): config_db.set_entry("PORTCHANNEL_INTERFACE", (interface_name, ip_addr), None) if_table = "PORTCHANNEL_INTERFACE" @@ -1003,7 +1126,7 @@ def remove(ctx, interface_name, ip_addr): ctx.fail("'interface_name' is not valid. Valid names [Ethernet/PortChannel/Vlan/Loopback]") except ValueError: ctx.fail("'ip_addr' is not valid.") - + exists = False if if_table: interfaces = config_db.get_table(if_table) diff --git a/show/main.py b/show/main.py index 9f5631d038..cd1640082b 100755 --- a/show/main.py +++ b/show/main.py @@ -418,6 +418,93 @@ def ndp(ip6address, iface, verbose): run_command(cmd, display_cmd=verbose) +# +# 'mgmt-vrf' group ("show mgmt-vrf ...") +# + +@cli.group('mgmt-vrf', invoke_without_command=True) +@click.pass_context +def mgmt_vrf(ctx): + + """Show management VRF attributes""" + + if ctx.invoked_subcommand is None: + cmd = 'sonic-cfggen -d --var-json "MGMT_VRF_CONFIG"' + + p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + res = p.communicate() + if p.returncode == 0 : + p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + mvrf_dict = json.loads(p.stdout.read()) + + # if the mgmtVrfEnabled attribute is configured, check the value + # and print Enabled or Disabled accordingly. + if 'mgmtVrfEnabled' in mvrf_dict['vrf_global']: + if (mvrf_dict['vrf_global']['mgmtVrfEnabled'] == "true"): + click.echo("\nManagementVRF : Enabled") + else: + click.echo("\nManagementVRF : Disabled") + + click.echo("\nManagement VRF in Linux:") + cmd = "sudo ip link show type vrf" + run_command(cmd) + +@mgmt_vrf.command('interfaces') +def mgmt_vrf_interfaces (): + """Show management VRF attributes""" + + click.echo("\neth0 Interfaces in Management VRF:") + cmd = "sudo ifconfig eth0" + run_command(cmd) + return None + +@mgmt_vrf.command('route') +def mgmt_vrf_route (): + """Show management VRF routes""" + + click.echo("\nRoutes in Management VRF Routing Table:") + cmd = "sudo ip route show table 1001" + run_command(cmd) + return None + + +@mgmt_vrf.command('addresses') +def mgmt_vrf_addresses (): + """Show management VRF addresses""" + + click.echo("\nIP Addresses for interfaces in Management VRF:") + cmd = "sudo ip address show mgmt" + run_command(cmd) + return None + + + +# +# 'management_interface' group ("show management_interface ...") +# + +@cli.group(cls=AliasedGroup, default_if_no_args=False) +def management_interface(): + """Show management interface parameters""" + pass + +# 'address' subcommand ("show management_interface address") +@management_interface.command() +def address (): + """Show IP address configured for management interface""" + + config_db = ConfigDBConnector() + config_db.connect() + header = ['IFNAME', 'IP Address', 'PrefixLen',] + body = [] + + # Fetching data from config_db for MGMT_INTERFACE + mgmt_ip_data = config_db.get_table('MGMT_INTERFACE') + for key in natsorted(mgmt_ip_data.keys()): + click.echo("Management IP address = {0}".format(key[1])) + click.echo("Management NetWork Default Gateway = {0}".format(mgmt_ip_data[key]['gwaddr'])) + + # # 'interfaces' group ("show interfaces ...") # @@ -1443,8 +1530,15 @@ def bgp(verbose): @click.option('--verbose', is_flag=True, help="Enable verbose output") def ntp(verbose): """Show NTP information""" - cmd = "ntpq -p -n" - run_command(cmd, display_cmd=verbose) + config_db = ConfigDBConnector() + config_db.connect() + entry = config_db.get_entry('MGMT_VRF_CONFIG', "vrf_global") + if entry and entry['mgmtVrfEnabled'] == 'true' : + cmd = "mgmtvrf_ntpq -p -n" + run_command(cmd, display_cmd=verbose) + else: + cmd = "ntpq -p -n" + run_command(cmd, display_cmd=verbose) #