Skip to content

Commit bd5e502

Browse files
authored
Merge pull request #35 from dell/SNMP_Server
Adding support for SNMP server object
2 parents df091a2 + e330a25 commit bd5e502

11 files changed

Lines changed: 404 additions & 3 deletions

File tree

ChangeLog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# PyPowerStore Change Log
22

3+
## Version 3.4.0.0 - released on 29/11/24
4+
- Added the Support for SNMP server object.
5+
36
## Version 3.3.0.0 - released on 31/05/24
47
- Added the Support for ACL in SMB Share object.
58

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright: (c) 2024, Dell Technologies
3+
4+
""" SNMP server Operations"""
5+
from PyPowerStore import powerstore_conn
6+
7+
CONN = powerstore_conn.PowerStoreConn(username="<username>",
8+
password="<password>",
9+
server_ip="<IP>",
10+
verify=False,
11+
application_type="<Application>",
12+
timeout=180.0)
13+
14+
print(CONN)
15+
16+
MODIFY_PARAMS = {
17+
"ip_address": "10.**.**.**",
18+
"port": 162,
19+
"trap_community": "community",
20+
"alert_severity": "Info"
21+
}
22+
23+
CREATE_PARAMS = {
24+
"ip_address": "10.**.**.**",
25+
"port": 162,
26+
"version": "V2c",
27+
"alert_severity": "Info",
28+
"trap_community": "public"
29+
}
30+
31+
# create SNMP server
32+
SNMP_SERVER = CONN.snmp_server.create_snmp_server(CREATE_PARAMS)
33+
print(SNMP_SERVER)
34+
35+
# Get SNMP server list
36+
SNMP_SERVERS = CONN.snmp_server.get_snmp_server_list(all_pages=True)
37+
print(SNMP_SERVERS)
38+
39+
# get SNMP server details by ID
40+
SNMP_SERVER = CONN.snmp_server.get_snmp_server_details(SNMP_SERVER['id'])
41+
print(SNMP_SERVER)
42+
43+
# modify SNMP server
44+
MODIFY_SNMP_SERVER = CONN.snmp_server.modify_snmp_server(SNMP_SERVERS[0]['id'],
45+
MODIFY_PARAMS)
46+
print(MODIFY_SNMP_SERVER)
47+
48+
# delete SNMP server
49+
DELETE_SNMP_SERVER = CONN.snmp_server.delete_snmp_server(SNMP_SERVERS[0]['id'])
50+
print(DELETE_SNMP_SERVER)
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright: (c) 2024, Dell Technologies
3+
4+
"""Collection of SNMP related functions for PowerStore"""
5+
6+
from PyPowerStore.client import Client
7+
from PyPowerStore.utils import constants, helpers
8+
9+
# TODO: kept LOG as global for now will improve it to avoid overriding
10+
LOG = helpers.get_logger(__name__)
11+
12+
SELECT_ALL_SNMP = {"select": "id, ip_address, port, version, trap_community,"
13+
"alert_severity, user_name, auth_protocol, privacy_protocol"}
14+
15+
# SNMP server endpoints
16+
GET_SNMP_LIST_URL = 'https://{0}/api/rest/snmp_server'
17+
GET_SNMP_DETAILS_URL = 'https://{0}/api/rest/snmp_server/{1}'
18+
GET_SNMP_DETAILS_BY_NAS_SERVER_URL = GET_SNMP_LIST_URL
19+
MODIFY_SNMP_URL = GET_SNMP_DETAILS_URL
20+
CREATE_SNMP_URL = GET_SNMP_LIST_URL
21+
DELETE_SNMP_URL = GET_SNMP_DETAILS_URL
22+
23+
class SNMPServer:
24+
"""Provisioning related functionality for PowerStore."""
25+
def __init__(self, provisioning, enable_log=False):
26+
""" Initializes ProtectionFunctions Class.
27+
28+
:param provisioning: Provisioning class object
29+
:type provisioning: Provisioning
30+
:param enable_log: (optional) Whether to enable log or not
31+
:type enable_log: bool
32+
"""
33+
global LOG
34+
self.provisioning = provisioning
35+
self.server_ip = provisioning.server_ip
36+
self.snmp_server_client = provisioning.client
37+
LOG = helpers.get_logger(__name__, enable_log=enable_log)
38+
39+
# SNMP server methods begin
40+
def get_snmp_server_list(self, filter_dict=None, all_pages=False):
41+
"""Get a list of SNMP servers.
42+
43+
:param filter_dict: (optional) Filter detail
44+
:type filter_dict: dict
45+
:param all_pages: (optional) Indicates whether to return all element
46+
or not
47+
:type all_pages: bool
48+
:returns: SNMP servers
49+
:rtype: list of dict
50+
"""
51+
LOG.info("Getting SNMP servers with filter: '%s' and all_pages: %s"
52+
% (filter_dict, all_pages))
53+
querystring = helpers.prepare_querystring(SELECT_ALL_SNMP, filter_dict)
54+
LOG.info("Querystring: '%s'" % querystring)
55+
return self.snmp_server_client.request(constants.GET,
56+
GET_SNMP_LIST_URL.format
57+
(self.server_ip), payload=None,
58+
querystring=querystring,
59+
all_pages=all_pages)
60+
61+
def get_snmp_server_details(self, snmp_server_id):
62+
"""Details of a SNMP server.
63+
64+
:param snmp_server_id: The SNMP server ID
65+
:type snmp_server_id: str
66+
:return:SNMP server details
67+
:rtype: dict
68+
"""
69+
querystring = SELECT_ALL_SNMP
70+
71+
LOG.info("Getting SNMP server details by ID: '%s'" % snmp_server_id)
72+
return self.snmp_server_client.request(
73+
constants.GET,
74+
GET_SNMP_DETAILS_URL.format(self.server_ip,
75+
snmp_server_id),
76+
payload=None,
77+
querystring=querystring)
78+
79+
def create_snmp_server(self, payload):
80+
"""Create an SNMP server.
81+
82+
:param payload: The payload to create the SNMP server
83+
:type payload: dict
84+
:return: SNMP server ID on success else raise exception
85+
:rtype: dict
86+
"""
87+
LOG.info("Creating SNMP server")
88+
return self.snmp_server_client.request(
89+
constants.POST,
90+
CREATE_SNMP_URL.format(self.server_ip),
91+
payload=payload)
92+
93+
def modify_snmp_server(self, snmp_server_id, modify_parameters):
94+
"""Modify SNMP server attributes.
95+
96+
:param snmp_server_id: The ID of the SNMP server
97+
:type snmp_server_id: str
98+
:param modify_parameters: Attributes to be modified
99+
:type modify_parameters: dict
100+
:return: None if success else raise exception
101+
:rtype: None
102+
"""
103+
LOG.info("Modifying SNMP server: '%s'" % snmp_server_id)
104+
if modify_parameters:
105+
payload = dict()
106+
for key, value in modify_parameters.items():
107+
if value is not None:
108+
payload[key] = value
109+
110+
if payload:
111+
return self.snmp_server_client.request(
112+
constants.PATCH,
113+
MODIFY_SNMP_URL.format(
114+
self.server_ip, snmp_server_id),
115+
payload=payload)
116+
117+
raise ValueError("Nothing to modify")
118+
119+
def delete_snmp_server(self, snmp_server_id):
120+
"""Delete an SNMP server.
121+
122+
:param snmp_server_id: The ID of the SNMP server to delete
123+
:type snmp_server_id: str
124+
:return: None on success else raise exception
125+
:rtype: None
126+
"""
127+
LOG.info("Deleting SNMP server: '%s'" % snmp_server_id)
128+
return self.snmp_server_client.request(
129+
constants.DELETE,
130+
DELETE_SNMP_URL.format(self.server_ip, snmp_server_id))
131+
132+
# SNMP server methods end

