Skip to content

Commit

Permalink
Merge pull request #35 from dell/SNMP_Server
Browse files Browse the repository at this point in the history
Adding support for SNMP server object
  • Loading branch information
trisha-dell authored Nov 12, 2024
2 parents df091a2 + e330a25 commit bd5e502
Show file tree
Hide file tree
Showing 11 changed files with 404 additions and 3 deletions.
3 changes: 3 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# PyPowerStore Change Log

## Version 3.4.0.0 - released on 29/11/24
- Added the Support for SNMP server object.

## Version 3.3.0.0 - released on 31/05/24
- Added the Support for ACL in SMB Share object.

Expand Down
50 changes: 50 additions & 0 deletions ProgrammersGuideExamples/snmp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2024, Dell Technologies

""" SNMP server Operations"""
from PyPowerStore import powerstore_conn

CONN = powerstore_conn.PowerStoreConn(username="<username>",
password="<password>",
server_ip="<IP>",
verify=False,
application_type="<Application>",
timeout=180.0)

print(CONN)

MODIFY_PARAMS = {
"ip_address": "10.**.**.**",
"port": 162,
"trap_community": "community",
"alert_severity": "Info"
}

CREATE_PARAMS = {
"ip_address": "10.**.**.**",
"port": 162,
"version": "V2c",
"alert_severity": "Info",
"trap_community": "public"
}

# create SNMP server
SNMP_SERVER = CONN.snmp_server.create_snmp_server(CREATE_PARAMS)
print(SNMP_SERVER)

# Get SNMP server list
SNMP_SERVERS = CONN.snmp_server.get_snmp_server_list(all_pages=True)
print(SNMP_SERVERS)

# get SNMP server details by ID
SNMP_SERVER = CONN.snmp_server.get_snmp_server_details(SNMP_SERVER['id'])
print(SNMP_SERVER)

# modify SNMP server
MODIFY_SNMP_SERVER = CONN.snmp_server.modify_snmp_server(SNMP_SERVERS[0]['id'],
MODIFY_PARAMS)
print(MODIFY_SNMP_SERVER)

# delete SNMP server
DELETE_SNMP_SERVER = CONN.snmp_server.delete_snmp_server(SNMP_SERVERS[0]['id'])
print(DELETE_SNMP_SERVER)
132 changes: 132 additions & 0 deletions PyPowerStore/objects/snmp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2024, Dell Technologies

"""Collection of SNMP related functions for PowerStore"""

from PyPowerStore.client import Client
from PyPowerStore.utils import constants, helpers

# TODO: kept LOG as global for now will improve it to avoid overriding
LOG = helpers.get_logger(__name__)

SELECT_ALL_SNMP = {"select": "id, ip_address, port, version, trap_community,"
"alert_severity, user_name, auth_protocol, privacy_protocol"}

# SNMP server endpoints
GET_SNMP_LIST_URL = 'https://{0}/api/rest/snmp_server'
GET_SNMP_DETAILS_URL = 'https://{0}/api/rest/snmp_server/{1}'
GET_SNMP_DETAILS_BY_NAS_SERVER_URL = GET_SNMP_LIST_URL
MODIFY_SNMP_URL = GET_SNMP_DETAILS_URL
CREATE_SNMP_URL = GET_SNMP_LIST_URL
DELETE_SNMP_URL = GET_SNMP_DETAILS_URL

class SNMPServer:
"""Provisioning related functionality for PowerStore."""
def __init__(self, provisioning, enable_log=False):
""" Initializes ProtectionFunctions Class.
:param provisioning: Provisioning class object
:type provisioning: Provisioning
:param enable_log: (optional) Whether to enable log or not
:type enable_log: bool
"""
global LOG
self.provisioning = provisioning
self.server_ip = provisioning.server_ip
self.snmp_server_client = provisioning.client
LOG = helpers.get_logger(__name__, enable_log=enable_log)

# SNMP server methods begin
def get_snmp_server_list(self, filter_dict=None, all_pages=False):
"""Get a list of SNMP servers.
:param filter_dict: (optional) Filter detail
:type filter_dict: dict
:param all_pages: (optional) Indicates whether to return all element
or not
:type all_pages: bool
:returns: SNMP servers
:rtype: list of dict
"""
LOG.info("Getting SNMP servers with filter: '%s' and all_pages: %s"
% (filter_dict, all_pages))
querystring = helpers.prepare_querystring(SELECT_ALL_SNMP, filter_dict)
LOG.info("Querystring: '%s'" % querystring)
return self.snmp_server_client.request(constants.GET,
GET_SNMP_LIST_URL.format
(self.server_ip), payload=None,
querystring=querystring,
all_pages=all_pages)

