Skip to content

Commit

Permalink
[dhcp_server] Adjust the dhcp_server cli data format to align with dh…
Browse files Browse the repository at this point in the history
…cp_cfggen (#18519)
  • Loading branch information
w1nda authored Apr 16, 2024
1 parent 81d0b16 commit 8d54b0d
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 50 deletions.
23 changes: 10 additions & 13 deletions dockers/docker-dhcp-server/cli-plugin-tests/mock_config_db.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"lease_time": "3600",
"mode": "PORT",
"netmask": "255.255.255.0",
"customized_options": "option60",
"customized_options@": "option60",
"state": "enabled"
},
"DHCP_SERVER_IPV4|Vlan300": {
Expand All @@ -46,33 +46,30 @@
"value": "dummy_value"
},
"DHCP_SERVER_IPV4_RANGE|range1": {
"range": "100.1.1.3,100.1.1.5"
"range@": "100.1.1.3,100.1.1.5"
},
"DHCP_SERVER_IPV4_RANGE|range2": {
"range": "100.1.1.9,100.1.1.8"
"range@": "100.1.1.9,100.1.1.8"
},
"DHCP_SERVER_IPV4_RANGE|range3": {
"range": "100.1.1.10"
"range@": "100.1.1.10"
},
"DHCP_SERVER_IPV4_RANGE|range5": {
"range": "100.1.2.10"
"range@": "100.1.2.10"
},
"DHCP_SERVER_IPV4_RANGE|range6": {
"range": "100.1.2.11"
},
"DHCP_SERVER_IPV4_IP|eth0": {
"ip": "240.127.1.2"
"range@": "100.1.2.11"
},
"DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet4": {
"ips": "100.1.1.10,100.1.1.11"
"ips@": "100.1.1.10,100.1.1.11"
},
"DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet7": {
"ranges": "range1,range3"
"ranges@": "range1,range3"
},
"DHCP_SERVER_IPV4_PORT|Vlan200|Ethernet8": {
"ranges": "range5,range6"
"ranges@": "range5,range6"
},
"DHCP_SERVER_IPV4_PORT|Ethernet9": {
"ranges": "range5,range6"
"ranges@": "range5,range6"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def test_config_dhcp_server_ipv4_update_wrong_netmask(self, mock_db):

def test_config_dhcp_server_ipv4_range_add(self, mock_db):
expected_value = {
"range": "10.10.10.10,10.10.10.11"
"range@": "10.10.10.10,10.10.10.11"
}
runner = CliRunner()
db = clicommon.Db()
Expand All @@ -278,7 +278,7 @@ def test_config_dhcp_server_ipv4_range_add_existing(self, mock_db):

def test_config_dhcp_server_ipv4_range_add_single_ip(self, mock_db):
expected_value = {
"range": "10.10.10.10,10.10.10.10"
"range@": "10.10.10.10,10.10.10.10"
}
runner = CliRunner()
db = clicommon.Db()
Expand Down Expand Up @@ -306,7 +306,7 @@ def test_config_dhcp_server_ipv4_range_add_wrong_order(self, mock_db):

def test_config_dhcp_server_ipv4_range_update(self, mock_db):
expected_value = {
"range": "10.10.10.10,10.10.10.11"
"range@": "10.10.10.10,10.10.10.11"
}
runner = CliRunner()
db = clicommon.Db()
Expand All @@ -326,7 +326,7 @@ def test_config_dhcp_server_ipv4_range_update_nonexisting(self, mock_db):

def test_config_dhcp_server_ipv4_range_update_single_ip(self, mock_db):
expected_value = {
"range": "10.10.10.10,10.10.10.10"
"range@": "10.10.10.10,10.10.10.10"
}
runner = CliRunner()
db = clicommon.Db()
Expand Down Expand Up @@ -394,7 +394,7 @@ def test_config_dhcp_server_ipv4_bind_range_nonexisting(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["bind"], \
["Vlan100", "Ethernet2", "--range", "range2,range3"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet2", "ranges")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet2", "ranges@")
assert result and set(result.split(",")) == set(expected_value.split(","))

def test_config_dhcp_server_ipv4_bind_ip_nonexisting(self, mock_db):
Expand All @@ -405,7 +405,7 @@ def test_config_dhcp_server_ipv4_bind_ip_nonexisting(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["bind"], \
["Vlan100", "Ethernet2", "100.1.1.1,100.1.1.2"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet2", "ips")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet2", "ips@")
assert result and set(result.split(",")) == set(expected_value.split(","))

def test_config_dhcp_server_ipv4_bind_range_existing_no_duplicate(self, mock_db):
Expand All @@ -416,7 +416,7 @@ def test_config_dhcp_server_ipv4_bind_range_existing_no_duplicate(self, mock_db)
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["bind"], \
["Vlan100", "Ethernet7", "--range", "range2"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet7", "ranges")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet7", "ranges@")
assert result and set(result.split(",")) == set(expected_value.split(","))

def test_config_dhcp_server_ipv4_bind_range_existing_duplicate(self, mock_db):
Expand All @@ -427,7 +427,7 @@ def test_config_dhcp_server_ipv4_bind_range_existing_duplicate(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["bind"], \
["Vlan100", "Ethernet7", "--range", "range2,range3"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet7", "ranges")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet7", "ranges@")
assert result and set(result.split(",")) == set(expected_value.split(","))

def test_config_dhcp_server_ipv4_bind_ip_existing_no_duplicate(self, mock_db):
Expand All @@ -438,7 +438,7 @@ def test_config_dhcp_server_ipv4_bind_ip_existing_no_duplicate(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["bind"], \
["Vlan100", "Ethernet4", "100.1.1.12,100.1.1.13"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet4", "ips")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet4", "ips@")
assert result and set(result.split(",")) == set(expected_value.split(","))

def test_config_dhcp_server_ipv4_bind_ip_existing_duplicate(self, mock_db):
Expand All @@ -449,7 +449,7 @@ def test_config_dhcp_server_ipv4_bind_ip_existing_duplicate(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["bind"], \
["Vlan100", "Ethernet4", "100.1.1.11,100.1.1.12"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet4", "ips")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet4", "ips@")
assert result and set(result.split(",")) == set(expected_value.split(","))

def test_config_dhcp_server_ipv4_bind_nonexisting_range(self, mock_db):
Expand Down Expand Up @@ -524,7 +524,7 @@ def test_config_dhcp_server_ipv4_unbind_range_with_remain(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["unbind"], \
["Vlan100", "Ethernet7", "--range", "range3"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet7", "ranges")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet7", "ranges@")
assert result and set(result.split(",")) == set(expected_value.split(","))

def test_config_dhcp_server_ipv4_unbind_range_with_no_remain(self, mock_db):
Expand Down Expand Up @@ -553,7 +553,7 @@ def test_config_dhcp_server_ipv4_unbind_ip_with_remain(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["unbind"], \
["Vlan100", "Ethernet4", "100.1.1.11"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet4", "ips")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4_PORT|Vlan100|Ethernet4", "ips@")
assert result and set(result.split(",")) == set(expected_value.split(","))

def test_config_dhcp_server_ipv4_unbind_ip_with_no_remain(self, mock_db):
Expand Down Expand Up @@ -624,7 +624,7 @@ def test_config_dhcp_server_ipv4_unbind_unbind_ip(self, mock_db):

def test_config_dhcp_server_ipv4_option_add(self, mock_db):
expected_value = {
"option_id": "165",
"id": "165",
"type": "string",
"value": "dummy_value"
}
Expand Down Expand Up @@ -700,7 +700,7 @@ def test_config_dhcp_server_ipv4_option_bind(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["option"].commands["bind"], \
["Vlan300", "option60"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
assert mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan300", "customized_options") == "option60"
assert mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan300", "customized_options@") == "option60"

def test_config_dhcp_server_ipv4_option_bind_multiple_options(self, mock_db):
runner = CliRunner()
Expand All @@ -709,7 +709,7 @@ def test_config_dhcp_server_ipv4_option_bind_multiple_options(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["option"].commands["bind"], \
["Vlan300", "option60,option61"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan300", "customized_options")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan300", "customized_options@")
assert result and set(result.split(",")) == set("option60,option61".split(","))

def test_config_dhcp_server_ipv4_option_bind_to_existing(self, mock_db):
Expand All @@ -719,7 +719,7 @@ def test_config_dhcp_server_ipv4_option_bind_to_existing(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["option"].commands["bind"], \
["Vlan100", "option61"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan100", "customized_options")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan100", "customized_options@")
assert result and set(result.split(",")) == set("option60,option61".split(","))

def test_config_dhcp_server_ipv4_option_bind_same_option_to_existing(self, mock_db):
Expand All @@ -729,7 +729,7 @@ def test_config_dhcp_server_ipv4_option_bind_same_option_to_existing(self, mock_
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["option"].commands["bind"], \
["Vlan100", "option60"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
assert mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan100", "customized_options") == "option60"
assert mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan100", "customized_options@") == "option60"

def test_config_dhcp_server_ipv4_option_bind_to_nonexisting_intf(self, mock_db):
runner = CliRunner()
Expand All @@ -754,7 +754,7 @@ def test_config_dhcp_server_ipv4_option_unbind(self, mock_db):
result = runner.invoke(dhcp_server.dhcp_server.commands["ipv4"].commands["option"].commands["unbind"], \
["Vlan100", "option60"], obj=db)
assert result.exit_code == 0, "exit code: {}, Exception: {}, Traceback: {}".format(result.exit_code, result.exception, result.exc_info)
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan100", "customized_options")
result = mock_db.get("CONFIG_DB", "DHCP_SERVER_IPV4|Vlan100", "customized_options@")
assert result == None or result == ""

def test_config_dhcp_server_ipv4_option_unbind_nonexisting_intf(self, mock_db):
Expand Down
26 changes: 13 additions & 13 deletions dockers/docker-dhcp-server/cli/config/plugins/dhcp_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def dhcp_server_ipv4_range_add(db, range_name, ip_start, ip_end):
if dbconn.exists("CONFIG_DB", key):
ctx.fail("Range {} already exist".format(range_name))
else:
dbconn.hmset("CONFIG_DB", key, {"range": ip_start + "," + ip_end})
dbconn.hmset("CONFIG_DB", key, {"range@": ip_start + "," + ip_end})


@dhcp_server_ipv4_range.command(name="update")
Expand All @@ -238,7 +238,7 @@ def dhcp_server_ipv4_range_update(db, range_name, ip_start, ip_end):
dbconn = db.db
key = "DHCP_SERVER_IPV4_RANGE|" + range_name
if dbconn.exists("CONFIG_DB", key):
dbconn.set("CONFIG_DB", key, "range", ip_start + "," + ip_end)
dbconn.set("CONFIG_DB", key, "range@", ip_start + "," + ip_end)
else:
ctx.fail("Range {} does not exist, cannot update".format(range_name))

Expand All @@ -254,7 +254,7 @@ def dhcp_sever_ipv4_range_del(db, range_name, force):
if dbconn.exists("CONFIG_DB", key):
if not force:
for port in dbconn.keys("CONFIG_DB", "DHCP_SERVER_IPV4_PORT*"):
ranges = dbconn.get("CONFIG_DB", port, "ranges")
ranges = dbconn.get("CONFIG_DB", port, "ranges@")
if ranges and range_name in ranges.split(","):
ctx.fail("Range {} is referenced in {}, cannot delete, add --force to bypass or range unbind to unbind range first".format(range_name, port))
dbconn.delete("CONFIG_DB", key)
Expand All @@ -280,7 +280,7 @@ def dhcp_server_ipv4_ip_bind(db, dhcp_interface, member_interface, range_, ip_li
for r in range_:
if not dbconn.exists("CONFIG_DB", "DHCP_SERVER_IPV4_RANGE|" + r):
ctx.fail("Cannot bind nonexistent range {} to interface".format(r))
ip_range = dbconn.get("CONFIG_DB", "DHCP_SERVER_IPV4_RANGE|" + r, "range").split(",")
ip_range = dbconn.get("CONFIG_DB", "DHCP_SERVER_IPV4_RANGE|" + r, "range@").split(",")
if len(ip_range) == 1:
ip_start = ip_range[0]
ip_end = ip_range[0]
Expand All @@ -300,7 +300,7 @@ def dhcp_server_ipv4_ip_bind(db, dhcp_interface, member_interface, range_, ip_li
ctx.fail("Only one of range and ip list need to be provided")
key = "DHCP_SERVER_IPV4_PORT|" + dhcp_interface + "|" + member_interface
key_exist = dbconn.exists("CONFIG_DB", key)
for bind_value_name, bind_value in [["ips", ip_list], ["ranges", range_]]:
for bind_value_name, bind_value in [["ips@", ip_list], ["ranges@", range_]]:
if key_exist:
existing_value = dbconn.get("CONFIG_DB", key, bind_value_name)
if (not not existing_value) == (not bind_value):
Expand Down Expand Up @@ -330,7 +330,7 @@ def dhcp_server_ipv4_ip_unbind(db, dhcp_interface, member_interface, range_, ip_
ctx.fail("Only one of range and ip list need to be provided")
if not dbconn.exists("CONFIG_DB", key):
ctx.fail("The specified dhcp_interface and member interface is not bind to ip or range")
for unbind_value_name, unbind_value in [["ips", ip_list], ["ranges", range_]]:
for unbind_value_name, unbind_value in [["ips@", ip_list], ["ranges@", range_]]:
if unbind_value:
unbind_value = set(unbind_value.split(","))
existing_value = dbconn.get("CONFIG_DB", key, unbind_value_name)
Expand Down Expand Up @@ -372,7 +372,7 @@ def dhcp_server_ipv4_option_add(db, option_name, option_id, type_, value):
if dbconn.exists("CONFIG_DB", key):
ctx.fail("Option {} already exist".format(option_name))
dbconn.hmset("CONFIG_DB", key, {
"option_id": option_id,
"id": option_id,
"type": type_,
"value": value,
})
Expand All @@ -388,7 +388,7 @@ def dhcp_server_ipv4_option_del(db, option_name):
if not dbconn.exists("CONFIG_DB", option_key):
ctx.fail("Option {} does not exist, cannot delete".format(option_name))
for key in dbconn.keys("CONFIG_DB", "DHCP_SERVER_IPV4|*"):
existing_options = dbconn.get("CONFIG_DB", key, "customized_options")
existing_options = dbconn.get("CONFIG_DB", key, "customized_options@")
if existing_options and option_name in existing_options.split(","):
ctx.fail("Option {} is referenced in {}, cannot delete".format(option_name, key[len("DHCP_SERVER_IPV4|"):]))
dbconn.delete("CONFIG_DB", option_key)
Expand All @@ -409,10 +409,10 @@ def dhcp_server_ipv4_option_bind(db, dhcp_interface, option_list):
option_key = "DHCP_SERVER_IPV4_CUSTOMIZED_OPTIONS|" + option_name
if not dbconn.exists("CONFIG_DB", option_key):
ctx.fail("Option {} does not exist, cannot bind".format(option_name))
existing_value = dbconn.get("CONFIG_DB", key, "customized_options")
existing_value = dbconn.get("CONFIG_DB", key, "customized_options@")
value_set = set(existing_value.split(",")) if existing_value else set()
new_value_set = value_set.union(option_list)
dbconn.set("CONFIG_DB", key, "customized_options", ",".join(new_value_set))
dbconn.set("CONFIG_DB", key, "customized_options@", ",".join(new_value_set))


@dhcp_server_ipv4_option.command(name="unbind")
Expand All @@ -427,14 +427,14 @@ def dhcp_server_ipv4_option_unbind(db, dhcp_interface, option_list, all_):
if not dbconn.exists("CONFIG_DB", key):
ctx.fail("Interface {} is not valid dhcp interface".format(dhcp_interface))
if all_:
dbconn.set("CONFIG_DB", key, "customized_options", "")
dbconn.set("CONFIG_DB", key, "customized_options@", "")
else:
unbind_value = set(option_list.split(","))
existing_value = dbconn.get("CONFIG_DB", key, "customized_options")
existing_value = dbconn.get("CONFIG_DB", key, "customized_options@")
value_set = set(existing_value.split(",")) if existing_value else set()
if value_set.issuperset(unbind_value):
new_value_set = value_set.difference(unbind_value)
dbconn.set("CONFIG_DB", key, "customized_options", ",".join(new_value_set))
dbconn.set("CONFIG_DB", key, "customized_options@", ",".join(new_value_set))
else:
ctx.fail("Attempting to unbind option that is not binded")

Expand Down
Loading

0 comments on commit 8d54b0d

Please sign in to comment.