Forked from
ICS Control System Infrastructure / csentry
80 commits behind the upstream repository.
-
Benjamin Bertrand authored
JIRA INFRA-1671
Benjamin Bertrand authoredJIRA INFRA-1671
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
test_web.py 28.67 KiB
# -*- coding: utf-8 -*-
"""
tests.functional.test_web
~~~~~~~~~~~~~~~~~~~~~~~~~
This module defines basic web tests.
:copyright: (c) 2017 European Spallation Source ERIC
:license: BSD 2-Clause, see LICENSE for more details.
"""
import pytest
import re
from app import models
def login(client, username, password):
data = {"username": username, "password": password}
return client.post("/user/login", data=data, follow_redirects=True)
def logout(client):
return client.get("/user/logout", follow_redirects=True)
@pytest.fixture
def logged_client(client):
login(client, "user_ro", "userro")
yield client
logout(client)
@pytest.fixture
def logged_rw_client(client):
login(client, "user_rw", "userrw")
yield client
logout(client)
@pytest.fixture
def logged_admin_client(client):
login(client, "admin", "adminpasswd")
yield client
logout(client)
@pytest.fixture
def no_login_check_client(request, app):
app.config["LOGIN_DISABLED"] = True
client = app.test_client()
# We still need to login, otherwise an AnonymousUserMixin is returned
# An AnonymousUser doesn't have all the User methods
login(client, "user_ro", "userro")
yield client
app.config["LOGIN_DISABLED"] = False
logout(client)
def test_login_logout(client):
response = login(client, "unknown", "invalid")
assert b"<title>Login - CSEntry</title>" in response.data
response = login(client, "user_rw", "invalid")
assert b"<title>Login - CSEntry</title>" in response.data
response = login(client, "user_rw", "userrw")
assert b"Control System Entry" in response.data
assert b"User RW" in response.data
response = logout(client)
assert b"<title>Login - CSEntry</title>" in response.data
def test_index(logged_client):
response = logged_client.get("/")
assert b"Control System Entry" in response.data
assert b"User RO" in response.data
@pytest.mark.parametrize("url", ["/", "/inventory/items", "/network/hosts"])
def test_protected_url_get(url, client):
response = client.get(url)
assert response.status_code == 302
assert "/user/login" in response.headers["Location"]
login(client, "user_ro", "userro")
response = client.get(url)
assert response.status_code == 200
@pytest.mark.parametrize("url", ["/network/networks", "/network/scopes"])
def test_admin_protected_url_get(url, client):
login(client, "user_rw", "userrw")
response = client.get(url)
assert response.status_code == 403
logout(client)
login(client, "admin", "adminpasswd")
response = client.get(url)
assert response.status_code == 200
@pytest.mark.parametrize(
"url", ["/inventory/_retrieve_items", "/network/_retrieve_hosts"]
)
def test_protected_url_post(url, client):
response = client.post(url)
assert response.status_code == 302
assert "/user/login" in response.headers["Location"]
login(client, "user_ro", "userro")
response = client.post(url)
assert response.status_code == 200
def test_retrieve_items(logged_client, item_factory):
response = logged_client.post("/inventory/_retrieve_items")
assert response.get_json()["data"] == []
serial_numbers = ("12345", "45678")
for sn in serial_numbers:
item_factory(serial_number=sn)
response = logged_client.post("/inventory/_retrieve_items")
items = response.get_json()["data"]
assert set(serial_numbers) == set(item["serial_number"] for item in items)
assert len(items[0]) == 18
def test_retrieve_items_pagination(logged_client, item_factory):
for sn in range(1000, 1030):
item_factory(serial_number=sn)
response = logged_client.post(
"/inventory/_retrieve_items", data={"draw": "50", "length": 10, "start": 0}
)
r = response.get_json()
assert r["draw"] == 50
assert r["recordsTotal"] == 30
assert r["recordsFiltered"] == 30
assert len(r["data"]) == 10
serial_numbers = [item["serial_number"] for item in r["data"]]
response = logged_client.post(
"/inventory/_retrieve_items", data={"draw": "51", "length": 10, "start": 10}
)
serial_numbers.extend(
[item["serial_number"] for item in response.get_json()["data"]]
)
response = logged_client.post(
"/inventory/_retrieve_items", data={"draw": "52", "length": 10, "start": 20}
)
serial_numbers.extend(
[item["serial_number"] for item in response.get_json()["data"]]
)
assert sorted(serial_numbers) == list(str(i) for i in range(1000, 1030))
def test_retrieve_items_filter(logged_client, item_factory):
for sn in range(1000, 1010):
item_factory(serial_number=sn)
response = logged_client.post(
"/inventory/_retrieve_items",
data={
"draw": "50",
"length": 20,
"start": 0,
"search[value]": "serial_number:1005",
},
)
r = response.get_json()
assert r["recordsTotal"] == 10
assert r["recordsFiltered"] == 1
assert len(r["data"]) == 1
assert r["data"][0]["serial_number"] == "1005"
def test_retrieve_items_sort(logged_client, item_factory):
serial_numbers = ["AAA001", "AAB034", "AAA100", "AAB001"]
for sn in serial_numbers:
item_factory(serial_number=sn)
response = logged_client.post(
"/inventory/_retrieve_items",
data={
"draw": "50",
"length": 20,
"start": 0,
"order[0][column]": "3",
"columns[3][data]": "serial_number",
},
)
items = response.get_json()["data"]
assert sorted(serial_numbers) == [item["serial_number"] for item in items]
response = logged_client.post(
"/inventory/_retrieve_items",
data={
"draw": "50",
"length": 20,
"start": 0,
"order[0][column]": "3",
"order[0][dir]": "desc",
"columns[3][data]": "serial_number",
},
)
items = response.get_json()["data"]
assert sorted(serial_numbers, reverse=True) == [
item["serial_number"] for item in items
]
def test_retrieve_items_case_insensitive(logged_client, model_factory, item_factory):
juniper_model = model_factory(name="Juniper")
item_factory(serial_number="BBB001", model=juniper_model)
item_factory(serial_number="ABB042")
response = logged_client.post(
"/inventory/_retrieve_items",
data={"draw": "50", "length": 20, "start": 0, "search[value]": "juniper"},
)
r = response.get_json()
assert r["recordsTotal"] == 2
assert r["recordsFiltered"] == 1
assert len(r["data"]) == 1
assert r["data"][0]["model"] == "Juniper"
def test_retrieve_items_one_word(logged_client, manufacturer_factory, item_factory):
manufacturer = manufacturer_factory(name="Concurrent Technologies")
item_factory(serial_number="AAA001", manufacturer=manufacturer)
item_factory(serial_number="ABB042")
response = logged_client.post(
"/inventory/_retrieve_items",
data={"draw": "50", "length": 20, "start": 0, "search[value]": "concurrent"},
)
r = response.get_json()
assert r["recordsTotal"] == 2
assert r["recordsFiltered"] == 1
assert len(r["data"]) == 1
assert r["data"][0]["manufacturer"] == "Concurrent Technologies"
def test_generate_random_mac(logged_client):
response = logged_client.get("/network/_generate_random_mac")
mac = response.get_json()["data"]["mac"]
assert re.match("^(?:[0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$", mac) is not None
assert mac.startswith("02:42:42")
def test_retrieve_hosts(logged_client, interface_factory, host_factory):
response = logged_client.post("/network/_retrieve_hosts")
assert response.get_json()["data"] == []
host1 = host_factory(name="host1")
host2 = host_factory(name="host2")
interface_factory(name="host1", host=host1)
interface_factory(name="host2", host=host2)
response = logged_client.post("/network/_retrieve_hosts")
hosts = response.get_json()["data"]
assert {host1.name, host2.name} == set(host["name"] for host in hosts)
assert len(hosts[0]) == 15
assert len(hosts[0]["interfaces"][0]) == 15
def test_retrieve_hosts_by_ip(logged_client, interface_factory):
interface1 = interface_factory()
interface_factory()
response = logged_client.post(
"/network/_retrieve_hosts",
data={"draw": "50", "length": 20, "start": 0, "search[value]": interface1.ip},
)
r = response.get_json()
assert r["recordsTotal"] == 2
assert r["recordsFiltered"] == 1
assert len(r["data"]) == 1
assert r["data"][0]["name"] == interface1.host.name
def test_delete_interface_from_index(
no_login_check_client, interface_factory, host_factory
):
host1 = host_factory(name="host1")
interface_factory(name="host1", host=host1)
interface2 = interface_factory(name="host1b", host=host1)
# The interface is in the index
instances, nb = models.Host.search("host1b")
assert list(instances) == [host1]
assert nb == 1
# Delete the interface
response = no_login_check_client.post(
"/network/interfaces/delete", data={"interface_id": interface2.id}
)
assert response.status_code == 302
# It's not in the database anymore
assert models.Interface.query.get(interface2.id) is None
# Neither in the index
instances, nb = models.Host.search("host1b")
assert list(instances) == []
assert nb == 0
# But host1 is still in the index
instances, nb = models.Host.search("host1")
assert list(instances) == [host1]
assert nb == 1
def test_edit_item_comment_in_index(
logged_rw_client, item_factory, item_comment_factory
):
item1 = item_factory(ics_id="AAA001")
comment = item_comment_factory(body="Hello", item_id=item1.id)
assert item1.comments == [comment]
# Edit the comment
body = "Hello world!"
response = logged_rw_client.post(
f"/inventory/items/comment/edit/{comment.id}", data={"body": body}
)
assert response.status_code == 302
# The comment was updated in the database
updated_comment = models.ItemComment.query.get(comment.id)
assert updated_comment.body == body
# And in the index
instances, nb = models.Item.search("world")
assert list(instances) == [item1]
def test_create_host(client, network_scope_factory, network_factory, device_type):
scope = network_scope_factory(name="ProdNetworks", supernet="192.168.0.0/16")
network = network_factory(
address="192.168.1.0/24",
first_ip="192.168.1.10",
last_ip="192.168.1.250",
scope=scope,
)
name = "myhost"
ip = "192.168.1.11"
mac = "02:42:42:45:3c:89"
form = {
"network_id": network.id,
"name": name,
"device_type_id": device_type.id,
"is_ioc": False,
"ip": ip,
"mac": mac,
"description": "test",
"ansible_vars": "foo: hello",
"ansible_groups": [],
"random_mac": False,
"cnames_string": "",
}
# Invalid network_id with user_lab user
# (form validation error because the network is not part of the choices
# for this user)
login(client, "user_lab", "userlab")
response = client.post(f"/network/hosts/create", data=form)
assert response.status_code == 200
# The host wasn't created
assert models.Host.query.filter_by(name=name).first() is None
logout(client)
# Success with user_prod user
login(client, "user_prod", "userprod")
response = client.post(f"/network/hosts/create", data=form, follow_redirects=True)
assert response.status_code == 200
# The host was created
assert b"created!" in response.data
assert b"View host" in response.data
host = models.Host.query.filter_by(name=name).first()
assert host is not None
assert host.interfaces[0].ip == ip
assert host.interfaces[0].mac == mac
assert host.interfaces[0].name == name
def test_create_host_invalid_fields(
session, client, network_scope_factory, network_factory, device_type
):
scope = network_scope_factory(name="ProdNetworks", supernet="192.168.0.0/16")
network = network_factory(
address="192.168.1.0/24",
first_ip="192.168.1.10",
last_ip="192.168.1.250",
scope=scope,
)
name = "myhost"
ip = "192.168.1.11"
mac = "02:42:42:45:3c:89"
form = {
"network_id": network.id,
"name": name,
"device_type_id": device_type.id,
"is_ioc": False,
"ip": ip,
"mac": mac,
"description": "test",
"ansible_vars": "",
"ansible_groups": [],
"random_mac": False,
"cnames_string": "",
}
login(client, "user_prod", "userprod")
# Invalid mac
data = form.copy()
data["mac"] = "ea:ea:60:45:a8:96:se"
response = client.post(f"/network/hosts/create", data=data, follow_redirects=True)
assert response.status_code == 200
assert b"Register new host" in response.data
assert b"Invalid MAC address" in response.data
# An exception was raised during validation (on Select in the Unique Validator),
# so we need to rollback.
session.rollback()
# Invalid hostname
data = form.copy()
data["name"] = "invalid_host"
response = client.post(f"/network/hosts/create", data=data, follow_redirects=True)
assert response.status_code == 200
assert b"Register new host" in response.data
assert b"Invalid input" in response.data
def test_create_interface(
client, host_factory, network_scope_factory, network_factory, interface_factory
):
host = host_factory(name="myhost")
scope = network_scope_factory(name="ProdNetworks", supernet="192.168.0.0/16")
network1 = network_factory(scope=scope)
interface_factory(network=network1, host=host)
network2 = network_factory(
address="192.168.2.0/24",
first_ip="192.168.2.10",
last_ip="192.168.2.250",
scope=scope,
)
name = host.name + "-2"
ip = "192.168.2.11"
mac = "02:42:42:46:3c:75"
form = {
"host_id": host.id,
"interface_name": name,
"network_id": network2.id,
"random_mac": False,
"ip": ip,
"mac": mac,
"cnames_string": "",
}
# Permission denied
# user_lab doesn't have permissions for the host domain: prod.example.org
login(client, "user_lab", "userlab")
response = client.post(f"/network/interfaces/create/{host.name}", data=form)
assert response.status_code == 403
# The host wasn't created
assert models.Interface.query.filter_by(name=name).first() is None
logout(client)
# Success with user_prod user
login(client, "user_prod", "userprod")
response = client.post(f"/network/interfaces/create/{host.name}", data=form)
assert response.status_code == 302
# The interface was created
interface = models.Interface.query.filter_by(name=name).first()
assert interface is not None
assert interface.ip == ip
assert interface.mac == mac
assert interface.name == name
assert interface.host == host
def test_add_interface_to_empty_host(
client, host_factory, network_scope_factory, network_factory
):
host = host_factory(name="myhost")
scope = network_scope_factory(name="ProdNetworks", supernet="192.168.0.0/16")
network = network_factory(
address="192.168.2.0/24",
first_ip="192.168.2.10",
last_ip="192.168.2.250",
scope=scope,
)
name = host.name
ip = "192.168.2.11"
mac = "02:42:42:46:3c:75"
form = {
"host_id": host.id,
"interface_name": name,
"network_id": network.id,
"random_mac": False,
"ip": ip,
"mac": mac,
"cnames_string": "",
}
# user_lab doesn't have permissions for the network domain: prod.example.org
# form validation will fail because the network_id won't be in the choices
login(client, "user_lab", "userlab")
response = client.post(f"/network/interfaces/create/{host.name}", data=form)
assert response.status_code == 200
# The host wasn't created
assert models.Interface.query.filter_by(name=name).first() is None
logout(client)
# Success with user_prod user
login(client, "user_prod", "userprod")
response = client.post(f"/network/interfaces/create/{host.name}", data=form)
assert response.status_code == 302
# The interface was created
interface = models.Interface.query.filter_by(name=name).first()
assert interface.ip == ip
assert interface.mac == mac
assert interface.name == name
assert interface.host == host
def check_vm_creation_response(response, success=True):
assert response.status_code == 200
assert (b"View task" in response.data) is success
assert (b"View host" in response.data) is not success
assert (b"Please contact an admin user" in response.data) is not success
def test_create_vm(
client,
network_scope_factory,
network_factory,
device_type_factory,
host_factory,
interface_factory,
):
virtualmachine = device_type_factory(name="VirtualMachine")
scope_prod = network_scope_factory(name="ProdNetworks")
scope_lab = network_scope_factory(name="LabNetworks")
network_prod = network_factory(scope=scope_prod)
network_lab = network_factory(scope=scope_lab)
vm_prod = host_factory(device_type=virtualmachine)
interface_factory(name=vm_prod.name, host=vm_prod, network=network_prod)
vioc_prod = host_factory(device_type=virtualmachine, is_ioc=True)
interface_factory(name=vioc_prod.name, host=vioc_prod, network=network_prod)
vm_lab = host_factory(device_type=virtualmachine)
interface_factory(name=vm_lab.name, host=vm_lab, network=network_lab)
vioc_lab = host_factory(device_type=virtualmachine, is_ioc=True)
interface_factory(name=vioc_lab.name, host=vioc_lab, network=network_lab)
form = {"cores": 1, "memory": 4, "disk": 15, "osversion": "centos7"}
# User has access to the lab networks and can create VM and VIOC there
login(client, "user_lab", "userlab")
response = client.post(
f"/network/hosts/view/{vm_prod.name}", data=form, follow_redirects=True
)
check_vm_creation_response(response, success=False)
response = client.post(
f"/network/hosts/view/{vioc_prod.name}", data=form, follow_redirects=True
)
check_vm_creation_response(response, success=False)
response = client.post(
f"/network/hosts/view/{vm_lab.name}", data=form, follow_redirects=True
)
check_vm_creation_response(response, success=True)
response = client.post(
f"/network/hosts/view/{vioc_lab.name}", data=form, follow_redirects=True
)
check_vm_creation_response(response, success=True)
logout(client)
# User has access to the prod networks but can only create VIOC due to ALLOWED_VM_CREATION_DOMAINS
login(client, "user_prod", "userprod")
response = client.post(
f"/network/hosts/view/{vm_prod.name}", data=form, follow_redirects=True
)
check_vm_creation_response(response, success=False)
response = client.post(
f"/network/hosts/view/{vioc_prod.name}", data=form, follow_redirects=True
)
check_vm_creation_response(response, success=True)
response = client.post(
f"/network/hosts/view/{vm_lab.name}", data=form, follow_redirects=True
)
check_vm_creation_response(response, success=False)
response = client.post(
f"/network/hosts/view/{vioc_lab.name}", data=form, follow_redirects=True
)
check_vm_creation_response(response, success=False)
def test_delete_host_as_admin(logged_admin_client, host_factory, user_factory):
# admin can delete any host
admin = models.User.query.filter_by(username="admin").first()
user1 = user_factory(username="user1")
host1 = host_factory(name="host1", user=admin)
host2 = host_factory(name="host2", user=user1)
assert len(models.Host.query.all()) == 2
response = logged_admin_client.post(
"/network/hosts/delete", data={"host_id": host1.id}
)
assert response.status_code == 302
response = logged_admin_client.post(
"/network/hosts/delete", data={"host_id": host2.id}
)
assert response.status_code == 302
assert len(models.Host.query.all()) == 0
def test_delete_host_as_normal_user(logged_rw_client, host_factory, user_factory):
# a normal user can only delete its own hosts
user_rw = models.User.query.filter_by(username="user_rw").first()
user1 = user_factory(username="user1")
host1 = host_factory(name="host1", user=user_rw)
host2 = host_factory(name="host2", user=user1)
assert len(models.Host.query.all()) == 2
# user_rw can delete its host
response = logged_rw_client.post(
"/network/hosts/delete", data={"host_id": host1.id}
)
assert response.status_code == 302
# user_rw can't delete host owned by user1
response = logged_rw_client.post(
"/network/hosts/delete", data={"host_id": host2.id}
)
assert response.status_code == 403
assert len(models.Host.query.all()) == 1
def test_create_network_scope(logged_admin_client, domain_factory):
domain = domain_factory(name="prod.example.org")
name = "MyNetworks"
first_vlan = 200
last_vlan = 300
supernet = "192.168.0.0/16"
form = {
"name": name,
"first_vlan": first_vlan,
"last_vlan": last_vlan,
"supernet": supernet,
"domain_id": domain.id,
}
response = logged_admin_client.post("/network/scopes/create", data=form)
assert response.status_code == 302
# The network scope was created
scope = models.NetworkScope.query.filter_by(name=name).first()
assert scope is not None
assert scope.name == name
assert scope.first_vlan == first_vlan
assert scope.last_vlan == last_vlan
assert scope.supernet == supernet
def test_create_network_scope_no_vlan(logged_admin_client, domain_factory):
domain = domain_factory(name="lab.example.org")
name = "NoVlan"
supernet = "192.168.0.0/16"
form = {
"name": name,
"first_vlan": "",
"last_vlan": None,
"supernet": supernet,
"domain_id": domain.id,
}
response = logged_admin_client.post("/network/scopes/create", data=form)
assert response.status_code == 302
# The network scope was created
scope = models.NetworkScope.query.filter_by(name=name).first()
assert scope is not None
assert scope.name == name
assert scope.first_vlan is None
assert scope.last_vlan is None
assert scope.supernet == supernet
def test_create_network(logged_admin_client, domain_factory, network_scope_factory):
domain = domain_factory(name="lab.example.org")
scope = network_scope_factory(
name="MyNetworks",
first_vlan=100,
last_vlan=200,
supernet="192.168.0.0/16",
domain_id=domain.id,
)
vlan_name = "my-network"
form = {
"scope_id": scope.id,
"vlan_name": vlan_name,
"vlan_id": 101,
"address": "192.168.0.0/24",
"first_ip": "192.168.0.11",
"last_ip": "192.168.0.249",
"gateway": "192.168.0.254",
"domain_id": domain.id,
"admin_only": False,
}
response = logged_admin_client.post("/network/networks/create", data=form)
assert response.status_code == 302
# The network was created
network = models.Network.query.filter_by(vlan_name=vlan_name).first()
assert network is not None
assert network.vlan_name == vlan_name
assert network.address == form["address"]
assert network.vlan_id == form["vlan_id"]
def test_create_network_no_vlan(
logged_admin_client, domain_factory, network_scope_factory
):
domain = domain_factory(name="lab.example.org")
scope = network_scope_factory(
name="NoVlanNetworks",
first_vlan=None,
last_vlan=None,
supernet="192.168.0.0/16",
domain_id=domain.id,
)
vlan_name = "my-network"
form = {
"scope_id": scope.id,
"vlan_name": vlan_name,
"vlan_id": "",
"address": "192.168.0.0/24",
"first_ip": "192.168.0.11",
"last_ip": "192.168.0.249",
"gateway": "192.168.0.254",
"domain_id": domain.id,
"admin_only": False,
}
response = logged_admin_client.post("/network/networks/create", data=form)
assert response.status_code == 302
# The network was created
network = models.Network.query.filter_by(vlan_name=vlan_name).first()
assert network is not None
assert network.vlan_name == vlan_name
assert network.address == form["address"]
assert network.vlan_id is None
def test_create_item_invalid_ics_id(logged_rw_client):
ics_id = "AAA1100"
form = {"ics_id": ics_id, "serial_number": "12345"}
response = logged_rw_client.post(
f"/inventory/items/create", data=form, follow_redirects=True
)
assert response.status_code == 200
assert b"Register new item" in response.data
assert b"The ICS id shall be composed of 3 letters and 3 digits" in response.data
def test_create_item_with_stack_member(
host_factory, device_type_factory, item_factory, logged_rw_client
):
# Test for JIRA INFRA-1648
network_type = device_type_factory(name="NETWORK")
host = host_factory(device_type=network_type)
item1 = item_factory(ics_id="AAA001", host=host, stack_member=0)
ics_id = "AAA042"
form = {
"ics_id": ics_id,
"serial_number": "12345",
"host_id": host.id,
"stack_member": 1,
}
response = logged_rw_client.post(f"/inventory/items/create", data=form)
assert response.status_code == 302
item2 = models.Item.query.filter_by(ics_id=ics_id).first()
assert host.stack_members() == [item1, item2]
def test_create_item_with_host_and_no_stack_member(
host_factory, device_type_factory, item_factory, logged_rw_client
):
network_type = device_type_factory(name="NETWORK")
host = host_factory(device_type=network_type)
ics_id = "AAA042"
form = {
"ics_id": ics_id,
"serial_number": "12345",
"host_id": host.id,
"stack_member": "",
}
response = logged_rw_client.post(f"/inventory/items/create", data=form)
assert response.status_code == 302
item = models.Item.query.filter_by(ics_id=ics_id).first()
assert item.host == host
assert item.stack_member is None
def test_ansible_groups_no_recursive_dependency(
ansible_group_factory, logged_admin_client
):
group3 = ansible_group_factory()
group2 = ansible_group_factory(children=[group3])
group1 = ansible_group_factory(children=[group2])
form = {"name": group3.name, "type": group3.type, "children": [group1.id]}
response = logged_admin_client.post(
f"/network/groups/edit/{group3.name}", data=form
)
assert response.status_code == 200
assert b"creates a recursive dependency loop" in response.data
def test_create_network_overlapping(
network_scope_factory, network_factory, logged_admin_client
):
scope = network_scope_factory(
first_vlan=3800, last_vlan=4000, supernet="172.30.0.0/16"
)
network_factory(
vlan_name="network1",
vlan_id=3800,
address="172.30.0.0/23",
first_ip="172.30.0.3",
last_ip="172.30.1.240",
scope=scope,
)
form = {
"vlan_name": "network2",
"vlan_id": 3842,
"scope_id": scope.id,
"address": "172.30.1.0/24",
"first_ip": "172.30.1.5",
"last_ip": "172.30.1.245",
"gateway": "172.30.1.248",
"domain_id": scope.domain_id,
}
response = logged_admin_client.post("/network/networks/create", data=form)
assert response.status_code == 200
assert b"172.30.1.0/24 overlaps network1 (172.30.0.0/23)" in response.data
def test_create_network_scope_overlapping(network_scope_factory, logged_admin_client):
scope1 = network_scope_factory(
name="scope1", first_vlan=3800, last_vlan=4000, supernet="172.30.0.0/16"
)
form = {
"name": "scope2",
"first_vlan": 200,
"last_vlan": 500,
"supernet": "172.30.200.0/22",
"domain_id": scope1.domain_id,
}
response = logged_admin_client.post("/network/scopes/create", data=form)
assert response.status_code == 200
assert b"172.30.200.0/22 overlaps scope1 (172.30.0.0/16)" in response.data
def test_view_network_restriction(client, network_scope_factory, network_factory):
scope = network_scope_factory(name="ProdNetworks", supernet="192.168.0.0/16")
network = network_factory(
address="192.168.1.0/24",
first_ip="192.168.1.10",
last_ip="192.168.1.250",
scope=scope,
)
# user_lab doesn't have the permissions to see that network
login(client, "user_lab", "userlab")
response = client.get(f"/network/networks/view/{network}")
assert response.status_code == 403
logout(client)
# Success with user_prod user
login(client, "user_prod", "userprod")
response = client.get(f"/network/networks/view/{network}")
assert response.status_code == 200