Skip to content

Commit dc2945b

Browse files
[dns] Implement config and show commands for static DNS. (sonic-net#2737)
- What I did Implement config and show commands for static DNS feature. According to sonic-net/SONiC#1262 HLD. - How I did it Static DNS config commands are implemented in the new config/dns.py file. DNS config commands are available under config dns ... sub-command. Show commands are implemented in the new show/dns.py file. DNS show commands are available under show dns ... sub-command. - How to verify it Compile sonic-utilities package. The unit tests will run automatically during the compilation. Coverage for config/dns.py : 94% Coverage for show/dns.py : 86% - Previous command output (if the output of a command-line utility has changed) - New command output (if the output of a command-line utility has changed) # config dns nameserver add 1.1.1.1 # config dns nameserver add 8.8.8.8 # show dns nameserver Nameserver ------------ 1.1.1.1 8.8.8.8
1 parent 8414a70 commit dc2945b

File tree

6 files changed

+381
-1
lines changed

6 files changed

+381
-1
lines changed

config/dns.py

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
2+
import click
3+
from swsscommon.swsscommon import ConfigDBConnector
4+
from .validated_config_db_connector import ValidatedConfigDBConnector
5+
import ipaddress
6+
7+
8+
ADHOC_VALIDATION = True
9+
NAMESERVERS_MAX_NUM = 3
10+
11+
12+
def to_ip_address(address):
13+
"""Check if the given IP address is valid"""
14+
try:
15+
ip = ipaddress.ip_address(address)
16+
17+
if ADHOC_VALIDATION:
18+
if ip.is_reserved or ip.is_multicast or ip.is_loopback:
19+
return
20+
21+
invalid_ips = [
22+
ipaddress.IPv4Address('0.0.0.0'),
23+
ipaddress.IPv4Address('255.255.255.255'),
24+
ipaddress.IPv6Address("0::0"),
25+
ipaddress.IPv6Address("0::1")
26+
]
27+
if ip in invalid_ips:
28+
return
29+
30+
return ip
31+
except Exception:
32+
return
33+
34+
35+
def get_nameservers(db):
36+
nameservers = db.get_table('DNS_NAMESERVER')
37+
return [ipaddress.ip_address(ip) for ip in nameservers]
38+
39+
40+
# 'dns' group ('config dns ...')
41+
@click.group()
42+
@click.pass_context
43+
def dns(ctx):
44+
"""Static DNS configuration"""
45+
config_db = ValidatedConfigDBConnector(ConfigDBConnector())
46+
config_db.connect()
47+
ctx.obj = {'db': config_db}
48+
49+
50+
# dns nameserver config
51+
@dns.group('nameserver')
52+
@click.pass_context
53+
def nameserver(ctx):
54+
"""Static DNS nameservers configuration"""
55+
pass
56+
57+
58+
# dns nameserver add
59+
@nameserver.command('add')
60+
@click.argument('ip_address_str', metavar='<ip_address>', required=True)
61+
@click.pass_context
62+
def add_dns_nameserver(ctx, ip_address_str):
63+
"""Add static DNS nameserver entry"""
64+
ip_address = to_ip_address(ip_address_str)
65+
if not ip_address:
66+
ctx.fail(f"{ip_address_str} invalid nameserver ip address")
67+
68+
db = ctx.obj['db']
69+
70+
nameservers = get_nameservers(db)
71+
if ip_address in nameservers:
72+
ctx.fail(f"{ip_address} nameserver is already configured")
73+
74+
if len(nameservers) >= NAMESERVERS_MAX_NUM:
75+
ctx.fail(f"The maximum number ({NAMESERVERS_MAX_NUM}) of nameservers exceeded.")
76+
77+
db.set_entry('DNS_NAMESERVER', ip_address, {})
78+
79+
# dns nameserver delete
80+
@nameserver.command('del')
81+
@click.argument('ip_address_str', metavar='<ip_address>', required=True)
82+
@click.pass_context
83+
def del_dns_nameserver(ctx, ip_address_str):
84+
"""Delete static DNS nameserver entry"""
85+
86+
ip_address = to_ip_address(ip_address_str)
87+
if not ip_address:
88+
ctx.fail(f"{ip_address_str} invalid nameserver ip address")
89+
90+
db = ctx.obj['db']
91+
92+
nameservers = get_nameservers(db)
93+
if ip_address not in nameservers:
94+
ctx.fail(f"DNS nameserver {ip_address} is not configured")
95+
96+
db.set_entry('DNS_NAMESERVER', ip_address, None)

config/main.py

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
from .config_mgmt import ConfigMgmtDPB, ConfigMgmt
5757
from . import mclag
5858
from . import syslog
59+
from . import dns
5960

6061
# mock masic APIs for unit test
6162
try:
@@ -1198,6 +1199,9 @@ def config(ctx):
11981199
# syslog module
11991200
config.add_command(syslog.syslog)
12001201

1202+
# DNS module
1203+
config.add_command(dns.dns)
1204+
12011205
@config.command()
12021206
@click.option('-y', '--yes', is_flag=True, callback=_abort_if_false,
12031207
expose_value=False, prompt='Existing files will be overwritten, continue?')

doc/Command-Reference.md

+56-1
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,15 @@
194194
* [MACsec config command](#macsec-config-command)
195195
* [MACsec show command](#macsec-show-command)
196196
* [MACsec clear command](#macsec-clear-command)
197-
197+
* [Static DNS Commands](#static-dns-commands)
198+
* [Static DNS config command](#static-dns-config-command)
199+
* [Static DNS show command](#static-dns-show-command)
198200

199201
## Document History
200202

201203
| Version | Modification Date | Details |
202204
| --- | --- | --- |
205+
| v7 | Jun-22-2023 | Add static DNS show and config commands |
203206
| v6 | May-06-2021 | Add SNMP show and config commands |
204207
| v5 | Nov-05-2020 | Add document for console commands |
205208
| v4 | Oct-17-2019 | Unify usage statements and other formatting; Replace tabs with spaces; Modify heading sizes; Fix spelling, grammar and other errors; Fix organization of new commands |
@@ -12442,3 +12445,55 @@ Clear MACsec counters which is to reset all MACsec counters to ZERO.
1244212445
```
1244312446
1244412447
Go Back To [Beginning of the document](#) or [Beginning of this section](#macsec-commands)
12448+
12449+
# Static DNS Commands
12450+
12451+
This sub-section explains the list of the configuration options available for static DNS feature.
12452+
12453+
## Static DNS config command
12454+
12455+
- Add static DNS nameserver entry
12456+
12457+
```
12458+
admin@sonic:~$ config dns nameserver add -h
12459+
Usage: config dns nameserver add [OPTIONS] <ip_address>
12460+
12461+
Add static DNS nameserver entry
12462+
12463+
Options:
12464+
-?, -h, --help Show this message and exit.
12465+
```
12466+
12467+
- Delete static DNS nameserver entry
12468+
12469+
```
12470+
admin@sonic:~$ config dns nameserver del -h
12471+
Usage: config dns nameserver del [OPTIONS] <ip_address>
12472+
12473+
Delete static DNS nameserver entry
12474+
12475+
Options:
12476+
-h, -?, --help Show this message and exit.
12477+
```
12478+
12479+
## Static DNS show command
12480+
12481+
- Show static DNS configuration
12482+
12483+
```
12484+
admin@sonic:~$ show dns nameserver -h
12485+
Usage: show dns nameserver [OPTIONS]
12486+
12487+
Show static DNS configuration
12488+
12489+
Options:
12490+
-h, -?, --help Show this message and exit.
12491+
```
12492+
```
12493+
admin@sonic:~$ show dns nameserver
12494+
Nameserver
12495+
------------
12496+
1.1.1.1
12497+
8.8.8.8
12498+
12499+
```

show/dns.py

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import click
2+
import utilities_common.cli as clicommon
3+
from natsort import natsorted
4+
from tabulate import tabulate
5+
6+
from swsscommon.swsscommon import ConfigDBConnector
7+
from utilities_common.cli import pass_db
8+
9+
10+
# 'dns' group ("show dns ...")
11+
@click.group(cls=clicommon.AliasedGroup)
12+
@click.pass_context
13+
def dns(ctx):
14+
"""Show details of the static DNS configuration """
15+
config_db = ConfigDBConnector()
16+
config_db.connect()
17+
ctx.obj = {'db': config_db}
18+
19+
20+
# 'nameserver' subcommand ("show dns nameserver")
21+
@dns.command()
22+
@click.pass_context
23+
def nameserver(ctx):
24+
""" Show static DNS configuration """
25+
header = ["Nameserver"]
26+
db = ctx.obj['db']
27+
28+
nameservers = db.get_table('DNS_NAMESERVER')
29+
30+
click.echo(tabulate([(ns,) for ns in nameservers.keys()], header, tablefmt='simple', stralign='right'))

show/main.py

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
from . import warm_restart
6565
from . import plugins
6666
from . import syslog
67+
from . import dns
6768

6869
# Global Variables
6970
PLATFORM_JSON = 'platform.json'
@@ -295,6 +296,7 @@ def cli(ctx):
295296
cli.add_command(vxlan.vxlan)
296297
cli.add_command(system_health.system_health)
297298
cli.add_command(warm_restart.warm_restart)
299+
cli.add_command(dns.dns)
298300

299301
# syslog module
300302
cli.add_command(syslog.syslog)

0 commit comments

Comments
 (0)