-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[dhcp_server] Add dhcp server cli #17105
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -1,13 +1,371 @@ | ||||
import click | ||||
import utilities_common.cli as clicommon | ||||
|
||||
import ipaddress | ||||
|
||||
|
||||
@click.group(cls=clicommon.AbbreviationGroup, name="dhcp_server") | ||||
def dhcp_server(): | ||||
"""config DHCP Server information""" | ||||
pass | ||||
|
||||
|
||||
@dhcp_server.group(cls=clicommon.AliasedGroup) | ||||
def ipv4(): | ||||
"""Show ipv4 related dhcp_server info""" | ||||
pass | ||||
|
||||
|
||||
@dhcp_server.group(cls=clicommon.AliasedGroup) | ||||
def ipv6(): | ||||
"""Show ipv6 related dhcp_server info""" | ||||
pass | ||||
|
||||
|
||||
def sanity_check_add(mode, lease_time, infer_gw_nm, gateway, netmask, dhcp_interface): | ||||
if mode != "PORT": | ||||
raise Exception("Only mode PORT is supported") | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May be use ctx.fail instead raising exception is better?
|
||||
if not lease_time.isdigit(): | ||||
raise Exception("lease_time is required and must be nonnegative integer") | ||||
if not inter_gw_nm: | ||||
ipaddress.ip_address(gateway) | ||||
ipaddress.ip_address(netmask) | ||||
|
||||
|
||||
def infer_param_for_add(dhcp_interface): | ||||
pass | ||||
|
||||
|
||||
@ipv4.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@click.option("--mode", required=True) | ||||
@click.option("--lease_time", required=False, default="900") | ||||
@click.option("--infer_gw_nm", required=False, default=False, is_flag=True) | ||||
@click.option("--gateway", required=False) | ||||
@click.option("--netmask", required=False) | ||||
@clicommon.pass_db | ||||
def add(db, mode, lease_time, infer_gw_nm, gateway, netmask, dhcp_interface): | ||||
sanity_check_add(mode, lease_time, infer_gw_nm, gateway, netmask, dhcp_interface): | ||||
if infer_gw_nm: | ||||
gateway, netmask = infer_param_for_add(dhcp_interface) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add check to make sure gateway and netmask are given if infer_gw_nm is not given |
||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4|" + dhcp_interface | ||||
dbconn.hmset("CONFIG_DB", key, { | ||||
"mode": mode, | ||||
"lease_time": lease_time, | ||||
"gateway": gateway, | ||||
"netmask": netmask, | ||||
"customized_options": "", | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In yang model, "customized_options" field is not required. I think maybe we can delete this field if it is empty? |
||||
"state": "disabled", | ||||
}) | ||||
|
||||
|
||||
@ipv6.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@click.option("--mode", required=True) | ||||
@click.option("--lease_time", required=False, default="900") | ||||
@click.option("--infer_gw_nm", required=False, default=False, is_flag=True) | ||||
@click.option("--gateway", required=False) | ||||
@click.option("--netmask", required=False) | ||||
@clicommon.pass_db | ||||
def add(db, mode, lease_time, infer_gw_nm, gateway, netmask, dhcp_interface): | ||||
pass | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need for ipv6 too |
||||
|
||||
|
||||
@ipv4.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@clicommon.pass_db | ||||
def del(db, dhcp_interface): | ||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4|" + dhcp_interface | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's better to check whether this key exist and give related echo msg |
||||
dbconn.delete("CONFIG_DB", key) | ||||
|
||||
|
||||
@ipv6.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@clicommon.pass_db | ||||
def del(db, dhcp_interface): | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as previous |
||||
pass | ||||
|
||||
|
||||
@ipv4.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@clicommon.pass_db | ||||
def enable(db, dhcp_interface): | ||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4|" + dhcp_interface | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether key and entry exist |
||||
dbconn.set("CONFIG_DB", key, "state", "enabled") | ||||
|
||||
|
||||
@ipv6.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@clicommon.pass_db | ||||
def enable(db, dhcp_interface): | ||||
pass | ||||
|
||||
|
||||
@ipv4.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@clicommon.pass_db | ||||
def disable(db, dhcp_interface): | ||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4|" + dhcp_interface | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether key and entry exist |
||||
dbconn.set("CONFIG_DB", key, "state", "disabled") | ||||
|
||||
|
||||
@ipv6.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@clicommon.pass_db | ||||
def disable(db, dhcp_interface): | ||||
pass | ||||
|
||||
|
||||
@ipv4.command() | ||||
@clicommon.pass_db | ||||
def update(db): | ||||
pass | ||||
|
||||
|
||||
@ipv6.command() | ||||
@clicommon.pass_db | ||||
def update(db): | ||||
pass | ||||
|
||||
|
||||
@ipv4.group(cls=clicommon.AliasedGroup) | ||||
def range(): | ||||
pass | ||||
|
||||
|
||||
@range.command() | ||||
@click.argument("range_name", required=True) | ||||
@click.argument("ip_start", required=True) | ||||
@click.argument("ip_end", required=False) | ||||
@clicommon.pass_db | ||||
def add(db, range_name, ip_start, ip_end): | ||||
if not ip_end: | ||||
ip_end = ip_start | ||||
ipaddress.ip_address(ip_start) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether range_name exist (expected: not exist) |
||||
ipaddress.ip_address(ip_end) | ||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4_RANGE|" + range_name | ||||
db.hmset("CONFIG_DB", key, {"ranges": ip_start + "," + ip_end}) | ||||
|
||||
|
||||
@range.command() | ||||
@click.argument("range_name", required=True) | ||||
@click.argument("ip_start", required=True) | ||||
@click.argument("ip_end", required=False) | ||||
@clicommon.pass_db | ||||
def update(db, range_name, ip_start, ip_end): | ||||
if not ip_end: | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether range_name exist(expected: exist) |
||||
ip_end = ip_start | ||||
ipaddress.ip_address(ip_start) | ||||
ipaddress.ip_address(ip_end) | ||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4_RANGE|" + range_name | ||||
db.hmset("CONFIG_DB", key, {"ranges": ip_start + "," + ip_end}) | ||||
|
||||
|
||||
@range.command() | ||||
@click.argument("range_name", required=True) | ||||
@clicommon.pass_db | ||||
def del(db, range_name) | ||||
dbconn = db.db | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether range_name exist(expected: exist) |
||||
key = "DHCP_SERVER_IPV4_RANGE|" + range_name | ||||
db.delete("CONFIG_DB", key) | ||||
|
||||
|
||||
@ipv6.group(cls=clicommon.AliasedGroup) | ||||
def range(): | ||||
pass | ||||
|
||||
|
||||
@range.command() | ||||
@click.argument("range_name", required=True) | ||||
@click.argument("ip_start", required=True) | ||||
@click.argument("ip_end", required=False) | ||||
@clicommon.pass_db | ||||
def add(db, range_name, ip_start, ip_end): | ||||
pass | ||||
|
||||
|
||||
@range.command() | ||||
@click.argument("range_name", required=True) | ||||
@click.argument("ip_start", required=True) | ||||
@click.argument("ip_end", required=False) | ||||
@clicommon.pass_db | ||||
def update(db, range_name, ip_start, ip_end): | ||||
pass | ||||
|
||||
|
||||
@range.command() | ||||
@click.argument("range_name", required=True) | ||||
@clicommon.pass_db | ||||
def del(db, range_name) | ||||
pass | ||||
|
||||
|
||||
@ipv4.group(cls=clicommon.AliasedGroup) | ||||
def ip(): | ||||
pass | ||||
|
||||
|
||||
@ip.command() | ||||
@click.argument("vlan_interface", required=True) | ||||
@click.argument("interface", required=True) | ||||
@click.options("--range", required=False, nargs=-1) | ||||
@click.argument("ip_list", required=False, nargs=-1) | ||||
@clicommon.pass_db | ||||
def bind(db, vlan_interface, interface, range_, ip_list): | ||||
dbconn = db.db | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether key exist. |
||||
key = "DHCP_SERVER_IPV4_PORT|" + vlan_interface + "|" + interface | ||||
if range_: | ||||
dbconn.hmset("CONFIG_DB", key, {"ranges": ",".join(range_)}) | ||||
elif ip_list: | ||||
dbconn.hmset("CONFIG_DB", key, {"ips": ",".join(ip_list)}) | ||||
else: | ||||
raise Exception("One of range and ip_list should be provided") | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest to use ctx.fail too |
||||
|
||||
|
||||
@ip.command() | ||||
@click.argument("vlan_interface", required=True) | ||||
@click.argument("interface", required=True) | ||||
@click.options("--range", required=False, nargs=-1) | ||||
@click.argument("ip_list", required=False, nargs=-1) | ||||
@clicommon.pass_db | ||||
def unbind(db, vlan_interface, interface, range_, ip_list): | ||||
pass | ||||
|
||||
|
||||
@ipv6.group(cls=clicommon.AliasedGroup) | ||||
def ip(): | ||||
pass | ||||
|
||||
|
||||
@ip.command() | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Duplicate with line 214? |
||||
@click.argument("vlan_interface", required=True) | ||||
@click.argument("interface", required=True) | ||||
@click.options("--range", required=False, nargs=-1) | ||||
@click.argument("ip_list", required=False, nargs=-1) | ||||
@clicommon.pass_db | ||||
def bind(db, vlan_interface, interface, range_, ip_list): | ||||
pass | ||||
|
||||
|
||||
@ip.command() | ||||
@click.argument("vlan_interface", required=True) | ||||
@click.argument("interface", required=True) | ||||
@click.options("--range", required=False, nargs=-1) | ||||
@click.argument("ip_list", required=False, nargs=-1) | ||||
@clicommon.pass_db | ||||
def unbind(db, vlan_interface, interface, range_, ip_list): | ||||
pass | ||||
|
||||
|
||||
@ipv4.group(cls=clicommon.AliasedGroup) | ||||
def option(): | ||||
pass | ||||
|
||||
|
||||
@option.command() | ||||
@click.argument("option_name", required=True) | ||||
@click.argument("option_id", required=True) | ||||
@click.argument("type", required=True) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggest changing to no required and default "string" for feature support assigned options which type should not be customized and should follow ietf doc |
||||
@click.argument("value", required=True) | ||||
@clicommon.pass_db | ||||
def add(db, option_name, option_id, type_, value): | ||||
assert option_id.isdigit() | ||||
assert type_ == "string" | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Support type ["binary", "boolean", "ipv4-address", "string", "uint8", "uint16", "uint32"] |
||||
dbconn = db.db | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Currently only support unassigned options |
||||
key = "DHCP_SERVER_IPV4_CUSTOMIZED_OPTIONS|" + option_name | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether key exist(expected: not exist) |
||||
dbconn.hmset("CONFIG_DB", key, { | ||||
"option_id": option_id, | ||||
"type": type_, | ||||
"value": value, | ||||
}) | ||||
|
||||
|
||||
@option.command() | ||||
@click.argument("option_name", required=True) | ||||
@clicommon.pass_db | ||||
def del(db, option_name): | ||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4_CUSTOMIZED_OPTIONS|" + option_name | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether key exist (expected: exist) |
||||
dbconn.delete("CONFIG_DB", key) | ||||
|
||||
|
||||
@option.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@click.argument("option_list", nargs=-1) | ||||
@clicommon.pass_db | ||||
def bind(db, dhcp_interface, option_list): | ||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4|" + dhcp_interface | ||||
if dbconn.exists("CONFIG_DB", key) and option_list: | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether option_list exist (expected: exist). I think fail if any of option_list not exist is better? |
||||
old_value = dbconn.get("CONFIG_DB", key, "customized_options") | ||||
if old_value: | ||||
option_list = [old_value] + option_list | ||||
dbconn.set("CONFIG_DB", key, "customized_options", ",".join(option_list)) | ||||
|
||||
|
||||
@option.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@click.argument("option_list", nargs=-1) | ||||
@click.option("--all", required=False, default=False, is_flag=True) | ||||
@clicommon.pass_db | ||||
def unbind(db, dhcp_interface, option_list, all_): | ||||
dbconn = db.db | ||||
key = "DHCP_SERVER_IPV4|" + dhcp_interface | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check whether dhcp_interface/option_list exist |
||||
if all_: | ||||
dbconn.set("CONFIG_DB", key, "customized_options", "") | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In yang model, "customized_options" field is not required. I think maybe we can delete this field if it is empty? |
||||
else: | ||||
old_options = dbconn.get("CONFIG_DB", key, "customized_options") | ||||
option_set = set(old_options.split(",")) | ||||
new_option_set = option_set - set(option_list) | ||||
new_options = ",".join(new_option_set) | ||||
dbconn.set("CONFIG_DB", key, "customized_options", new_options) | ||||
|
||||
|
||||
@ipv6.group(cls=clicommon.AliasedGroup) | ||||
def option(): | ||||
pass | ||||
|
||||
|
||||
@option.command() | ||||
@click.argument("option_name", required=True) | ||||
@click.argument("option_id", required=True) | ||||
@click.argument("type", required=True) | ||||
@click.argument("value", required=True) | ||||
@clicommon.pass_db | ||||
def add(db, option_name, option_id, type_, value): | ||||
pass | ||||
|
||||
|
||||
@option.command() | ||||
@click.argument("option_name", required=True) | ||||
@clicommon.pass_db | ||||
def del(db, option_name): | ||||
pass | ||||
|
||||
|
||||
@option.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@click.argument("option_list", nargs=-1) | ||||
@clicommon.pass_db | ||||
def bind(db, dhcp_interface, option_list): | ||||
pass | ||||
|
||||
|
||||
@option.command() | ||||
@click.argument("dhcp_interface", required=True) | ||||
@click.argument("option_list", nargs=-1) | ||||
@click.option("--all", required=False, default=False, is_flag=True) | ||||
@clicommon.pass_db | ||||
def unbind(db, dhcp_interface, option_list, all_): | ||||
pass | ||||
|
||||
|
||||
def register(cli): | ||||
# cli.add_command(dhcp_server) | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rember to add register |
||||
pass | ||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need ipv6 currently, you can remove it. I think if add ipv6 part here, it will auto generate command when press "tab"