From d10e0ee60ef48168197969d9f30785bdfe671a8c Mon Sep 17 00:00:00 2001
From: Benjamin Bertrand <benjamin.bertrand@ess.eu>
Date: Wed, 8 Jul 2020 09:09:32 +0200
Subject: [PATCH] Add API endpoint to patch network scope

JIRA INFRA-2316
---
 app/api/network.py           | 26 +++++++++++++++++++++++++
 tests/functional/test_api.py | 37 ++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/app/api/network.py b/app/api/network.py
index 0e7d582..5cca239 100644
--- a/app/api/network.py
+++ b/app/api/network.py
@@ -64,6 +64,32 @@ def delete_scope(scope_id):
     return utils.delete_generic_model(models.NetworkScope, scope_id)
 
 
+@bp.route("/scopes/<int:scope_id>", methods=["PATCH"])
+@login_groups_accepted("admin")
+def patch_scope(scope_id):
+    r"""Patch an existing network scope
+
+    .. :quickref: Network; Update an existing network scope
+
+    :param scope_id: network scope primary key
+    :jsonparam name: network scope name
+    :jsonparam description: description
+    :jsonparam first_vlan: network scope first vlan
+    :jsonparam last_vlan: network scope last vlan
+    :jsonparam supernet: network scope supernet
+    :jsonparam domain: name of the default domain
+    """
+    allowed_fields = (
+        ("name", str, None),
+        ("description", str, None),
+        ("first_vlan", int, None),
+        ("last_vlan", int, None),
+        ("supernet", str, None),
+        ("domain", models.Domain, "name"),
+    )
+    return utils.update_generic_model(models.NetworkScope, scope_id, allowed_fields)
+
+
 @bp.route("/networks")
 @login_groups_accepted("admin", "network")
 def get_networks():
diff --git a/tests/functional/test_api.py b/tests/functional/test_api.py
index 5b70c7c..7001ae7 100644
--- a/tests/functional/test_api.py
+++ b/tests/functional/test_api.py
@@ -2752,6 +2752,43 @@ def test_patch_network_invalid_domain(client, network_factory, admin_token):
     check_response_message(response, "foo is not a valid domain", 400)
 
 
+@pytest.mark.parametrize(
+    "field,value",
+    [
+        ("name", "new-name"),
+        ("description", "This is a test"),
+        ("first_vlan", 110),
+        ("last_vlan", 300),
+        ("supernet", "172.16.0.0/16"),
+    ],
+)
+def test_patch_network_scope(client, network_scope_factory, admin_token, field, value):
+    scope = network_scope_factory(first_vlan=100, last_vlan=400)
+    data = {field: value}
+    response = patch(
+        client, f"{API_URL}/network/scopes/{scope.id}", data=data, token=admin_token
+    )
+    assert response.status_code == 200
+    assert response.get_json()[field] == value
+    updated_scope = models.NetworkScope.query.get(scope.id)
+    assert getattr(updated_scope, field) == value
+
+
+def test_patch_network_scope_domain(
+    client, network_scope_factory, domain_factory, admin_token
+):
+    scope = network_scope_factory()
+    domain = domain_factory(name="foo.example.org")
+    data = {"domain": domain.name}
+    response = patch(
+        client, f"{API_URL}/network/scopes/{scope.id}", data=data, token=admin_token
+    )
+    assert response.status_code == 200
+    assert response.get_json()["domain"] == domain.name
+    updated_scope = models.NetworkScope.query.get(scope.id)
+    assert updated_scope.domain == domain
+
+
 def test_delete_item_success(client, admin_token, item):
     check_delete_success(
         client, admin_token, item, "inventory/items", models.Item,
-- 
GitLab