def get_snmp_server_details(self, snmp_server_id):
"""Details of a SNMP server.
:param snmp_server_id: The SNMP server ID
:type snmp_server_id: str
:return:SNMP server details
:rtype: dict
"""
querystring = SELECT_ALL_SNMP

LOG.info("Getting SNMP server details by ID: '%s'" % snmp_server_id)
return self.snmp_server_client.request(
constants.GET,
GET_SNMP_DETAILS_URL.format(self.server_ip,
snmp_server_id),
payload=None,
querystring=querystring)

def create_snmp_server(self, payload):
"""Create an SNMP server.
:param payload: The payload to create the SNMP server
:type payload: dict
:return: SNMP server ID on success else raise exception
:rtype: dict
"""
LOG.info("Creating SNMP server")
return self.snmp_server_client.request(
constants.POST,
CREATE_SNMP_URL.format(self.server_ip),
payload=payload)

def modify_snmp_server(self, snmp_server_id, modify_parameters):
"""Modify SNMP server attributes.
:param snmp_server_id: The ID of the SNMP server
:type snmp_server_id: str
:param modify_parameters: Attributes to be modified
:type modify_parameters: dict
:return: None if success else raise exception
:rtype: None
"""
LOG.info("Modifying SNMP server: '%s'" % snmp_server_id)
if modify_parameters:
payload = dict()
for key, value in modify_parameters.items():
if value is not None:
payload[key] = value

if payload:
return self.snmp_server_client.request(
constants.PATCH,
MODIFY_SNMP_URL.format(
self.server_ip, snmp_server_id),
payload=payload)

raise ValueError("Nothing to modify")

def delete_snmp_server(self, snmp_server_id):
"""Delete an SNMP server.
:param snmp_server_id: The ID of the SNMP server to delete
:type snmp_server_id: str
:return: None on success else raise exception
:rtype: None
"""
LOG.info("Deleting SNMP server: '%s'" % snmp_server_id)
return self.snmp_server_client.request(
constants.DELETE,
DELETE_SNMP_URL.format(self.server_ip, snmp_server_id))

# SNMP server methods end
3 changes: 3 additions & 0 deletions PyPowerStore/powerstore_conn.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from PyPowerStore.objects.nfs_server import NFSServer
from PyPowerStore.objects.file_dns import FileDNS
from PyPowerStore.objects.file_nis import FileNIS
from PyPowerStore.objects.snmp_server import SNMPServer

class PowerStoreConn():
"""Class for establishing connection with PowerStore"""
Expand Down Expand Up @@ -55,3 +56,5 @@ def __init__(self, username, password, server_ip, verify=False,
enable_log=enable_log)
self.file_nis = FileNIS(self.provisioning,
enable_log=enable_log)
self.snmp_server = SNMPServer(self.provisioning,
enable_log=enable_log)
3 changes: 3 additions & 0 deletions PyPowerStore/tests/unit_tests/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from PyPowerStore.tests.unit_tests.data.nfs_server_data import NFSServerData
from PyPowerStore.tests.unit_tests.data.file_dns_data import FileDNSData
from PyPowerStore.tests.unit_tests.data.file_nis_data import FileNISData
from PyPowerStore.tests.unit_tests.data.snmp_server_data import SNMPServerData
from unittest import mock

class TestBase(TestCase):
Expand Down Expand Up @@ -57,6 +58,7 @@ def setUp(self):
self.nfs_server_data = NFSServerData()
self.file_dns_data = FileDNSData()
self.file_nis_data = FileNISData()
self.snmp_server_data = SNMPServerData()
self.conf = PowerStoreConfig()
self.mock_client = mock.patch('PyPowerStore.provisioning.Client',
new=MockClient)
Expand All @@ -74,3 +76,4 @@ def setUp(self):
self.file_nis = self.conn.file_nis
self.smb_server = self.conn.smb_server
self.nfs_server = self.conn.nfs_server
self.snmp_server = self.conn.snmp_server
75 changes: 75 additions & 0 deletions PyPowerStore/tests/unit_tests/data/snmp_server_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
class SNMPServerData():

snmp_server_id = "snmp_server_id_1"

