Merge "Remove REST API for host-based snmp"

This commit is contained in:
Zuul 2021-01-25 16:34:30 +00:00 committed by Gerrit Code Review
commit 19da5cc1b9
17 changed files with 184 additions and 937 deletions

View File

@ -0,0 +1,128 @@
#!/usr/bin/python
# Copyright (c) 2021 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# This script will remove snmp related data (icommunity and
# itrapdest) in dcorch database according to the host based
# SNMP removal in preparation for upgrade from release 20.06.
#
import psycopg2
import sys
from controllerconfig.common import log
from psycopg2.extras import RealDictCursor
LOG = log.get_logger(__name__)
def main():
action = None
from_release = None
to_release = None
arg = 1
while arg < len(sys.argv):
if arg == 1:
from_release = sys.argv[arg]
elif arg == 2:
to_release = sys.argv[arg]
elif arg == 3:
action = sys.argv[arg]
else:
print ("Invalid option %s." % sys.argv[arg])
return 1
arg += 1
log.configure()
LOG.debug("%s invoked with from_release = %s to_release = %s action = %s"
% (sys.argv[0], from_release, to_release, action))
if from_release == "20.06" and action == "migrate":
try:
if is_system_controller():
LOG.info("Performing dcorch snmp data removal...")
remove_snmp_record()
except Exception as ex:
LOG.exception(ex)
print(ex)
return 1
def is_system_controller():
with open('/etc/platform/platform.conf', 'r') as f:
lines = f.readlines()
for line in lines:
if line.strip() == 'distributed_cloud_role=systemcontroller':
return True
return False
def remove_snmp_in_orch_request(cur, job_id):
# Check if the record exists in orch_request
cur.execute("select * from orch_request where orch_job_id = '%d'" %
job_id)
orch_request = cur.fetchall()
if orch_request:
cur.execute("delete from orch_request where orch_job_id = '%d'" %
job_id)
LOG.info("icommunity/itrapdest is removed in orch_request.")
else:
LOG.info("There is no icommunity/itrapdest in orch_request.")
def remove_snmp_in_orch_job(cur, master_id):
# Check if the record exists in orch_job
cur.execute("select * from orch_job where source_resource_id = '%s'" %
master_id)
orch_job = cur.fetchall()
if orch_job:
for orch_job_record in orch_job:
remove_id = orch_job_record['id']
remove_snmp_in_orch_request(cur, remove_id)
cur.execute("delete from orch_job where id = %d" % (remove_id))
LOG.info("icommunity is removed in orch_job.")
else:
LOG.info("There is no icommunity/itrapdest in orch_job.")
def remove_snmp_in_subcloud_resource(cur, master_id):
# Check if the record exists in subcloud_resource
cur.execute("select * from subcloud_resource "
"where subcloud_resource_id = '%s'" % (master_id))
resource_subcloud = cur.fetchall()
if resource_subcloud:
cur.execute("delete from subcloud_resource "
"where subcloud_resource_id = '%s'" % (master_id))
LOG.info("icommunity is removed in subcloud_resource.")
else:
LOG.info("There is no icommunity/itrapdest in subcloud_resource.")
def remove_snmp_record():
conn = psycopg2.connect("dbname='dcorch' user='postgres'")
with conn:
with conn.cursor(cursor_factory=RealDictCursor) as cur:
# Check if any icommunity or itrapdest record exists
cur.execute("select * from resource where resource_type in "
"('icommunity','itrapdest')")
resource_records = cur.fetchall()
if not resource_records:
LOG.info("Nothing to do - "
"there is no icommunity/itrapdest in resource.")
return
for data_resource in resource_records:
master_id = data_resource['master_id']
remove_snmp_in_subcloud_resource(cur, master_id)
remove_snmp_in_orch_job(cur, master_id)
cur.execute("delete from resource "
"where master_id = '%s'" % (master_id))
LOG.info("icommunity/itrapdest is removed from resource.")
LOG.info("snmp community and trapdest data removal completed.")
if __name__ == "__main__":
sys.exit(main())

View File

@ -67,8 +67,7 @@ class Root(base.APIBase):
"management of physical servers. This includes inventory "
"collection and configuration of hosts, ports, interfaces, CPUs, disk, "
"memory, and system configuration. The API also supports "
"alarms and fault collection for the cloud itself as well "
"as the configuration of the cloud's SNMP interface. "
"alarms and fault collection for the cloud itself."
)
root.versions = [Version.convert('v1')]
root.default_version = Version.convert('v1')

View File