PyPowerStore/powerstore_conn.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from PyPowerStore.objects.nfs_server import NFSServer
1212
from PyPowerStore.objects.file_dns import FileDNS
1313
from PyPowerStore.objects.file_nis import FileNIS
14+
from PyPowerStore.objects.snmp_server import SNMPServer
1415

1516
class PowerStoreConn():
1617
"""Class for establishing connection with PowerStore"""
@@ -55,3 +56,5 @@ def __init__(self, username, password, server_ip, verify=False,
5556
enable_log=enable_log)
5657
self.file_nis = FileNIS(self.provisioning,
5758
enable_log=enable_log)
59+
self.snmp_server = SNMPServer(self.provisioning,
60+
enable_log=enable_log)

PyPowerStore/tests/unit_tests/base_test.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from PyPowerStore.tests.unit_tests.data.nfs_server_data import NFSServerData
2828
from PyPowerStore.tests.unit_tests.data.file_dns_data import FileDNSData
2929
from PyPowerStore.tests.unit_tests.data.file_nis_data import FileNISData
30+
from PyPowerStore.tests.unit_tests.data.snmp_server_data import SNMPServerData
3031
from unittest import mock
3132

3233
class TestBase(TestCase):
@@ -57,6 +58,7 @@ def setUp(self):
5758
self.nfs_server_data = NFSServerData()
5859
self.file_dns_data = FileDNSData()
5960
self.file_nis_data = FileNISData()
61+
self.snmp_server_data = SNMPServerData()
6062
self.conf = PowerStoreConfig()
6163
self.mock_client = mock.patch('PyPowerStore.provisioning.Client',
6264
new=MockClient)
@@ -74,3 +76,4 @@ def setUp(self):
7476
self.file_nis = self.conn.file_nis
7577
self.smb_server = self.conn.smb_server
7678
self.nfs_server = self.conn.nfs_server
79+
self.snmp_server = self.conn.snmp_server
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
class SNMPServerData():
2+
3+
snmp_server_id = "snmp_server_id_1"
4+
5+
snmp_server_list = [
6+
{
7+
"id": "2bf5709d-0466-437a-a28f-9d31f2fdfcc5",
8+
"ip_address": "127.0.0.1",
9+
"port": 162,
10+
"version": "V2c",
11+
"trap_community": "commnity",
12+
"alert_severity": "Info",
13+
"user_name": None,
14+
"auth_protocol": None,
15+
"privacy_protocol": None
16+
},
17+
{
18+
"id": "54261519-c5c2-446a-ad76-5f4ca63581df",
19+
"ip_address": "100.96.32.85",
20+
"port": 162,
21+
"version": "V2c",
22+
"trap_community": "public",
23+
"alert_severity": "Info",
24+
"user_name": None,
25+
"auth_protocol": None,
26+
"privacy_protocol": None
27+
},
28+
{
29+
"id": "789f4c09-9e15-4b44-a9f3-baf716172140",
30+
"ip_address": "10.250.230.45",
31+
"port": 162,
32+
"version": "V3",
33+
"trap_community": None,
34+
"alert_severity": "Info",
35+
"user_name": "test",
36+
"auth_protocol": "None",
37+
"privacy_protocol": "None"
38+
}]
39+
40+
snmp_server_detail = {
41+
"id": "789f4c09-9e15-4b44-a9f3-baf716172140",
42+
"ip_address": "10.250.230.45",
43+
"port": 162,
44+
"version": "V3",
45+
"trap_community": None,
46+
"alert_severity": "Info",
47+
"user_name": "test",
48+
"auth_protocol": "None",
49+
"privacy_protocol": "None"
50+
}
51+
52+
snmp_server_valid_param_list = [
53+
"ip_address", "port", "version", "alert_severity", "trap_community"]
54+
55+
snmp_server_id_not_exist = "5f4a3017-0bad-899e-e1eb-c6f547282e66"
56+
snmp_server_error = {
57+
400: {'messages': [{'arguments': ['Object instance has properties '
58+
'which are not allowed by the '
59+
'schema.'],
60+
'code': '0xE04040030001',
61+
'message_l10n': 'Validation failed: Object '
62+
'instance has properties which '
63+
'are not allowed by the schema.',
64+
'severity': 'Error'}]},
65+
422: {"messages": [{
66+
"code": "0xE0F0101D0024",
67+
"severity": "Error",
68+
"message_l10n": "Server Record Not Found, id: c5fdeb93-42ed-4ec9-988e-daec2974f2fk",
69+
"arguments": [
70+
"c5fdeb93-42ed-4ec9-988e-daec2974f2fk"
71+
]
72+
}
73+
]
74+
}
75+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from PyPowerStore.tests.unit_tests.entity.base_abstract import Entity
2+
from PyPowerStore.tests.unit_tests.data.snmp_server_data import SNMPServerData
3+
from PyPowerStore.utils import constants
4+
from PyPowerStore.objects import snmp_server
5+
6+
class SNMPServerResponse(Entity):
7+
8+
def __init__(self, method, url, **kwargs):
9+
self.method = method
10+
self.url = url
11+
self.kwargs = kwargs
12+
self.snmp_server_data = SNMPServerData()
13+
self.status_code = 200
14+
15+
def get_api_name(self):
16+
if self.method == 'GET':
17+
if self.url.endswith('/snmp_server'):
18+
return self.get_snmp_server_list
19+
else:
20+
return self.get_snmp_server_details
21+
elif self.method == 'PATCH':
22+
return self.modify_snmp_server
23+
elif self.method == 'POST':
24+
return self.create_snmp_server
25+
elif self.method == 'DELETE':
26+
return self.delete_snmp_server
27+
28+
def execute_api(self, api_name):
29+
status_code, response = api_name()
30+
return status_code, response
31+
32+
def get_snmp_server_list(self):
33+
return self.status_code, self.snmp_server_data.snmp_server_list
34+
35+
def get_snmp_server_details(self):
36+
if self.url.endswith('/snmp_server/{0}'.format(
37+
self.snmp_server_data.snmp_server_id_not_exist)):
38+
return 422, self.snmp_server_data.snmp_server_error[422]
39+
return 200, self.snmp_server_data.snmp_server_detail
40+
41+
def modify_snmp_server(self):
42+
data = self.kwargs.get('data', {})
43+
param = list(data.keys())
44+
if set(param) - set(self.snmp_server_data.snmp_server_valid_param_list):
45+
# invalid param given
46+
return 400, self.snmp_server_data.snmp_server_error[400]
47+
return 204, None
48+
49+
def create_snmp_server(self):
50+
return 201, self.snmp_server_data.snmp_server_id
51+
52+
def delete_snmp_server(self):
53+
return 204, None

PyPowerStore/tests/unit_tests/myrequests.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
from PyPowerStore.tests.unit_tests.entity.nfs_server import NFSServerResponse
5050
from PyPowerStore.tests.unit_tests.entity.file_dns import FileDNSResponse
5151
from PyPowerStore.tests.unit_tests.entity.file_nis import FileNISResponse
52+
from PyPowerStore.tests.unit_tests.entity.snmp_server import SNMPServerResponse
5253
import json
5354

5455
# map the entity class name with the url resource name
@@ -103,7 +104,8 @@
103104
'smb_server': SMBServerResponse,
104105
'nfs_server': NFSServerResponse,
105106
'file_dns': FileDNSResponse,
106-
'file_nis': FileNISResponse
107+
'file_nis': FileNISResponse,
108+
'snmp_server': SNMPServerResponse
107109
}
108110

109111

0 commit comments

Comments
 (0)