snmp_server_list = [
{
"id": "2bf5709d-0466-437a-a28f-9d31f2fdfcc5",
"ip_address": "127.0.0.1",
"port": 162,
"version": "V2c",
"trap_community": "commnity",
"alert_severity": "Info",
"user_name": None,
"auth_protocol": None,
"privacy_protocol": None
},
{
"id": "54261519-c5c2-446a-ad76-5f4ca63581df",
"ip_address": "100.96.32.85",
"port": 162,
"version": "V2c",
"trap_community": "public",
"alert_severity": "Info",
"user_name": None,
"auth_protocol": None,
"privacy_protocol": None
},
{
"id": "789f4c09-9e15-4b44-a9f3-baf716172140",
"ip_address": "10.250.230.45",
"port": 162,
"version": "V3",
"trap_community": None,
"alert_severity": "Info",
"user_name": "test",
"auth_protocol": "None",
"privacy_protocol": "None"
}]

snmp_server_detail = {
"id": "789f4c09-9e15-4b44-a9f3-baf716172140",
"ip_address": "10.250.230.45",
"port": 162,
"version": "V3",
"trap_community": None,
"alert_severity": "Info",
"user_name": "test",
"auth_protocol": "None",
"privacy_protocol": "None"
}

snmp_server_valid_param_list = [
"ip_address", "port", "version", "alert_severity", "trap_community"]

snmp_server_id_not_exist = "5f4a3017-0bad-899e-e1eb-c6f547282e66"
snmp_server_error = {
400: {'messages': [{'arguments': ['Object instance has properties '
'which are not allowed by the '
'schema.'],
'code': '0xE04040030001',
'message_l10n': 'Validation failed: Object '
'instance has properties which '
'are not allowed by the schema.',
'severity': 'Error'}]},
422: {"messages": [{
"code": "0xE0F0101D0024",
"severity": "Error",
"message_l10n": "Server Record Not Found, id: c5fdeb93-42ed-4ec9-988e-daec2974f2fk",
"arguments": [
"c5fdeb93-42ed-4ec9-988e-daec2974f2fk"
]
}
]
}
}
53 changes: 53 additions & 0 deletions PyPowerStore/tests/unit_tests/entity/snmp_server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from PyPowerStore.tests.unit_tests.entity.base_abstract import Entity
from PyPowerStore.tests.unit_tests.data.snmp_server_data import SNMPServerData
from PyPowerStore.utils import constants
from PyPowerStore.objects import snmp_server

class SNMPServerResponse(Entity):

def __init__(self, method, url, **kwargs):
self.method = method
self.url = url
self.kwargs = kwargs
self.snmp_server_data = SNMPServerData()
self.status_code = 200

def get_api_name(self):
if self.method == 'GET':
if self.url.endswith('/snmp_server'):
return self.get_snmp_server_list
else:
return self.get_snmp_server_details
elif self.method == 'PATCH':
return self.modify_snmp_server
elif self.method == 'POST':
return self.create_snmp_server
elif self.method == 'DELETE':
return self.delete_snmp_server

def execute_api(self, api_name):
status_code, response = api_name()
return status_code, response

def get_snmp_server_list(self):
return self.status_code, self.snmp_server_data.snmp_server_list

def get_snmp_server_details(self):
if self.url.endswith('/snmp_server/{0}'.format(
self.snmp_server_data.snmp_server_id_not_exist)):
return 422, self.snmp_server_data.snmp_server_error[422]
return 200, self.snmp_server_data.snmp_server_detail

def modify_snmp_server(self):
data = self.kwargs.get('data', {})
param = list(data.keys())
if set(param) - set(self.snmp_server_data.snmp_server_valid_param_list):
# invalid param given
return 400, self.snmp_server_data.snmp_server_error[400]
return 204, None

def create_snmp_server(self):
return 201, self.snmp_server_data.snmp_server_id

def delete_snmp_server(self):
return 204, None
4 changes: 3 additions & 1 deletion PyPowerStore/tests/unit_tests/myrequests.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
from PyPowerStore.tests.unit_tests.entity.nfs_server import NFSServerResponse
from PyPowerStore.tests.unit_tests.entity.file_dns import FileDNSResponse
from PyPowerStore.tests.unit_tests.entity.file_nis import FileNISResponse
from PyPowerStore.tests.unit_tests.entity.snmp_server import SNMPServerResponse
import json

# map the entity class name with the url resource name
Expand Down Expand Up @@ -103,7 +104,8 @@
'smb_server': SMBServerResponse,
'nfs_server': NFSServerResponse,
'file_dns': FileDNSResponse,
'file_nis': FileNISResponse
'file_nis': FileNISResponse,
'snmp_server': SNMPServerResponse
}


Expand Down
Loading

0 comments on commit bd5e502

Please sign in to comment.