Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/add groups and hosts separately #38

Merged
merged 1 commit into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions backend/SC4SNMP_UI_backend/common/backend_ui_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,16 @@ def ui2backend(self, document: dict, **kwargs):
raise ValueError("No delete provided")

def backend2ui(self, document: dict, **kwargs):
if "inventory_type" not in kwargs.keys():
raise ValueError("No inventory_type provided")
profiles_mongo = document['profiles']
if len(profiles_mongo) > 0:
profiles = profiles_mongo.split(";")
else:
profiles = []
result = {
'_id': str(document["_id"]),
'inventoryType': kwargs['inventory_type'],
'address': document['address'],
'port': str(document['port']),
'version': document['version'],
Expand Down
33 changes: 22 additions & 11 deletions backend/SC4SNMP_UI_backend/common/inventory_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ class HostConfiguration(Enum):
SINGLE = 1
GROUP = 2

def get_inventory_type(document):
if list(mongo_groups.find({document["address"]: {"$exists": 1}})):
result = "Group"
else:
result = "Host"
return result

def update_profiles_in_inventory(profile_to_search: str, process_record: Callable, **kwargs):
"""
When profile is edited, then in some cases inventory records using this profile should be updated.
Expand All @@ -25,7 +32,7 @@ def update_profiles_in_inventory(profile_to_search: str, process_record: Callabl
inventory_records = list(mongo_inventory.find({"profiles": {"$regex": f'.*{profile_to_search}.*'}}))
for record in inventory_records:
record_id = record["_id"]
record_updated = inventory_conversion.backend2ui(record)
record_updated = inventory_conversion.backend2ui(record, inventory_type=None) # inventory_type isn't used
index_to_update = record_updated["profiles"].index(profile_to_search)
record_updated = process_record(index_to_update, record_updated, kwargs)
record_updated = inventory_conversion.ui2backend(record_updated, delete=False)
Expand Down Expand Up @@ -92,11 +99,15 @@ def _is_host_configured(self, address: str, port: str):
def add_single_host(self, address, port, device_object=None, add: bool=True):
host_configured, deleted_inventory_record, host_configuration, existing_id_string, group_name = \
self._is_host_configured(address, port)
groups = list(mongo_groups.find({address: {"$exists": True}}))
if host_configured:
host_location_message = "as a single host in the inventory" if host_configuration == HostConfiguration.SINGLE else \
host_location_message = "in the inventory" if host_configuration == HostConfiguration.SINGLE else \
f"in group {group_name}"
message = f"Host {address}:{port} already exists {host_location_message}. Record was not added."
host_added = False
elif groups:
message = f"There is a group with the same name configured. Record {address} can't be added as a single host."
host_added = False
else:
if add and device_object is not None:
self._mongo_inventory.insert_one(device_object)
Expand Down Expand Up @@ -130,7 +141,7 @@ def edit_single_host(self, address: str, port: str, host_id: str, device_object=
if len(deleted_inventory_record) > 0:
self._mongo_inventory.delete_one({"_id": deleted_inventory_record[0]["_id"]})
else:
host_location_message = "as a single host in the inventory" if host_configuration == HostConfiguration.SINGLE else \
host_location_message = "in the inventory" if host_configuration == HostConfiguration.SINGLE else \
f"in group {group_name}"
message = f"Host {address}:{port} already exists {host_location_message}. Record was not edited."
host_edited = False
Expand Down Expand Up @@ -191,12 +202,9 @@ def add_group_to_inventory(self, group_name: str, group_port: str, group_object=
existing_inventory_record = list(self._mongo_inventory.find({'address': group_name, "delete": False}))
deleted_inventory_record = list(self._mongo_inventory.find({'address': group_name, "delete": True}))
group = list(self._mongo_groups.find({group_name: {"$exists": 1}}))
if len(group) == 0 and len(existing_inventory_record) == 0:
group_added = True
message = f"Group {group_name} doesn't exist in the configuration. Treating {group_name} as a hostname."
elif len(group) == 0 and len(existing_inventory_record) > 0:
if len(group) == 0:
group_added = False
message = f"{group_name} has already been configured. Record was not added."
message = f"Group {group_name} doesn't exist in the configuration. Record was not added."
elif len(existing_inventory_record) > 0:
group_added = False
message = f"Group {group_name} has already been added to the inventory. Record was not added."
Expand Down Expand Up @@ -229,8 +237,11 @@ def edit_group_in_inventory(self, group_name: str, group_id: str, group_object=N
group_id = ObjectId(group_id)
existing_inventory_record = list(self._mongo_inventory.find({'address': group_name, "delete": False}))
deleted_inventory_record = list(self._mongo_inventory.find({'address': group_name, "delete": True}))

if len(existing_inventory_record) == 0 or (len(existing_inventory_record) > 0 and existing_inventory_record[0]["_id"] == group_id):
group = list(self._mongo_groups.find({group_name: {"$exists": 1}}))
if len(group) == 0:
group_edited = False
message = f"Group {group_name} doesn't exist in the configuration. Record was not edited."
elif len(existing_inventory_record) == 0 or (len(existing_inventory_record) > 0 and existing_inventory_record[0]["_id"] == group_id):
message = "success"
group_edited = True
if edit and group_object is not None:
Expand All @@ -249,7 +260,7 @@ def edit_group_in_inventory(self, group_name: str, group_id: str, group_object=N
if len(deleted_inventory_record) > 0:
self._mongo_inventory.delete_one({"_id": deleted_inventory_record[0]["_id"]})
else:
message = f"Group wit name {group_name} already exists. Record was not edited."
message = f"Group with name {group_name} already exists. Record was not edited."
group_edited = False

return group_edited, message
13 changes: 11 additions & 2 deletions backend/SC4SNMP_UI_backend/groups/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from SC4SNMP_UI_backend.common.backend_ui_conversions import GroupConversion, GroupDeviceConversion, InventoryConversion, \
get_group_or_profile_name_from_backend
from copy import copy
from SC4SNMP_UI_backend.common.inventory_utils import HandleNewDevice
from SC4SNMP_UI_backend.common.inventory_utils import HandleNewDevice, get_inventory_type

groups_blueprint = Blueprint('groups_blueprint', __name__)

Expand Down Expand Up @@ -35,6 +35,10 @@ def add_group_record():
if len(same_name_groups) > 0:
result = jsonify(
{"message": f"Group with name {group_obj['groupName']} already exists. Group was not added."}), 400
elif list(mongo_inventory.find({"address": group_obj['groupName'], "delete": False})):
result = jsonify(
{"message": f"In the inventory there is a record with name {group_obj['groupName']}. Group was not added."}
), 400
else:
group_obj = group_conversion.ui2backend(group_obj)
mongo_groups.insert_one(group_obj)
Expand All @@ -50,6 +54,10 @@ def update_group(group_id):
if len(same_name_groups) > 0:
result = jsonify(
{"message": f"Group with name {group_obj['groupName']} already exists. Group was not edited."}), 400
elif list(mongo_inventory.find({"address": group_obj['groupName'], "delete": False})):
result = jsonify(
{"message": f"In the inventory there is a record with name {group_obj['groupName']}. Group was not edited."}
), 400
else:
old_group = list(mongo_groups.find({'_id': ObjectId(group_id)}))[0]
old_group_name = get_group_or_profile_name_from_backend(old_group)
Expand Down Expand Up @@ -110,7 +118,8 @@ def get_devices_of_group(group_id, page_num, dev_per_page):
def get_group_config_from_inventory(group_name):
group_from_inventory = list(mongo_inventory.find({"address": group_name, "delete": False}))
if len(group_from_inventory) > 0:
result = jsonify(inventory_conversion.backend2ui(group_from_inventory[0])), 200
inventory_type = get_inventory_type(group_from_inventory[0])
result = jsonify(inventory_conversion.backend2ui(group_from_inventory[0], inventory_type=inventory_type)), 200
else:
result = "", 204
return result
Expand Down
18 changes: 9 additions & 9 deletions backend/SC4SNMP_UI_backend/inventory/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
from flask_cors import cross_origin
from SC4SNMP_UI_backend import mongo_client
from SC4SNMP_UI_backend.common.backend_ui_conversions import InventoryConversion
from SC4SNMP_UI_backend.common.inventory_utils import HandleNewDevice
from SC4SNMP_UI_backend.common.inventory_utils import HandleNewDevice, get_inventory_type

inventory_blueprint = Blueprint('inventory_blueprint', __name__)

inventory_conversion = InventoryConversion()
mongo_groups = mongo_client.sc4snmp.groups_ui
mongo_inventory = mongo_client.sc4snmp.inventory_ui


@inventory_blueprint.route('/inventory/<page_num>/<dev_per_page>')
@cross_origin()
def get_inventory_list(page_num, dev_per_page):
Expand All @@ -22,7 +21,8 @@ def get_inventory_list(page_num, dev_per_page):
inventory = list(mongo_inventory.find({"delete": False}).skip(skips).limit(dev_per_page))
inventory_list = []
for inv in inventory:
inventory_list.append(inventory_conversion.backend2ui(inv))
inventory_type = get_inventory_type(inv)
inventory_list.append(inventory_conversion.backend2ui(inv, inventory_type=inventory_type))
return jsonify(inventory_list)


Expand All @@ -37,9 +37,10 @@ def get_inventory_count():
@cross_origin()
def add_inventory_record():
inventory_obj = request.json
inventory_type = inventory_obj["inventoryType"]
inventory_obj = inventory_conversion.ui2backend(inventory_obj, delete=False)
handler = HandleNewDevice(mongo_groups, mongo_inventory)
if inventory_obj["address"][0].isdigit():
if inventory_type == "Host":
record_added, message = handler.add_single_host(inventory_obj["address"], str(inventory_obj["port"]),
inventory_obj, True)
else:
Expand Down Expand Up @@ -68,23 +69,22 @@ def delete_inventory_record(inventory_id):
@cross_origin()
def update_inventory_record(inventory_id):
inventory_obj = request.json
inventory_type = inventory_obj["inventoryType"]
inventory_obj = inventory_conversion.ui2backend(inventory_obj, delete=False)
current_inventory = list(mongo_inventory.find({"_id": ObjectId(inventory_id)}))[0]
current_inventory_type = get_inventory_type(current_inventory)
handler = HandleNewDevice(mongo_groups, mongo_inventory)

is_current_a_single_host = current_inventory["address"][0].isdigit()
is_new_a_single_host = inventory_obj["address"][0].isdigit()
if is_current_a_single_host != is_new_a_single_host:
if inventory_type != current_inventory_type:
result = jsonify({"message": "Can't edit single host to the group or group to the single host"}), 400
else:
if is_new_a_single_host:
if inventory_type == "Host":
record_edited, message = handler.edit_single_host(inventory_obj["address"], str(inventory_obj["port"]),
str(inventory_id), inventory_obj, True)
else:
record_edited, message = handler.edit_group_in_inventory(inventory_obj["address"], str(inventory_id), inventory_obj, True)
if record_edited:
if message == "success" or message is None:
print(message)
result = jsonify("success"), 200
else:
result = jsonify({"message": message}), 200
Expand Down
6 changes: 4 additions & 2 deletions backend/tests/common/test_backend_ui_conversions.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ def setUpClass(cls):

cls.ui_inventory_1 = {
"_id": common_id,
"inventoryType": "Host",
"address": "11.0.78.114",
"port": "161",
"version": "3",
Expand Down Expand Up @@ -234,6 +235,7 @@ def setUpClass(cls):

cls.ui_inventory_2 = {
"_id": common_id,
"inventoryType": "Group",
"address": "group_1",
"port": "1161",
"version": "2c",
Expand Down Expand Up @@ -320,8 +322,8 @@ def test_group_device_ui_to_backend(self):
self.assertDictEqual(group_device_conversion.ui2backend(self.ui_group_device_4), device)

def test_inventory_backend_to_ui(self):
self.assertDictEqual(inventory_conversion.backend2ui(self.backend_inventory_1), self.ui_inventory_1)
self.assertDictEqual(inventory_conversion.backend2ui(self.backend_inventory_2), self.ui_inventory_2)
self.assertDictEqual(inventory_conversion.backend2ui(self.backend_inventory_1, inventory_type="Host"), self.ui_inventory_1)
self.assertDictEqual(inventory_conversion.backend2ui(self.backend_inventory_2, inventory_type="Group"), self.ui_inventory_2)

def test_inventory_ui_to_backend(self):
back_inv = self.backend_inventory_1
Expand Down
9 changes: 7 additions & 2 deletions backend/tests/ui_handling/get_endpoints/test_get_endpoints.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from unittest import mock
from bson import ObjectId


@mock.patch("pymongo.collection.Collection.find")
def test_get_profile_names(m_client, client):
m_client.return_value = [{
Expand Down Expand Up @@ -264,8 +263,9 @@ def test_get_devices_of_group(m_client, client):
assert response.json == third_result


@mock.patch("SC4SNMP_UI_backend.inventory.routes.get_inventory_type")
@mock.patch("pymongo.cursor.Cursor.limit")
def test_get_inventory_list(m_cursor, client):
def test_get_inventory_list(m_cursor, m_get_inventory_type, client):
common_id = "635916b2c8cb7a15f28af40a"

m_cursor.side_effect = [
Expand Down Expand Up @@ -314,9 +314,12 @@ def test_get_inventory_list(m_cursor, client):
]
]

m_get_inventory_type.side_effect = ["Host", "Group", "Group"]

first_result = [
{
"_id": common_id,
"inventoryType": "Host",
"address": "11.0.78.114",
"port": "161",
"version": "3",
Expand All @@ -329,6 +332,7 @@ def test_get_inventory_list(m_cursor, client):
},
{
"_id": common_id,
"inventoryType": "Group",
"address": "group_1",
"port": "1161",
"version": "2c",
Expand All @@ -344,6 +348,7 @@ def test_get_inventory_list(m_cursor, client):
second_result = [
{
"_id": common_id,
"inventoryType": "Group",
"address": "group_2",
"port": "161",
"version": "3",
Expand Down
Loading
Loading