156156 - VRF ID of third DHCP server
157157 type: str
158158 required: false
159+ dhcp_servers:
160+ description:
161+ - List of DHCP servers
162+ - This is an alternative to dhcp_srvr1_ip, dhcp_srvr1_vrf, dhcp_srvr2_ip, dhcp_srvr2_vrf,
163+ dhcp_srvr3_ip, dhcp_srvr3_vrf
164+ - If both dhcp_servers and any of dhcp_srvr1_ip, dhcp_srvr1_vrf, dhcp_srvr2_ip,
165+ dhcp_srvr2_vrf, dhcp_srvr3_ip, dhcp_srvr3_vrf are specified, unexpected results may occur
166+ type: list
167+ elements: dict
168+ required: false
159169 dhcp_loopback_id:
160170 description:
161171 - Loopback ID for DHCP Relay interface
480490 get_fabric_inventory_details ,
481491 get_ip_sn_dict ,
482492 get_ip_sn_fabric_dict ,
493+ has_partial_dhcp_config ,
483494 validate_list_of_dicts ,
484495)
485496
@@ -893,6 +904,7 @@ def diff_for_create(self, want, have):
893904 dhcp1_vrf_changed = False
894905 dhcp2_vrf_changed = False
895906 dhcp3_vrf_changed = False
907+ dhcp_servers_changed = False
896908 dhcp_loopback_changed = False
897909 multicast_group_address_changed = False
898910 gwv6_changed = False
@@ -934,7 +946,6 @@ def diff_for_create(self, want, have):
934946 arpsup_want = str (json_to_dict_want .get ("suppressArp" , "" )).lower ()
935947 arpsup_have = json_to_dict_have .get ("suppressArp" , "" )
936948 dhcp1_ip_want = json_to_dict_want .get ("dhcpServerAddr1" , "" )
937- dhcp1_ip_want = json_to_dict_want .get ("dhcpServerAddr1" , "" )
938949 dhcp1_ip_have = json_to_dict_have .get ("dhcpServerAddr1" , "" )
939950 dhcp2_ip_want = json_to_dict_want .get ("dhcpServerAddr2" , "" )
940951 dhcp2_ip_have = json_to_dict_have .get ("dhcpServerAddr2" , "" )
@@ -946,6 +957,8 @@ def diff_for_create(self, want, have):
946957 dhcp2_vrf_have = json_to_dict_have .get ("vrfDhcp2" , "" )
947958 dhcp3_vrf_want = json_to_dict_want .get ("vrfDhcp3" , "" )
948959 dhcp3_vrf_have = json_to_dict_have .get ("vrfDhcp3" , "" )
960+ dhcp_servers_want = json_to_dict_want .get ("dhcpServers" , "" )
961+ dhcp_servers_have = json_to_dict_have .get ("dhcpServers" , "" )
949962 dhcp_loopback_want = json_to_dict_want .get ("loopbackId" , "" )
950963 dhcp_loopback_have = json_to_dict_have .get ("loopbackId" , "" )
951964 multicast_group_address_want = json_to_dict_want .get ("mcastGroup" , "" )
@@ -1001,6 +1014,7 @@ def diff_for_create(self, want, have):
10011014 or dhcp1_vrf_have != dhcp1_vrf_want
10021015 or dhcp2_vrf_have != dhcp2_vrf_want
10031016 or dhcp3_vrf_have != dhcp3_vrf_want
1017+ or dhcp_servers_have != dhcp_servers_want
10041018 or dhcp_loopback_have != dhcp_loopback_want
10051019 or multicast_group_address_have != multicast_group_address_want
10061020 or gw_ipv6_have != gw_ipv6_want
@@ -1047,6 +1061,8 @@ def diff_for_create(self, want, have):
10471061 dhcp2_vrf_changed = True
10481062 if dhcp3_vrf_have != dhcp3_vrf_want :
10491063 dhcp3_vrf_changed = True
1064+ if dhcp_servers_have != dhcp_servers_want :
1065+ dhcp_servers_changed = True
10501066 if dhcp_loopback_have != dhcp_loopback_want :
10511067 dhcp_loopback_changed = True
10521068 if multicast_group_address_have != multicast_group_address_want :
@@ -1096,6 +1112,7 @@ def diff_for_create(self, want, have):
10961112 or dhcp1_vrf_have != dhcp1_vrf_want
10971113 or dhcp2_vrf_have != dhcp2_vrf_want
10981114 or dhcp3_vrf_have != dhcp3_vrf_want
1115+ or dhcp_servers_have != dhcp_servers_want
10991116 or dhcp_loopback_have != dhcp_loopback_want
11001117 or multicast_group_address_have != multicast_group_address_want
11011118 or gw_ipv6_have != gw_ipv6_want
@@ -1139,6 +1156,8 @@ def diff_for_create(self, want, have):
11391156 dhcp2_vrf_changed = True
11401157 if dhcp3_vrf_have != dhcp3_vrf_want :
11411158 dhcp3_vrf_changed = True
1159+ if dhcp_servers_have != dhcp_servers_want :
1160+ dhcp_servers_changed = True
11421161 if dhcp_loopback_have != dhcp_loopback_want :
11431162 dhcp_loopback_changed = True
11441163 if multicast_group_address_have != multicast_group_address_want :
@@ -1186,6 +1205,7 @@ def diff_for_create(self, want, have):
11861205 dhcp1_vrf_changed ,
11871206 dhcp2_vrf_changed ,
11881207 dhcp3_vrf_changed ,
1208+ dhcp_servers_changed ,
11891209 dhcp_loopback_changed ,
11901210 multicast_group_address_changed ,
11911211 gwv6_changed ,
@@ -1244,6 +1264,9 @@ def update_create_params(self, net):
12441264 "vrfDhcp" : net .get ("dhcp_srvr1_vrf" , "" ),
12451265 "vrfDhcp2" : net .get ("dhcp_srvr2_vrf" , "" ),
12461266 "vrfDhcp3" : net .get ("dhcp_srvr3_vrf" , "" ),
1267+ "dhcpServers" : [
1268+ {"srvrAddr" : srvr ["srvr_ip" ], "srvrVrf" : srvr ["srvr_vrf" ]} for srvr in net .get ("dhcp_servers" , [])
1269+ ],
12471270 "loopbackId" : net .get ("dhcp_loopback_id" , "" ),
12481271 "mcastGroup" : net .get ("multicast_group_address" , "" ),
12491272 "gatewayIpV6Address" : net .get ("gw_ipv6_subnet" , "" ),
@@ -1277,6 +1300,30 @@ def update_create_params(self, net):
12771300 template_conf ["vrfDhcp2" ] = ""
12781301 if template_conf ["vrfDhcp3" ] is None :
12791302 template_conf ["vrfDhcp3" ] = ""
1303+ if template_conf ["dhcpServers" ] == []:
1304+ dhcp_srvr_list = []
1305+ if template_conf ["dhcpServerAddr1" ] != "" and template_conf ["vrfDhcp" ] != "" :
1306+ dhcp_srvr_list .append ({"srvrAddr" : template_conf ["dhcpServerAddr1" ], "srvrVrf" : template_conf ["vrfDhcp" ]})
1307+ if template_conf ["dhcpServerAddr2" ] != "" and template_conf ["vrfDhcp2" ] != "" :
1308+ dhcp_srvr_list .append ({"srvrAddr" : template_conf ["dhcpServerAddr2" ], "srvrVrf" : template_conf ["vrfDhcp2" ]})
1309+ if template_conf ["dhcpServerAddr3" ] != "" and template_conf ["vrfDhcp3" ] != "" :
1310+ dhcp_srvr_list .append ({"srvrAddr" : template_conf ["dhcpServerAddr3" ], "srvrVrf" : template_conf ["vrfDhcp3" ]})
1311+ if dhcp_srvr_list != []:
1312+ template_conf ["dhcpServers" ] = json .dumps (dict (dhcpServers = dhcp_srvr_list ), separators = ("," , ":" ))
1313+ else :
1314+ template_conf ["dhcpServers" ] = ""
1315+ elif template_conf ["dhcpServers" ] != []:
1316+ dhcp_srvr_list = template_conf ["dhcpServers" ]
1317+ if dhcp_srvr_list [0 :1 ]:
1318+ template_conf ["dhcpServerAddr1" ] = dhcp_srvr_list [0 ]["srvrAddr" ]
1319+ template_conf ["vrfDhcp" ] = dhcp_srvr_list [0 ]["srvrVrf" ]
1320+ if dhcp_srvr_list [1 :2 ]:
1321+ template_conf ["dhcpServerAddr2" ] = dhcp_srvr_list [1 ]["srvrAddr" ]
1322+ template_conf ["vrfDhcp2" ] = dhcp_srvr_list [1 ]["srvrVrf" ]
1323+ if dhcp_srvr_list [2 :3 ]:
1324+ template_conf ["dhcpServerAddr3" ] = dhcp_srvr_list [2 ]["srvrAddr" ]
1325+ template_conf ["vrfDhcp3" ] = dhcp_srvr_list [2 ]["srvrVrf" ]
1326+ template_conf ["dhcpServers" ] = json .dumps (dict (dhcpServers = dhcp_srvr_list ), separators = ("," , ":" ))
12801327 if template_conf ["loopbackId" ] is None :
12811328 template_conf ["loopbackId" ] = ""
12821329 if self .is_ms_fabric is True :
@@ -1294,6 +1341,7 @@ def update_create_params(self, net):
12941341 template_conf ["secondaryGW3" ] = ""
12951342 if template_conf ["secondaryGW4" ] is None :
12961343 template_conf ["secondaryGW4" ] = ""
1344+
12971345 if self .dcnm_version > 11 :
12981346 if template_conf ["SVI_NETFLOW_MONITOR" ] is None :
12991347 template_conf ["SVI_NETFLOW_MONITOR" ] = ""
@@ -1375,6 +1423,7 @@ def get_have(self):
13751423 "vrfDhcp" : json_to_dict .get ("vrfDhcp" , "" ),
13761424 "vrfDhcp2" : json_to_dict .get ("vrfDhcp2" , "" ),
13771425 "vrfDhcp3" : json_to_dict .get ("vrfDhcp3" , "" ),
1426+ "dhcpServers" : json_to_dict .get ("dhcpServers" , "" ),
13781427 "loopbackId" : json_to_dict .get ("loopbackId" , "" ),
13791428 "mcastGroup" : json_to_dict .get ("mcastGroup" , "" ),
13801429 "gatewayIpV6Address" : json_to_dict .get ("gatewayIpV6Address" , "" ),
@@ -1428,6 +1477,7 @@ def get_have(self):
14281477 "vrfDhcp" : json_to_dict .get ("vrfDhcp" , "" ),
14291478 "vrfDhcp2" : json_to_dict .get ("vrfDhcp2" , "" ),
14301479 "vrfDhcp3" : json_to_dict .get ("vrfDhcp3" , "" ),
1480+ "dhcpServers" : json_to_dict .get ("dhcpServers" , "" ),
14311481 "loopbackId" : json_to_dict .get ("loopbackId" , "" ),
14321482 "mcastGroup" : json_to_dict .get ("mcastGroup" , "" ),
14331483 "gatewayIpV6Address" : json_to_dict .get ("gatewayIpV6Address" , "" ),
@@ -1868,6 +1918,7 @@ def get_diff_merge(self, replace=False):
18681918 dhcp1_vrf_changed = {}
18691919 dhcp2_vrf_changed = {}
18701920 dhcp3_vrf_changed = {}
1921+ dhcp_servers_changed = {}
18711922 dhcp_loopback_changed = {}
18721923 multicast_group_address_changed = {}
18731924 gwv6_changed = {}
@@ -1904,6 +1955,7 @@ def get_diff_merge(self, replace=False):
19041955 dhcp1_vrf_chg ,
19051956 dhcp2_vrf_chg ,
19061957 dhcp3_vrf_chg ,
1958+ dhcp_servers_chg ,
19071959 dhcp_loopbk_chg ,
19081960 mcast_grp_chg ,
19091961 gwv6_chg ,
@@ -1931,6 +1983,7 @@ def get_diff_merge(self, replace=False):
19311983 dhcp1_vrf_changed .update ({want_c ["networkName" ]: dhcp1_vrf_chg })
19321984 dhcp2_vrf_changed .update ({want_c ["networkName" ]: dhcp2_vrf_chg })
19331985 dhcp3_vrf_changed .update ({want_c ["networkName" ]: dhcp3_vrf_chg })
1986+ dhcp_servers_changed .update ({want_c ["networkName" ]: dhcp_servers_chg })
19341987 dhcp_loopback_changed .update ({want_c ["networkName" ]: dhcp_loopbk_chg })
19351988 if self .is_ms_fabric is False :
19361989 multicast_group_address_changed .update ({want_c ["networkName" ]: mcast_grp_chg })
@@ -2043,6 +2096,7 @@ def get_diff_merge(self, replace=False):
20432096 or dhcp1_vrf_changed .get (want_a ["networkName" ], False )
20442097 or dhcp2_vrf_changed .get (want_a ["networkName" ], False )
20452098 or dhcp3_vrf_changed .get (want_a ["networkName" ], False )
2099+ or dhcp_servers_changed .get (want_a ["networkName" ], False )
20462100 or dhcp_loopback_changed .get (want_a ["networkName" ], False )
20472101 or multicast_group_address_changed .get (want_a ["networkName" ], False )
20482102 or gwv6_changed .get (want_a ["networkName" ], False )
@@ -2151,6 +2205,7 @@ def format_diff(self):
21512205 found_c .update ({"dhcp_srvr1_vrf" : json_to_dict .get ("vrfDhcp" , "" )})
21522206 found_c .update ({"dhcp_srvr2_vrf" : json_to_dict .get ("vrfDhcp2" , "" )})
21532207 found_c .update ({"dhcp_srvr3_vrf" : json_to_dict .get ("vrfDhcp3" , "" )})
2208+ found_c .update ({"dhcp_servers" : json_to_dict .get ("dhcpServers" , "" )})
21542209 found_c .update ({"dhcp_loopback_id" : json_to_dict .get ("loopbackId" , "" )})
21552210 found_c .update ({"multicast_group_address" : json_to_dict .get ("mcastGroup" , "" )})
21562211 found_c .update ({"gw_ipv6_subnet" : json_to_dict .get ("gatewayIpV6Address" , "" )})
@@ -2531,6 +2586,7 @@ def push_to_remote(self, is_rollback=False):
25312586 "vrfDhcp" : json_to_dict .get ("vrfDhcp" , "" ),
25322587 "vrfDhcp2" : json_to_dict .get ("vrfDhcp2" , "" ),
25332588 "vrfDhcp3" : json_to_dict .get ("vrfDhcp3" , "" ),
2589+ "dhcpServers" : json_to_dict .get ("dhcpServers" , "" ),
25342590 "loopbackId" : json_to_dict .get ("loopbackId" , "" ),
25352591 "mcastGroup" : json_to_dict .get ("mcastGroup" , "" ),
25362592 "gatewayIpV6Address" : json_to_dict .get ("gatewayIpV6Address" , "" ),
@@ -2671,6 +2727,7 @@ def validate_input(self):
26712727 dhcp_srvr1_vrf = dict (type = "str" , length_max = 32 ),
26722728 dhcp_srvr2_vrf = dict (type = "str" , length_max = 32 ),
26732729 dhcp_srvr3_vrf = dict (type = "str" , length_max = 32 ),
2730+ dhcp_servers = dict (type = "list" , elements = "dict" , default = []),
26742731 dhcp_loopback_id = dict (type = "int" , range_min = 0 , range_max = 1023 ),
26752732 multicast_group_address = dict (type = "ipv4" , default = mcast_group_addr ),
26762733 gw_ipv6_subnet = dict (type = "ipv6_subnet" , default = "" ),
@@ -2737,6 +2794,7 @@ def validate_input(self):
27372794 dhcp_srvr1_vrf = dict (type = "str" , length_max = 32 ),
27382795 dhcp_srvr2_vrf = dict (type = "str" , length_max = 32 ),
27392796 dhcp_srvr3_vrf = dict (type = "str" , length_max = 32 ),
2797+ dhcp_servers = dict (type = "list" , elements = "dict" , default = []),
27402798 dhcp_loopback_id = dict (type = "int" , range_min = 0 , range_max = 1023 ),
27412799 multicast_group_address = dict (type = "ipv4" , default = mcast_group_addr ),
27422800 gw_ipv6_subnet = dict (type = "ipv6_subnet" , default = "" ),
@@ -2798,16 +2856,20 @@ def validate_input(self):
27982856 if net .get ("vrf_name" , "" ) is None :
27992857 invalid_params .append ("vrf_name is required for L3 Networks" )
28002858
2801- if (
2802- (net .get ("dhcp_srvr1_ip" ) and not net .get ("dhcp_srvr1_vrf" ))
2803- or (net .get ("dhcp_srvr1_vrf" ) and not net .get ("dhcp_srvr1_ip" ))
2804- or (net .get ("dhcp_srvr2_ip" ) and not net .get ("dhcp_srvr2_vrf" ))
2805- or (net .get ("dhcp_srvr2_vrf" ) and not net .get ("dhcp_srvr2_ip" ))
2806- or (net .get ("dhcp_srvr3_ip" ) and not net .get ("dhcp_srvr3_vrf" ))
2807- or (net .get ("dhcp_srvr3_vrf" ) and not net .get ("dhcp_srvr3_ip" ))
2808- ):
2859+ if any (has_partial_dhcp_config (srvr ) for srvr in [
2860+ dict (srvr_ip = net .get ("dhcp_srvr1_ip" ), srvr_vrf = net .get ("dhcp_srvr1_vrf" )),
2861+ dict (srvr_ip = net .get ("dhcp_srvr2_ip" ), srvr_vrf = net .get ("dhcp_srvr2_vrf" )),
2862+ dict (srvr_ip = net .get ("dhcp_srvr3_ip" ), srvr_vrf = net .get ("dhcp_srvr3_vrf" )),
2863+ ]):
28092864 invalid_params .append ("DHCP server IP should be specified along with DHCP server VRF" )
28102865
2866+ if net .get ("dhcp_servers" ):
2867+ dhcp_servers = net .get ("dhcp_servers" )
2868+ if len (dhcp_servers ) > 16 :
2869+ invalid_params .append ("A maximum of 16 DHCP servers can be specified" )
2870+ if any (has_partial_dhcp_config (srvr ) for srvr in dhcp_servers ):
2871+ invalid_params .append ("DHCP server IP should be specified along with DHCP server VRF" )
2872+
28112873 if self .dcnm_version == 11 :
28122874 if net .get ("netflow_enable" ) or net .get ("intfvlan_nf_monitor" ) or net .get ("vlan_nf_monitor" ):
28132875 invalid_params .append ("Netflow configurations are supported only on NDFC" )
@@ -2982,6 +3044,26 @@ def dcnm_update_network_information(self, want, have, cfg):
29823044 if cfg .get ("dhcp_srvr3_vrf" , None ) is None :
29833045 json_to_dict_want ["vrfDhcp3" ] = json_to_dict_have ["vrfDhcp3" ]
29843046
3047+ if cfg .get ("dhcp_servers" , None ) is None :
3048+ want_have_dhcp_servers = [None ] * 3
3049+ if cfg .get ("dhcp_srvr1_ip" , None ) is not None :
3050+ want_have_dhcp_servers [0 ] = dict (srvrAddr = cfg .get ("dhcp_srvr1_ip" ), srvrVrf = cfg .get ("dhcp_srvr1_vrf" ))
3051+ elif json_to_dict_have ["dhcpServerAddr1" ] != "" :
3052+ want_have_dhcp_servers [0 ] = dict (srvrAddr = json_to_dict_have ["dhcpServerAddr1" ], srvrVrf = json_to_dict_have ["vrfDhcp" ])
3053+ if cfg .get ("dhcp_srvr2_ip" , None ) is not None :
3054+ want_have_dhcp_servers [1 ] = dict (srvrAddr = cfg .get ("dhcp_srvr2_ip" ), srvrVrf = cfg .get ("dhcp_srvr2_vrf" ))
3055+ elif json_to_dict_have ["dhcpServerAddr2" ] != "" :
3056+ want_have_dhcp_servers [1 ] = dict (srvrAddr = json_to_dict_have ["dhcpServerAddr2" ], srvrVrf = json_to_dict_have ["vrfDhcp2" ])
3057+ if cfg .get ("dhcp_srvr3_ip" , None ) is not None :
3058+ want_have_dhcp_servers [2 ] = dict (srvrAddr = cfg .get ("dhcp_srvr3_ip" ), srvrVrf = cfg .get ("dhcp_srvr3_vrf" ))
3059+ elif json_to_dict_have ["dhcpServerAddr3" ] != "" :
3060+ want_have_dhcp_servers [2 ] = dict (srvrAddr = json_to_dict_have ["dhcpServerAddr3" ], srvrVrf = json_to_dict_have ["vrfDhcp3" ])
3061+ want_have_dhcp_servers = [srvr for srvr in want_have_dhcp_servers [:] if srvr is not None ]
3062+ if want_have_dhcp_servers != []:
3063+ json_to_dict_want ["dhcpServers" ] = json .dumps (dict (dhcpServers = want_have_dhcp_servers , separators = ("," , ":" )))
3064+ else :
3065+ json_to_dict_want ["dhcpServers" ] = json_to_dict_have ["dhcpServers" ]
3066+
29853067 if cfg .get ("dhcp_loopback_id" , None ) is None :
29863068 json_to_dict_want ["loopbackId" ] = json_to_dict_have ["loopbackId" ]
29873069
0 commit comments