@ -25,7 +25,6 @@ from sysinv.api.controllers.v1 import address_pool
from sysinv.api.controllers.v1 import base
from sysinv.api.controllers.v1 import ceph_mon
from sysinv.api.controllers.v1 import cluster
from sysinv.api.controllers.v1 import community
from sysinv.api.controllers.v1 import controller_fs
from sysinv.api.controllers.v1 import cpu
from sysinv.api.controllers.v1 import device_image
@ -86,7 +85,6 @@ from sysinv.api.controllers.v1 import storage_external
from sysinv.api.controllers.v1 import storage_tier
from sysinv.api.controllers.v1 import storage_ceph_external
from sysinv.api.controllers.v1 import system
from sysinv.api.controllers.v1 import trapdest
from sysinv.api.controllers.v1 import upgrade
from sysinv.api.controllers.v1 import user
from sysinv.api.controllers.v1 import host_fs
@ -136,12 +134,6 @@ class V1(base.APIBase):
iprofile = [link.Link]
"Links to the iprofile resource"
itrapdest = [link.Link]
"Links to the itrapdest node cluster resource"
icommunity = [link.Link]
"Links to the icommunity node cluster resource"
iuser = [link.Link]
"Links to the iuser resource"
@ -418,22 +410,6 @@ class V1(base.APIBase):
bookmark=True)
]
v1.itrapdest = [link.Link.make_link('self', pecan.request.host_url,
'itrapdest', ''),
link.Link.make_link('bookmark',
pecan.request.host_url,
'itrapdest', '',
bookmark=True)
]
v1.icommunity = [link.Link.make_link('self', pecan.request.host_url,
'icommunity', ''),
link.Link.make_link('bookmark',
pecan.request.host_url,
'icommunity', '',
bookmark=True)
]
v1.iuser = [link.Link.make_link('self', pecan.request.host_url,
'iuser', ''),
link.Link.make_link('bookmark',
@ -874,8 +850,6 @@ class Controller(rest.RestController):
idisks = disk.DiskController()
partitions = partition.PartitionController()
iprofile = profile.ProfileController()
itrapdest = trapdest.TrapDestController()
icommunity = community.CommunityController()
iuser = user.UserController()
idns = dns.DNSController()
intp = ntp.NTPController()

View File

@ -1,238 +0,0 @@
#!/usr/bin/env python
#
# Copyright (c) 2013-2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# All Rights Reserved.
#
import jsonpatch
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from oslo_db.exception import DBDuplicateEntry
from oslo_db.exception import DBError
from oslo_log import log
from sysinv._i18n import _
from sysinv.api.controllers.v1 import base
from sysinv.api.controllers.v1 import collection
from sysinv.api.controllers.v1 import link
from sysinv.api.controllers.v1 import types
from sysinv.api.controllers.v1 import utils as api_utils
from sysinv.common import exception
from sysinv.common import utils as cutils
from sysinv import objects
LOG = log.getLogger(__name__)
class CommunityPatchType(types.JsonPatchType):
pass
class Community(base.APIBase):
"""API representation of a Community.
This class enforces type checking and value constraints, and converts
between the internal object model and the API representation of
a icommunity.
"""
uuid = types.uuid
"The UUID of the icommunity"
community = wsme.wsattr(wtypes.text, mandatory=True)
"The community string of which the SNMP client is a member"
view = wtypes.text
"The SNMP MIB View"
access = wtypes.text
"The SNMP GET/SET access control"
links = [link.Link]
"A list containing a self link and associated community string links"
def __init__(self, **kwargs):
self.fields = objects.community.fields.keys()
for k in self.fields:
setattr(self, k, kwargs.get(k))
@classmethod
def convert_with_links(cls, rpc_icommunity, expand=True):
minimum_fields = ['id', 'uuid', 'community',
'view', 'access']
fields = minimum_fields if not expand else None
icomm = Community.from_rpc_object(rpc_icommunity, fields)
return icomm
class CommunityCollection(collection.Collection):
"""API representation of a collection of icommunity."""
icommunity = [Community]
"A list containing icommunity objects"
def __init__(self, **kwargs):
self._type = 'icommunity'
@classmethod
def convert_with_links(cls, icommunity, limit, url=None,
expand=False, **kwargs):
collection = CommunityCollection()
collection.icommunity = [Community.convert_with_links(ch, expand)
for ch in icommunity]
# url = url or None
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
LOCK_NAME = 'CommunityController'
class CommunityController(rest.RestController):
"""REST controller for icommunity."""
_custom_actions = {
'detail': ['GET'],
}
def _get_icommunity_collection(self, marker, limit, sort_key, sort_dir,
expand=False, resource_url=None):
limit = api_utils.validate_limit(limit)
sort_dir = api_utils.validate_sort_dir(sort_dir)
marker_obj = None
if marker:
marker_obj = objects.community.get_by_uuid(pecan.request.context,
marker)
icomm = pecan.request.dbapi.icommunity_get_list(limit, marker_obj,
sort_key=sort_key,
sort_dir=sort_dir)
return CommunityCollection.convert_with_links(icomm, limit,
url=resource_url,
expand=expand,
sort_key=sort_key,
sort_dir=sort_dir)
@wsme_pecan.wsexpose(CommunityCollection, types.uuid,
int, wtypes.text, wtypes.text)
def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc'):
"""Retrieve a list of icommunity.
:param marker: pagination marker for large data sets.
:param limit: maximum number of resources to return in a single result.
:param sort_key: column to sort results by. Default: id.
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
"""
return self._get_icommunity_collection(marker, limit, sort_key, sort_dir)
@wsme_pecan.wsexpose(CommunityCollection, types.uuid, int,
wtypes.text, wtypes.text)
def detail(self, marker=None, limit=None, sort_key='id', sort_dir='asc'):
"""Retrieve a list of icommunity with detail.
:param marker: pagination marker for large data sets.
:param limit: maximum number of resources to return in a single result.
:param sort_key: column to sort results by. Default: id.
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
"""
# /detail should only work agaist collections
parent = pecan.request.path.split('/')[:-1][-1]
if parent != "icommunity":
raise exception.HTTPNotFound
expand = True
resource_url = '/'.join(['icommunity', 'detail'])
return self._get_icommunity_collection(marker, limit, sort_key, sort_dir,
expand, resource_url)
@wsme_pecan.wsexpose(Community, wtypes.text)
def get_one(self, name):
"""Retrieve information about the given icommunity.
:param icommunity_uuid: UUID of a icommunity.
"""
rpc_icommunity = objects.community.get_by_name(
pecan.request.context, name)
return Community.convert_with_links(rpc_icommunity)
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(Community, body=Community)
def post(self, icommunity):
"""Create a new icommunity.
:param icommunity: a icommunity within the request body.
"""
try:
new_icommunity = \
pecan.request.dbapi.icommunity_create(icommunity.as_dict())
except DBDuplicateEntry as e:
LOG.error(e)
raise wsme.exc.ClientSideError(_(
"Rejected: Cannot add %s, it is an existing community.") % icommunity.as_dict().get('community'))
except DBError as e:
LOG.error(e)
raise wsme.exc.ClientSideError(_(
"Database check error on community %s create.") % icommunity.as_dict().get('community'))
except Exception as e:
LOG.error(e)
raise wsme.exc.ClientSideError(_(
"Database error on community %s create. See log for details.") % icommunity.as_dict().get('community'))
# update snmpd.conf
pecan.request.rpcapi.update_snmp_config(pecan.request.context)
return icommunity.convert_with_links(new_icommunity)
@cutils.synchronized(LOCK_NAME)
@wsme.validate(types.uuid, [CommunityPatchType])
@wsme_pecan.wsexpose(Community, types.uuid, body=[CommunityPatchType])
def patch(self, icommunity_uuid, patch):
"""Update an existing icommunity.
:param icommunity_uuid: UUID of a icommunity.
:param patch: a json PATCH document to apply to this icommunity.
"""
rpc_icommunity = objects.community.get_by_uuid(pecan.request.context,
icommunity_uuid)
try:
icomm = Community(**jsonpatch.apply_patch(rpc_icommunity.as_dict(),
jsonpatch.JsonPatch(patch)))
except api_utils.JSONPATCH_EXCEPTIONS as e:
raise exception.PatchError(patch=patch, reason=e)
# Update only the fields that have changed
comm = ""
for field in objects.community.fields:
if rpc_icommunity[field] != getattr(icomm, field):
rpc_icommunity[field] = getattr(icomm, field)
if field == 'community':
comm = rpc_icommunity[field]
rpc_icommunity.save()
if comm:
LOG.debug("Modify community: uuid (%s) community (%s) ",
icommunity_uuid, comm)
return Community.convert_with_links(rpc_icommunity)
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, name):
"""Delete a icommunity.
:param name: community name of a icommunity.
"""
pecan.request.dbapi.icommunity_destroy(name)
# update snmpd.conf
pecan.request.rpcapi.update_snmp_config(pecan.request.context)

View File

@ -511,8 +511,6 @@ class SystemController(rest.RestController):
# Update only the fields that have changed
name = ""
contact = ""
location = ""
system_mode = ""
timezone = ""
capabilities = {}
@ -524,10 +522,6 @@ class SystemController(rest.RestController):
rpc_isystem[field] = patched_system[field]
if field == 'name':
name = rpc_isystem[field]
if field == 'contact':
contact = rpc_isystem[field]
if field == 'location':
location = rpc_isystem[field]
if field == 'system_mode':
system_mode = rpc_isystem[field]
if field == 'timezone':
@ -547,9 +541,6 @@ class SystemController(rest.RestController):
LOG.info("update system name")
pecan.request.rpcapi.configure_isystemname(pecan.request.context,
name)
if name or location or contact:
LOG.info("update SNMP config")
pecan.request.rpcapi.update_snmp_config(pecan.request.context)
if 'system_mode' in delta_handle:
LOG.info("update system mode %s" % system_mode)
pecan.request.rpcapi.update_system_mode_config(

View File

@ -1,240 +0,0 @@
#!/usr/bin/env python
#
# Copyright (c) 2013-2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# All Rights Reserved.
#
import jsonpatch
import pecan
from pecan import rest
import wsme
from wsme import types as wtypes
import wsmeext.pecan as wsme_pecan
from oslo_log import log
from oslo_utils import excutils
from sysinv.api.controllers.v1 import base
from sysinv.api.controllers.v1 import collection
from sysinv.api.controllers.v1 import link
from sysinv.api.controllers.v1 import types
from sysinv.api.controllers.v1 import utils as api_utils
from sysinv.common import exception
from sysinv.common import utils as cutils
from sysinv import objects
LOG = log.getLogger(__name__)
class TrapDestPatchType(types.JsonPatchType):
pass
class TrapDest(base.APIBase):
"""API representation of a trap destination.
This class enforces type checking and value constraints, and converts
between the internal object model and the API representation of
a itrapdest.
"""
uuid = types.uuid
"The UUID of the itrapdest"
ip_address = wsme.wsattr(wtypes.text, mandatory=True)
"The ip address of the trap destination"
community = wsme.wsattr(wtypes.text, mandatory=True)
"The community of which the trap destination is a member"
port = int
"The port number of which the SNMP manager is listening for trap"
type = wtypes.text
"The SNMP version of the trap message"
transport = wtypes.text
"The SNMP version of the trap message"
links = [link.Link]
"A list containing a self link and associated trap destination links"
def __init__(self, **kwargs):
self.fields = objects.trapdest.fields.keys()
for k in self.fields:
setattr(self, k, kwargs.get(k))
@classmethod
def convert_with_links(cls, rpc_itrapdest, expand=True):
minimum_fields = ['id', 'uuid', 'ip_address',
'community', 'port',
'type', 'transport']
fields = minimum_fields if not expand else None
itrap = TrapDest.from_rpc_object(rpc_itrapdest, fields)
itrap.links = [link.Link.make_link('self', pecan.request.host_url,
'itrapdest', itrap.uuid),
link.Link.make_link('bookmark',
pecan.request.host_url,
'itrapdest', itrap.uuid,
bookmark=True)
]
return itrap
class TrapDestCollection(collection.Collection):
"""API representation of a collection of itrapdest."""
itrapdest = [TrapDest]
"A list containing itrapdest objects"
def __init__(self, **kwargs):
self._type = 'itrapdest'
@classmethod
def convert_with_links(cls, itrapdest, limit, url=None,
expand=False, **kwargs):
collection = TrapDestCollection()
collection.itrapdest = [TrapDest.convert_with_links(ch, expand)
for ch in itrapdest]
# url = url or None
collection.next = collection.get_next(limit, url=url, **kwargs)
return collection
LOCK_NAME = 'TrapDestController'
class TrapDestController(rest.RestController):
"""REST controller for itrapdest."""
_custom_actions = {
'detail': ['GET'],
}
def _get_itrapdest_collection(self, marker, limit, sort_key, sort_dir,
expand=False, resource_url=None):
limit = api_utils.validate_limit(limit)
sort_dir = api_utils.validate_sort_dir(sort_dir)
marker_obj = None
if marker:
marker_obj = objects.trapdest.get_by_uuid(pecan.request.context,
marker)
itrap = pecan.request.dbapi.itrapdest_get_list(limit, marker_obj,
sort_key=sort_key,
sort_dir=sort_dir)
return TrapDestCollection.convert_with_links(itrap, limit,
url=resource_url,
expand=expand,
sort_key=sort_key,
sort_dir=sort_dir)
@wsme_pecan.wsexpose(TrapDestCollection, types.uuid,
int, wtypes.text, wtypes.text)
def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc'):
"""Retrieve a list of itrapdests.
:param marker: pagination marker for large data sets.
:param limit: maximum number of resources to return in a single result.
:param sort_key: column to sort results by. Default: id.
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
"""
return self._get_itrapdest_collection(marker, limit, sort_key, sort_dir)
@wsme_pecan.wsexpose(TrapDestCollection, types.uuid, int,
wtypes.text, wtypes.text)
def detail(self, marker=None, limit=None, sort_key='id', sort_dir='asc'):
"""Retrieve a list of itrapdest with detail.
:param marker: pagination marker for large data sets.
:param limit: maximum number of resources to return in a single result.
:param sort_key: column to sort results by. Default: id.
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
"""
# /detail should only work agaist collections
parent = pecan.request.path.split('/')[:-1][-1]
if parent != "itrapdest":
raise exception.HTTPNotFound
expand = True
resource_url = '/'.join(['itrapdest', 'detail'])
return self._get_itrapdest_collection(marker, limit, sort_key, sort_dir,
expand, resource_url)
@wsme_pecan.wsexpose(TrapDest, wtypes.text)
def get_one(self, ip):
"""Retrieve information about the given itrapdest.
:param itrapdest_uuid: UUID of a itrapdest.
"""
rpc_itrapdest = objects.trapdest.get_by_ip(
pecan.request.context, ip)
return TrapDest.convert_with_links(rpc_itrapdest)
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(TrapDest, body=TrapDest)
def post(self, itrapdest):
"""Create a new itrapdest.
:param itrapdest: a itrapdest within the request body.
"""
try:
new_itrapdest = pecan.request.dbapi.itrapdest_create(itrapdest.as_dict())
except Exception as e:
with excutils.save_and_reraise_exception():
LOG.exception(e)
# update snmpd.conf
pecan.request.rpcapi.update_snmp_config(pecan.request.context)
return itrapdest.convert_with_links(new_itrapdest)
@cutils.synchronized(LOCK_NAME)
@wsme.validate(types.uuid, [TrapDestPatchType])
@wsme_pecan.wsexpose(TrapDest, types.uuid, body=[TrapDestPatchType])
def patch(self, itrapdest_uuid, patch):
"""Update an existing itrapdest.
:param itrapdest_uuid: UUID of a itrapdest.
:param patch: a json PATCH document to apply to this itrapdest.
"""
rpc_itrapdest = objects.trapdest.get_by_uuid(pecan.request.context,
itrapdest_uuid)
try:
itrap = TrapDest(**jsonpatch.apply_patch(rpc_itrapdest.as_dict(),
jsonpatch.JsonPatch(patch)))
except api_utils.JSONPATCH_EXCEPTIONS as e:
raise exception.PatchError(patch=patch, reason=e)
# Update only the fields that have changed
ip = ""
for field in objects.trapdest.fields:
if rpc_itrapdest[field] != getattr(itrap, field):
rpc_itrapdest[field] = getattr(itrap, field)
if field == 'ip_address':
ip = rpc_itrapdest[field]
rpc_itrapdest.save()
if ip:
LOG.debug("Modify destination IP: uuid (%s), ip (%s",
itrapdest_uuid, ip)
return TrapDest.convert_with_links(rpc_itrapdest)
@cutils.synchronized(LOCK_NAME)
@wsme_pecan.wsexpose(None, wtypes.text, status_code=204)
def delete(self, ip):
"""Delete a itrapdest.
:param ip: ip address of a itrapdest.
"""
pecan.request.dbapi.itrapdest_destroy(ip)
# update snmpd.conf
pecan.request.rpcapi.update_snmp_config(pecan.request.context)

View File

@ -479,18 +479,10 @@ class StorageExternalAlreadyExists(Conflict):
message = _("A StorageExternal with UUID %(uuid)s already exists.")
class TrapDestAlreadyExists(Conflict):
message = _("A TrapDest with UUID %(uuid)s already exists.")
class UserAlreadyExists(Conflict):
message = _("A User with UUID %(uuid)s already exists.")
class CommunityAlreadyExists(Conflict):
message = _("A Community with UUID %(uuid)s already exists.")
class ServiceAlreadyExists(Conflict):
message = _("A Service with UUID %(uuid)s already exists.")

View File

@ -9906,17 +9906,6 @@ class ConductorManager(service.PeriodicService):
"""
self._openstack.delete_barbican_secret(context=context, name=name)
def update_snmp_config(self, context):
"""Update the snmpd configuration"""
personalities = [constants.CONTROLLER]
config_uuid = self._config_update_hosts(context, personalities)
config_dict = {
"personalities": personalities,
"classes": ['platform::snmp::runtime',
'platform::fm::runtime'],
}
self._config_apply_runtime_manifest(context, config_uuid, config_dict)
def get_ceph_pools_config(self, context):
return self._ceph.get_pools_config()

View File

@ -1419,17 +1419,6 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
self.make_msg('delete_barbican_secret',
name=name))
def update_snmp_config(self, context):
"""Synchronously, have a conductor configure the SNMP configuration.
Does the following tasks:
- Update puppet hiera configuration file and apply run time manifest
:param context: request context.
"""
return self.call(context,
self.make_msg('update_snmp_config'))
def ceph_manager_config_complete(self, context, applied_config):
self.call(context,
self.make_msg('ceph_service_config_complete',

View File

@ -16,7 +16,7 @@
# License for the specific language governing permissions and limitations
# under the License.
#
# Copyright (c) 2013-2019 Wind River Systems, Inc.
# Copyright (c) 2013-2020 Wind River Systems, Inc.
#
@ -1616,100 +1616,6 @@ class Connection(object):
:param ipv_id: The id or uuid of an ipv.
"""
@abc.abstractmethod
def itrapdest_create(self, values):
"""Create a trap destination entry.
param values: A dict containing several items used to identify
a trap destination
:returns: An itrapdest.
"""
@abc.abstractmethod
def itrapdest_get(self, iid):
"""Return an itrapdest.
:param iid: The id of an itrapdest.
:returns: An itrapdest.
"""
@abc.abstractmethod
def itrapdest_get_list(self, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Return a list of itrapdest.
"""
@abc.abstractmethod
def itrapdest_get_by_ip(self, ip):
"""Return an itrapdest.
:param ip: The ip address of an itrapdest.
:returns: An itrapdest.
"""
@abc.abstractmethod
def itrapdest_update(self, iid, values):
"""Update properties of an itrapdest.
:param node: The id of an itrapdest.
:param values: Dict of values to update.
:returns: An itrapdest.
"""
@abc.abstractmethod
def itrapdest_destroy(self, ip):
"""Destroy an itrapdest.
:param ip: The ip address of an itrapdest.
"""
@abc.abstractmethod
def icommunity_create(self, values):
"""Create a community entry.
param values: A dict containing several items used to identify
a community entry
:returns: An icommunity.
"""
@abc.abstractmethod
def icommunity_get(self, uuid):
"""Return an icommunity.
:param uuid: The id of an icommunity.
:returns: An icommunity.
"""
@abc.abstractmethod
def icommunity_get_list(self, limit=None, marker=None,
sort_key=None, sort_dir=None):
"""Return a list of icommunity.
"""
@abc.abstractmethod
def icommunity_get_by_name(self, name):
"""Return an icommunity.
:param name: The community name of an icommunity.
:returns: An icommunity.
"""
@abc.abstractmethod
def icommunity_update(self, iid, values):
"""Update properties of an icommunity.
:param node: The id of an icommunity.
:param values: Dict of values to update.
:returns: An icommunity.
"""
@abc.abstractmethod
def icommunity_destroy(self, name):
"""Destroy an icommunity.
:param name: The name of an icommunity.
"""
@abc.abstractmethod
def iuser_create(self, values):
"""Create a new iuser for an isystem

View File

@ -3418,145 +3418,6 @@ class Connection(api.Connection):
filter_by(id=ipv_id).\
delete()
@objects.objectify(objects.trapdest)
def itrapdest_create(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
itrapdest = models.itrapdest()
itrapdest.update(values)
with _session_for_write() as session:
try:
session.add(itrapdest)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.TrapDestAlreadyExists(uuid=values['uuid'])
return itrapdest
@objects.objectify(objects.trapdest)
def itrapdest_get(self, iid):
query = model_query(models.itrapdest)
query = add_identity_filter(query, iid)
try:
result = query.one()
except NoResultFound:
raise exception.NotFound(iid)
return result
@objects.objectify(objects.trapdest)
def itrapdest_get_list(self, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.itrapdest)
return _paginate_query(models.itrapdest, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.trapdest)
def itrapdest_get_by_ip(self, ip):
result = model_query(models.itrapdest, read_deleted="no").\
filter_by(ip_address=ip).\
first()
if not result:
raise exception.NotFound(ip)
return result
@objects.objectify(objects.trapdest)
def itrapdest_update(self, iid, values):
with _session_for_write() as session:
query = model_query(models.itrapdest, session=session)
query = add_identity_filter(query, iid)
count = query.update(values, synchronize_session='fetch')
if count != 1:
raise exception.NotFound(iid)
return query.one()
def itrapdest_destroy(self, ip):
with _session_for_write() as session:
query = model_query(models.itrapdest, session=session)
query = add_identity_filter(query, ip, use_ipaddress=True)
try:
query.one()
except NoResultFound:
raise exception.NotFound(ip)
query.delete()
@objects.objectify(objects.community)
def icommunity_create(self, values):
if not values.get('uuid'):
values['uuid'] = uuidutils.generate_uuid()
icommunity = models.icommunity()
icommunity.update(values)
with _session_for_write() as session:
try:
session.add(icommunity)
session.flush()
except db_exc.DBDuplicateEntry:
raise exception.CommunityAlreadyExists(uuid=values['uuid'])
return icommunity
@objects.objectify(objects.community)
def icommunity_get(self, iid):
query = model_query(models.icommunity)
query = add_identity_filter(query, iid)
try:
result = query.one()
except NoResultFound:
raise exception.NotFound(iid)
return result
@objects.objectify(objects.community)
def icommunity_get_list(self, limit=None, marker=None,
sort_key=None, sort_dir=None):
query = model_query(models.icommunity)
return _paginate_query(models.icommunity, limit, marker,
sort_key, sort_dir, query)
@objects.objectify(objects.community)
def icommunity_get_by_name(self, name):
result = model_query(models.icommunity, read_deleted="no").\
filter_by(community=name).\
first()
if not result:
raise exception.NotFound(name)
return result
@objects.objectify(objects.community)
def icommunity_update(self, iid, values):
with _session_for_write() as session:
query = model_query(models.icommunity, session=session)
query = add_identity_filter(query, iid)
count = query.update(values, synchronize_session='fetch')
if count != 1:
raise exception.NotFound(iid)
return query.one()
def icommunity_destroy(self, name):
with _session_for_write() as session:
query = model_query(models.icommunity, session=session)
query = add_identity_filter(query, name, use_community=True)
try:
query.one()
except NoResultFound:
raise exception.NotFound(name)
query.delete()
def _user_get(self, server):
# server may be passed as a string. It may be uuid or Int.
# server = int(server)

View File

@ -0,0 +1,53 @@
#
# Copyright (c) 2020 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
from sqlalchemy import Enum
from sqlalchemy import MetaData
from sqlalchemy import Table
from sqlalchemy.dialects import postgresql
ENGINE = 'InnoDB'
CHARSET = 'utf8'
def upgrade(migrate_engine):
"""
This database upgrade removes host-based
snmp related table (community and trapdest)
"""
meta = MetaData()
meta.bind = migrate_engine
i_community = Table('i_community', meta, autoload=True)
i_community.drop()
i_trap_destination = Table('i_trap_destination', meta, autoload=True)
i_trap_destination.drop()
if migrate_engine.url.get_dialect() is postgresql.dialect:
old_typeEnum = Enum('snmpv2c_trap',
'reserve1',
'reserve2',
name='snmpVersionEnum')
old_transportEnum = Enum('udp',
'reserve1',
'reserve2',
name='snmpTransportType')
old_accessEnum = Enum('ro',
'rw',
'reserve1',
'reserve2',
name='accessEnum')
old_typeEnum.drop(bind=migrate_engine, checkfirst=False)
old_transportEnum.drop(bind=migrate_engine, checkfirst=False)
old_accessEnum.drop(bind=migrate_engine, checkfirst=False)
def downgrade(migrate_engine):
# Downgrade is unsupported in this release.
raise NotImplementedError('SysInv database downgrade is unsupported.')

View File

@ -718,46 +718,6 @@ class journal(Base):
foristorid = Column(Integer, ForeignKey('i_istor.id', ondelete='CASCADE'))
class itrapdest(Base):
snmpEnum = Enum('snmpv2c_trap',
'reserve1',
'reserve2',
name='snmpVersionEnum')
transportEnum = Enum('udp',
'reserve1',
'reserve2',
name='snmpTransportType')
__tablename__ = 'i_trap_destination'
id = Column(Integer, primary_key=True)
uuid = Column(String(36), unique=True)
ip_address = Column(String(255), unique=True, index=True)
community = Column(String(255))
port = Column(Integer, default=162)
type = Column(snmpEnum, default='snmpv2c_trap')
transport = Column(transportEnum, default='udp')
class icommunity(Base):
accessEnum = Enum('ro',
'rw',
'reserve1',
'reserve2',
name='accessEnum')
__tablename__ = 'i_community'
id = Column(Integer, primary_key=True)
uuid = Column(String(36), unique=True)
community = Column(String(255), unique=True, index=True)
view = Column(String(255), default='.1')
access = Column(accessEnum, default='ro')
class iuser(Base):
__tablename__ = 'i_user'

View File

@ -24,7 +24,6 @@ from sysinv.objects import address_pool
from sysinv.objects import ceph_mon
from sysinv.objects import certificate
from sysinv.objects import cluster
from sysinv.objects import community
from sysinv.objects import controller_fs
from sysinv.objects import cpu
from sysinv.objects import datanetwork
@ -88,7 +87,6 @@ from sysinv.objects import storage_backend
from sysinv.objects import storage_ceph
from sysinv.objects import storage_lvm
from sysinv.objects import system
from sysinv.objects import trapdest
from sysinv.objects import user
from sysinv.objects import service
from sysinv.objects import tpmconfig
@ -149,8 +147,6 @@ storage = storage.Storage
journal = journal.Journal
lvg = lvg.LVG
pv = pv.PV
trapdest = trapdest.TrapDest
community = community.Community
user = user.User
dns = dns.DNS
ntp = ntp.NTP
@ -226,8 +222,6 @@ __all__ = ("system",
"journal",
"lvg",
"pv",
"trapdest",
"community",
"user",
"dns",
"ntp",

View File

@ -1,38 +0,0 @@
#
# Copyright (c) 2013-2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# coding=utf-8
#
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
class Community(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'community': utils.str_or_none,
'view': utils.str_or_none,
'access': utils.str_or_none,
}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
return cls.dbapi.icommunity_get(uuid)
@base.remotable_classmethod
def get_by_name(cls, context, name):
return cls.dbapi.icommunity_get_by_name(name)
def save_changes(self, context, updates):
self.dbapi.icommunity_update(self.uuid, # pylint: disable=no-member
updates)

View File

@ -1,40 +0,0 @@
#
# Copyright (c) 2013-2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# coding=utf-8
#
from sysinv.db import api as db_api
from sysinv.objects import base
from sysinv.objects import utils
class TrapDest(base.SysinvObject):
dbapi = db_api.get_instance()
fields = {
'id': int,
'uuid': utils.str_or_none,
'ip_address': utils.str_or_none,
'community': utils.str_or_none,
'port': utils.int_or_none,
'type': utils.str_or_none,
'transport': utils.str_or_none,
}
@base.remotable_classmethod
def get_by_uuid(cls, context, uuid):
return cls.dbapi.itrapdest_get(uuid)
@base.remotable_classmethod
def get_by_ip(cls, context, ip):
return cls.dbapi.itrapdest_get_by_ip(ip)
def save_changes(self, context, updates):
self.dbapi.itrapdest_update(self.uuid, # pylint: disable=no-member
updates)

View File

@ -1,6 +1,4 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright (c) 2016 Wind River Systems, Inc.
# Copyright (c) 2016-2020 Wind River Systems, Inc.
# Copyright 2010-2011 OpenStack Foundation
# Copyright 2012-2013 IBM Corp.
# All Rights Reserved.
@ -841,37 +839,6 @@ class TestMigrations(BaseMigrationTestCase, WalkVersionsMixin):
self.assertTrue(isinstance(services.c[col].type,
getattr(sqlalchemy.types, coltype)))
traps = db_utils.get_table(engine, 'i_trap_destination')
traps_col = {
'id': 'Integer', 'uuid': 'String', 'deleted_at': 'DateTime',
'created_at': 'DateTime', 'updated_at': 'DateTime', # 'type': 'typeEnum',
'ip_address': 'String', 'community': 'String', 'port': 'Integer',
# 'transport': 'transportEnum',
}
for col, coltype in traps_col.items():
self.assertTrue(isinstance(traps.c[col].type,
getattr(sqlalchemy.types, coltype)))
traps_enums_col = [
'type', 'transport'
]
for col in traps_enums_col:
self.assertColumnExists(engine, 'i_trap_destination', col)
communities = db_utils.get_table(engine, 'i_community')
communities_col = {
'id': 'Integer', 'uuid': 'String', 'deleted_at': 'DateTime',
'created_at': 'DateTime', 'updated_at': 'DateTime', # 'access': 'accessEnum',
'community': 'String', 'view': 'String',
}
for col, coltype in communities_col.items():
self.assertTrue(isinstance(communities.c[col].type,
getattr(sqlalchemy.types, coltype)))
communities_enums_col = [
'access'
]
for col in communities_enums_col:
self.assertColumnExists(engine, 'i_community', col)
users = db_utils.get_table(engine, 'i_user')
users_col = {
'id': 'Integer', 'uuid': 'String', 'deleted_at': 'DateTime',