diff --git a/api-daemon/pvcapid/flaskapi.py b/api-daemon/pvcapid/flaskapi.py index 422daf3d..0d01f59c 100755 --- a/api-daemon/pvcapid/flaskapi.py +++ b/api-daemon/pvcapid/flaskapi.py @@ -7139,7 +7139,11 @@ class API_Provisioner_Template_Network_Net_Root(Resource): "name": "vni", "required": True, "helptext": "A valid VNI must be specified.", - } + }, + { + "name": "permit_duplicate", + "required": False, + }, ] ) @Authenticator @@ -7155,6 +7159,11 @@ class API_Provisioner_Template_Network_Net_Root(Resource): type: integer required: false description: PVC network VNI + - in: query + name: permit_duplicate + type: boolean + required: false + description: Bypass checks to permit duplicate VNIs for niche usecases responses: 200: description: OK @@ -7168,7 +7177,7 @@ class API_Provisioner_Template_Network_Net_Root(Resource): id: Message """ return api_provisioner.create_template_network_element( - template, reqargs.get("vni", None) + template, reqargs.get("vni", None), reqargs.get("permit_duplicate", False) ) @@ -7206,13 +7215,27 @@ class API_Provisioner_Template_Network_Net_Element(Resource): return _vni, 200 abort(404) + @RequestParser( + [ + { + "name": "permit_duplicate", + "required": False, + } + ] + ) @Authenticator - def post(self, template, vni): + def post(self, template, vni, reqargs): """ Create a new network {vni} in network template {template} --- tags: - provisioner / template + parameters: + - in: query + name: permit_duplicate + type: boolean + required: false + description: Bypass checks to permit duplicate VNIs for niche usecases responses: 200: description: OK @@ -7225,7 +7248,9 @@ class API_Provisioner_Template_Network_Net_Element(Resource): type: object id: Message """ - return api_provisioner.create_template_network_element(template, vni) + return api_provisioner.create_template_network_element( + template, vni, reqargs.get("permit_duplicate", False) + ) @Authenticator def delete(self, template, vni): diff --git a/api-daemon/pvcapid/provisioner.py b/api-daemon/pvcapid/provisioner.py index 0a1535b2..472ecf57 100755 --- a/api-daemon/pvcapid/provisioner.py +++ b/api-daemon/pvcapid/provisioner.py @@ -284,27 +284,28 @@ def create_template_network(name, mac_template=None): return retmsg, retcode -def create_template_network_element(name, vni): +def create_template_network_element(name, vni, permit_duplicate=False): if list_template_network(name, is_fuzzy=False)[-1] != 200: retmsg = {"message": 'The network template "{}" does not exist.'.format(name)} retcode = 400 return retmsg, retcode - networks, code = list_template_network_vnis(name) - if code != 200: - networks = [] - found_vni = False - for network in networks: - if network["vni"] == vni: - found_vni = True - if found_vni: - retmsg = { - "message": 'The VNI "{}" in network template "{}" already exists.'.format( - vni, name - ) - } - retcode = 400 - return retmsg, retcode + if not permit_duplicate: + networks, code = list_template_network_vnis(name) + if code != 200: + networks = [] + found_vni = False + for network in networks: + if network["vni"] == vni: + found_vni = True + if found_vni: + retmsg = { + "message": 'The VNI "{}" in network template "{}" already exists.'.format( + vni, name + ) + } + retcode = 400 + return retmsg, retcode conn, cur = open_database(config) try: diff --git a/client-cli/pvc/cli/cli.py b/client-cli/pvc/cli/cli.py index aea25275..e3e0ab85 100644 --- a/client-cli/pvc/cli/cli.py +++ b/client-cli/pvc/cli/cli.py @@ -4849,13 +4849,27 @@ def cli_provisioner_template_network_vni(): @connection_req @click.argument("name") @click.argument("vni") -def cli_provisioner_template_network_vni_add(name, vni): +@click.option( + "-d", + "--permit-duplicate", + "permit_duplicate_flag", + is_flag=True, + default=False, + help="Permit a duplicate VNI if one already exists", +) +def cli_provisioner_template_network_vni_add(name, vni, permit_duplicate_flag): """ Add a new network VNI to network template NAME. Networks will be added to VMs in the order they are added and displayed within the template. + + NOTE: Normally, the API prevents duplicate VNIs from being added to the same network template + by returning an error, as this requirement is very niche. If you do not desire this behaviour, + use the "-d"/"--permit-duplicate" option to bypass the check. """ params = dict() + if permit_duplicate_flag: + params["permit_duplicate"] = True retcode, retdata = pvc.lib.provisioner.template_element_add( CLI_CONFIG, name, vni, params, element_type="net", template_type="network"