From c5d118b7f2454103176ae9f47867722b2b42a72d Mon Sep 17 00:00:00 2001 From: Juliana Cardozo <93846188+boubeejul@users.noreply.github.com> Date: Tue, 26 May 2026 16:44:43 +0000 Subject: [PATCH] add PATCH to /v3/vlan/ --- docs/vlan/url-api-v3-vlan.rst | 1 + docs/vlan/url-api-v3-vlan/patch.rst | 37 +++++++++++++++++++++++ networkapi/api_vlan/facade/v3.py | 16 ++++++++++ networkapi/api_vlan/specs/vlan_patch.json | 28 +++++++++++++++++ networkapi/api_vlan/views/v3.py | 19 ++++++++++++ networkapi/settings.py | 4 +++ networkapi/vlan/models.py | 28 +++++++++++++++++ 7 files changed, 133 insertions(+) create mode 100644 docs/vlan/url-api-v3-vlan/patch.rst create mode 100644 networkapi/api_vlan/specs/vlan_patch.json diff --git a/docs/vlan/url-api-v3-vlan.rst b/docs/vlan/url-api-v3-vlan.rst index 9f8a9f4b1..dcf1d9a99 100644 --- a/docs/vlan/url-api-v3-vlan.rst +++ b/docs/vlan/url-api-v3-vlan.rst @@ -6,3 +6,4 @@ url-api-v3-vlan/post url-api-v3-vlan/put url-api-v3-vlan/delete + url-api-v3-vlan/patch diff --git a/docs/vlan/url-api-v3-vlan/patch.rst b/docs/vlan/url-api-v3-vlan/patch.rst new file mode 100644 index 000000000..5731db99a --- /dev/null +++ b/docs/vlan/url-api-v3-vlan/patch.rst @@ -0,0 +1,37 @@ +PATCH +##### + +.. _url-api-v3-vlan-patch-partially-update-list-vlans: + +Partially updating list of Vlans in database +******************************************** + +URL:: + + /api/v3/vlan/ + +Request body: + +.. code-block:: json + + { + "vlans": [{ + "id": [integer], + "active": [boolean] + },..] + } + +Request Example: + +.. code-block:: json + + { + "vlans": [{ + "id": 1, + "active": false + }] + } + +In Vlan PATCH request, you only need to specify the fields you want to change. For now, only **active** field can be changed. + +* **active** - If not specified, Vlan will be the same as before. If specified, it will be updated with the new value. diff --git a/networkapi/api_vlan/facade/v3.py b/networkapi/api_vlan/facade/v3.py index b109665d5..74a146260 100644 --- a/networkapi/api_vlan/facade/v3.py +++ b/networkapi/api_vlan/facade/v3.py @@ -70,6 +70,22 @@ def update_vlan(vlan, user): return vlan_obj +def patch_vlan(vlan, user): + """Patch vlan.""" + + try: + vlan_obj = get_vlan_by_id(vlan.get('id')) + vlan_obj.patch_v3(vlan, user) + except ObjectDoesNotExistException, e: + raise ObjectDoesNotExistException(str(e)) + except (VlanError, VlanErrorV3, ValidationAPIException), e: + raise ValidationAPIException(str(e)) + except (Exception, NetworkAPIException), e: + raise NetworkAPIException(str(e)) + else: + return vlan_obj + + def create_vlan(vlan, user): """Create vlan.""" diff --git a/networkapi/api_vlan/specs/vlan_patch.json b/networkapi/api_vlan/specs/vlan_patch.json new file mode 100644 index 000000000..fdf8c0126 --- /dev/null +++ b/networkapi/api_vlan/specs/vlan_patch.json @@ -0,0 +1,28 @@ +{ + "title": "Vlan Patch", + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "required": [ + "vlans" + ], + "properties": { + "vlans": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "active": { + "type": "boolean" + } + }, + "required": [ + "id" + ], + "additionalProperties": false + } + } + } +} \ No newline at end of file diff --git a/networkapi/api_vlan/views/v3.py b/networkapi/api_vlan/views/v3.py index cb06a8ee1..9ac4c39b5 100644 --- a/networkapi/api_vlan/views/v3.py +++ b/networkapi/api_vlan/views/v3.py @@ -172,6 +172,25 @@ def put(self, request, *args, **kwargs): return Response(response, status=status.HTTP_202_ACCEPTED) + @logs_method_apiview + @raise_json_validate('vlan_patch') + @permission_classes_apiview((IsAuthenticated, permissions.Write)) + @permission_obj_apiview([permissions.write_obj_permission]) + @commit_on_success + def patch(self, request, *args, **kwargs): + """Patches list of vlans.""" + + data = request.DATA + + json_validate(SPECS.get('vlan_patch')).validate(data) + + response = list() + for vlan in data['vlans']: + vl = facade.patch_vlan(vlan, request.user) + response.append({'id': vl.id, 'active': vl.ativada}) + + return Response(response, status=status.HTTP_200_OK) + @logs_method_apiview @raise_json_validate('') @permission_classes_apiview((IsAuthenticated, permissions.Write)) diff --git a/networkapi/settings.py b/networkapi/settings.py index ea5e647d1..a9d909b2c 100644 --- a/networkapi/settings.py +++ b/networkapi/settings.py @@ -518,6 +518,10 @@ def local_files(path): PROJECT_ROOT_PATH, 'api_vlan/specs/vlan_post.json' ), + 'vlan_patch': os.path.join( + PROJECT_ROOT_PATH, + 'api_vlan/specs/vlan_patch.json' + ), 'vlan_put': os.path.join( PROJECT_ROOT_PATH, 'api_vlan/specs/vlan_put.json' diff --git a/networkapi/vlan/models.py b/networkapi/vlan/models.py index 666e63f29..2a25c8c16 100644 --- a/networkapi/vlan/models.py +++ b/networkapi/vlan/models.py @@ -1260,6 +1260,34 @@ def update_v3(self, vlan, user): return self + def patch_v3(self, vlan, user): + """Patch vlan.""" + + try: + self.ativada = vlan.get('active', self.ativada) + + except Exception, e: + raise VlanErrorV3(e) + + else: + # Prepare locks for vlan + locks_name = [LOCK_VLAN % self.id] + locks_list = create_lock_with_blocking(locks_name) + + try: + # validate name and number + #self.validate_v3() + self.save() + + except Exception, e: + raise VlanErrorV3(e) + + finally: + # Destroy locks + destroy_lock(locks_list) + + return self + def delete_v3(self): ogp_models = get_app('api_ogp', 'models') ipcantberemovedfromvip = get_model('ip', 'IpCantBeRemovedFromVip')