StarlingX open source release updates

Signed-off-by: Dean Troyer <dtroyer@gmail.com>
This commit is contained in:
Dean Troyer 2018-05-30 16:16:06 -07:00
parent 17d46f6ab8
commit 6cd8940170
90 changed files with 15576 additions and 0 deletions

7
CONTRIBUTORS.wrs Normal file
View File

@ -0,0 +1,7 @@
The following contributors from Wind River have developed the seed code in this
repository. We look forward to community collaboration and contributions for
additional features, enhancements and refactoring.
Contributors:
=============
Tao Liu <Tao.Liu@windriver.com>

202
LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

5
README.rst Normal file
View File

@ -0,0 +1,5 @@
=========
stx-fault
=========
StarlingX Fault Management

6
fm-api/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
!.distro
.distro/centos7/rpmbuild/RPMS
.distro/centos7/rpmbuild/SRPMS
.distro/centos7/rpmbuild/BUILD
.distro/centos7/rpmbuild/BUILDROOT
.distro/centos7/rpmbuild/SOURCES/fm-api*tar.gz

202
fm-api/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

14
fm-api/PKG-INFO Normal file
View File

@ -0,0 +1,14 @@
Metadata-Version: 1.1
Name: fm-api
Version: 1.0
Summary: CGTS Platform Fault Management Python API Package
Home-page:
Author: Windriver
Author-email: info@windriver.com
License: Apache-2.0
Description: CGTS platform Fault Management Client Library that provides APIs \
for applications to raise/clear/update active alarms.
Platform: UNKNOWN

5
fm-api/centos/build_srpm.data Executable file
View File

@ -0,0 +1,5 @@
SRC_DIR="."
COPY_LIST="$PKG_BASE/LICENSE"
EXCLUDE_FILES_FROM_TAR="centos"
TIS_PATCH_VER=13

66
fm-api/centos/fm-api.spec Normal file
View File

@ -0,0 +1,66 @@
Summary: CGTS Platform Fault Management Python API Package
Name: fm-api
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
Source1: LICENSE
%define debug_package %{nil}
BuildRequires: python-setuptools
%description
CGTS platform Fault Management Client Library that provides APIs
for applications to raise/clear/update active alarms.
%package -n fm-api-doc
Summary: fm-api deploy doc
Group: doc
Provides: fm-api-doc
%description -n fm-api-doc
Contains contansts which is to be used by fm-doc package to validate
the Alarms & Logs Doc Yaml file
%define pythonroot /usr/lib64/python2.7/site-packages
%define cgcs_doc_deploy_dir /opt/deploy/cgcs_doc
%prep
%setup
%build
%{__python} setup.py build
%install
%{__python} setup.py install --root=$RPM_BUILD_ROOT \
--install-lib=%{pythonroot} \
--prefix=/usr \
--install-data=/usr/share \
--single-version-externally-managed
CGCS_DOC_DEPLOY=$RPM_BUILD_ROOT/%{cgcs_doc_deploy_dir}
install -d $CGCS_DOC_DEPLOY
# install constants.py in CGCS_DOC_DEPLOY_DIR
# used by fm-doc package to validate the Alarms & Logs Doc Yaml file
install -m 644 fm_api/constants.py $CGCS_DOC_DEPLOY
%clean
rm -rf $RPM_BUILD_ROOT
# Note: RPM package name is fm-api but import package name is fm_api so can't
# use '%{name}'.
%files
%license LICENSE
%defattr(-,root,root,-)
%dir %{pythonroot}/fm_api
%{pythonroot}/fm_api/*
%dir %{pythonroot}/fm_api-%{version}.0-py2.7.egg-info
%{pythonroot}/fm_api-%{version}.0-py2.7.egg-info/*
%files -n fm-api-doc
%defattr(-,root,root,-)
%{cgcs_doc_deploy_dir}/*

11
fm-api/fm_api/__init__.py Normal file
View File

@ -0,0 +1,11 @@
#
# Copyright (c) 2013-2014 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2014 Wind River Inc.
# All Rights Reserved.
#

498
fm-api/fm_api/constants.py Executable file
View File

@ -0,0 +1,498 @@
#
# Copyright (c) 2013-2017 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# -*- encoding: utf-8 -*-
#
#
# Author: Tao Liu
#
# This file contains CGTS alarm definitions. The alarm ids that used by Python
# applications are defined here. For a completed alarm id list see the alarm ids
# that used by the C/C++ applications defined in
# fm-common/sources/fmAlarm.h
################################################################################
#
# Please make sure that all FM_ALARM_ID_xxx entries in this file
# have a corresponding Alarm record entry in file events.yaml
#
################################################################################
# alarm sub entity types
FM_ENTITY_TYPE_SYSTEM = 'system'
FM_ENTITY_TYPE_HOST = 'host'
FM_ENTITY_TYPE_PORT = 'port'
FM_ENTITY_TYPE_INTERFACE = 'interface'
FM_ENTITY_TYPE_SERVICE = 'service'
FM_ENTITY_TYPE_AGENT = 'agent'
FM_ENTITY_TYPE_PROVIDERNET = 'providernet'
FM_ENTITY_TYPE_INSTANCE = 'instance'
FM_ENTITY_TYPE_CLUSTER = 'cluster'
FM_ENTITY_TYPE_NTP = 'ntp'
FM_ENTITY_TYPE_ML2DRIVER = 'ml2driver'
FM_ENTITY_TYPE_PV = 'pv'
FM_ENTITY_TYPE_BGP_PEER = "bgp-peer"
FM_ENTITY_TYPE_STORAGE_BACKEND = 'storage_backend'
FM_ENTITY_TYPE_SUBCLOUD = 'subcloud'
# alarm service sub entity values
FM_SERVICE_NETWORKING = 'networking'
# alarm_id = <Alarm Group ID>.<Alarm Event ID>
# <Alarm Group ID> = 000 - 999
# <Alarm Event ID> = 000 999
ALARM_GROUP_GENERAL = "100"
ALARM_GROUP_MAINTENANCE = "200"
ALARM_GROUP_BACKUP_RESTORE = "210"
ALARM_GROUP_SYSCONFIG = "250"
ALARM_GROUP_HOST_SERVICES = "270"
ALARM_GROUP_HYPERVISOR = "275"
ALARM_GROUP_DISTRIBUTED_CLOUD = "280"
ALARM_GROUP_NETWORK = "300"
ALARM_GROUP_HA = "400"
ALARM_GROUP_SECURITY = "500"
ALARM_GROUP_LICENSING = "600"
ALARM_GROUP_VM = "700"
ALARM_GROUP_STORAGE = "800"
ALARM_GROUP_SW_MGMT = "900"
# Maintenance Log id
FM_LOG_ID_HOST_DISCOVERED = ALARM_GROUP_MAINTENANCE + ".020"
# System Config Alarm id
FM_ALARM_ID_SYSCONFIG_OUT_OF_DATE = ALARM_GROUP_SYSCONFIG + ".001"
# This CONFIG_REQD alarm ID is deprecated and commented out to avoid its
# alarm id .010 from being unintentinally reused for some unrelated purpose.
# Deprecation followed the removal of the compute-config-complete command.
# FM_ALARM_ID_CONFIG_REQD = ALARM_GROUP_SYSCONFIG + ".010"
FM_ALARM_ID_CEPH_CACHE_TIER_CONFIG_OUT_OF_DATE = ALARM_GROUP_SYSCONFIG + ".002"
# Backup/Restore Alarm id
FM_ALARM_ID_BACKUP_IN_PROGRESS = ALARM_GROUP_BACKUP_RESTORE + ".001"
# Backup/Restore Log id
FM_LOG_ID_RESTORE_COMPLETE = ALARM_GROUP_BACKUP_RESTORE + ".101"
# Network alarm id
FM_ALARM_ID_NETWORK_PORT = ALARM_GROUP_NETWORK + ".001"
FM_ALARM_ID_NETWORK_INTERFACE = ALARM_GROUP_NETWORK + ".002"
FM_ALARM_ID_NETWORK_AGENT = ALARM_GROUP_NETWORK + ".003"
FM_ALARM_ID_NETWORK_PROVIDERNET = ALARM_GROUP_NETWORK + ".004"
FM_ALARM_ID_NETWORK_PROVIDERNET_CONNECTIVITY = ALARM_GROUP_NETWORK + ".005"
FM_ALARM_ID_NETWORK_ML2_DRIVER = ALARM_GROUP_NETWORK + ".010"
FM_ALARM_ID_NETWORK_OPENFLOW_CONTROLLER = ALARM_GROUP_NETWORK + ".012"
FM_ALARM_ID_NETWORK_OVSDB_MANAGER = ALARM_GROUP_NETWORK + ".014"
FM_ALARM_ID_NETWORK_BGP_PEER = ALARM_GROUP_NETWORK + ".016"
# Storage alarm id
FM_ALARM_ID_STORAGE_CEPH_CRITICAL = ALARM_GROUP_STORAGE + ".010"
FM_ALARM_ID_STORAGE_CEPH_MAJOR = ALARM_GROUP_STORAGE + ".011"
FM_ALARM_ID_STORAGE_CEPH = ALARM_GROUP_STORAGE + ".001"
FM_ALARM_ID_STORAGE_IMAGE = ALARM_GROUP_STORAGE + ".002"
FM_ALARM_ID_STORAGE_CEPH_FREE_SPACE = ALARM_GROUP_STORAGE + ".003"
FM_ALARM_ID_STORAGE_CINDER_IO_BUILDING = ALARM_GROUP_STORAGE + ".100"
FM_ALARM_ID_STORAGE_CINDER_IO_LIMITING = ALARM_GROUP_STORAGE + ".101"
FM_ALARM_ID_STORAGE_PV_FAILED = ALARM_GROUP_STORAGE + ".102"
# Alarm .103 is reserved for LVM thin pool metadata alarm
FM_ALARM_ID_STORAGE_BACKEND_FAILED = ALARM_GROUP_STORAGE + ".104"
# Host-Services alarm id
FM_ALARM_ID_HOST_SERVICES_FAILED = ALARM_GROUP_HOST_SERVICES + ".001"
# Host-Services log id
FM_LOG_ID_HOST_SERVICES_FAILED = ALARM_GROUP_HOST_SERVICES + ".101"
FM_LOG_ID_HOST_SERVICES_ENABLED = ALARM_GROUP_HOST_SERVICES + ".102"
FM_LOG_ID_HOST_SERVICES_DISABLED = ALARM_GROUP_HOST_SERVICES + ".103"
# Hypervisor log id
FM_LOG_ID_HYPERVISOR_STATE_CHANGE = ALARM_GROUP_HYPERVISOR + ".001"
# Distributed Cloud alarm id
FM_ALARM_ID_DC_SUBCLOUD_OFFLINE = ALARM_GROUP_DISTRIBUTED_CLOUD + ".001"
FM_ALARM_ID_DC_SUBCLOUD_RESOURCE_OUT_OF_SYNC = ALARM_GROUP_DISTRIBUTED_CLOUD + ".002"
# VM alarm id
FM_ALARM_ID_VM_FAILED = ALARM_GROUP_VM + ".001"
FM_ALARM_ID_VM_PAUSED = ALARM_GROUP_VM + ".002"
FM_ALARM_ID_VM_SUSPENDED = ALARM_GROUP_VM + ".003"
FM_ALARM_ID_VM_STOPPED = ALARM_GROUP_VM + ".004"
FM_ALARM_ID_VM_REBOOTING = ALARM_GROUP_VM + ".005"
FM_ALARM_ID_VM_REBUILDING = ALARM_GROUP_VM + ".006"
FM_ALARM_ID_VM_EVACUATING = ALARM_GROUP_VM + ".007"
FM_ALARM_ID_VM_LIVE_MIGRATING = ALARM_GROUP_VM + ".008"
FM_ALARM_ID_VM_COLD_MIGRATING = ALARM_GROUP_VM + ".009"
FM_ALARM_ID_VM_COLD_MIGRATED = ALARM_GROUP_VM + ".010"
FM_ALARM_ID_VM_COLD_MIGRATE_REVERTING = ALARM_GROUP_VM + ".011"
FM_ALARM_ID_VM_RESIZING = ALARM_GROUP_VM + ".012"
FM_ALARM_ID_VM_RESIZED = ALARM_GROUP_VM + ".013"
FM_ALARM_ID_VM_RESIZE_REVERTING = ALARM_GROUP_VM + ".014"
FM_ALARM_ID_VM_GUEST_HEARTBEAT = ALARM_GROUP_VM + ".015"
FM_ALARM_ID_VM_MULTI_NODE_RECOVERY_MODE = ALARM_GROUP_VM + ".016"
FM_ALARM_ID_VM_GROUP_POLICY_CONFLICT = ALARM_GROUP_VM + ".017"
# VM log id
FM_LOG_ID_VM_ENABLED = ALARM_GROUP_VM + ".101"
FM_LOG_ID_VM_FAILED = ALARM_GROUP_VM + ".102"
FM_LOG_ID_VM_CREATE = ALARM_GROUP_VM + ".103"
FM_LOG_ID_VM_CREATING = ALARM_GROUP_VM + ".104"
FM_LOG_ID_VM_CREATE_REJECTED = ALARM_GROUP_VM + ".105"
FM_LOG_ID_VM_CREATE_CANCELLED = ALARM_GROUP_VM + ".106"
FM_LOG_ID_VM_CREATE_FAILED = ALARM_GROUP_VM + ".107"
FM_LOG_ID_VM_CREATED = ALARM_GROUP_VM + ".108"
FM_LOG_ID_VM_DELETE = ALARM_GROUP_VM + ".109"
FM_LOG_ID_VM_DELETING = ALARM_GROUP_VM + ".110"
FM_LOG_ID_VM_DELETE_REJECTED = ALARM_GROUP_VM + ".111"
FM_LOG_ID_VM_DELETE_CANCELLED = ALARM_GROUP_VM + ".112"
FM_LOG_ID_VM_DELETE_FAILED = ALARM_GROUP_VM + ".113"
FM_LOG_ID_VM_DELETED = ALARM_GROUP_VM + ".114"
FM_LOG_ID_VM_PAUSE = ALARM_GROUP_VM + ".115"
FM_LOG_ID_VM_PAUSING = ALARM_GROUP_VM + ".116"
FM_LOG_ID_VM_PAUSE_REJECTED = ALARM_GROUP_VM + ".117"
FM_LOG_ID_VM_PAUSE_CANCELLED = ALARM_GROUP_VM + ".118"
FM_LOG_ID_VM_PAUSE_FAILED = ALARM_GROUP_VM + ".119"
FM_LOG_ID_VM_PAUSED = ALARM_GROUP_VM + ".120"
FM_LOG_ID_VM_UNPAUSE = ALARM_GROUP_VM + ".121"
FM_LOG_ID_VM_UNPAUSING = ALARM_GROUP_VM + ".122"
FM_LOG_ID_VM_UNPAUSE_REJECTED = ALARM_GROUP_VM + ".123"
FM_LOG_ID_VM_UNPAUSE_CANCELLED = ALARM_GROUP_VM + ".124"
FM_LOG_ID_VM_UNPAUSE_FAILED = ALARM_GROUP_VM + ".125"
FM_LOG_ID_VM_UNPAUSED = ALARM_GROUP_VM + ".126"
FM_LOG_ID_VM_SUSPEND = ALARM_GROUP_VM + ".127"
FM_LOG_ID_VM_SUSPENDING = ALARM_GROUP_VM + ".128"
FM_LOG_ID_VM_SUSPEND_REJECTED = ALARM_GROUP_VM + ".129"
FM_LOG_ID_VM_SUSPEND_CANCELLED = ALARM_GROUP_VM + ".130"
FM_LOG_ID_VM_SUSPEND_FAILED = ALARM_GROUP_VM + ".131"
FM_LOG_ID_VM_SUSPENDED = ALARM_GROUP_VM + ".132"
FM_LOG_ID_VM_RESUME = ALARM_GROUP_VM + ".133"
FM_LOG_ID_VM_RESUMING = ALARM_GROUP_VM + ".134"
FM_LOG_ID_VM_RESUME_REJECTED = ALARM_GROUP_VM + ".135"
FM_LOG_ID_VM_RESUME_CANCELLED = ALARM_GROUP_VM + ".136"
FM_LOG_ID_VM_RESUME_FAILED = ALARM_GROUP_VM + ".137"
FM_LOG_ID_VM_RESUMED = ALARM_GROUP_VM + ".138"
FM_LOG_ID_VM_START = ALARM_GROUP_VM + ".139"
FM_LOG_ID_VM_STARTING = ALARM_GROUP_VM + ".140"
FM_LOG_ID_VM_START_REJECTED = ALARM_GROUP_VM + ".141"
FM_LOG_ID_VM_START_CANCELLED = ALARM_GROUP_VM + ".142"
FM_LOG_ID_VM_START_FAILED = ALARM_GROUP_VM + ".143"
FM_LOG_ID_VM_STARTED = ALARM_GROUP_VM + ".144"
FM_LOG_ID_VM_STOP = ALARM_GROUP_VM + ".145"
FM_LOG_ID_VM_STOPPING = ALARM_GROUP_VM + ".146"
FM_LOG_ID_VM_STOP_REJECTED = ALARM_GROUP_VM + ".147"
FM_LOG_ID_VM_STOP_CANCELLED = ALARM_GROUP_VM + ".148"
FM_LOG_ID_VM_STOP_FAILED = ALARM_GROUP_VM + ".149"
FM_LOG_ID_VM_STOPPED = ALARM_GROUP_VM + ".150"
FM_LOG_ID_VM_LIVE_MIGRATE = ALARM_GROUP_VM + ".151"
FM_LOG_ID_VM_LIVE_MIGRATING = ALARM_GROUP_VM + ".152"
FM_LOG_ID_VM_LIVE_MIGRATE_REJECTED = ALARM_GROUP_VM + ".153"
FM_LOG_ID_VM_LIVE_MIGRATE_CANCELLED = ALARM_GROUP_VM + ".154"
FM_LOG_ID_VM_LIVE_MIGRATE_FAILED = ALARM_GROUP_VM + ".155"
FM_LOG_ID_VM_LIVE_MIGRATED = ALARM_GROUP_VM + ".156"
FM_LOG_ID_VM_COLD_MIGRATE = ALARM_GROUP_VM + ".157"
FM_LOG_ID_VM_COLD_MIGRATING = ALARM_GROUP_VM + ".158"
FM_LOG_ID_VM_COLD_MIGRATE_REJECTED = ALARM_GROUP_VM + ".159"
FM_LOG_ID_VM_COLD_MIGRATE_CANCELLED = ALARM_GROUP_VM + ".160"
FM_LOG_ID_VM_COLD_MIGRATE_FAILED = ALARM_GROUP_VM + ".161"
FM_LOG_ID_VM_COLD_MIGRATED = ALARM_GROUP_VM + ".162"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRM = ALARM_GROUP_VM + ".163"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRMING = ALARM_GROUP_VM + ".164"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRM_REJECTED = ALARM_GROUP_VM + ".165"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRM_CANCELLED = ALARM_GROUP_VM + ".166"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRM_FAILED = ALARM_GROUP_VM + ".167"
FM_LOG_ID_VM_COLD_MIGRATE_CONFIRMED = ALARM_GROUP_VM + ".168"
FM_LOG_ID_VM_COLD_MIGRATE_REVERT = ALARM_GROUP_VM + ".169"
FM_LOG_ID_VM_COLD_MIGRATE_REVERTING = ALARM_GROUP_VM + ".170"
FM_LOG_ID_VM_COLD_MIGRATE_REVERT_REJECTED = ALARM_GROUP_VM + ".171"
FM_LOG_ID_VM_COLD_MIGRATE_REVERT_CANCELLED = ALARM_GROUP_VM + ".172"
FM_LOG_ID_VM_COLD_MIGRATE_REVERT_FAILED = ALARM_GROUP_VM + ".173"
FM_LOG_ID_VM_COLD_MIGRATE_REVERTED = ALARM_GROUP_VM + ".174"
FM_LOG_ID_VM_EVACUATE = ALARM_GROUP_VM + ".175"
FM_LOG_ID_VM_EVACUATING = ALARM_GROUP_VM + ".176"
FM_LOG_ID_VM_EVACUATE_REJECTED = ALARM_GROUP_VM + ".177"
FM_LOG_ID_VM_EVACUATE_CANCELLED = ALARM_GROUP_VM + ".178"
FM_LOG_ID_VM_EVACUATE_FAILED = ALARM_GROUP_VM + ".179"
FM_LOG_ID_VM_EVACUATED = ALARM_GROUP_VM + ".180"
FM_LOG_ID_VM_REBOOT = ALARM_GROUP_VM + ".181"
FM_LOG_ID_VM_REBOOTING = ALARM_GROUP_VM + ".182"
FM_LOG_ID_VM_REBOOT_REJECTED = ALARM_GROUP_VM + ".183"
FM_LOG_ID_VM_REBOOT_CANCELLED = ALARM_GROUP_VM + ".184"
FM_LOG_ID_VM_REBOOT_FAILED = ALARM_GROUP_VM + ".185"
FM_LOG_ID_VM_REBOOTED = ALARM_GROUP_VM + ".186"
FM_LOG_ID_VM_REBUILD = ALARM_GROUP_VM + ".187"
FM_LOG_ID_VM_REBUILDING = ALARM_GROUP_VM + ".188"
FM_LOG_ID_VM_REBUILD_REJECTED = ALARM_GROUP_VM + ".189"
FM_LOG_ID_VM_REBUILD_CANCELLED = ALARM_GROUP_VM + ".190"
FM_LOG_ID_VM_REBUILD_FAILED = ALARM_GROUP_VM + ".191"
FM_LOG_ID_VM_REBUILT = ALARM_GROUP_VM + ".192"
FM_LOG_ID_VM_RESIZE = ALARM_GROUP_VM + ".193"
FM_LOG_ID_VM_RESIZING = ALARM_GROUP_VM + ".194"
FM_LOG_ID_VM_RESIZE_REJECTED = ALARM_GROUP_VM + ".195"
FM_LOG_ID_VM_RESIZE_CANCELLED = ALARM_GROUP_VM + ".196"
FM_LOG_ID_VM_RESIZE_FAILED = ALARM_GROUP_VM + ".197"
FM_LOG_ID_VM_RESIZED = ALARM_GROUP_VM + ".198"
FM_LOG_ID_VM_RESIZE_CONFIRM = ALARM_GROUP_VM + ".199"
FM_LOG_ID_VM_RESIZE_CONFIRMING = ALARM_GROUP_VM + ".200"
FM_LOG_ID_VM_RESIZE_CONFIRM_REJECTED = ALARM_GROUP_VM + ".201"
FM_LOG_ID_VM_RESIZE_CONFIRM_CANCELLED = ALARM_GROUP_VM + ".202"
FM_LOG_ID_VM_RESIZE_CONFIRM_FAILED = ALARM_GROUP_VM + ".203"
FM_LOG_ID_VM_RESIZE_CONFIRMED = ALARM_GROUP_VM + ".204"
FM_LOG_ID_VM_RESIZE_REVERT = ALARM_GROUP_VM + ".205"
FM_LOG_ID_VM_RESIZE_REVERTING = ALARM_GROUP_VM + ".206"
FM_LOG_ID_VM_RESIZE_REVERT_REJECTED = ALARM_GROUP_VM + ".207"
FM_LOG_ID_VM_RESIZE_REVERT_CANCELLED = ALARM_GROUP_VM + ".208"
FM_LOG_ID_VM_RESIZE_REVERT_FAILED = ALARM_GROUP_VM + ".209"
FM_LOG_ID_VM_RESIZE_REVERTED = ALARM_GROUP_VM + ".210"
FM_LOG_ID_VM_GUEST_HEARTBEAT_ESTABLISHED = ALARM_GROUP_VM + ".211"
FM_LOG_ID_VM_GUEST_HEARTBEAT_DISCONNECTED = ALARM_GROUP_VM + ".212"
FM_LOG_ID_VM_GUEST_HEARTBEAT_FAILED = ALARM_GROUP_VM + ".213"
FM_LOG_ID_VM_RENAMED = ALARM_GROUP_VM + ".214"
FM_LOG_ID_VM_GUEST_HEALTH_CHECK_FAILED = ALARM_GROUP_VM + ".215"
FM_LOG_ID_VM_MULTI_NODE_RECOVERY_MODE_ENTER = ALARM_GROUP_VM + ".216"
FM_LOG_ID_VM_MULTI_NODE_RECOVERY_MODE_EXIT = ALARM_GROUP_VM + ".217"
# Patching alarm id
FM_ALARM_ID_PATCH_IN_PROGRESS = ALARM_GROUP_SW_MGMT + ".001"
FM_ALARM_ID_PATCH_HOST_INSTALL_FAILED = ALARM_GROUP_SW_MGMT + ".002"
FM_ALARM_ID_PATCH_OBS_IN_SYSTEM = ALARM_GROUP_SW_MGMT + ".003"
# Upgrades alarm id
FM_ALARM_ID_HOST_VERSION_MISMATCH = ALARM_GROUP_SW_MGMT + ".004"
FM_ALARM_ID_UPGRADE_IN_PROGRESS = ALARM_GROUP_SW_MGMT + ".005"
# Security log id
FM_LOG_ID_INVALID_PASSWORD = ALARM_GROUP_SECURITY + ".001"
FM_LOG_ID_USER_LOCKOUT = ALARM_GROUP_SECURITY + ".002"
# Security alarm id
FM_ALARM_ID_TPM_INIT = ALARM_GROUP_SECURITY + ".100"
# Security nonstandard certificate in use for patching alarm id
FM_ALARM_ID_NONSTANDARD_CERT_PATCH = ALARM_GROUP_SECURITY + ".101"
# Software Update Orchestration
FM_ALARM_ID_SW_PATCH_AUTO_APPLY_INPROGRESS = ALARM_GROUP_SW_MGMT + ".101"
FM_ALARM_ID_SW_PATCH_AUTO_APPLY_ABORTING = ALARM_GROUP_SW_MGMT + ".102"
FM_ALARM_ID_SW_PATCH_AUTO_APPLY_FAILED = ALARM_GROUP_SW_MGMT + ".103"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_START = ALARM_GROUP_SW_MGMT + ".111"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_INPROGRESS = ALARM_GROUP_SW_MGMT + ".112"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_REJECTED = ALARM_GROUP_SW_MGMT + ".113"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_CANCELLED = ALARM_GROUP_SW_MGMT + ".114"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_FAILED = ALARM_GROUP_SW_MGMT + ".115"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_COMPLETED = ALARM_GROUP_SW_MGMT + ".116"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORT = ALARM_GROUP_SW_MGMT + ".117"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORTING = ALARM_GROUP_SW_MGMT + ".118"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORT_REJECTED = ALARM_GROUP_SW_MGMT + ".119"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORT_FAILED = ALARM_GROUP_SW_MGMT + ".120"
FM_LOG_ID_SW_PATCH_AUTO_APPLY_ABORTED = ALARM_GROUP_SW_MGMT + ".121"
FM_ALARM_ID_SW_UPGRADE_AUTO_APPLY_INPROGRESS = ALARM_GROUP_SW_MGMT + ".201"
FM_ALARM_ID_SW_UPGRADE_AUTO_APPLY_ABORTING = ALARM_GROUP_SW_MGMT + ".202"
FM_ALARM_ID_SW_UPGRADE_AUTO_APPLY_FAILED = ALARM_GROUP_SW_MGMT + ".203"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_START = ALARM_GROUP_SW_MGMT + ".211"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_INPROGRESS = ALARM_GROUP_SW_MGMT + ".212"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_REJECTED = ALARM_GROUP_SW_MGMT + ".213"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_CANCELLED = ALARM_GROUP_SW_MGMT + ".214"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_FAILED = ALARM_GROUP_SW_MGMT + ".215"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_COMPLETED = ALARM_GROUP_SW_MGMT + ".216"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORT = ALARM_GROUP_SW_MGMT + ".217"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORTING = ALARM_GROUP_SW_MGMT + ".218"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORT_REJECTED = ALARM_GROUP_SW_MGMT + ".219"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORT_FAILED = ALARM_GROUP_SW_MGMT + ".220"
FM_LOG_ID_SW_UPGRADE_AUTO_APPLY_ABORTED = ALARM_GROUP_SW_MGMT + ".221"
FM_ALARM_STATE_SET = 'set'
FM_ALARM_STATE_CLEAR = 'clear'
FM_ALARM_STATE_MSG = 'msg'
FM_ALARM_TYPE_0 = 'other'
FM_ALARM_TYPE_1 = 'communication'
FM_ALARM_TYPE_2 = 'qos'
FM_ALARM_TYPE_3 = 'processing-error'
FM_ALARM_TYPE_4 = 'equipment'
FM_ALARM_TYPE_5 = 'environmental'
FM_ALARM_TYPE_6 = 'integrity-violation'
FM_ALARM_TYPE_7 = 'operational-violation'
FM_ALARM_TYPE_8 = 'physical-violation'
FM_ALARM_TYPE_9 = 'security-service-or-mechanism-violation'
FM_ALARM_TYPE_10 = 'time-domain-violation'
FM_ALARM_SEVERITY_CLEAR = 'clear'
FM_ALARM_SEVERITY_WARNING = 'warning'
FM_ALARM_SEVERITY_MINOR = 'minor'
FM_ALARM_SEVERITY_MAJOR = 'major'
FM_ALARM_SEVERITY_CRITICAL = 'critical'
FM_ALARM_OK_STATUS = "OK"
FM_ALARM_DEGRADED_STATUS = "degraded"
FM_ALARM_CRITICAL_STATUS = "critical"
ALARM_CRITICAL_REPLICATION = 'Potential data loss. No available OSDs in storage replication group '
ALARM_MAJOR_REPLICATION = 'Loss of replication in replication group '
ALARM_PROBABLE_CAUSE_1 = 'adaptor-error'
ALARM_PROBABLE_CAUSE_2 = 'application-subsystem-failure'
ALARM_PROBABLE_CAUSE_3 = 'bandwidth-reduced'
ALARM_PROBABLE_CAUSE_4 = 'call-establishment-error'
ALARM_PROBABLE_CAUSE_5 = 'communication-protocol-error'
ALARM_PROBABLE_CAUSE_6 = 'communication-subsystem-failure'
ALARM_PROBABLE_CAUSE_7 = 'configuration-or-customization-error'
ALARM_PROBABLE_CAUSE_8 = 'congestion'
ALARM_PROBABLE_CAUSE_9 = 'corrupt-data'
ALARM_PROBABLE_CAUSE_10 = 'cpu-cycles-limit-exceeded'
ALARM_PROBABLE_CAUSE_11 = 'dataset-or-modem-error'
ALARM_PROBABLE_CAUSE_12 = 'degraded-signal'
ALARM_PROBABLE_CAUSE_13 = 'dte-dce-interface-error'
ALARM_PROBABLE_CAUSE_14 = 'enclosure-door-open'
ALARM_PROBABLE_CAUSE_15 = 'equipment-malfunction'
ALARM_PROBABLE_CAUSE_16 = 'excessive-vibration'
ALARM_PROBABLE_CAUSE_17 = 'file-error'
ALARM_PROBABLE_CAUSE_18 = 'fire-detected'
ALARM_PROBABLE_CAUSE_19 = 'flood-detected'
ALARM_PROBABLE_CAUSE_20 = 'framing-error'
ALARM_PROBABLE_CAUSE_21 = 'heating-ventilation-cooling-system-problem'
ALARM_PROBABLE_CAUSE_22 = 'humidity-unacceptable'
ALARM_PROBABLE_CAUSE_23 = 'io-device-error'
ALARM_PROBABLE_CAUSE_24 = 'input-device-error'
ALARM_PROBABLE_CAUSE_25 = 'lan-error'
ALARM_PROBABLE_CAUSE_26 = 'leak-detected'
ALARM_PROBABLE_CAUSE_27 = 'local-node-transmission-error'
ALARM_PROBABLE_CAUSE_28 = 'loss-of-frame'
ALARM_PROBABLE_CAUSE_29 = 'loss-of-signal'
ALARM_PROBABLE_CAUSE_30 = 'material-supply-exhausted'
ALARM_PROBABLE_CAUSE_31 = 'multiplexer-problem'
ALARM_PROBABLE_CAUSE_32 = 'out-of-memory'
ALARM_PROBABLE_CAUSE_33 = 'output-device-error'
ALARM_PROBABLE_CAUSE_34 = 'performance-degraded'
ALARM_PROBABLE_CAUSE_35 = 'power-problem'
ALARM_PROBABLE_CAUSE_36 = 'processor-problem'
ALARM_PROBABLE_CAUSE_37 = 'pump-failure'
ALARM_PROBABLE_CAUSE_38 = 'queue-size-exceeded'
ALARM_PROBABLE_CAUSE_39 = 'receive-failure'
ALARM_PROBABLE_CAUSE_40 = 'receiver-failure'
ALARM_PROBABLE_CAUSE_41 = 'remote-node-transmission-error'
ALARM_PROBABLE_CAUSE_42 = 'resource-at-or-nearing-capacity'
ALARM_PROBABLE_CAUSE_43 = 'response-time-excessive'
ALARM_PROBABLE_CAUSE_44 = 'retransmission-rate-excessive'
ALARM_PROBABLE_CAUSE_45 = 'software-error'
ALARM_PROBABLE_CAUSE_46 = 'software-program-abnormally-terminated'
ALARM_PROBABLE_CAUSE_47 = 'software-program-error'
ALARM_PROBABLE_CAUSE_48 = 'storage-capacity-problem'
ALARM_PROBABLE_CAUSE_49 = 'temperature-unacceptable'
ALARM_PROBABLE_CAUSE_50 = 'threshold-crossed'
ALARM_PROBABLE_CAUSE_51 = 'timing-problem'
ALARM_PROBABLE_CAUSE_52 = 'toxic-leak-detected'
ALARM_PROBABLE_CAUSE_53 = 'transmit-failure'
ALARM_PROBABLE_CAUSE_54 = 'transmitter-failure'
ALARM_PROBABLE_CAUSE_55 = 'underlying-resource-unavailable'
ALARM_PROBABLE_CAUSE_56 = 'version-mismatch'
ALARM_PROBABLE_CAUSE_57 = 'duplicate-information'
ALARM_PROBABLE_CAUSE_58 = 'information-missing'
ALARM_PROBABLE_CAUSE_59 = 'information-modification-detected'
ALARM_PROBABLE_CAUSE_60 = 'information-out-of-sequence'
ALARM_PROBABLE_CAUSE_61 = 'unexpected-information'
ALARM_PROBABLE_CAUSE_62 = 'denial-of-service'
ALARM_PROBABLE_CAUSE_63 = 'out-of-service'
ALARM_PROBABLE_CAUSE_64 = 'procedural-error'
ALARM_PROBABLE_CAUSE_65 = 'unspecified-reason'
ALARM_PROBABLE_CAUSE_66 = 'cable-tamper'
ALARM_PROBABLE_CAUSE_67 = 'intrusion-detection'
ALARM_PROBABLE_CAUSE_68 = 'authentication-failure'
ALARM_PROBABLE_CAUSE_69 = 'breach-of-confidentiality'
ALARM_PROBABLE_CAUSE_70 = 'non-repudiation-failure'
ALARM_PROBABLE_CAUSE_71 = 'unauthorized-access-attempt'
ALARM_PROBABLE_CAUSE_72 = 'delayed-information'
ALARM_PROBABLE_CAUSE_73 = 'key-expired'
ALARM_PROBABLE_CAUSE_74 = 'out-of-hours-activity'
ALARM_PROBABLE_CAUSE_75 = 'configuration-out-of-date'
ALARM_PROBABLE_CAUSE_76 = 'configuration-provisioning-required'
ALARM_PROBABLE_CAUSE_UNKNOWN = 'unknown'
ALARM_STATE = [FM_ALARM_STATE_SET, FM_ALARM_STATE_CLEAR, FM_ALARM_STATE_MSG]
ALARM_TYPE = [FM_ALARM_TYPE_0, FM_ALARM_TYPE_1, FM_ALARM_TYPE_2,
FM_ALARM_TYPE_3, FM_ALARM_TYPE_4, FM_ALARM_TYPE_5,
FM_ALARM_TYPE_6, FM_ALARM_TYPE_7, FM_ALARM_TYPE_8,
FM_ALARM_TYPE_9, FM_ALARM_TYPE_10]
ALARM_SEVERITY = [FM_ALARM_SEVERITY_CLEAR, FM_ALARM_SEVERITY_WARNING,
FM_ALARM_SEVERITY_MINOR, FM_ALARM_SEVERITY_MAJOR,
FM_ALARM_SEVERITY_CRITICAL]
ALARM_STATUS = [FM_ALARM_OK_STATUS, FM_ALARM_DEGRADED_STATUS,
FM_ALARM_CRITICAL_STATUS]
ALARM_PROBABLE_CAUSE = [ALARM_PROBABLE_CAUSE_1, ALARM_PROBABLE_CAUSE_2,
ALARM_PROBABLE_CAUSE_3, ALARM_PROBABLE_CAUSE_4,
ALARM_PROBABLE_CAUSE_5, ALARM_PROBABLE_CAUSE_6,
ALARM_PROBABLE_CAUSE_7, ALARM_PROBABLE_CAUSE_8,
ALARM_PROBABLE_CAUSE_9, ALARM_PROBABLE_CAUSE_10,
ALARM_PROBABLE_CAUSE_11, ALARM_PROBABLE_CAUSE_12,
ALARM_PROBABLE_CAUSE_13, ALARM_PROBABLE_CAUSE_14,
ALARM_PROBABLE_CAUSE_15, ALARM_PROBABLE_CAUSE_16,
ALARM_PROBABLE_CAUSE_17, ALARM_PROBABLE_CAUSE_18,
ALARM_PROBABLE_CAUSE_19, ALARM_PROBABLE_CAUSE_20,
ALARM_PROBABLE_CAUSE_21, ALARM_PROBABLE_CAUSE_22,
ALARM_PROBABLE_CAUSE_23, ALARM_PROBABLE_CAUSE_24,
ALARM_PROBABLE_CAUSE_25, ALARM_PROBABLE_CAUSE_26,
ALARM_PROBABLE_CAUSE_27, ALARM_PROBABLE_CAUSE_28,
ALARM_PROBABLE_CAUSE_29, ALARM_PROBABLE_CAUSE_30,
ALARM_PROBABLE_CAUSE_31, ALARM_PROBABLE_CAUSE_32,
ALARM_PROBABLE_CAUSE_33, ALARM_PROBABLE_CAUSE_34,
ALARM_PROBABLE_CAUSE_35, ALARM_PROBABLE_CAUSE_36,
ALARM_PROBABLE_CAUSE_37, ALARM_PROBABLE_CAUSE_38,
ALARM_PROBABLE_CAUSE_39, ALARM_PROBABLE_CAUSE_40,
ALARM_PROBABLE_CAUSE_41, ALARM_PROBABLE_CAUSE_42,
ALARM_PROBABLE_CAUSE_43, ALARM_PROBABLE_CAUSE_44,
ALARM_PROBABLE_CAUSE_45, ALARM_PROBABLE_CAUSE_46,
ALARM_PROBABLE_CAUSE_47, ALARM_PROBABLE_CAUSE_48,
ALARM_PROBABLE_CAUSE_49, ALARM_PROBABLE_CAUSE_50,
ALARM_PROBABLE_CAUSE_51, ALARM_PROBABLE_CAUSE_52,
ALARM_PROBABLE_CAUSE_53, ALARM_PROBABLE_CAUSE_54,
ALARM_PROBABLE_CAUSE_55, ALARM_PROBABLE_CAUSE_56,
ALARM_PROBABLE_CAUSE_57, ALARM_PROBABLE_CAUSE_58,
ALARM_PROBABLE_CAUSE_59, ALARM_PROBABLE_CAUSE_60,
ALARM_PROBABLE_CAUSE_61, ALARM_PROBABLE_CAUSE_62,
ALARM_PROBABLE_CAUSE_63, ALARM_PROBABLE_CAUSE_64,
ALARM_PROBABLE_CAUSE_65, ALARM_PROBABLE_CAUSE_66,
ALARM_PROBABLE_CAUSE_67, ALARM_PROBABLE_CAUSE_68,
ALARM_PROBABLE_CAUSE_69, ALARM_PROBABLE_CAUSE_70,
ALARM_PROBABLE_CAUSE_71, ALARM_PROBABLE_CAUSE_72,
ALARM_PROBABLE_CAUSE_73, ALARM_PROBABLE_CAUSE_74,
ALARM_PROBABLE_CAUSE_75, ALARM_PROBABLE_CAUSE_76,
ALARM_PROBABLE_CAUSE_UNKNOWN]
FM_CLIENT_SET_FAULT = "/usr/local/bin/fmClientCli -c "
FM_CLIENT_CLEAR_FAULT = "/usr/local/bin/fmClientCli -d "
FM_CLIENT_GET_FAULT = "/usr/local/bin/fmClientCli -g "
FM_CLIENT_GET_FAULTS = "/usr/local/bin/fmClientCli -G "
FM_CLIENT_GET_FAULTS_BY_ID = "/usr/local/bin/fmClientCli -A "
FM_CLIENT_CLEAR_ALL = "/usr/local/bin/fmClientCli -D "
FM_CLIENT_STR_SEP = "###"
FM_UUID_INDEX = 0
FM_ALARM_ID_INDEX = 1
FM_ALARM_STATE_INDEX = 2
FM_ENT_TYPE_ID_INDEX = 3
FM_ENT_INST_ID_INDEX = 4
FM_TIMESTAMP_INDEX = 5
FM_SEVERITY_INDEX = 6
FM_REASON_TEXT_INDEX = 7
FM_ALARM_TYPE_INDEX = 8
FM_CAUSE_INDEX = 9
FM_REPAIR_ACTION_INDEX = 10
FM_SERVICE_AFFECTING_INDEX = 11
FM_SUPPRESSION_INDEX = 12
FM_INHIBIT_ALARMS_INDEX = 13
MAX_ALARM_ATTRIBUTES = 14

247
fm-api/fm_api/fm_api.py Executable file
View File

@ -0,0 +1,247 @@
#
# Copyright (c) 2013-2014 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# -*- encoding: utf-8 -*-
#
#
# Author:
#
import copy
import subprocess
import constants
import six
class ClientException(Exception):
pass
# Fields explanation:
#
# alarm_id: a text string of the alarm identifier
# alarm_state: see ALARM_STATE
# entity_type_id: type of the object raising alarm.
# entity_instance_id: instance information of the object raising alarm.
# severity: see ALARM_SEVERITY
# reason_text: free-format string providing description and additional details
# on the alarm. Optional.
# alarm_type: see ALARM_TYPE
# probable_cause: see ALARM_PROBABLE_CAUSE
# proposed_repair_action:free-format string providing additional details on how to
# clear the alarm. Optional.
# service_affecting: true/false, default to false
# suppression: true/false (allowed/not-allowed), default to false
# uuid: unique identifier of an active alarm instance, filled by FM system
# Timestamp: when the alarm has been raised/updated, filled by FM system
# See CGCS FM Guide for the alarm model specification
class Fault(object):
def __init__(self, alarm_id, alarm_state, entity_type_id,
entity_instance_id, severity, reason_text,
alarm_type, probable_cause, proposed_repair_action,
service_affecting=False, suppression=False,
uuid=None, timestamp=None):
self.alarm_id = alarm_id
self.alarm_state = alarm_state
self.entity_type_id = self._unicode(entity_type_id)
self.entity_instance_id = self._unicode(entity_instance_id)
self.severity = severity
self.reason_text = self._unicode(reason_text)
self.alarm_type = alarm_type
self.probable_cause = probable_cause
self.proposed_repair_action = self._unicode(proposed_repair_action)
self.service_affecting = service_affecting
self.suppression = suppression
self.uuid = uuid
self.timestamp = timestamp
def as_dict(self):
return copy.copy(self.__dict__)
@staticmethod
def _unicode(value):
if isinstance(value, str):
return six.text_type(value.decode('utf-8'))
else:
return value
class FaultAPIs(object):
def set_fault(self, data):
self._check_required_attributes(data)
self._validate_attributes(data)
buff = self._alarm_to_str(data)
cmd = constants.FM_CLIENT_SET_FAULT + '"' + buff + '"'
resp = self._run_cmd_and_get_resp(cmd)
if (resp[0] == "Ok") and (len(resp) > 1):
return resp[1]
else:
return None
def clear_fault(self, alarm_id, entity_instance_id):
sep = constants.FM_CLIENT_STR_SEP
buff = (sep + self._check_val(alarm_id) + sep +
self._check_val(entity_instance_id) + sep)
cmd = constants.FM_CLIENT_CLEAR_FAULT + '"' + buff + '"'
resp = self._run_cmd_and_get_resp(cmd)
if resp[0] == "Ok":
return True
else:
return False
def get_fault(self, alarm_id, entity_instance_id):
sep = constants.FM_CLIENT_STR_SEP
buff = (sep + self._check_val(alarm_id) + sep +
self._check_val(entity_instance_id) + sep)
cmd = constants.FM_CLIENT_GET_FAULT + '"' + buff + '"'
resp = self._run_cmd_and_get_resp(cmd)
if (resp[0] == "Ok") and (len(resp) > 1):
return self._str_to_alarm(resp[1])
else:
return None
def clear_all(self, entity_instance_id):
cmd = constants.FM_CLIENT_CLEAR_ALL + '"' + entity_instance_id + '"'
resp = self._run_cmd_and_get_resp(cmd)
if resp[0] == "Ok":
return True
else:
return False
def get_faults(self, entity_instance_id):
cmd = constants.FM_CLIENT_GET_FAULTS + '"' + entity_instance_id + '"'
resp = self._run_cmd_and_get_resp(cmd)
data = []
if resp[0] == "Ok":
for i in range(1, len(resp)):
alarm = self._str_to_alarm(resp[i])
data.append(alarm)
return data
else:
return None
def get_faults_by_id(self, alarm_id):
cmd = constants.FM_CLIENT_GET_FAULTS_BY_ID + '"' + alarm_id + '"'
resp = self._run_cmd_and_get_resp(cmd)
data = []
if resp[0] == "Ok":
for i in range(1, len(resp)):
alarm = self._str_to_alarm(resp[i])
data.append(alarm)
return data
else:
return None
@staticmethod
def _check_val(data):
if data is None:
return " "
else:
return data
def _alarm_to_str(self, data):
sep = constants.FM_CLIENT_STR_SEP
return (sep + self._check_val(data.uuid) + sep + data.alarm_id + sep +
data.alarm_state + sep + data.entity_type_id + sep +
data.entity_instance_id + sep + self._check_val(data.timestamp)
+ sep + data.severity + sep + self._check_val(data.reason_text)
+ sep + data.alarm_type + sep + data.probable_cause + sep +
self._check_val(data.proposed_repair_action) + sep +
str(data.service_affecting) + sep + str(data.suppression) + sep)
@staticmethod
def _str_to_alarm(alarm_str):
l = alarm_str.split(constants.FM_CLIENT_STR_SEP)
if len(l) < constants.MAX_ALARM_ATTRIBUTES:
return None
else:
data = Fault(l[constants.FM_ALARM_ID_INDEX],
l[constants.FM_ALARM_STATE_INDEX],
l[constants.FM_ENT_TYPE_ID_INDEX],
l[constants.FM_ENT_INST_ID_INDEX],
l[constants.FM_SEVERITY_INDEX],
l[constants.FM_REASON_TEXT_INDEX],
l[constants.FM_ALARM_TYPE_INDEX],
l[constants.FM_CAUSE_INDEX],
l[constants.FM_REPAIR_ACTION_INDEX],
l[constants.FM_SERVICE_AFFECTING_INDEX],
l[constants.FM_SUPPRESSION_INDEX],
l[constants.FM_UUID_INDEX],
l[constants.FM_TIMESTAMP_INDEX])
return data
@staticmethod
def _run_cmd_and_get_resp(cmd):
resp = []
cmd = cmd.encode('utf-8')
pro = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE)
output = pro.communicate()[0]
lines = output.split('\n')
for line in lines:
if line != '':
resp.append(line)
if len(resp) == 0:
resp.append("Unknown")
return resp
@staticmethod
def _check_required_attributes(data):
if data.alarm_id is None:
raise ClientException("Alarm id is is required.")
if data.alarm_state is None:
raise ClientException("Alarm state is required.")
if data.severity is None:
raise ClientException("Severity is required.")
if data.alarm_type is None:
raise ClientException("Alarm type is required.")
if data.probable_cause is None:
raise ClientException("Probable Cause is required.")
if data.entity_type_id is None:
raise ClientException("Entity type id is required.")
if data.entity_instance_id is None:
raise ClientException("Entity instance id is required.")
@staticmethod
def _validate_attributes(data):
""" Validate the attributes
only applies to Telco specific attributes"""
if data.alarm_state not in constants.ALARM_STATE:
raise ClientException("Invalid Fault State: %s" %
data.alarm_state)
if data.severity not in constants.ALARM_SEVERITY:
raise ClientException("Invalid Fault Severity: %s" %
data.severity)
if data.alarm_type not in constants.ALARM_TYPE:
raise ClientException("Invalid Fault Type: %s" %
data.alarm_type)
if data.probable_cause not in constants.ALARM_PROBABLE_CAUSE:
raise ClientException("Invalid Fault Probable Cause: %s" %
data.probable_cause)
@staticmethod
def alarm_allowed(alarm_severity, threshold):
def severity_to_int(severity):
if severity == 'none':
return 5
elif severity == constants.FM_ALARM_SEVERITY_CRITICAL:
return 4
elif severity == constants.FM_ALARM_SEVERITY_MAJOR:
return 3
elif severity == constants.FM_ALARM_SEVERITY_MINOR:
return 2
elif severity == constants.FM_ALARM_SEVERITY_WARNING:
return 1
given = severity_to_int(alarm_severity)
threshold = severity_to_int(threshold)
if given < threshold:
return True
return False

105
fm-api/fm_api_test.py Normal file
View File

@ -0,0 +1,105 @@
# -*- encoding: utf-8 -*-
#
# Copyright (c) 2014 Wind River Systems, Inc.
#
# Author:
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import sys
from fm_api import *
from fm_api import constants
def print_alarm(alarm):
alarm_str = "alarm_id: " + alarm.alarm_id + ", " + "uuid: " + alarm.uuid + ", "
alarm_str += "alarm_type: " + alarm.alarm_type + "\n"
alarm_str += "state: " + alarm.alarm_state + ", ""severity: " + alarm.severity + ", " \
+ "entity_type_id: " + alarm.entity_type_id + ", timestamp: "+ alarm.timestamp + "\n"
alarm_str += "entity_instance_id: " + alarm.entity_instance_id + ", "
alarm_str += "probable cause:" + alarm.probable_cause + "\n"
print alarm_str
def create():
ser = FaultAPIs()
fault = Fault(alarm_id=constants.FM_ALARM_ID_VM_RESCUED,
alarm_state=constants.FM_ALARM_STATE_SET,
entity_type_id=constants.FM_ENTITY_TYPE_INSTANCE,
entity_instance_id=constants.FM_ENTITY_TYPE_INSTANCE + '=' + 'a4e4cdb7-2ee6-4818-84c8-5310fcd67b5d',
severity = constants.FM_ALARM_SEVERITY_CRITICAL,
reason_text = "Unknown",
alarm_type = constants.FM_ALARM_TYPE_5,
probable_cause = constants.ALARM_PROBABLE_CAUSE_8,
proposed_repair_action = None,
service_affecting = False,
suppression = False)
uuid =ser.set_fault(fault)
print uuid
def delete(alarm_id, instance_id):
ser=FaultAPIs()
ret = ser.clear_fault(alarm_id,instance_id)
print "Delete fault return %s" % str(ret)
def del_all(instance_id):
ser=FaultAPIs()
ret= ser.clear_all(instance_id)
print "Delete faults return: %s" % str(ret)
def get(alarm_id, instance_id):
ser=FaultAPIs()
a = ser.get_fault(alarm_id, instance_id)
if a is not None:
print_alarm(a)
else:
print "Alarm not found"
def get_all(instance_id):
ser=FaultAPIs()
ll= ser.get_faults(instance_id)
if ll is not None:
print "Total alarm returned: %d\n" % len(ll)
for i in ll:
print_alarm(i)
else:
print "No alarm returned"
def get_list(alarm_id):
ser=FaultAPIs()
ll= ser.get_faults_by_id(alarm_id)
if ll is not None:
print "Total alarm returned: %d\n" % len(ll)
for i in ll:
print_alarm(i)
else:
print "No alarm returned"
if __name__ == "__main__":
if sys.argv[1] == "create":
sys.exit(create())
elif sys.argv[1] == "del":
sys.exit(delete(sys.argv[2],sys.argv[3]))
elif sys.argv[1] == "get":
sys.exit(get(sys.argv[2],sys.argv[3]))
elif sys.argv[1] == "get_all":
sys.exit(get_all(sys.argv[2]))
elif sys.argv[1] == "del_all":
sys.exit(del_all(sys.argv[2]))
elif sys.argv[1] == "get_list":
sys.exit(get_list(sys.argv[2]))

17
fm-api/setup.py Normal file
View File

@ -0,0 +1,17 @@
#
# Copyright (c) 2013-2014 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import setuptools
setuptools.setup(
name='fm_api',
description='CGCS FM Python API',
version='1.0.0',
license='Apache-2.0',
packages=['fm_api'],
entry_points={
}
)

6
fm-common/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
!.distro
.distro/centos7/rpmbuild/RPMS
.distro/centos7/rpmbuild/SRPMS
.distro/centos7/rpmbuild/BUILD
.distro/centos7/rpmbuild/BUILDROOT
.distro/centos7/rpmbuild/SOURCES/fm-common*tar.gz

14
fm-common/PKG-INFO Normal file
View File

@ -0,0 +1,14 @@
Metadata-Version: 1.1
Name: fm-common
Version: 1.0
Summary: Titanium Cloud Platform Fault Management Common Package
Home-page:
Author: Windriver
Author-email: info@windriver.com
License: Apache-2.0
Description: CGTS platform Fault Management Client Library that provides APIs
for applications to raise/clear/update active alarms."
Platform: UNKNOWN

View File

@ -0,0 +1,2 @@
SRC_DIR="sources"
TIS_PATCH_VER=8

View File

@ -0,0 +1,85 @@
%define local_dir /usr/local
%define local_bindir %{local_dir}/bin
%define cgcs_doc_deploy_dir /opt/deploy/cgcs_doc
Summary: CGTS Platform Fault Management Common Package
Name: fm-common
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
BuildRequires: util-linux
BuildRequires: postgresql-devel
BuildRequires: libuuid-devel
BuildRequires: python-devel
%package -n fm-common-dev
Summary: CGTS Platform Fault Management Common Package - Development files
Group: devel
Requires: fm-common = %{version}-%{release}
%description
Titanium Cloud platform Fault Management Client Library that provides APIs for
applications to raise/clear/update active alarms.
%description -n fm-common-dev
Titanium Cloud platform Fault Management Client Library that provides APIs for
applications to raise/clear/update active alarms. This package contains
symbolic links, header files, and related items necessary for software
development.
%package -n fm-common-doc
Summary: fm-common deploy doc
Group: doc
%description -n fm-common-doc
Contains fmAlarm.h which is to be used by fm-doc package to validate
the Alarms & Logs Doc Yaml file
%prep
%setup
%build
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
make MAJOR=$MAJOR MINOR=$MINOR %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
make DEST_DIR=$RPM_BUILD_ROOT BIN_DIR=%{local_bindir} LIB_DIR=%{_libdir} INC_DIR=%{_includedir} MAJOR=$MAJOR MINOR=$MINOR install_non_bb
install -d $RPM_BUILD_ROOT/usr/bin
install -m 755 fm_db_sync_event_suppression.py $RPM_BUILD_ROOT/usr/bin/fm_db_sync_event_suppression.py
CGCS_DOC_DEPLOY=$RPM_BUILD_ROOT/%{cgcs_doc_deploy_dir}
install -d $CGCS_DOC_DEPLOY
# install fmAlarm.h in CGCS_DOC_DEPLOY_DIR
# used by fm-doc package to validate the Alarms & Logs Doc Yaml file
install -m 644 fmAlarm.h $CGCS_DOC_DEPLOY
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%doc LICENSE
%{local_bindir}/*
%{_libdir}/*.so.*
/usr/bin/fm_db_sync_event_suppression.py
%files -n fm-common-dev
%defattr(-,root,root,-)
%{_includedir}/*
%{_libdir}/*.so
%files -n fm-common-doc
%defattr(-,root,root,-)
%{cgcs_doc_deploy_dir}/*

202
fm-common/sources/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

40
fm-common/sources/Makefile Executable file
View File

@ -0,0 +1,40 @@
SRCS = fmAPI.cpp fmFile.cpp fmLog.cpp fmMsgServer.cpp fmMutex.cpp fmSocket.cpp fmThread.cpp fmTime.cpp \
fmAlarmUtils.cpp fmDb.cpp fmDbUtils.cpp fmDbAlarm.cpp fmSnmpUtils.cpp \
fmDbEventLog.cpp fmEventSuppression.cpp
CLI_SRCS = fm_cli.cpp
OBJS = $(SRCS:.cpp=.o)
CLI_OBJS = fm_cli.o
LDLIBS = -lstdc++ -lrt -luuid -lpq -lpthread -lpython2.7
INCLUDES = -I./
CCFLAGS = -g -O2 -Wall -Werror -fPIC
LIBFMCOMMON_SO := libfmcommon.so
build: lib fmClientCli
.cpp.o:
$(CXX) $(CCFLAGS) $(INCLUDES) $(EXTRACCFLAGS) -c $< -o $@
lib: $(OBJS)
$(CXX) -Wl,-soname,$(LIBFMCOMMON_SO).$(MAJOR) -o $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) -shared $(OBJS) $(EXTRAARFLAGS) ${LDLIBS}
ln -sf $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(LIBFMCOMMON_SO).$(MAJOR)
ln -sf $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(LIBFMCOMMON_SO)
fmClientCli: $(CLI_OBJS) lib
$(CXX) -o $@ $(CLI_OBJS) -L./ -lfmcommon
clean:
@rm -f $(OBJ) *.o *.so fmClientCli
install_non_bb:
install -m 755 -d $(DEST_DIR)$(BIN_DIR)
install -m 755 -d $(DEST_DIR)$(LIB_DIR)
install -m 755 -d $(DEST_DIR)$(INC_DIR)
install -m 755 fmClientCli $(DEST_DIR)$(BIN_DIR)
install -m 644 fmDbAPI.h $(DEST_DIR)$(INC_DIR)
install -m 644 fmAPI.h $(DEST_DIR)$(INC_DIR)
install -m 644 fmThread.h $(DEST_DIR)$(INC_DIR)
install -m 644 fmAlarm.h $(DEST_DIR)$(INC_DIR)
install -m 755 $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(DEST_DIR)$(LIB_DIR)
ln -s $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(DEST_DIR)$(LIB_DIR)/$(LIBFMCOMMON_SO).$(MAJOR)
ln -s $(LIBFMCOMMON_SO).$(MAJOR).$(MINOR) $(DEST_DIR)$(LIB_DIR)/$(LIBFMCOMMON_SO)

514
fm-common/sources/fmAPI.cpp Normal file
View File

@ -0,0 +1,514 @@
//
// Copyright (c) 2017 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <list>
#include <new>
#include <vector>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <signal.h>
#include "fmAPI.h"
#include "fmMsg.h"
#include "fmLog.h"
#include "fmSocket.h"
#include "fmMutex.h"
#include "fmThread.h"
#include "fmAlarmUtils.h"
#define FM_MGR_HOST_NAME "controller"
#define MAX_PENDING_REQUEST 1000
#define HANDLE_SERVER_RC(hdr) \
if ((hdr)->msg_rc!=FM_ERR_OK) return (EFmErrorT) (hdr)->msg_rc
#define CHECK_RESPONSE(hdr,neededstruct) \
if (!fm_valid_srv_msg(hdr,sizeof(neededstruct))) \
return FM_ERR_COMMUNICATIONS
#define CHECK_LIST_FULL(l) \
if (l.size() == MAX_PENDING_REQUEST) \
return FM_ERR_NOT_ENOUGH_SPACE
#define CHECK_LIST_NOT_EMPTY(l) \
if (l.size() != 0) \
return FM_ERR_REQUEST_PENDING
static CFmSocket m_client;
static bool m_connected = false;
static bool m_thread = false;
typedef std::list<fm_buff_t> FmRequestListT;
static FmRequestListT & GetListOfFmRequests(){
static FmRequestListT reqs;
return reqs;
}
static CFmMutex & getListMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
static CFmMutex & getThreadMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
CFmMutex & getAPIMutex(){
static pthread_mutex_t ml = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static CFmMutex *m = NULL;
if (m == NULL){
pthread_mutex_lock(&ml);
m = new CFmMutex;
pthread_mutex_unlock(&ml);
}
return *m;
}
static void enqueue(fm_buff_t &req){
CFmMutexGuard m(getListMutex());
GetListOfFmRequests().push_back(req);
}
static bool dequeue(fm_buff_t &req){
CFmMutexGuard m(getListMutex());
if (GetListOfFmRequests().size() == 0){
return false;
}
FmRequestListT::iterator it = GetListOfFmRequests().begin();
req.clear();
req = (*it);
GetListOfFmRequests().pop_front();
return true;
}
static bool fm_lib_reconnect() {
char addr[INET6_ADDRSTRLEN];
while (!m_connected) {
struct addrinfo hints;
struct addrinfo *result=NULL, *rp;
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
hints.ai_flags = 0; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
int rc = getaddrinfo(FM_MGR_HOST_NAME,NULL,
&hints,
&result);
if (rc!=0) {
FM_ERROR_LOG("controller lookup failed... errno:%d",errno);
break;
} else {
for (rp = result; rp != NULL; rp = rp->ai_next) {
if (rp->ai_family==AF_INET||rp->ai_family==AF_INET6) {
if(rp->ai_family==AF_INET) {
inet_ntop(AF_INET, &(((sockaddr_in*)rp->ai_addr)->sin_addr), addr, sizeof(addr));
} else if (rp->ai_family==AF_INET6) {
inet_ntop(AF_INET6, &(((sockaddr_in6*)rp->ai_addr)->sin6_addr), addr, sizeof(addr));
}
m_connected=m_client.connect(addr,8001,rp->ai_family);
if (m_connected==true) {
FM_INFO_LOG("Connected to FM Manager.");
break;
} else {
FM_WARNING_LOG("Failed to connect to FM Manager.");
}
}
}
freeaddrinfo(result);
}
break;
}
return (m_connected);
}
EFmErrorT fm_msg_utils_prep_requet_msg(fm_buff_t &buff,
EFmMsgActionsT act,
const void * data,
uint32_t len) {
try {
buff.resize(sizeof(SFmMsgHdrT) + len);
} catch (...) {
FM_ERROR_LOG("Buff resize failed: errno:%d",errno);
return FM_ERR_NOMEM;
}
SFmMsgHdrT *hdr = ptr_to_hdr(buff);
hdr->action = act;
hdr->msg_size = len;
hdr->version = EFmMsgV1;
hdr->msg_rc = 0;
memcpy(ptr_to_data(buff),data,len);
return FM_ERR_OK;
}
static void fmApiJobHandlerThread(void *context){
while (true){
fm_buff_t buff;
buff.clear();
while (dequeue(buff)){
while (true) {
while (!fm_lib_reconnect()){
fmThreadSleep(200);
}
fm_log_request(buff);
// protect from other sync APIs to access the same socket
CFmMutexGuard m(getAPIMutex());
if(m_client.write_packet(buff)) {
fm_buff_t in_buff;
in_buff.clear();
if(!m_client.read_packet(in_buff)) {
// retry after read failure
fm_log_response(buff, in_buff, true);
m_connected = false;
continue;
}
else {
fm_log_response(buff, in_buff);
break;
}
}else{
//retry after write failure
fm_log_request(buff, true);
m_connected = false;
continue;
}
}
}
fmThreadSleep(50);
}
}
static bool fm_lib_thread(){
CFmMutexGuard m(getThreadMutex());
if (!m_thread){
FM_INFO_LOG("Creating thread");
if (!fmCreateThread(fmApiJobHandlerThread,NULL)) {
FM_ERROR_LOG("Fail to create API job thread");
}
else {
m_thread = true;
}
}
return m_thread;
}
static EFmErrorT fm_check_thread_pending_request(){
CFmMutexGuard m(getThreadMutex());
if (m_thread){
CHECK_LIST_NOT_EMPTY(GetListOfFmRequests());
}
return FM_ERR_OK;
}
extern "C" {
EFmErrorT fm_init_lib() {
signal(SIGINT,SIG_IGN);
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) {
FM_ERROR_LOG("Socket connection failed\n");
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_set_fault(const SFmAlarmDataT *alarm,
fm_uuid_t *uuid){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmCreateFault,
alarm,sizeof(*alarm));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
HANDLE_SERVER_RC(ptr_to_hdr(buff));
CHECK_RESPONSE(ptr_to_hdr(buff),fm_uuid_t);
if (uuid != NULL)
memcpy(*uuid,ptr_to_data(buff),sizeof(*uuid)-1);
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_clear_fault(AlarmFilter *filter){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmDeleteFault,
filter,sizeof(*filter));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
HANDLE_SERVER_RC(ptr_to_hdr(buff));
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_clear_all(fm_ent_inst_t *inst_id){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmDeleteFaults,
(*inst_id), sizeof(*inst_id));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
FM_ERROR_LOG("Read ERR: return FM_ERR_NOCONNECT");
return FM_ERR_NOCONNECT;
}
HANDLE_SERVER_RC(ptr_to_hdr(buff));
} else {
m_connected = false;
FM_ERROR_LOG("Write ERR: return FM_ERR_NOCONNECT");
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_get_fault(AlarmFilter *filter, SFmAlarmDataT *alarm ){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_check_thread_pending_request();
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmGetFault,
filter,sizeof(*filter));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
HANDLE_SERVER_RC(ptr_to_hdr(buff));
CHECK_RESPONSE(ptr_to_hdr(buff),SFmAlarmDataT);
SFmAlarmDataT * data = (SFmAlarmDataT * ) ptr_to_data(buff);
*alarm = *data;
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_get_faults(fm_ent_inst_t *inst_id,
SFmAlarmDataT *alarm, unsigned int *max_alarms_to_get) {
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_check_thread_pending_request();
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmGetFaults,
(*inst_id),sizeof(*inst_id));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
if (ptr_to_hdr(buff)->msg_rc != FM_ERR_OK){
*max_alarms_to_get = 0;
EFmErrorT rc = (EFmErrorT)ptr_to_hdr(buff)->msg_rc;
return rc;
}
uint32_t pkt_size = ptr_to_hdr(buff)->msg_size;
if (pkt_size < sizeof(uint32_t)) {
FM_ERROR_LOG("Received invalid pkt size: %u\n",pkt_size );
m_connected = false;
return FM_ERR_COMMUNICATIONS;
}
pkt_size-=sizeof(uint32_t);
char *dptr = (char*)ptr_to_data(buff);
uint32_t *len = (uint32_t*)dptr;
dptr+=sizeof(uint32_t);
if (*max_alarms_to_get < *len) {
return FM_ERR_NOT_ENOUGH_SPACE;
}
if (pkt_size < (*len*sizeof(SFmAlarmDataT)) ) {
return FM_ERR_COMMUNICATIONS;
}
*max_alarms_to_get = *len;
memcpy(alarm,dptr,pkt_size);
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
EFmErrorT fm_get_faults_by_id(fm_alarm_id *alarm_id, SFmAlarmDataT *alarm,
unsigned int *max_alarms_to_get){
CFmMutexGuard m(getAPIMutex());
if (!fm_lib_reconnect()) return FM_ERR_NOCONNECT;
fm_check_thread_pending_request();
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmGetFaultsById,
(*alarm_id),sizeof(*alarm_id));
if (erc!=FM_ERR_OK) return erc;
if(m_client.write_packet(buff)) {
if(!m_client.read_packet(buff)) {
m_connected = false;
return FM_ERR_NOCONNECT;
}
if (ptr_to_hdr(buff)->msg_rc != FM_ERR_OK){
*max_alarms_to_get = 0;
EFmErrorT rc = (EFmErrorT)ptr_to_hdr(buff)->msg_rc;
return rc;
}
uint32_t pkt_size = ptr_to_hdr(buff)->msg_size;
if (pkt_size < sizeof(uint32_t)) {
FM_ERROR_LOG("Received invalid pkt size: %u\n",pkt_size );
m_connected = false;
return FM_ERR_COMMUNICATIONS;
}
pkt_size-=sizeof(uint32_t);
char *dptr = (char*)ptr_to_data(buff);
uint32_t *len = (uint32_t*)dptr;
dptr+=sizeof(uint32_t);
if (*max_alarms_to_get < *len) {
return FM_ERR_NOT_ENOUGH_SPACE;
}
if (pkt_size < (*len*sizeof(SFmAlarmDataT)) ) {
return FM_ERR_COMMUNICATIONS;
}
*max_alarms_to_get = *len;
memcpy(alarm,dptr,pkt_size);
} else {
m_connected = false;
return FM_ERR_NOCONNECT;
}
return FM_ERR_OK;
}
/*
* APIs that enqueue the request and return ok for acknowledgment.
* A backgroup thread will pick up the request and send it to the FM Manager
*/
EFmErrorT fm_set_fault_async(const SFmAlarmDataT *alarm, fm_uuid_t *uuid){
if ( !fm_lib_thread()) return FM_ERR_RESOURCE_UNAVAILABLE;
CHECK_LIST_FULL(GetListOfFmRequests());
fm_uuid_t id;
fm_buff_t buff;
buff.clear();
fm_uuid_create(id);
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmCreateFault,
alarm,sizeof(*alarm));
if (erc!=FM_ERR_OK) return erc;
memcpy(ptr_to_data(buff), id, sizeof(fm_uuid_t)-1);
FM_INFO_LOG("Enqueue raise alarm request: UUID (%s) alarm id (%s) instant id (%s)",
id, alarm->alarm_id, alarm->entity_instance_id);
enqueue(buff);
if (uuid != NULL){
memcpy(*uuid,id,sizeof(*uuid)-1);
}
return FM_ERR_OK;
}
EFmErrorT fm_clear_fault_async(AlarmFilter *filter){
if ( !fm_lib_thread()) return FM_ERR_RESOURCE_UNAVAILABLE;
CHECK_LIST_FULL(GetListOfFmRequests());
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmDeleteFault,
filter,sizeof(*filter));
if (erc!=FM_ERR_OK) return erc;
FM_INFO_LOG("Enqueue clear alarm request: alarm id (%s), instant id (%s)",
filter->alarm_id, filter->entity_instance_id);
enqueue(buff);
return FM_ERR_OK;
}
EFmErrorT fm_clear_all_async(fm_ent_inst_t *inst_id){
if ( !fm_lib_thread()) return FM_ERR_RESOURCE_UNAVAILABLE;
CHECK_LIST_FULL(GetListOfFmRequests());
fm_buff_t buff;
buff.clear();
EFmErrorT erc = fm_msg_utils_prep_requet_msg(buff,EFmDeleteFaults,
(*inst_id), sizeof(*inst_id));
if (erc!=FM_ERR_OK) return erc;
FM_INFO_LOG("Enqueue clear all alarm request: instant id (%s)", *inst_id);
enqueue(buff);
return FM_ERR_OK;
}
}

224
fm-common/sources/fmAPI.h Normal file
View File

@ -0,0 +1,224 @@
//
// Copyright (c) 2017 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef _FM_API_H
#define _FM_API_H
#include <string.h>
#include <stdio.h>
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FM_MAX_BUFFER_LENGTH 255
/* unsigned 64-bit data, 8-byte alignment, Time in microsecond */
typedef unsigned long long int FMTimeT __attribute__((__aligned__(8)));
typedef unsigned char FMBoolTypeT;
#define FM_TRUE 1 //any non-zero value is also considered to be True
#define FM_FALSE 0
typedef enum{
FM_ALARM_STATE_CLEAR = 0,
FM_ALARM_STATE_SET = 1,
FM_ALARM_STATE_MSG = 2,
FM_ALARM_STATE_LOG = 3, // Use only for SNMP Agent
FM_ALARM_STATE_MAX = 4
}EFmAlarmStateT;
typedef enum{
FM_ALARM_SEVERITY_CLEAR = 0,
FM_ALARM_SEVERITY_WARNING = 1,
FM_ALARM_SEVERITY_MINOR = 2,
FM_ALARM_SEVERITY_MAJOR = 3,
FM_ALARM_SEVERITY_CRITICAL = 4,
FM_ALARM_SEVERITY_MAX = 5
}EFmAlarmSeverityT;
typedef enum{
FM_ALARM_TYPE_UNKNOWN = 0,
FM_ALARM_COMM = 1, //communication
FM_ALARM_QOS = 2, //qos
FM_ALARM_PROCESSING_ERROR = 3, //processing-error
FM_ALARM_EQUIPMENT = 4 , //equipment
FM_ALARM_ENVIRONMENTAL = 5, //environmental
FM_ALARM_INTERGRITY = 6, //integrity-violation
FM_ALARM_OPERATIONAL = 7, //operational-violation
FM_ALARM_PHYSICAL = 8, //physical-violation
FM_ALARM_SECURITY = 9, //security-service-or-mechanism-violation
FM_ALARM_TIME = 10, //time-domain-violation
FM_ALARM_TYPE_MAX = 11
}EFmAlarmTypeT;
typedef enum{
FM_ALARM_CAUSE_UNKNOWN = 0,
FM_ALARM_ADAPTOR_ERROR = 1, //adaptor-error
FM_ALARM_APP_SUBSYS_FAILURE = 2, //application-subsystem-failure
FM_ALARM_BANDWIDTH_REDUCED = 3, //bandwidth-reduced
FM_ALARM_CALL_ERROR = 4 , //call-establishment-error
FM_ALARM_COMM_PROTOCOL_ERROR = 5, //communication-protocol-error
FM_ALARM_COMM_SUBSYS_FAILURE = 6, //communication-subsystem-failure
FM_ALARM_CONFIG_ERROR = 7, //configuration-or-customization-error
FM_ALARM_CONGESTION = 8, //congestion
FM_ALARM_CORRUPT_DATA = 9, //corrupt-data
FM_ALARM_CPU_LIMITED_EXCEEDED = 10, //cpu-cycles-limit-exceeded
FM_ALARM_DATASET_ERROR = 11, //dataset-or-modem-error
FM_ALARM_DEGRADED_SIGNAL = 12, //degraded-signal
FM_ALARM_DTE_DCE_INTERFACE_ERROR = 13, //dte-dce-interface-error
FM_ALARM_DOOR_OPEN = 14, //enclosure-door-open',
FM_ALARM_EQUIPMENT_MALFUNCTION = 15, //equipment-malfunction
FM_ALARM_EXCESSIVE_VIBRATION = 16, //excessive-vibration'
FM_ALARM_FILE_ERROR = 17, //file-error
FM_ALARM_FIRE_DETECTED = 18, //fire-detected
FM_ALARM_FLOOD_DETECTED = 19, //flood-detected
FM_ALARM_FRAMING_ERROR = 20, //framing-error
FM_ALARM_COOLING_PROBLEM = 21, //heating-ventilation-cooling-system-problem
FM_ALARM_HUMIDITY_UNACCEPTABLE = 22, //humidity-unacceptable
FM_ALARM_IO_DEVICE_ERROR = 23, //io-device-error
FM_ALARM_INPUT_DEVICE_ERROR = 24, //input-device-error
FM_ALARM_LAN_ERROR = 25, //lan-error
FM_ALARM_LEAK_DETECTED = 26, //leak-detected
FM_ALARM_LOCAL_TX_ERROR = 27, //local-node-transmission-error
FM_ALARM_LOSS_OF_FRAME = 28, //loss-of-frame
FM_ALARM_LOSS_OF_SIGNAL = 29, //loss-of-signal
FM_ALARM_MATERIAL_SUPPlY_EXHAUSTED = 30, //material-supply-exhausted
FM_ALARM_MULTIPLEXER_PROBLEM = 31, //multiplexer-problem
FM_ALARM_OUT_OF_MEMORY = 32, //out-of-memory',
FM_ALARM_OUTPUT_DEVICE_ERROR = 33, //output-device-error
FM_ALARM_PERMFORMANCE_DEGRADED = 34, //performance-degraded
FM_ALARM_POWER_PROBLEM = 35, //power-problem
FM_ALARM_PROCESSOR_PROBLEM = 36, //processor-problem
FM_ALARM_PUMP_FAILURE = 37, //pump-failure
FM_ALARM_Q_SIZE_EXCEEDED = 38, //queue-size-exceeded
FM_ALARM_RX_FAILURE = 39, //receive-failure
FM_ALARM_RXER_FAILURE = 40, //receiver-failure
FM_ALARM_REMOTE_TX_ERROR = 41, //remote-node-transmission-error
FM_ALARM_RESOURCE_NEAR_CAPACITY = 42, //resource-at-or-nearing-capacity
FM_ALARM_RESPONSE_TIME_EXCESSIVE = 43, //response-time-excessive
FM_ALARM_RETX_RATE_EXCESSIVE = 44, //retransmission-rate-excessive
FM_ALARM_SOFTWARE_ERROR = 45, //software-error
FM_ALARM_PROGRAM_TERMINATED = 46, //software-program-abnormally-terminated
FM_ALARM_PROGRAM_ERROR = 47, //software-program-error
FM_ALARM_STORAGE_PROBLEM = 48, //storage-capacity-problem
FM_ALARM_TEMP_UNACCEPTABLE = 49, //temperature-unacceptable
FM_ALARM_THRESHOLD_CROSSED = 50, //threshold-crossed
FM_ALARM_TIMING_PROBLEM = 51, //timing-problem
FM_ALARM_TOXIC_LEAK_DETECTED = 52, //toxic-leak-detected
FM_ALARM_TRANSMIT_FAILURE = 53, //transmit-failure
FM_ALARM_TRANSMITTER_FAILURE = 54, //transmitter-failure
FM_ALARM_UNDERLYING_RESOURCE_UNAVAILABLE = 55,//underlying-resource-unavailable
FM_ALARM_VERSION_MISMATCH = 56, //version-mismatch
FM_ALARM_DUPLICATE_INFO = 57, //duplicate-information
FM_ALARM_INFO_MISSING = 58, //information-missing
FM_ALARM_INFO_MODIFICATION = 59, //information-modification-detected
FM_ALARM_INFO_OUT_OF_SEQ = 60, //information-out-of-sequence
FM_ALARM_UNEXPECTED_INFO = 61, //unexpected-information
FM_ALARM_DENIAL_OF_SERVICE = 62, //denial-of-service
FM_ALARM_OUT_OF_SERVICE = 63, //out-of-service
FM_ALARM_PROCEDURAL_ERROR = 64, //procedural-error
FM_ALARM_UNSPECIFIED_REASON = 65, //unspecified-reason
FM_ALARM_CABLE_TAMPER = 66, //cable-tamper
FM_ALARM_INTRUSION_DETECTION = 67, //intrusion-detection
FM_ALARM_AUTH_FAILURE = 68, //authentication-failure
FM_ALARM_BREACH_CONFIDENT = 69, //breach-of-confidentiality
FM_ALARM_NON_REPUD_FAILURE = 70, //non-repudiation-failure
FM_ALARM_UNAUTH_ACCESS_ATTEMP = 71, //unauthorized-access-attempt
FM_ALARM_DELAYED_INFO = 72, //delayed-information
FM_ALARM_KEY_EXPIRED = 73, //key-expired
FM_ALARM_OUT_OF_HR_ACTIVITY = 74, //out-of-hours-activity
FM_ALARM_CAUSE_MAX = 75
}EFmAlarmProbableCauseT;
typedef char fm_uuid_t[FM_MAX_BUFFER_LENGTH];
typedef char fm_ent_inst_t[FM_MAX_BUFFER_LENGTH];
typedef char fm_alarm_id[FM_MAX_BUFFER_LENGTH];
typedef struct{
fm_uuid_t uuid; //generated by FM system
char alarm_id[FM_MAX_BUFFER_LENGTH]; //structured id for the fault
EFmAlarmStateT alarm_state; //state of the fault
char entity_type_id[FM_MAX_BUFFER_LENGTH];//type of the object raising fault
char entity_instance_id[FM_MAX_BUFFER_LENGTH];//instance information of the object raising fault
FMTimeT timestamp; //time in UTC at which the fault state is last updated
EFmAlarmSeverityT severity; //severity of the fault
char reason_text[FM_MAX_BUFFER_LENGTH];
EFmAlarmTypeT alarm_type;
EFmAlarmProbableCauseT probable_cause;
char proposed_repair_action[FM_MAX_BUFFER_LENGTH];
FMBoolTypeT service_affecting;
FMBoolTypeT suppression; //'allowed' or 'not-allowed'
FMBoolTypeT inhibit_alarms; //hierarchical suppression of alarms if it is set to true
}SFmAlarmDataT;
typedef enum{
FM_ERR_OK = 0,
FM_ERR_ALARM_EXISTS = 1,
FM_ERR_INVALID_ATTRIBUTE = 2,
FM_ERR_NOCONNECT=3,
FM_ERR_NOMEM=4,
FM_ERR_COMMUNICATIONS=5,
FM_ERR_NOT_ENOUGH_SPACE=6,
FM_ERR_INVALID_REQ=7,
FM_ERR_SERVER_NO_MEM=8,
FM_ERR_SCRIPT_FAILURE=9,
FM_ERR_ENTITY_NOT_FOUND = 10,
FM_ERR_DB_OPERATION_FAILURE = 11,
FM_ERR_DB_CONNECT_FAILURE = 12,
FM_ERR_INVALID_PARAMETER = 13,
FM_ERR_RESOURCE_UNAVAILABLE = 14,
FM_ERR_REQUEST_PENDING = 15,
FM_ERR_MAX
}EFmErrorT;
typedef struct {
char alarm_id[FM_MAX_BUFFER_LENGTH];
fm_ent_inst_t entity_instance_id;
}AlarmFilter ;
EFmErrorT fm_set_fault(const SFmAlarmDataT *alarm, fm_uuid_t *uuid);
EFmErrorT fm_clear_fault(AlarmFilter *filter);
EFmErrorT fm_clear_all(fm_ent_inst_t *inst_id);
EFmErrorT fm_get_fault(AlarmFilter *filter, SFmAlarmDataT *alarm);
EFmErrorT fm_get_faults(fm_ent_inst_t *inst_id, SFmAlarmDataT *alarm,
unsigned int *max_alarms_to_get);
EFmErrorT fm_get_faults_by_id(fm_alarm_id *alarm_id, SFmAlarmDataT *alarm,
unsigned int *max_alarms_to_get);
/*
* APIs that enqueue the request and return ok for acknowledgment.
* It is up to the client to query and find out whether
* the alarm is raised or cleared successfully
*/
EFmErrorT fm_set_fault_async(const SFmAlarmDataT *alarm, fm_uuid_t *uuid);
EFmErrorT fm_clear_fault_async(AlarmFilter *filter);
EFmErrorT fm_clear_all_async(fm_ent_inst_t *inst_id);
//used by fmManager
EFmErrorT fm_server_create(const char *fn) ;
#ifdef __cplusplus
}
#endif
#endif /* _FM_API_H */

View File

@ -0,0 +1,58 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
/* This file contains CGTS alarm definitions. The alarm ids that used by
* C/C++ applications are defined here. For a completed alarm id list see
* the alarm ids that used by the Python applications defined in
* fm-api/fm_api/constants.py
*/
#ifndef _FM_ALARM_H
#define _FM_ALARM_H
/* alarm sub entity types*/
#define FM_ENTITY_TYPE_SYSTEM "system"
#define FM_ENTITY_TYPE_HOST "host"
#define FM_ENTITY_TYPE_PORT "port"
#define FM_ENTITY_TYPE_INTERFACE "interface"
#define FM_ENTITY_TYPE_DISK "disk"
#define FM_ENTITY_TYPE_SERVICE "service"
#define FM_ENTITY_TYPE_AGENT "agent"
#define FM_ENTITY_TYPE_PROVIDERNET "providernet"
#define FM_ENTITY_TYPE_INSTANCE "instance"
/* alarm_id = <Alarm Group ID>.<Alarm Event ID> */
/* <Alarm Group ID> = 000 - 999 */
/* <Alarm Event ID> = 000 999 */
#define ALARM_GROUP_GENERAL "100"
#define ALARM_GROUP_MAINTENANCE "200"
#define ALARM_GROUP_NETWORK "300"
#define ALARM_GROUP_HA "400"
#define ALARM_GROUP_SECURITY "500"
#define ALARM_GROUP_LICENSING "600"
#define ALARM_GROUP_VM "700"
#define ALARM_GROUP_STORAGE "800"
#define ALARM_GROUP_SW_MGMT "900"
/* Maintenance group alarm id */
#define FM_ALARM_ID_MTC_LOCK (ALARM_GROUP_MAINTENANCE ".001")
#define FM_ALARM_ID_MTC_CONFIG (ALARM_GROUP_MAINTENANCE ".004")
#define FM_ALARM_ID_MTC_HB (ALARM_GROUP_MAINTENANCE ".005")
#define FM_ALARM_ID_MTC_PMOND (ALARM_GROUP_MAINTENANCE ".006")
#define FM_ALARM_ID_MTC_RESMON (ALARM_GROUP_MAINTENANCE ".007")
/* HA alarm id */
#define FM_ALARM_ID_SERVICE_GROUP_STATE (ALARM_GROUP_HA ".001")
#define FM_ALARM_ID_SERVICE_GROUP_REDUNDANCY (ALARM_GROUP_HA ".002")
/* Patching alarm id */
#define FM_ALARM_ID_PATCH_IN_PROGRESS (ALARM_GROUP_SW_MGMT ".001")
#define FM_ALARM_ID_PATCH_HOST_INSTALL_FAILED (ALARM_GROUP_SW_MGMT ".002")
#define FM_ALARM_ID_PATCH_OBS_IN_SYSTEM (ALARM_GROUP_SW_MGMT ".003")
#endif /* _FM_ALARM_H */

View File

@ -0,0 +1,580 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <pthread.h>
#include <map>
#include <vector>
#include <uuid/uuid.h>
#include "fmAlarmUtils.h"
#include "fmDbUtils.h"
#include "fmLog.h"
typedef std::map<int,std::string> itos_t;
typedef std::map<std::string,int> stoi_t;
typedef std::vector<std::string> strvect_t;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static itos_t state_to_str;
static itos_t severity_to_str;
static itos_t type_to_str;
static itos_t cause_to_str;
static itos_t bool_to_str;
static itos_t err_to_str;
static stoi_t state_to_int;
static stoi_t severity_to_int;
static stoi_t type_to_int;
static stoi_t cause_to_int;
static stoi_t bool_to_int;
static stoi_t err_to_int;
#define STRCP_TO(charb,str)\
if (((str).length()==0) || \
((str).length()==1 && ((str).c_str())[0]==' ')) { \
memset(charb,0,sizeof(charb)); \
} else { \
strncpy((charb),str.c_str(),sizeof(charb)); \
}
void add_both_tables(int id, const char *str, itos_t &t1,stoi_t &t2 ) {
t1[id]=str;
t2[str]=id;
}
static void init_tables() {
pthread_mutex_lock(&mutex);
static bool has_inited=false;
while (!has_inited) {
add_both_tables(FM_ALARM_STATE_CLEAR,"clear",state_to_str,state_to_int);
add_both_tables(FM_ALARM_STATE_SET,"set",state_to_str,state_to_int);
add_both_tables(FM_ALARM_STATE_MSG,"msg",state_to_str,state_to_int);
add_both_tables(FM_ALARM_STATE_LOG,"log",state_to_str,state_to_int);
add_both_tables(FM_ALARM_SEVERITY_CLEAR,"not-applicable",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_SEVERITY_WARNING,"warning",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_SEVERITY_MINOR,"minor",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_SEVERITY_MAJOR,"major",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_SEVERITY_CRITICAL,"critical",severity_to_str,severity_to_int);
add_both_tables(FM_ALARM_TYPE_UNKNOWN,"other",type_to_str,type_to_int);
add_both_tables(FM_ALARM_COMM,"communication",type_to_str,type_to_int);
add_both_tables(FM_ALARM_QOS,"qos",type_to_str,type_to_int);
add_both_tables(FM_ALARM_PROCESSING_ERROR,"processing-error",type_to_str,type_to_int);
add_both_tables(FM_ALARM_EQUIPMENT,"equipment",type_to_str,type_to_int);
add_both_tables(FM_ALARM_ENVIRONMENTAL,"environmental",type_to_str,type_to_int);
add_both_tables(FM_ALARM_INTERGRITY,"integrity-violation",type_to_str,type_to_int);
add_both_tables(FM_ALARM_OPERATIONAL,"operational-violation",type_to_str,type_to_int);
add_both_tables(FM_ALARM_PHYSICAL,"physical-violation",type_to_str,type_to_int);
add_both_tables(FM_ALARM_SECURITY,"security-service-or-mechanism-violation",type_to_str,type_to_int);
add_both_tables(FM_ALARM_TIME,"time-domain-violation",type_to_str,type_to_int);
add_both_tables( FM_ALARM_CAUSE_UNKNOWN ,"not-applicable",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_ADAPTOR_ERROR ,"adaptor-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_APP_SUBSYS_FAILURE ,"application-subsystem-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_BANDWIDTH_REDUCED ,"bandwidth-reduced",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CALL_ERROR ,"call-establishment-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_COMM_PROTOCOL_ERROR ,"communication-protocol-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_COMM_SUBSYS_FAILURE ,"communication-subsystem-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CONFIG_ERROR ,"configuration-or-customization-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CONGESTION ,"congestion",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CORRUPT_DATA ,"corrupt-data",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CPU_LIMITED_EXCEEDED ,"cpu-cycles-limit-exceeded",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DATASET_ERROR ,"dataset-or-modem-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DEGRADED_SIGNAL ,"degraded-signal",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DTE_DCE_INTERFACE_ERROR ,"dte-dce-interface-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DOOR_OPEN ,"enclosure-door-open",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_EQUIPMENT_MALFUNCTION ,"equipment-malfunction",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_EXCESSIVE_VIBRATION ,"excessive-vibration'",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_FILE_ERROR ,"file-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_FIRE_DETECTED ,"fire-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_FLOOD_DETECTED ,"flood-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_FRAMING_ERROR ,"framing-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_COOLING_PROBLEM ,"heating-ventilation-cooling-system-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_HUMIDITY_UNACCEPTABLE ,"humidity-unacceptable",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_IO_DEVICE_ERROR ,"io-device-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INPUT_DEVICE_ERROR ,"input-device-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LAN_ERROR ,"lan-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LEAK_DETECTED ,"leak-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LOCAL_TX_ERROR ,"local-node-transmission-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LOSS_OF_FRAME ,"loss-of-frame",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_LOSS_OF_SIGNAL ,"loss-of-signal",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_MATERIAL_SUPPlY_EXHAUSTED ,"material-supply-exhausted",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_MULTIPLEXER_PROBLEM ,"multiplexer-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_OUT_OF_MEMORY ,"out-of-memory",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_OUTPUT_DEVICE_ERROR ,"output-device-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PERMFORMANCE_DEGRADED ,"performance-degraded",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_POWER_PROBLEM ,"power-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PROCESSOR_PROBLEM ,"processor-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PUMP_FAILURE ,"pump-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_Q_SIZE_EXCEEDED ,"queue-size-exceeded",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RX_FAILURE ,"receive-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RXER_FAILURE ,"receiver-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_REMOTE_TX_ERROR ,"remote-node-transmission-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RESOURCE_NEAR_CAPACITY ,"resource-at-or-nearing-capacity",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RESPONSE_TIME_EXCESSIVE ,"response-time-excessive",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_RETX_RATE_EXCESSIVE ,"retransmission-rate-excessive",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_SOFTWARE_ERROR ,"software-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PROGRAM_TERMINATED ,"software-program-abnormally-terminated",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PROGRAM_ERROR ,"software-program-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_STORAGE_PROBLEM ,"storage-capacity-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TEMP_UNACCEPTABLE ,"temperature-unacceptable",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_THRESHOLD_CROSSED ,"threshold-crossed",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TIMING_PROBLEM ,"timing-problem",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TOXIC_LEAK_DETECTED ,"toxic-leak-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TRANSMIT_FAILURE ,"transmit-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_TRANSMITTER_FAILURE ,"transmitter-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_UNDERLYING_RESOURCE_UNAVAILABLE ,"underlying-resource-unavailable",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_VERSION_MISMATCH ,"version-mismatch",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DUPLICATE_INFO ,"duplicate-information",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INFO_MISSING ,"information-missing",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INFO_MODIFICATION ,"information-modification-detected",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INFO_OUT_OF_SEQ ,"information-out-of-sequence",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_UNEXPECTED_INFO ,"unexpected-information",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DENIAL_OF_SERVICE ,"denial-of-service",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_OUT_OF_SERVICE ,"out-of-service",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_PROCEDURAL_ERROR ,"procedural-error",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_UNSPECIFIED_REASON ,"unspecified-reason",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_CABLE_TAMPER ,"cable-tamper",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_INTRUSION_DETECTION ,"intrusion-detection",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_AUTH_FAILURE ,"authentication-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_BREACH_CONFIDENT ,"breach-of-confidentiality",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_NON_REPUD_FAILURE ,"non-repudiation-failure",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_UNAUTH_ACCESS_ATTEMP ,"unauthorized-access-attempt",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_DELAYED_INFO ,"delayed-information",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_KEY_EXPIRED ,"key-expired",cause_to_str,cause_to_int);
add_both_tables( FM_ALARM_OUT_OF_HR_ACTIVITY ,"out-of-hours-activity",cause_to_str,cause_to_int);
add_both_tables( FM_ERR_OK, "Ok", err_to_str, err_to_int);
add_both_tables( FM_ERR_ALARM_EXISTS, "FM_ERR_ALARM_EXISTS", err_to_str, err_to_int);
add_both_tables( FM_ERR_INVALID_ATTRIBUTE, "FM_ERR_INVALID_ATTRIBUTE", err_to_str, err_to_int);
add_both_tables( FM_ERR_ENTITY_NOT_FOUND, "FM_ERR_ENTITY_NOT_FOUND", err_to_str, err_to_int);
add_both_tables( FM_ERR_DB_OPERATION_FAILURE, "FM_ERR_DB_OPERATION_FAILURE", err_to_str, err_to_int);
add_both_tables( FM_ERR_SCRIPT_FAILURE, "FM_ERR_SCRIPT_FAILURE",err_to_str, err_to_int);
add_both_tables( FM_ERR_NOCONNECT, "FM_ERR_NOCONNECT", err_to_str, err_to_int);
add_both_tables( FM_ERR_NOMEM, "FM_ERR_NOMEM", err_to_str, err_to_int);
add_both_tables( FM_ERR_COMMUNICATIONS, "FM_ERR_COMMUNICATIONS", err_to_str, err_to_int);
add_both_tables( FM_ERR_NOT_ENOUGH_SPACE, "FM_ERR_NOT_ENOUGH_SPACE", err_to_str, err_to_int);
add_both_tables( FM_ERR_INVALID_REQ, "FM_ERR_INVALID_REQ", err_to_str, err_to_int);
add_both_tables( FM_ERR_SERVER_NO_MEM, "FM_ERR_SERVER_NO_MEM", err_to_str, err_to_int);
add_both_tables( FM_ERR_INVALID_PARAMETER, "FM_ERR_INVALID_PARAMETER",err_to_str, err_to_int);
add_both_tables( FM_ERR_RESOURCE_UNAVAILABLE, "FM_ERR_RESOURCE_UNAVAILABLE",err_to_str, err_to_int);
add_both_tables( 0 ,"False",bool_to_str,bool_to_int);
add_both_tables( 1 ,"True",bool_to_str,bool_to_int);
has_inited=true;
}
pthread_mutex_unlock(&mutex);
}
static void add_s(std::string &s) { s+="###"; };
static std::string tostr(int id, const itos_t &t ){
itos_t::const_iterator it = t.find(id);
if (it!=t.end()) return it->second;
return "unknown";
}
static int toint(const std::string &s, const stoi_t &t) {
stoi_t::const_iterator it = t.find(s);
if (it!=t.end()) return it->second ;
return 0;
}
static std::string chkstr(const std::string &s) {
if (s.length()==0) return " ";
return s;
}
static void str_to_vector(const std::string &s, std::vector<std::string> &alarm) {
size_t offset = 0;
alarm.clear();
while (true) {
size_t beg = (offset==0) ? 0 : s.find("###",offset);
if (beg==std::string::npos) break;
size_t e = s.find("###",beg+3);
std::string cont = s.substr(beg+3,e-(beg+3));
alarm.push_back(cont);
offset=e;
}
}
static void fm_set_uuid(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->uuid);
else STRCP_TO(a->uuid,s);
}
static void fm_tr_alarm_id(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->alarm_id);
else STRCP_TO(a->alarm_id,s);
}
static void fm_alarm_state(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->alarm_state,state_to_str);
else a->alarm_state = (EFmAlarmStateT)toint(s,state_to_int);
}
static void fm_entity_id(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->entity_type_id);
else STRCP_TO(a->entity_type_id,s);
}
static void fm_instance_id(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->entity_instance_id);
else STRCP_TO(a->entity_instance_id,s);
}
static void fm_timestamp(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) {
fm_db_util_make_timestamp_string(s, a->timestamp);
} else {
fm_db_util_get_timestamp(s.c_str(), a->timestamp);
}
}
static void fm_alarm_severity(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->severity,severity_to_str);
else a->severity = (EFmAlarmSeverityT)toint(s,severity_to_int);
}
static void fm_reason_text(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->reason_text);
else STRCP_TO(a->reason_text,s);
}
static void fm_alarm_type(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s =tostr(a->alarm_type,type_to_str);
else a->alarm_type = (EFmAlarmTypeT)toint(s,type_to_int);
}
static void fm_prop_cause(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->probable_cause,cause_to_str);
else a->probable_cause = (EFmAlarmProbableCauseT)toint(s,cause_to_int);
}
static void fm_repair(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = chkstr(a->proposed_repair_action);
else STRCP_TO(a->proposed_repair_action,s);
}
static void fm_service_affect(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->service_affecting,bool_to_str);
else a->service_affecting = (((s == "t") || (s == "True"))? 1 :0);
}
static void fm_suppression(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->suppression,bool_to_str);
else a->suppression = (((s == "t") || (s == "True"))? 1 :0);
}
static void fm_inhibit_alarm(SFmAlarmDataT *a, std::string &s, bool is_get) {
if(is_get) s = tostr(a->inhibit_alarms,bool_to_str);
else a->inhibit_alarms = (((s == "t") || (s == "True"))? 1 :0);
}
typedef void (*set_get_field_type)(SFmAlarmDataT *a, std::string &s, bool is_get);
struct alarm_struct_update_t{
EFmAlarmIndexMap id;
set_get_field_type func;
} fm_alarm_convert_func [] = {
{ FM_ALM_IX_UUID, fm_set_uuid },
{ FM_ALM_IX_ALARM_ID, fm_tr_alarm_id },
{ FM_ALM_IX_ALARM_STATE, fm_alarm_state },
{ FM_ALM_IX_ENTITY_ID, fm_entity_id },
{ FM_ALM_IX_INSTANCE_ID, fm_instance_id },
{ FM_ALM_IX_TIMESTAMP, fm_timestamp },
{ FM_ALM_IX_SEVERITY, fm_alarm_severity },
{ FM_ALM_IX_REASON, fm_reason_text },
{ FM_ALM_IX_ALARM_TYPE, fm_alarm_type },
{ FM_ALM_IX_PROBABLE_CAUSE, fm_prop_cause },
{ FM_ALM_IX_REPAIR_ACTION, fm_repair },
{ FM_ALM_IX_SERVICE_AFFECT, fm_service_affect },
{ FM_ALM_IX_SUPPRESSION, fm_suppression },
{ FM_ALM_IX_INHIBIT_ALARM, fm_inhibit_alarm }
};
static set_get_field_type find_func_set_get(EFmAlarmIndexMap id) {
size_t ix = 0;
size_t mx = sizeof (fm_alarm_convert_func)/sizeof(*fm_alarm_convert_func);
for ( ; ix < mx ; ++ix ) {
if (fm_alarm_convert_func[ix].id==id)
return fm_alarm_convert_func[ix].func;
}
return NULL;
}
bool fm_alarm_set_field(EFmAlarmIndexMap field, SFmAlarmDataT *a, std::string &val) {
init_tables();
set_get_field_type p = find_func_set_get(field);
if (p==NULL) return false;
p(a,val,false);
return true;
}
struct log_struct_update_t{
EFmLogIndexMap id;
set_get_field_type func;
} fm_log_convert_func [] = {
{ FM_LOG_IX_UUID, fm_set_uuid },
{ FM_LOG_IX_LOG_ID, fm_tr_alarm_id },
{ FM_LOG_IX_ENTITY_ID, fm_entity_id },
{ FM_LOG_IX_INSTANCE_ID, fm_instance_id },
{ FM_LOG_IX_TIMESTAMP, fm_timestamp },
{ FM_LOG_IX_SEVERITY, fm_alarm_severity },
{ FM_LOG_IX_REASON, fm_reason_text },
{ FM_LOG_IX_LOG_TYPE, fm_alarm_type },
{ FM_LOG_IX_PROBABLE_CAUSE, fm_prop_cause },
{ FM_LOG_IX_SERVICE_AFFECT, fm_service_affect }
};
static set_get_field_type fm_log_find_func_set_get(EFmLogIndexMap id) {
size_t ix = 0;
size_t mx = sizeof (fm_log_convert_func)/sizeof(*fm_log_convert_func);
for ( ; ix < mx ; ++ix ) {
if (fm_log_convert_func[ix].id==id)
return fm_log_convert_func[ix].func;
}
return NULL;
}
bool fm_log_set_field(EFmLogIndexMap field, SFmAlarmDataT *a, std::string &val) {
init_tables();
set_get_field_type p = fm_log_find_func_set_get(field);
if (p==NULL) return false;
p(a,val,false);
return true;
}
struct event_log_struct_update_t{
EFmEventLogIndexMap id;
set_get_field_type func;
} fm_event_log_convert_func [] = {
{ FM_EVENT_LOG_IX_UUID, fm_set_uuid },
{ FM_EVENT_LOG_IX_EVENT_ID, fm_tr_alarm_id },
{ FM_EVENT_LOG_IX_STATE, fm_alarm_state },
{ FM_EVENT_LOG_IX_ENTITY_ID, fm_entity_id },
{ FM_EVENT_LOG_IX_INSTANCE_ID, fm_instance_id },
{ FM_EVENT_LOG_IX_TIMESTAMP, fm_timestamp },
{ FM_EVENT_LOG_IX_SEVERITY, fm_alarm_severity },
{ FM_EVENT_LOG_IX_REASON, fm_reason_text },
{ FM_EVENT_LOG_IX_EVENT_TYPE, fm_alarm_type },
{ FM_EVENT_LOG_IX_PROBABLE_CAUSE, fm_prop_cause },
{ FM_EVENT_LOG_IX_REPAIR_ACTION, fm_repair },
{ FM_EVENT_LOG_IX_SERVICE_AFFECT, fm_service_affect },
{ FM_EVENT_LOG_IX_SUPPRESSION, fm_suppression }
};
static set_get_field_type fm_event_log_find_func_set_get(EFmEventLogIndexMap id) {
size_t ix = 0;
size_t mx = sizeof (fm_event_log_convert_func)/sizeof(*fm_event_log_convert_func);
for ( ; ix < mx ; ++ix ) {
if (fm_event_log_convert_func[ix].id==id)
return fm_event_log_convert_func[ix].func;
}
return NULL;
}
bool fm_event_log_set_field(EFmEventLogIndexMap field, SFmAlarmDataT *a, std::string &val) {
init_tables();
set_get_field_type p = fm_event_log_find_func_set_get(field);
if (p==NULL) return false;
p(a,val,false);
return true;
}
bool fm_alarm_get_field(EFmAlarmIndexMap field, const SFmAlarmDataT *a, std::string &val) {
init_tables();
set_get_field_type p = find_func_set_get(field);
if (p==NULL) return false;
p((SFmAlarmDataT*)a,val,true);
return true;
}
static std::string fm_alarm_to_string(const SFmAlarmDataT *a) {
std::string s;
size_t ix = 0;
size_t mx = FM_ALM_IX_INHIBIT_ALARM ;
std::string field;
for ( ; ix <= mx ; ++ix ) {
fm_alarm_get_field(((EFmAlarmIndexMap)ix),a,field);
s+=field;
add_s(s);
}
return s;
}
void fm_alarm_to_list(const SFmAlarmDataT *a, std::vector<std::string> &list) {
size_t ix = 0;
size_t mx = FM_ALM_IX_INHIBIT_ALARM ;
std::string field;
for ( ; ix <= mx ; ++ix ) {
fm_alarm_get_field(((EFmAlarmIndexMap)ix),a,field);
list.push_back(field);
}
}
void fm_formatted_str_to_vector(const std::string &s, std::vector<std::string> &alarm) {
str_to_vector(s,alarm);
}
/**
* public APIs
*/
EFmErrorT fm_error_from_string(const std::string &str){
return (EFmErrorT)toint(str,err_to_int);
}
std::string fm_error_from_int(EFmErrorT id){
return tostr((int)id,err_to_str);
}
bool fm_alarm_filter_to_string(const AlarmFilter *filter, std::string &str) {
init_tables();
str+= chkstr(filter->alarm_id);
add_s(str);
str+= chkstr(filter->entity_instance_id);
add_s(str);
return true;
}
bool fm_alarm_filter_from_string(const std::string &str, AlarmFilter *filter) {
strvect_t s;
str_to_vector(str,s);
if (s.size()<2) {
FM_ERROR_LOG("Alarm filter wrong format: %s",str.c_str());
return false;
}
init_tables();
STRCP_TO(filter->alarm_id,s[0]);
STRCP_TO(filter->entity_instance_id,s[1]);
return true;
}
bool fm_alarm_to_string(const SFmAlarmDataT *alarm, std::string &str) {
init_tables();
str+= fm_alarm_to_string(alarm);
return str.size()>0;
}
bool fm_alarm_from_string(const std::string &alstr,SFmAlarmDataT *a) {
strvect_t s;
str_to_vector(alstr, s);
if (s.size()<(FM_ALM_IX_MAX)) { //includes adjustment for last entry + 1 (for starting at 0)
return false;
}
init_tables();
size_t ix = 0;
size_t mx = s.size();
for ( ; ix < mx ; ++ix ) {
fm_alarm_set_field((EFmAlarmIndexMap)ix,a,s[ix]);
}
return true;
}
void fm_uuid_create(fm_uuid_t &uuid){
uuid_t uu;
memset(uuid, 0, sizeof(uuid));
uuid_generate(uu);
uuid_unparse_lower(uu, uuid);
}
void fm_log_request(fm_buff_t &req, bool failed){
SFmMsgHdrT *hdr = ptr_to_hdr(req);
std::string description;
if (failed) {
description.assign("Failed to send FM");
} else {
description.assign("Sending FM");
}
switch(hdr->action) {
case EFmCreateFault: {
SFmAlarmDataT *data = (SFmAlarmDataT * )ptr_to_data(req);
FM_INFO_LOG("%s raise alarm request: alarm_id (%s), entity_id (%s)",
description.c_str(), data->alarm_id, data->entity_instance_id);
}
break;
case EFmDeleteFault: {
AlarmFilter *filter = (AlarmFilter * )ptr_to_data(req);
FM_INFO_LOG("%s clear alarm request: alarm_id (%s), entity_id (%s)",
description.c_str(), filter->alarm_id, filter->entity_instance_id);
}
break;
case EFmDeleteFaults: {
fm_ent_inst_t *entity_id = (fm_ent_inst_t*)ptr_to_data(req);
fm_ent_inst_t &eid = *entity_id;
FM_INFO_LOG("%s clear all request: entity_id (%s)", description.c_str(), eid);
}
break;
default:
FM_ERROR_LOG("Unexpected API action:%u\n", hdr->action);
break;
}
}
void fm_log_response(fm_buff_t &req, fm_buff_t &resp, bool failed){
SFmMsgHdrT *hdr = ptr_to_hdr(req);
SFmMsgHdrT *resp_hdr = ptr_to_hdr(resp);
switch(hdr->action) {
case EFmCreateFault: {
SFmAlarmDataT *data = (SFmAlarmDataT * )ptr_to_data(req);
if (failed) {
FM_WARNING_LOG("Failed to get response for FM raise alarm: alarm_id (%s), entity_id (%s)",
data->alarm_id, data->entity_instance_id);
} else {
FM_INFO_LOG("FM Response for raise alarm: (%d), alarm_id (%s), entity_id (%s)",
resp_hdr->msg_rc, data->alarm_id, data->entity_instance_id);
}
}
break;
case EFmDeleteFault: {
AlarmFilter *filter = (AlarmFilter * )ptr_to_data(req);
if (failed) {
FM_WARNING_LOG("Failed to get response for FM clear alarm: alarm_id (%s), entity_id (%s)",
filter->alarm_id, filter->entity_instance_id);
} else {
FM_INFO_LOG("FM Response for clear alarm: (%d), alarm_id (%s), entity_id (%s)",
resp_hdr->msg_rc, filter->alarm_id, filter->entity_instance_id);
}
}
break;
case EFmDeleteFaults: {
fm_ent_inst_t *entity_id = (fm_ent_inst_t*)ptr_to_data(req);
fm_ent_inst_t &eid = *entity_id;
if (failed) {
FM_WARNING_LOG("Failed to get response for FM clear all: entity_id (%s)", eid);
} else {
FM_INFO_LOG("FM Response for clear all: (%d), entity_id (%s)",
resp_hdr->msg_rc, eid);
}
}
break;
default:
FM_ERROR_LOG("Unexpected API action:%u\n", hdr->action);
break;
}
}

View File

@ -0,0 +1,99 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMALARMUTILS_H_
#define FMALARMUTILS_H_
#include "fmAPI.h"
#include "fmMsg.h"
#include <string>
#include <vector>
enum EFmAlarmIndexMap {
FM_ALM_IX_UUID=0,
FM_ALM_IX_ALARM_ID,
FM_ALM_IX_ALARM_STATE,
FM_ALM_IX_ENTITY_ID,
FM_ALM_IX_INSTANCE_ID,
FM_ALM_IX_TIMESTAMP,
FM_ALM_IX_SEVERITY,
FM_ALM_IX_REASON,
FM_ALM_IX_ALARM_TYPE,
FM_ALM_IX_PROBABLE_CAUSE,
FM_ALM_IX_REPAIR_ACTION,
FM_ALM_IX_SERVICE_AFFECT,
FM_ALM_IX_SUPPRESSION,
FM_ALM_IX_INHIBIT_ALARM,
FM_ALM_IX_MAX
};
enum EFmLogIndexMap {
FM_LOG_IX_UUID=0,
FM_LOG_IX_LOG_ID,
FM_LOG_IX_ENTITY_ID,
FM_LOG_IX_INSTANCE_ID,
FM_LOG_IX_TIMESTAMP,
FM_LOG_IX_SEVERITY,
FM_LOG_IX_REASON,
FM_LOG_IX_LOG_TYPE,
FM_LOG_IX_PROBABLE_CAUSE,
FM_LOG_IX_SERVICE_AFFECT,
FM_LOG_IX_MAX
};
enum EFmEventLogIndexMap {
FM_EVENT_LOG_IX_UUID=0,
FM_EVENT_LOG_IX_EVENT_ID,
FM_EVENT_LOG_IX_STATE,
FM_EVENT_LOG_IX_ENTITY_ID,
FM_EVENT_LOG_IX_INSTANCE_ID,
FM_EVENT_LOG_IX_TIMESTAMP,
FM_EVENT_LOG_IX_SEVERITY,
FM_EVENT_LOG_IX_REASON,
FM_EVENT_LOG_IX_EVENT_TYPE,
FM_EVENT_LOG_IX_PROBABLE_CAUSE,
FM_EVENT_LOG_IX_REPAIR_ACTION,
FM_EVENT_LOG_IX_SERVICE_AFFECT,
FM_EVENT_LOG_IX_SUPPRESSION,
FM_EVENT_LOG_IX_MAX
};
bool fm_alarm_set_field(EFmAlarmIndexMap field, SFmAlarmDataT *a, std::string &val);
bool fm_alarm_get_field(EFmAlarmIndexMap field, const SFmAlarmDataT *a, std::string &val);
bool fm_log_set_field(EFmLogIndexMap field, SFmAlarmDataT *a, std::string &val);
bool fm_event_log_set_field(EFmEventLogIndexMap field, SFmAlarmDataT *a, std::string &val);
void fm_formatted_str_to_vector(const std::string &s, std::vector<std::string> &alarm);
bool fm_alarm_to_string(const SFmAlarmDataT *alarm, std::string &str);
bool fm_alarm_from_string(const std::string &str,SFmAlarmDataT *alarm);
/**
* This will create an alarm list from an alarm - will translate to string.
* The indexes of this API are based on EFmAlarmIndexMap
*/
void fm_alarm_to_list(const SFmAlarmDataT *a, std::vector<std::string> &list);
bool fm_alarm_filter_to_string(const AlarmFilter *alarm, std::string &str);
bool fm_alarm_filter_from_string(const std::string &str, AlarmFilter *alarm);
/**
* Generate a FM UUID
*/
void fm_uuid_create(fm_uuid_t &uuid);
/**
* General utilities to conver alarm fields to and from strings
*/
EFmErrorT fm_error_from_string(const std::string &str);
std::string fm_error_from_int(EFmErrorT id);
void fm_log_request(fm_buff_t &req, bool failed=false);
void fm_log_response(fm_buff_t &req, fm_buff_t &resp, bool failed=false);
#endif /* FMALARMUTILS_H_ */

199
fm-common/sources/fmDb.cpp Normal file
View File

@ -0,0 +1,199 @@
//
// Copyright (c) 2016 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "fmLog.h"
#include "fmAPI.h"
#include "fmTime.h"
#include "fmAlarmUtils.h"
#include "fmDbUtils.h"
#include "fmDb.h"
#include "fmDbConstants.h"
#include "fmThread.h"
CFmDBSession::CFmDBSession() {
m_conn.uri = NULL;
m_conn.pgconn = NULL;
m_conn.status = DB_DISCONNECTED;
}
CFmDBSession::~CFmDBSession() {
if (m_conn.pgconn != NULL){
PQfinish(m_conn.pgconn);
}
}
bool CFmDBSession::connect(const char *uri){
const char *val = NULL;
PGconn *pgconn = NULL;
size_t retries = 30, count = 0, my_sleep = 2; //2 seconds
while (count < retries){
/* Make a connection to the database */
pgconn = PQconnectdb(uri);
/* Check to see that the backend connection was successfully made */
if ((pgconn == NULL) || (PQstatus(pgconn) != CONNECTION_OK)){
FM_INFO_LOG("failed to connected to DB: (%s), retry (%d of %d) ",
uri, count+1, retries);
if (pgconn != NULL) {
FM_INFO_LOG("Postgress error message: (%s).", PQerrorMessage(pgconn));
PQfinish(pgconn);
}
sleep(my_sleep);
count++;
}else {
break;
}
}
if (count == retries) return false;
m_conn.status = DB_CONNECTED;
m_conn.pgconn = pgconn;
m_conn.uri = uri;
val = get_parameter_status("standard_conforming_strings");
//FM_INFO_LOG("connect: server standard_conforming_strings parameter: %s",
// val ? val : "unavailable");
m_conn.equote = (val && (0 == strcmp("off", val)));
//FM_INFO_LOG("connect: server requires E'' quotes: %s", m_conn.equote ? "YES" : "NO");
m_conn.server_version = PQserverVersion(m_conn.pgconn);
m_conn.protocol = PQprotocolVersion(m_conn.pgconn);
m_conn.encoding = get_parameter_status("client_encoding");
return true;
}
bool CFmDBSession::check_conn(){
if (PQstatus(m_conn.pgconn) != CONNECTION_OK) {
FM_ERROR_LOG("DB connection NOT OK\n");
disconnect();
return connect(m_conn.uri);
}
return true;
}
void CFmDBSession::disconnect(){
if (m_conn.pgconn != NULL){
PQfinish(m_conn.pgconn);
}
if (m_conn.status == DB_CONNECTED){
m_conn.status = DB_DISCONNECTED;
}
}
const char * CFmDBSession::get_parameter_status(const char *param){
return PQparameterStatus(m_conn.pgconn, param);
}
bool CFmDBSession::query(const char *db_cmd,fm_db_result_t & result) {
PGresult *res;
int nfields, ntuples, i, j;
if (check_conn() == false){
FM_ERROR_LOG("Failed to reconnect: %s", PQerrorMessage(m_conn.pgconn));
return false;
}
res = PQexec(m_conn.pgconn, db_cmd);
if (PQresultStatus(res) != PGRES_TUPLES_OK){
FM_ERROR_LOG("Status:(%s)\n", PQresStatus(PQresultStatus(res)));
FM_ERROR_LOG("Failed to execute (%s) (%s)", db_cmd, PQresultErrorMessage(res));
PQclear(res);
return false;
}
nfields = PQnfields(res);
ntuples = PQntuples(res);
FM_DEBUG_LOG("Execute cmd:(%s) OK, entries found: (%u)\n", db_cmd, ntuples);
for (i = 0; i < ntuples; ++i){
fm_db_single_result_t single_result;
for (j =0; j < nfields; ++j){
char * key = PQfname(res, j);
char * value = PQgetvalue(res, i, j);
single_result[key] = value;
}
result.push_back(single_result);
}
PQclear(res);
return true;
}
bool CFmDBSession::cmd(const char *db_cmd){
PGresult *res;
bool rc = true;
if (check_conn() == false){
FM_ERROR_LOG("Failed to reconnect: %s", PQerrorMessage(m_conn.pgconn));
return false;
}
res = PQexec(m_conn.pgconn, db_cmd);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
FM_ERROR_LOG("Status:(%s)\n", PQresStatus(PQresultStatus(res)));
FM_ERROR_LOG("Failed to execute (%s) (%s)", db_cmd, PQresultErrorMessage(res));
rc = false;
}
if (rc){
int row = atoi(PQcmdTuples(res));
FM_DEBUG_LOG("SQL command returned successful: %d rows affected.\n", row);
if (row < 1) rc = false;
}
PQclear(res);
return rc;
}
bool CFmDBSession::params_cmd(fm_db_util_sql_params & sql_params){
PGresult *res, *last_res;
bool rc = true;
if (check_conn() == false){
FM_ERROR_LOG("Failed to reconnect: %s", PQerrorMessage(m_conn.pgconn));
return false;
}
res = PQexecParams(m_conn.pgconn, sql_params.db_cmd.c_str(), sql_params.n_params,
NULL,(const char* const*)&(sql_params.param_values[0]),
(const int*)&(sql_params.param_lengths[0]), (const int*)&(sql_params.param_format[0]), 1);
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
FM_ERROR_LOG("Status:(%s)\n", PQresStatus(PQresultStatus(res)));
FM_ERROR_LOG("Failed to execute (%s) (%s)", sql_params.db_cmd.c_str(),
PQresultErrorMessage(res));
rc = false;
}
if (rc){
while ((last_res=PQgetResult(m_conn.pgconn)) != NULL){
if (PQstatus(m_conn.pgconn) == CONNECTION_BAD){
FM_INFO_LOG("POSTGRES DB connection is bad.");
PQclear(last_res);
break;
}
FM_INFO_LOG("Waiting for POSTGRES command to finish: (%d)", PQresultStatus(last_res));
PQclear(last_res);
fmThreadSleep(10);
}
int row = atoi(PQcmdTuples(res));
FM_DEBUG_LOG("SQL command returned successful: %d rows affected.", row);
if (row < 1) {
rc = false;
FM_ERROR_LOG("SQL command returned successful, but no row affected.");
}
}
PQclear(res);
return rc;
}

67
fm-common/sources/fmDb.h Normal file
View File

@ -0,0 +1,67 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDB_H_
#define FMDB_H_
#include "fmAPI.h"
#include <libpq-fe.h>
#include <string>
#include <vector>
#include <map>
struct fm_db_util_sql_params {
int id;
int n_params;
std::string db_cmd;
std::vector<const char*> param_values;
std::vector<int> param_lengths;
std::vector<int> param_format;
std::map<std::string,bool> scratch;
};
typedef std::map<std::string,std::string> fm_db_single_result_t;
typedef std::vector<fm_db_single_result_t> fm_db_result_t;
typedef struct{
const char *uri; /* Connection URI */
int status; /* status of the connection */
int equote; /* use E''-style quotes for escaped strings */
int protocol; /* protocol version */
int server_version; /* server version */
const char *encoding; /* client encoding */
PGconn *pgconn; /* the postgresql connection */
}SFmDBConn;
class CFmDBSession {
protected:
SFmDBConn m_conn;
const char *get_parameter_status(const char *param);
public:
CFmDBSession();
~CFmDBSession();
bool connect(const char *uri);
void disconnect();
bool check_conn();
bool reconnect();
bool query(const char *db_cmd,fm_db_result_t & result);
bool cmd(const char *db_cmd);
bool params_cmd(fm_db_util_sql_params & sql_params);
PGconn* get_pgconn(){
return m_conn.pgconn;
}
};
#endif /* FMDB_H_ */

View File

@ -0,0 +1,49 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBAPI_H_
#define FMDBAPI_H_
#include <stdbool.h>
#include "fmAPI.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FM_SNMP_TRAP_UTIL_SESSION_NULL NULL
typedef void * TFmAlarmSessionT;
typedef struct {
SFmAlarmDataT *alarm;
size_t num;
} SFmAlarmQueryT;
bool fm_snmp_util_create_session(TFmAlarmSessionT *handle, const char *db_conn);
void fm_snmp_util_destroy_session(TFmAlarmSessionT handle);
/*
* Used for applications running on the controller only. Pass in an struct
* and the API will allocate some alarms and return the number of alarms
*
* It is up to the caller to free the SFmAlamarQueryT->alarms entry when done
*/
bool fm_snmp_util_get_all_alarms(TFmAlarmSessionT handle,
SFmAlarmQueryT *query);
bool fm_snmp_util_get_all_event_logs(TFmAlarmSessionT handle,
SFmAlarmQueryT *query);
#ifdef __cplusplus
}
#endif
#endif /* FMDBAPI_H_ */

View File

@ -0,0 +1,532 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <string>
#include <map>
#include "fmLog.h"
#include "fmDbAlarm.h"
#include "fmAlarmUtils.h"
#include "fmDbConstants.h"
#include "fmDbUtils.h"
typedef std::map<int,std::string> itos_t;
typedef std::map<std::string,int> stoi_t;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static itos_t db_alarm_field_ix_to_str;
static stoi_t db_alarm_field_str_to_ix;
static const char * field_map[] = {
FM_ALARM_COLUMN_CREATED_AT, //0
FM_ALARM_COLUMN_UPDATED_AT,
FM_ALARM_COLUMN_DELETED_AT,
FM_ALARM_COLUMN_ID,
FM_ALARM_COLUMN_UUID,
FM_ALARM_COLUMN_ALARM_ID,
FM_ALARM_COLUMN_ALARM_STATE,
FM_ALARM_COLUMN_ENTITY_TYPE_ID,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID,
FM_ALARM_COLUMN_TIMESTAMP,
FM_ALARM_COLUMN_SEVERITY,
FM_ALARM_COLUMN_REASON_TEXT,
FM_ALARM_COLUMN_ALARM_TYPE,
FM_ALARM_COLUMN_PROBABLE_CAUSE,
FM_ALARM_COLUMN_PROPOSED_REPAIR_ACTION,
FM_ALARM_COLUMN_SERVICE_AFFECTING,
FM_ALARM_COLUMN_SUPPRESSION,
FM_ALARM_COLUMN_INHIBIT_ALARMS,
FM_ALARM_COLUMN_MASKED //18
};
void add_both_tables(const char *str, int id, itos_t &t1,stoi_t &t2 ) {
t1[id]=str;
t2[str]=id;
}
static std::string tostr(int id, const itos_t &t ){
itos_t::const_iterator it = t.find(id);
if (it!=t.end()) return it->second;
return "unknown";
}
/*
static int toint(const std::string &s, const stoi_t &t) {
stoi_t::const_iterator it = t.find(s);
if (it!=t.end()) return it->second ;
return 0;
}
*/
static void init_tables() {
pthread_mutex_lock(&mutex);
static bool has_inited=false;
while (!has_inited) {
add_both_tables(FM_ALARM_COLUMN_UUID,FM_ALM_IX_UUID,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ALARM_ID,FM_ALM_IX_ALARM_ID,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ALARM_STATE,FM_ALM_IX_ALARM_STATE,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ENTITY_TYPE_ID,FM_ALM_IX_ENTITY_ID,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ENTITY_INSTANCE_ID,FM_ALM_IX_INSTANCE_ID,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_TIMESTAMP,FM_ALM_IX_TIMESTAMP,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_SEVERITY,FM_ALM_IX_SEVERITY,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_REASON_TEXT,FM_ALM_IX_REASON,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_ALARM_TYPE,FM_ALM_IX_ALARM_TYPE,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_PROBABLE_CAUSE,FM_ALM_IX_PROBABLE_CAUSE,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_PROPOSED_REPAIR_ACTION,FM_ALM_IX_REPAIR_ACTION,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_SERVICE_AFFECTING,FM_ALM_IX_SERVICE_AFFECT,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_SUPPRESSION,FM_ALM_IX_SUPPRESSION,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
add_both_tables(FM_ALARM_COLUMN_INHIBIT_ALARMS,FM_ALM_IX_INHIBIT_ALARM,db_alarm_field_ix_to_str,db_alarm_field_str_to_ix);
has_inited = true;
}
pthread_mutex_unlock(&mutex);
}
void append(std::string &str, const std::string &what) {
str+=what;
str+="###";
}
bool CFmDbAlarm::import_data(data_type &m ) {
m_alarm_data = m;
return true;
}
bool CFmDbAlarm::create_data(SFmAlarmDataT *alarm) {
init_tables();
m_alarm_data.clear();
size_t ix = FM_ALM_IX_UUID;
size_t mx = FM_ALM_IX_MAX;
std::string field;
for ( ; ix < mx ; ++ix ) {
std::string field_n = tostr(ix,db_alarm_field_ix_to_str);
fm_alarm_get_field((EFmAlarmIndexMap)ix,alarm,field);
m_alarm_data[field_n] = field;
}
return true;
}
bool CFmDbAlarm::export_data(CFmDbAlarm::data_type &m) {
m = m_alarm_data;
return true;
}
bool CFmDbAlarm::export_data(SFmAlarmDataT *alarm) {
init_tables();
memset(alarm,0,sizeof(*alarm));
size_t ix = FM_ALM_IX_UUID;
size_t mx =FM_ALM_IX_MAX;
std::string field;
for ( ; ix < mx ; ++ix ) {
std::string field_n = tostr(ix,db_alarm_field_ix_to_str);
if (m_alarm_data.find(field_n)==m_alarm_data.end()) return false;
fm_alarm_set_field((EFmAlarmIndexMap)ix,alarm,m_alarm_data[field_n]);
}
return true;
}
std::string CFmDbAlarm::find_field(const char *field) {
if (field==NULL) return "";
if (m_alarm_data.find(field)==m_alarm_data.end()) return "";
return m_alarm_data[field];
}
std::string CFmDbAlarm::to_formatted_db_string(const char ** list, size_t len) {
std::string details;
if (list == NULL) {
list = &field_map[0];
len = sizeof(field_map)/sizeof(*field_map);
}
size_t ix = 0;
for ( ; ix < len ; ++ix ) {
FM_DB_UT_NAME_VAL(details,
list[ix],
m_alarm_data[list[ix]]);
if (ix < (len-1))
details += "', ";
}
return details;
}
void CFmDbAlarm::print() {
std::string str = to_formatted_db_string();
FM_INFO_LOG("%s\n",str.c_str());
}
bool CFmDbAlarmOperation::create_alarm(CFmDBSession &sess,CFmDbAlarm &a) {
CFmDbAlarm::data_type data;
if (!a.export_data(data)) return false;
CFmDbAlarm::data_type::iterator it =
data.find(FM_ALARM_COLUMN_DELETED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_ID);
if (it != data.end()){
data.erase(it);
}
std::string query;
FM_DB_UT_NAME_VAL(query,FM_ALARM_COLUMN_ALARM_ID,
data[FM_ALARM_COLUMN_ALARM_ID]);
query += " AND ";
FM_DB_UT_NAME_VAL(query,FM_ALARM_COLUMN_ENTITY_INSTANCE_ID,
data[FM_ALARM_COLUMN_ENTITY_INSTANCE_ID]);
std::string sql;
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query.c_str(), sql);
fm_db_result_t result;
if ((sess.query(sql.c_str(), result)) != true){
return false;
}
data[FM_ALARM_COLUMN_UUID] = a.find_field(FM_ALARM_COLUMN_UUID);
data[FM_ALARM_COLUMN_MASKED] = "False";
fm_db_util_sql_params sql_params;
if (result.size() == 0){
fm_db_util_build_sql_insert((const char*)FM_ALARM_TABLE_NAME, data, sql_params);
}else{
fm_db_single_result_t alm = result[0];
fm_db_util_build_sql_update((const char*)FM_ALARM_TABLE_NAME,
alm[FM_ALARM_COLUMN_ID],data, sql_params);
}
sql_params.n_params = data.size();
FM_DEBUG_LOG("execute CMD (%s)\n", sql_params.db_cmd.c_str());
return sess.params_cmd(sql_params);
}
bool CFmDbAlarmOperation::delete_alarms(CFmDBSession &sess, const char *id) {
std::string sql;
fm_db_util_build_sql_delete_all((const char*)FM_ALARM_TABLE_NAME, id, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
return sess.cmd(sql.c_str());
}
bool CFmDbAlarmOperation::delete_alarm(CFmDBSession &sess, AlarmFilter &af) {
std::string sql;
fm_db_util_build_sql_delete((const char*)FM_ALARM_TABLE_NAME, &af, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
return sess.cmd(sql.c_str());
}
bool CFmDbAlarmOperation::get_alarm(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & alarms) {
std::string sql;
char query[FM_MAX_SQL_STATEMENT_MAX];
if (strlen(af.entity_instance_id) == 0){
snprintf(query, sizeof(query),"%s = '%s' AND %s = ' '", FM_ALARM_COLUMN_ALARM_ID, af.alarm_id,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID);
}
else{
snprintf(query, sizeof(query),"%s = '%s' AND %s = '%s'", FM_ALARM_COLUMN_ALARM_ID, af.alarm_id,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, af.entity_instance_id);
}
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query, sql);
FM_DEBUG_LOG("get_alarm:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), alarms)) != true){
return false;
}
return true;
}
bool CFmDbAlarmOperation::get_alarms(CFmDBSession &sess,const char *id, fm_db_result_t & alarms) {
std::string sql;
char query[FM_MAX_SQL_STATEMENT_MAX];
fm_db_result_t res;
res.clear();
sql = FM_DB_SELECT_FROM_TABLE(FM_ALARM_TABLE_NAME);
sql += " ";
sql += " INNER JOIN ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " ON ";
sql += FM_ALARM_TABLE_NAME;
sql += ".";
sql += FM_ALARM_COLUMN_ALARM_ID;
sql += " = ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
sql += " WHERE ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
sql += " = '";
sql += FM_EVENT_SUPPRESSION_UNSUPPRESSED;
sql += "'";
if (id != NULL){
snprintf(query, sizeof(query),"%s like '%s%s'", FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, id,"%");
if (NULL!=query) {
sql += " AND ";
sql += query;
}
}
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), alarms)) != true)
return false;
return true;
}
bool CFmDbAlarmOperation::get_alarms_by_id(CFmDBSession &sess,const char *id, fm_db_result_t & alarms) {
fm_alarm_id alm_id;
char query[FM_MAX_SQL_STATEMENT_MAX];
std::string sql;
memset(alm_id, 0 , sizeof(alm_id));
strncpy(alm_id, id ,sizeof(alm_id)-1);
snprintf(query, sizeof(query),"%s = '%s'", FM_ALARM_COLUMN_ALARM_ID, id);
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), alarms)) != true){
return false;
}
return true;
}
bool CFmDbAlarmOperation::get_all_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len ) {
fm_db_result_t res;
*len = 0;
*alarms = NULL;
if (!get_alarms(sess, NULL, res))
return false;
std::string sname = fm_db_util_get_system_name(sess);
unsigned int found_num_alarms = res.size();
if (found_num_alarms < 1)
return false;
SFmAlarmDataT *p =
(SFmAlarmDataT*)malloc(found_num_alarms*sizeof(SFmAlarmDataT));
if (p==NULL)
return false;
size_t ix = 0;
for ( ; ix < found_num_alarms; ++ix ){
CFmDbAlarm dbAlm;
CFmDbAlarm::convert_to(res[ix],p+ix);
std::string eid = (p+ix)->entity_instance_id;
eid = sname + "." + eid;
strncpy((p+ix)->entity_instance_id, eid.c_str(),
sizeof((p+ix)->entity_instance_id));
}
(*alarms) = p;
*len = found_num_alarms;
return true;
}
bool CFmDbAlarmOperation::get_history(CFmDBSession &sess,fm_db_result_t & alarms) {
std::string sql;
std::string separator = ", ";
std::string alias = " as ";
sql = "SELECT * FROM ";
sql += FM_EVENT_LOG_TABLE_NAME;
sql += " INNER JOIN ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " ON ";
sql += FM_EVENT_LOG_TABLE_NAME;
sql += ".";
sql += FM_EVENT_LOG_COLUMN_EVENT_ID;
sql += " = ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
sql += " WHERE ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
sql += " = '";
sql += FM_EVENT_SUPPRESSION_UNSUPPRESSED;
sql += "' AND (";
sql += FM_EVENT_LOG_COLUMN_STATE;
sql += " = 'set' OR ";
sql += FM_EVENT_LOG_COLUMN_STATE;
sql += " = 'clear' ) ";
sql += std::string(FM_DB_ORDERBY_TIME());
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), alarms)) != true){
return false;
}
return true;
}
bool CFmDbAlarmOperation::mask_unmask_alarms(CFmDBSession &sess,
SFmAlarmDataT &a, bool mask){
std::string sql;
char query[FM_MAX_SQL_STATEMENT_MAX];
fm_db_result_t res;
res.clear();
snprintf(query, sizeof(query),"%s like '%s%s' and suppression=True",
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, a.entity_instance_id,"%");
fm_db_util_build_sql_query((const char*)FM_ALARM_TABLE_NAME, query, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), res)) != true){
return false;
}
fm_db_result_t::iterator it = res.begin();
fm_db_result_t::iterator end = res.end();
for (; it != end; ++it){
if (((*it)[FM_ALARM_COLUMN_ALARM_ID]==std::string(a.alarm_id)) &&
((*it)[FM_ALARM_COLUMN_ENTITY_INSTANCE_ID]==std::string(a.entity_instance_id))){
FM_INFO_LOG("Skip the alarm that inhibits others (%s), (%s)\n",
a.alarm_id, a.entity_instance_id);
continue;
}
std::map<std::string,std::string> data;
data.clear();
fm_db_util_sql_params sql_params;
fm_db_util_build_sql_update((const char*)FM_ALARM_TABLE_NAME,
(*it)[FM_ALARM_COLUMN_ID],data, sql_params, mask);
sql_params.n_params = data.size();
FM_DEBUG_LOG("execute CMD (%s)\n", sql_params.db_cmd.c_str());
sess.params_cmd(sql_params);
}
return true;
}
bool CFmDbAlarmOperation::get_all_history_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len ) {
fm_db_result_t res;
*len = 0;
*alarms = NULL;
if (!get_history(sess,res)) return false;
std::string sname = fm_db_util_get_system_name(sess);
unsigned int found_num_alarms = res.size();
if (found_num_alarms < 1) return false;
SFmAlarmDataT *p =
(SFmAlarmDataT*)malloc(found_num_alarms*sizeof(SFmAlarmDataT));
if (p==NULL){
return false;
}
size_t ix = 0;
for ( ; ix < found_num_alarms; ++ix ){
CFmDbAlarm dbAlm;
CFmDbAlarm::convert_to(res[ix],p+ix);
std::string eid = (p+ix)->entity_instance_id;
eid = sname + "." + eid;
strncpy((p+ix)->entity_instance_id, eid.c_str(),
sizeof((p+ix)->entity_instance_id));
}
(*alarms) = p;
*len = found_num_alarms;
return true;
}
bool CFmDbAlarmOperation::add_alarm_history(CFmDBSession &sess,
SFmAlarmDataT &a, bool set){
if (set){
a.alarm_state = (a.alarm_state == FM_ALARM_STATE_CLEAR) ?
FM_ALARM_STATE_SET : a.alarm_state;
}else{
a.alarm_state = FM_ALARM_STATE_CLEAR;
}
CFmDbAlarm alm;
if (!alm.create_data(&a)) return false;
CFmDbAlarm::data_type data;
if (!alm.export_data(data)) return false;
CFmDbAlarm::data_type::iterator it =
data.find(FM_ALARM_COLUMN_DELETED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_UPDATED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_MASKED);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_INHIBIT_ALARMS);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_ALARM_COLUMN_ID);
if (it != data.end()){
data.erase(it);
}
int id =0;
std::string sql;
if (false == fm_db_util_get_next_log_id(sess, id)) {
return false;
}
if (0 != id) {
data[FM_ALARM_COLUMN_ID] = fm_db_util_int_to_string(id);
}
// get the current time for clear event
if (!set){
std::string time_str;
fm_db_util_make_timestamp_string(time_str);
data[FM_ALARM_COLUMN_TIMESTAMP] = time_str;
//set the same time in the alarm data that will be used for logging
fm_db_util_get_timestamp(time_str.c_str(), a.timestamp);
}
sql.clear();
fm_db_util_sql_params sql_params;
fm_db_util_event_log_build_sql_insert(data, sql_params);
FM_DEBUG_LOG("Add row (%s)\n", sql_params.db_cmd.c_str());
return sess.params_cmd(sql_params);
}

View File

@ -0,0 +1,74 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBALARM_H_
#define FMDBALARM_H_
#include <string>
#include <vector>
#include <stddef.h>
#include <map>
#include "fmAPI.h"
#include "fmDbConstants.h"
#include "fmDb.h"
class CFmDbAlarm {
public:
typedef std::map<std::string,std::string> data_type;
bool import_data(CFmDbAlarm::data_type &m);
bool create_data(SFmAlarmDataT *alarm);
bool export_data(SFmAlarmDataT *alarm);
bool export_data(CFmDbAlarm::data_type &m);
std::string find_field(const char *field);
void set_field(const std::string &lhs, const std::string &rhs) {
m_alarm_data[lhs] = rhs;
}
std::string to_formatted_db_string(const char ** list=NULL, size_t len=0);
void print();
static inline bool convert_to(CFmDbAlarm::data_type &m, SFmAlarmDataT *alarm ) {
CFmDbAlarm a;
if (!a.import_data(m)) return false;
return a.export_data(alarm);
}
protected:
data_type m_alarm_data;
};
class CFmDbAlarmOperation {
public:
bool create_alarm(CFmDBSession &sess, CFmDbAlarm &a);
bool delete_alarms(CFmDBSession &sess, const char *id);
bool delete_alarm(CFmDBSession &sess, AlarmFilter &af);
bool delete_row(CFmDBSession &sess, const char* db_table);
bool get_alarm(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & alarms);
bool get_alarms(CFmDBSession &sess, const char *id, fm_db_result_t & alarms) ;
bool get_history(CFmDBSession &sess, fm_db_result_t & alarms) ;
bool get_all_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len );
bool get_all_history_alarms(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len );
bool get_alarms_by_id(CFmDBSession &sess, const char *id, fm_db_result_t & alarms);
bool mask_unmask_alarms(CFmDBSession &sess, SFmAlarmDataT &a, bool mask = true);
bool add_alarm_history(CFmDBSession &sess, SFmAlarmDataT &a, bool set);
};
#endif /* FMDBALARM_H_ */

View File

@ -0,0 +1,99 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBCONSTANTS_H_
#define FMDBCONSTANTS_H_
/* DB connection status */
#define DB_DISCONNECTED 0
#define DB_CONNECTED 1
#define FM_MAX_SQL_STATEMENT_MAX 4096
#define FM_DB_TABLE_COUNT_COLUMN "count"
/* Alarm table name */
#define FM_ALARM_TABLE_NAME "i_alarm"
/* Event log table name */
#define FM_EVENT_LOG_TABLE_NAME "i_event_log"
/* Event suppression table name */
#define FM_EVENT_SUPPRESSION_TABLE_NAME "event_suppression"
/* Event suppression table sync script */
#define FM_DB_SYNC_EVENT_SUPPRESSION "/usr/bin/fm_db_sync_event_suppression.py"
/* Alarm Table Columns */
#define FM_ALARM_COLUMN_CREATED_AT "created_at"
#define FM_ALARM_COLUMN_UPDATED_AT "updated_at"
#define FM_ALARM_COLUMN_DELETED_AT "deleted_at"
#define FM_ALARM_COLUMN_ID "id"
#define FM_ALARM_COLUMN_UUID "uuid"
#define FM_ALARM_COLUMN_ALARM_ID "alarm_id"
#define FM_ALARM_COLUMN_ALARM_STATE "alarm_state"
#define FM_ALARM_COLUMN_ENTITY_TYPE_ID "entity_type_id"
#define FM_ALARM_COLUMN_ENTITY_INSTANCE_ID "entity_instance_id"
#define FM_ALARM_COLUMN_TIMESTAMP "timestamp"
#define FM_ALARM_COLUMN_SEVERITY "severity"
#define FM_ALARM_COLUMN_REASON_TEXT "reason_text"
#define FM_ALARM_COLUMN_ALARM_TYPE "alarm_type"
#define FM_ALARM_COLUMN_PROBABLE_CAUSE "probable_cause"
#define FM_ALARM_COLUMN_PROPOSED_REPAIR_ACTION "proposed_repair_action"
#define FM_ALARM_COLUMN_SERVICE_AFFECTING "service_affecting"
#define FM_ALARM_COLUMN_SUPPRESSION "suppression"
#define FM_ALARM_COLUMN_INHIBIT_ALARMS "inhibit_alarms"
#define FM_ALARM_COLUMN_MASKED "masked"
/* Event Log Table Columns */
#define FM_EVENT_LOG_COLUMN_CREATED_AT "created_at"
#define FM_EVENT_LOG_COLUMN_UPDATED_AT "updated_at"
#define FM_EVENT_LOG_COLUMN_DELETED_AT "deleted_at"
#define FM_EVENT_LOG_COLUMN_ID "id"
#define FM_EVENT_LOG_COLUMN_UUID "uuid"
#define FM_EVENT_LOG_COLUMN_EVENT_ID "event_log_id"
#define FM_EVENT_LOG_COLUMN_STATE "state"
#define FM_EVENT_LOG_COLUMN_ENTITY_TYPE_ID "entity_type_id"
#define FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID "entity_instance_id"
#define FM_EVENT_LOG_COLUMN_TIMESTAMP "timestamp"
#define FM_EVENT_LOG_COLUMN_SEVERITY "severity"
#define FM_EVENT_LOG_COLUMN_REASON_TEXT "reason_text"
#define FM_EVENT_LOG_COLUMN_EVENT_TYPE "event_log_type"
#define FM_EVENT_LOG_COLUMN_PROBABLE_CAUSE "probable_cause"
#define FM_EVENT_LOG_COLUMN_PROPOSED_REPAIR_ACTION "proposed_repair_action"
#define FM_EVENT_LOG_COLUMN_SERVICE_AFFECTING "service_affecting"
#define FM_EVENT_LOG_COLUMN_SUPPRESSION "suppression"
/* Event Suppression Table Columns */
#define FM_EVENT_SUPPRESSION_COLUMN_CREATED_AT "created_at"
#define FM_EVENT_SUPPRESSION_COLUMN_UPDATED_AT "updated_at"
#define FM_EVENT_SUPPRESSION_COLUMN_DELETED_AT "deleted_at"
#define FM_EVENT_SUPPRESSION_COLUMN_ID "id"
#define FM_EVENT_SUPPRESSION_COLUMN_UUID "uuid"
#define FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID "alarm_id"
#define FM_EVENT_SUPPRESSION_COLUMN_DESCRIPTION "description"
#define FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS "suppression_status"
#define FM_EVENT_SUPPRESSION_SUPPRESSED "suppressed"
#define FM_EVENT_SUPPRESSION_UNSUPPRESSED "unsuppressed"
#define FM_EVENT_SUPPRESSION_NONE "None"
/* System table name */
#define FM_SYSTEM_TABLE_NAME "i_system"
#define FM_SYSTEM_NAME_COLUMN "name"
#define FM_SYSTEM_REGION_COLUMN "region_name"
#define FM_ENTITY_ROOT_KEY "system="
#define FM_ENTITY_REGION_KEY "region="
/* config keys */
#define FM_SQL_CONNECTION "sql_connection"
#define FM_EVENT_LOG_MAX_SIZE "event_log_max_size"
#define CLEAR_ALL_REASON_TEXT "System initiated hierarchical alarm clear"
#endif /* FMDBCONSTANTS_H_ */

View File

@ -0,0 +1,318 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <string>
#include <map>
#include "fmLog.h"
#include "fmDbAlarm.h"
#include "fmDbEventLog.h"
#include "fmAlarmUtils.h"
#include "fmDbConstants.h"
#include "fmDbUtils.h"
typedef std::map<int,std::string> itos_t;
typedef std::map<std::string,int> stoi_t;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static itos_t db_event_log_field_ix_to_str;
static stoi_t db_event_log_field_str_to_ix;
static const char * field_map[] = {
FM_EVENT_LOG_COLUMN_CREATED_AT, //0
FM_EVENT_LOG_COLUMN_UPDATED_AT,
FM_EVENT_LOG_COLUMN_DELETED_AT,
FM_EVENT_LOG_COLUMN_ID,
FM_EVENT_LOG_COLUMN_UUID,
FM_EVENT_LOG_COLUMN_EVENT_ID,
FM_EVENT_LOG_COLUMN_STATE,
FM_EVENT_LOG_COLUMN_ENTITY_TYPE_ID,
FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID,
FM_EVENT_LOG_COLUMN_TIMESTAMP,
FM_EVENT_LOG_COLUMN_SEVERITY,
FM_EVENT_LOG_COLUMN_REASON_TEXT,
FM_EVENT_LOG_COLUMN_EVENT_TYPE,
FM_EVENT_LOG_COLUMN_PROBABLE_CAUSE,
FM_EVENT_LOG_COLUMN_PROPOSED_REPAIR_ACTION,
FM_EVENT_LOG_COLUMN_SERVICE_AFFECTING,
FM_EVENT_LOG_COLUMN_SUPPRESSION,
};
static const int alarm_to_event_log_index[] = {
FM_EVENT_LOG_IX_UUID,
FM_EVENT_LOG_IX_EVENT_ID,
FM_EVENT_LOG_IX_STATE,
FM_EVENT_LOG_IX_ENTITY_ID,
FM_EVENT_LOG_IX_INSTANCE_ID,
FM_EVENT_LOG_IX_TIMESTAMP,
FM_EVENT_LOG_IX_SEVERITY,
FM_EVENT_LOG_IX_REASON,
FM_EVENT_LOG_IX_EVENT_TYPE,
FM_EVENT_LOG_IX_PROBABLE_CAUSE,
FM_EVENT_LOG_IX_REPAIR_ACTION,
FM_EVENT_LOG_IX_SERVICE_AFFECT,
FM_EVENT_LOG_IX_SUPPRESSION,
-1,
FM_EVENT_LOG_IX_MAX
};
void CFmDbEventLog::add_both_tables(const char *str, int id, itos_t &t1,stoi_t &t2 ) {
t1[id]=str;
t2[str]=id;
}
static std::string tostr(int id, const itos_t &t ){
itos_t::const_iterator it = t.find(id);
if (it!=t.end()) return it->second;
return "unknown";
}
void CFmDbEventLog::init_tables() {
pthread_mutex_lock(&mutex);
static bool has_inited=false;
while (!has_inited) {
add_both_tables(FM_EVENT_LOG_COLUMN_UUID,FM_EVENT_LOG_IX_UUID,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_EVENT_ID,FM_EVENT_LOG_IX_EVENT_ID,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_STATE,FM_EVENT_LOG_IX_STATE,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_ENTITY_TYPE_ID,FM_EVENT_LOG_IX_ENTITY_ID,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID,FM_EVENT_LOG_IX_INSTANCE_ID,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_TIMESTAMP,FM_EVENT_LOG_IX_TIMESTAMP,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_SEVERITY,FM_EVENT_LOG_IX_SEVERITY,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_REASON_TEXT,FM_EVENT_LOG_IX_REASON,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_EVENT_TYPE,FM_EVENT_LOG_IX_EVENT_TYPE,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_PROBABLE_CAUSE,FM_EVENT_LOG_IX_PROBABLE_CAUSE,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_PROPOSED_REPAIR_ACTION, FM_EVENT_LOG_IX_REPAIR_ACTION, db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_SERVICE_AFFECTING,FM_EVENT_LOG_IX_SERVICE_AFFECT,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
add_both_tables(FM_EVENT_LOG_COLUMN_SUPPRESSION,FM_EVENT_LOG_IX_SUPPRESSION,db_event_log_field_ix_to_str,db_event_log_field_str_to_ix);
has_inited = true;
}
pthread_mutex_unlock(&mutex);
}
void CFmDbEventLog::append(std::string &str, const std::string &what) {
str+=what;
str+="###";
}
bool CFmDbEventLog::import_data(data_type &m ) {
m_event_log_data = m;
return true;
}
bool CFmDbEventLog::create_data(SFmAlarmDataT *alarm) {
init_tables();
m_event_log_data.clear();
size_t ix = FM_ALM_IX_UUID;
size_t mx = FM_ALM_IX_MAX;
std::string field;
int log_idx;
for ( ; ix < mx ; ++ix ) {
log_idx = alarm_to_event_log_index[ix];
if (log_idx == -1)
continue;
std::string field_n = tostr(log_idx,db_event_log_field_ix_to_str);
if (field_n == "unknown")
continue; // ignore these fields
fm_alarm_get_field((EFmAlarmIndexMap)ix,alarm,field);
m_event_log_data[field_n] = field;
}
return true;
}
bool CFmDbEventLog::export_data(CFmDbEventLog::data_type &m) {
m = m_event_log_data;
return true;
}
bool CFmDbEventLog::export_data(SFmAlarmDataT *data) {
init_tables();
memset(data,0,sizeof(*data));
size_t ix = FM_EVENT_LOG_IX_UUID;
size_t mx = FM_EVENT_LOG_IX_MAX;
std::string field;
for ( ; ix < mx ; ++ix ) {
std::string field_n = tostr(ix,db_event_log_field_ix_to_str);
if (m_event_log_data.find(field_n)==m_event_log_data.end()) return false;
fm_event_log_set_field((EFmEventLogIndexMap)ix,data,m_event_log_data[field_n]);
}
return true;
}
std::string CFmDbEventLog::find_field(const char *field) {
if (field==NULL) return "";
if (m_event_log_data.find(field)==m_event_log_data.end()) return "";
return m_event_log_data[field];
}
std::string CFmDbEventLog::to_formatted_db_string(const char ** list, size_t len) {
std::string details;
if (list == NULL) {
list = &field_map[0];
len = sizeof(field_map)/sizeof(*field_map);
}
size_t ix = 0;
for ( ; ix < len ; ++ix ) {
FM_DB_UT_NAME_VAL(details,
list[ix],
m_event_log_data[list[ix]]);
if (ix < (len-1))
details += "', ";
}
return details;
}
void CFmDbEventLog::print() {
std::string str = to_formatted_db_string();
FM_INFO_LOG("%s\n",str.c_str());
}
bool CFmDbEventLogOperation::create_event_log(CFmDBSession &sess,CFmDbEventLog &a) {
CFmDbEventLog::data_type data;
if (!a.export_data(data)) return false;
CFmDbEventLog::data_type::iterator it =
data.find(FM_EVENT_LOG_COLUMN_DELETED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_EVENT_LOG_COLUMN_UPDATED_AT);
if (it != data.end()){
data.erase(it);
}
it = data.find(FM_EVENT_LOG_COLUMN_ID);
if (it != data.end()){
data.erase(it);
}
int id =0;
std::string sql;
if ( false == fm_db_util_get_next_log_id(sess, id)) {
return false;
}
if (0 != id) {
data[FM_EVENT_LOG_COLUMN_ID] = fm_db_util_int_to_string(id);
}
fm_db_util_sql_params sql_params;
fm_db_util_build_sql_insert((const char*)FM_EVENT_LOG_TABLE_NAME, data, sql_params);
sql_params.n_params = data.size();
FM_DEBUG_LOG("Add row (%s)\n", sql_params.db_cmd.c_str());
return sess.params_cmd(sql_params);
}
bool CFmDbEventLogOperation::get_event_log(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & logs) {
std::string sql;
char query[FM_MAX_SQL_STATEMENT_MAX];
if (strlen(af.entity_instance_id) == 0){
snprintf(query, sizeof(query),"%s = '%s' AND %s = ' '", FM_EVENT_LOG_COLUMN_EVENT_ID, af.alarm_id,
FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID);
}
else{
snprintf(query, sizeof(query),"%s = '%s' AND %s = '%s'", FM_EVENT_LOG_COLUMN_EVENT_ID, af.alarm_id,
FM_EVENT_LOG_COLUMN_ENTITY_INSTANCE_ID, af.entity_instance_id);
}
fm_db_util_build_sql_query((const char*)FM_EVENT_LOG_TABLE_NAME, query, sql);
FM_DEBUG_LOG("get_log:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), logs)) != true){
return false;
}
return true;
}
bool CFmDbEventLogOperation::get_event_logs(CFmDBSession &sess, fm_db_result_t & logs) {
std::string sql;
sql = FM_DB_SELECT_FROM_TABLE(FM_EVENT_LOG_TABLE_NAME);
sql += " LEFT OUTER JOIN ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " ON ";
sql += FM_EVENT_LOG_TABLE_NAME;
sql += ".";
sql += FM_EVENT_LOG_COLUMN_EVENT_ID;
sql += " = ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
sql += " WHERE ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ".";
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
sql += " = '";
sql += FM_EVENT_SUPPRESSION_UNSUPPRESSED;
sql += "' OR ";
sql += FM_EVENT_LOG_COLUMN_STATE;
sql += " = 'log' ";
// select statement built
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), logs)) != true){
return false;
}
return true;
}
bool CFmDbEventLogOperation::get_event_logs_by_id(CFmDBSession &sess,const char *id, fm_db_result_t & logs) {
char query[FM_MAX_SQL_STATEMENT_MAX];
std::string sql;
snprintf(query, sizeof(query),"%s = '%s'", FM_EVENT_LOG_COLUMN_EVENT_ID, id);
fm_db_util_build_sql_query((const char*)FM_EVENT_LOG_TABLE_NAME, query, sql);
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), logs)) != true){
return false;
}
return true;
}
bool CFmDbEventLogOperation::get_all_event_logs(CFmDBSession &sess, SFmAlarmDataT **logs, size_t *len ) {
fm_db_result_t res;
*len = 0;
*logs = NULL;
if (!get_event_logs(sess, res)) return false;
std::string sname = fm_db_util_get_system_name(sess);
unsigned int found_num_logs = res.size();
if (found_num_logs < 1) return false;
SFmAlarmDataT *p =
(SFmAlarmDataT*)malloc(found_num_logs*sizeof(SFmAlarmDataT));
if (p==NULL){
return false;
}
size_t ix = 0;
for ( ; ix < found_num_logs; ++ix ){
CFmDbEventLog dbEventLog;
CFmDbEventLog::convert_to(res[ix],p+ix);
std::string eid = (p+ix)->entity_instance_id;
eid = sname + "." + eid;
strncpy((p+ix)->entity_instance_id, eid.c_str(),
sizeof((p+ix)->entity_instance_id));
}
(*logs) = p;
*len = found_num_logs;
return true;
}

View File

@ -0,0 +1,69 @@
//
// Copyright (c) 2016 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBEVENTLOG_H_
#define FMDBEVENTLOG_H_
#include <string>
#include <vector>
#include <stddef.h>
#include <map>
#include "fmAPI.h"
#include "fmDbConstants.h"
#include "fmDb.h"
typedef std::map<int,std::string> itos_t;
typedef std::map<std::string,int> stoi_t;
class CFmDbEventLog {
public:
typedef std::map<std::string,std::string> data_type;
bool create_data(SFmAlarmDataT *alarm);
bool import_data(CFmDbEventLog::data_type &m);
bool export_data(SFmAlarmDataT *alarm);
bool export_data(CFmDbEventLog::data_type &m);
void append(std::string &str, const std::string &what);
void add_both_tables(const char *str, int id, itos_t &t1,stoi_t &t2 );
void init_tables();
std::string find_field(const char *field);
void set_field(const std::string &lhs, const std::string &rhs) {
m_event_log_data[lhs] = rhs;
}
std::string to_formatted_db_string(const char ** list=NULL, size_t len=0);
void print();
static inline bool convert_to(CFmDbEventLog::data_type &m, SFmAlarmDataT *alarm ) {
CFmDbEventLog a;
if (!a.import_data(m)) return false;
return a.export_data(alarm);
}
protected:
data_type m_event_log_data;
};
class CFmDbEventLogOperation {
public:
bool create_event_log(CFmDBSession &sess, CFmDbEventLog &a);
bool get_event_log(CFmDBSession &sess, AlarmFilter &af, fm_db_result_t & alarms);
bool get_event_logs(CFmDBSession &sess, fm_db_result_t & alarms) ;
bool get_all_event_logs(CFmDBSession &sess, SFmAlarmDataT **alarms, size_t *len );
bool get_event_logs_by_id(CFmDBSession &sess, const char *id, fm_db_result_t & alarms);
};
#endif /* FMDBEVENTLOG_H_ */

View File

@ -0,0 +1,715 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <sstream>
#include <map>
#include <iostream>
#include <assert.h>
#include <arpa/inet.h>
#include <python2.7/Python.h>
#include "fmMutex.h"
#include "fmAPI.h"
#include "fmLog.h"
#include "fmFile.h"
#include "fmDb.h"
#include "fmDbUtils.h"
#include "fmDbAPI.h"
#include "fmDbConstants.h"
#include "fmAlarmUtils.h"
typedef std::map<std::string,std::string> configParams;
static const char *conf = NULL;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
CFmMutex & getConfMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
configParams &getConfigMap(){
static configParams conf;
return conf;
}
void FM_DB_UT_NAME_VAL(
std::string &result,
const std::string &lhs, const std::string &rhs) {
result+= lhs;
result+= " = '";
result+=rhs;
result+="'";
}
void FM_DB_UT_NAME_PARAM(
std::string &result,
const std::string &lhs, const std::string &rhs) {
result+= lhs;
result+= "=";
result+=rhs;
}
static inline void append_str(std::string &s, const std::string &app) {
if (s.size()!=0) s+= ", ";
s+=app;
}
static inline std::string add_quote(const std::string &s) {
return std::string("'")+s+"'";
}
static int get_oldest_id(CFmDBSession &sess, const char* db_table){
fm_db_result_t res;
int id = 0;
char sql[FM_MAX_SQL_STATEMENT_MAX];
memset(sql, 0, sizeof(sql));
snprintf(sql, sizeof(sql), "SELECT %s FROM %s order by %s limit 1",
FM_ALARM_COLUMN_ID, db_table,
FM_ALARM_COLUMN_CREATED_AT);
if (sess.query(sql, res)){
if (res.size() > 0){
std::map<std::string,std::string> entry = res[0];
id = fm_db_util_string_to_int(entry[FM_ALARM_COLUMN_ID]);
}
}
return id;
}
static void get_config_parameters(){
CfmFile f;
std::string delimiter = "=";
std::string line, key, value;
size_t pos = 0;
if (conf == NULL){
FM_ERROR_LOG("The config file is not set\n");
exit(-1);
}
if (!f.open(conf, CfmFile::READ, false)){
FM_ERROR_LOG("Failed to open config file: %s\n", conf);
exit(-1);
}
while (true){
if (!f.read_line(line)) break;
if (line.size() == 0) continue;
if (line[0] == '#') continue;
pos = line.find(delimiter);
key = line.substr(0, pos);
value = line.erase(0, pos + delimiter.length());
getConfigMap()[key] = value;
if (key.compare("sql_connection") != 0){
// Don't log sql_connection, as it has a password
FM_INFO_LOG("Config key (%s), value (%s)",
key.c_str(), value.c_str());
}
}
}
static inline CFmDBSession & FmDbSessionFromHandle(TFmAlarmSessionT *p){
return *((CFmDBSession*)p);
}
static void format_time_string(std::string &tstr, struct timespec *ts,
bool snmp){
char buff[200];
struct tm t;
int ret = 0;
//tzset();
memset(&t, 0, sizeof(t));
memset(buff, 0, sizeof(buff));
if (gmtime_r(&(ts->tv_sec), &t) == NULL)
return ;
if (snmp){
ret = strftime(buff, sizeof(buff), "%Y-%m-%d,%H:%M:%S.0,+0:0", &t);
}else{
ret = strftime(buff,sizeof(buff), "%F %T", &t);
}
if (ret == 0) return ;
tstr+=buff;
if (!snmp){
//append the microseconds
snprintf(buff,sizeof(buff), ".%06ld", ts->tv_nsec/1000);
tstr+=buff;
}
}
std::string fm_db_util_replace_single_quote(std::string const& original){
std::string result;
std::string::const_iterator it = original.begin();
for (; it != original.end(); ++it){
if (*it == '\''){
result.push_back('\'');
}
result.push_back(*it);
}
return result;
}
std::string fm_db_util_int_to_string(int val){
std::string result;
std::stringstream ss;
ss << val;
ss >> result;
return result;
}
int fm_db_util_string_to_int(std::string val){
int result;
std::stringstream ss;
ss << val;
ss >> result;
return result;
}
void fm_db_util_make_timestamp_string(std::string &tstr, FMTimeT tm,
bool snmp){
struct timespec ts;
if (tm != 0){
ts.tv_sec = tm / 1000000;
ts.tv_nsec = (tm % 1000000) * 1000;
}else{
clock_gettime(CLOCK_REALTIME, &ts);
}
tstr.clear();
format_time_string(tstr,&ts, snmp);
}
bool fm_db_util_get_timestamp(const char *str, FMTimeT &ft){
struct timespec ts;
memset(&ts, 0, sizeof(ts));
// only check if the year is present
if (strlen(str) < 10){
//get the current time
clock_gettime(CLOCK_REALTIME, &ts);
}else{
struct tm t;
memset(&t, 0, sizeof(t));
strptime(str, "%F %T", &t);
ts.tv_sec = mktime(&t);
//now get the nanoseconds
char *tstr = strdup(str);
strsep(&tstr, ".");
if (tstr != NULL){
ts.tv_nsec = atol(tstr)*1000;
}
}
ft = ts.tv_sec*1000000 + ts.tv_nsec/1000;
return true;
}
bool fm_db_util_build_sql_query(const char* db_table,
const char* db_query, std::string &db_cmd){
db_cmd = FM_DB_SELECT_FROM_TABLE(db_table);
if (NULL!=db_query) {
db_cmd += " ";
db_cmd += FM_DB_WHERE();
db_cmd += " ";
db_cmd += db_query;
}
return true;
}
bool fm_db_util_build_sql_insert(const char* db_table,
std::map<std::string,std::string> &map,
fm_db_util_sql_params &params) {
std::string keys;
std::string values;
std::string time_str;
fm_db_util_make_timestamp_string(time_str);
map[FM_ALARM_COLUMN_CREATED_AT] = time_str;
std::map<std::string,std::string>::iterator at =
map.find(FM_ALARM_COLUMN_UPDATED_AT);
if (at != map.end()){
map.erase(at);
}
std::map<std::string,std::string>::iterator it = map.begin();
std::map<std::string,std::string>::iterator end = map.end();
size_t i = 0;
std::string cmd_params;
char str[80];
std::string param;
for ( ; it != end ; ++it ) {
param.clear();
memset(str, 0, sizeof(str));
append_str(keys,it->first);
if (it->first == FM_ALARM_COLUMN_ID){
params.id = htonl(atoi(it->second.c_str()));
params.param_values.push_back((char*)&params.id);
params.param_lengths.push_back(sizeof(int));
params.param_format.push_back(1);
sprintf(str,"$%lu::int,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_CREATED_AT) ||
(it->first == FM_ALARM_COLUMN_TIMESTAMP)){
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str, "$%lu::timestamp,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_SERVICE_AFFECTING) ||
(it->first == FM_ALARM_COLUMN_SUPPRESSION) ||
(it->first == FM_ALARM_COLUMN_INHIBIT_ALARMS) ||
(it->first == FM_ALARM_COLUMN_MASKED)){
params.scratch[it->first] = (it->second == "True") ? 1 : 0;
params.param_values.push_back((char *)&(params.scratch[it->first]));
params.param_lengths.push_back(sizeof(bool));
params.param_format.push_back(1);
sprintf(str,"$%lu::boolean,", ++i);
} else {
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
}
param.assign(str);
cmd_params += param;
}
cmd_params.resize(cmd_params.size()-1);
params.db_cmd = "INSERT INTO ";
params.db_cmd += db_table;
params.db_cmd += " ( ";
params.db_cmd += keys;
params.db_cmd += ") VALUES (";
params.db_cmd += cmd_params;
params.db_cmd += ");";
return true;
}
bool fm_db_util_event_log_build_sql_insert(std::map<std::string,std::string> &map,
fm_db_util_sql_params &params) {
std::string keys;
std::string values;
std::string time_str;
fm_db_util_make_timestamp_string(time_str);
map[FM_ALARM_COLUMN_CREATED_AT] = time_str;
std::map<std::string,std::string>::iterator at =
map.find(FM_ALARM_COLUMN_UPDATED_AT);
if (at != map.end()){
map.erase(at);
}
std::map<std::string,std::string>::iterator it = map.begin();
std::map<std::string,std::string>::iterator end = map.end();
size_t i = 0;
std::string cmd_params;
char str[80];
std::string param;
params.n_params = 0;
for ( ; it != end ; ++it ) {
param.clear();
memset(str, 0, sizeof(str));
if (it->first == FM_ALARM_COLUMN_ID){
append_str(keys,it->first);
params.id = htonl(atoi(it->second.c_str()));
params.param_values.push_back((char*)&params.id);
params.param_lengths.push_back(sizeof(int));
params.param_format.push_back(1);
sprintf(str,"$%lu::int,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_CREATED_AT) ||
(it->first == FM_ALARM_COLUMN_TIMESTAMP)){
append_str(keys,it->first);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str, "$%lu::timestamp,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_SERVICE_AFFECTING) ||
(it->first == FM_ALARM_COLUMN_SUPPRESSION) ||
(it->first == FM_ALARM_COLUMN_INHIBIT_ALARMS) ||
(it->first == FM_ALARM_COLUMN_MASKED)){
append_str(keys,it->first);
params.scratch[it->first] = (it->second == "True") ? 1 : 0;
params.param_values.push_back((char *)&(params.scratch[it->first]));
params.param_lengths.push_back(sizeof(bool));
params.param_format.push_back(1);
sprintf(str,"$%lu::boolean,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_ALARM_ID) ||
(it->first == FM_EVENT_LOG_COLUMN_ID)){
std::string event_log_id = FM_EVENT_LOG_COLUMN_EVENT_ID;
append_str(keys,event_log_id);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
} else if ((it->first == FM_ALARM_COLUMN_ALARM_TYPE) ||
(it->first == FM_EVENT_LOG_COLUMN_EVENT_TYPE)){
std::string event_log_type = FM_EVENT_LOG_COLUMN_EVENT_TYPE;
append_str(keys,event_log_type);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
}else if (it->first == FM_ALARM_COLUMN_ALARM_STATE) {
std::string event_state = FM_EVENT_LOG_COLUMN_STATE;
append_str(keys,event_state);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
}
else {
append_str(keys,it->first);
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar,", ++i);
}
params.n_params++;
param.assign(str);
cmd_params += param;
}
cmd_params.resize(cmd_params.size()-1);
params.db_cmd = "INSERT INTO ";
params.db_cmd += FM_EVENT_LOG_TABLE_NAME;
params.db_cmd += " ( ";
params.db_cmd += keys;
params.db_cmd += ") VALUES (";
params.db_cmd += cmd_params;
params.db_cmd += ");";
return true;
}
bool fm_db_util_build_sql_update(const char* db_table,
const std::string & id, std::map<std::string,std::string> &map,
fm_db_util_sql_params &params, FMBoolTypeT masked){
std::string time_str;
params.db_cmd = "UPDATE ";
params.db_cmd += db_table;
params.db_cmd += " SET ";
fm_db_util_make_timestamp_string(time_str);
map[FM_ALARM_COLUMN_UPDATED_AT] = time_str;
map[FM_ALARM_COLUMN_MASKED] = masked ? "True" : "False";
std::map<std::string,std::string>::iterator at =
map.find(FM_ALARM_COLUMN_CREATED_AT);
if (at != map.end()){
map.erase(at);
}
std::map<std::string,std::string>::iterator it = map.begin();
std::map<std::string,std::string>::iterator end = map.end();
size_t i = 0;
char str[80];
std::string param;
for ( ; it != end ; ++it ) {
param.clear();
memset(str, 0, sizeof(str));
if (it != map.begin())
params.db_cmd.append(", ");
if ((it->first == FM_ALARM_COLUMN_UPDATED_AT) ||
(it->first == FM_ALARM_COLUMN_TIMESTAMP)){
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str, "$%lu::timestamp", ++i);
} else if ((it->first == FM_ALARM_COLUMN_SERVICE_AFFECTING) ||
(it->first == FM_ALARM_COLUMN_SUPPRESSION) ||
(it->first == FM_ALARM_COLUMN_INHIBIT_ALARMS) ||
(it->first == FM_ALARM_COLUMN_MASKED)){
params.scratch[it->first] = (it->second == "True") ? 1 : 0;
params.param_values.push_back((char *)&(params.scratch[it->first]));
params.param_lengths.push_back(sizeof(bool));
params.param_format.push_back(1);
sprintf(str,"$%lu::boolean", ++i);
} else {
params.param_values.push_back(it->second.c_str());
params.param_lengths.push_back(strlen(it->second.c_str()));
params.param_format.push_back(0);
sprintf(str,"$%lu::varchar", ++i);
}
param.assign(str);
FM_DB_UT_NAME_PARAM(params.db_cmd, it->first, param);
}
params.db_cmd += " WHERE ";
FM_DB_UT_NAME_VAL(params.db_cmd, FM_ALARM_COLUMN_ID, id);
return true;
}
bool fm_db_util_build_sql_delete(const char* db_table, AlarmFilter *db_data,
std::string &db_cmd){
if (db_data==NULL) return false;
char sql[FM_MAX_SQL_STATEMENT_MAX];
if (strlen(db_data->entity_instance_id) == 0){
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = '%s' AND %s = ' '",
db_table, FM_ALARM_COLUMN_ALARM_ID, db_data->alarm_id,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID);
}
else{
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = '%s' AND %s = '%s'",
db_table, FM_ALARM_COLUMN_ALARM_ID, db_data->alarm_id,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, db_data->entity_instance_id);
}
db_cmd.assign(sql);
return true;
}
bool fm_db_util_build_sql_delete_row(const char* db_table, int id,
std::string &db_cmd){
if (id == 0) return false;
char sql[FM_MAX_SQL_STATEMENT_MAX];
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s = %d",
db_table, FM_ALARM_COLUMN_ID, id);
db_cmd.assign(sql);
return true;
}
bool fm_db_util_build_sql_delete_all(const char* db_table, const char *id,
std::string &db_cmd){
char sql[FM_MAX_SQL_STATEMENT_MAX];
snprintf(sql, sizeof(sql), "DElETE FROM %s WHERE %s like '%s%s'", db_table,
FM_ALARM_COLUMN_ENTITY_INSTANCE_ID, id,"%");
db_cmd.assign(sql);
return true;
}
void fm_db_util_set_conf_file(const char *fn){
conf = fn;
}
bool fm_db_util_get_config(std::string &key, std::string &val){
configParams::iterator it;
static int loaded = false;
CFmMutexGuard m(getConfMutex());
if (!loaded){
get_config_parameters();
loaded = true;
}
it = getConfigMap().find(key);
if (it != getConfigMap().end()){
val = it->second;
return true;
}
return false;
}
int & fm_get_alarm_history_max_size(){
static int max_size = 0;
if (max_size == 0){
std::string val;
std::string key = FM_EVENT_LOG_MAX_SIZE;
if (fm_db_util_get_config(key, val)){
max_size = fm_db_util_string_to_int(val);
}else{
FM_ERROR_LOG("Fail to get config value for (%s)\n", key.c_str());
}
}
return max_size;
}
int & fm_get_log_max_size(){
static int max_size = 0;
if (max_size == 0){
std::string val;
std::string key = FM_EVENT_LOG_MAX_SIZE;
if (fm_db_util_get_config(key, val)){
max_size = fm_db_util_string_to_int(val);
}else{
FM_ERROR_LOG("Fail to get config value for (%s)\n", key.c_str());
}
}
return max_size;
}
std::string fm_db_util_get_system_name(CFmDBSession &sess){
fm_db_result_t res;
std::string cmd;
std::string name = "";
fm_db_util_build_sql_query(FM_SYSTEM_TABLE_NAME, NULL, cmd);
if (sess.query(cmd.c_str(), res)){
if (res.size() > 0){
std::map<std::string,std::string> entry = res[0];
name = FM_ENTITY_ROOT_KEY + entry[FM_SYSTEM_NAME_COLUMN];
}
}
return name;
}
std::string fm_db_util_get_region_name(CFmDBSession &sess){
fm_db_result_t res;
std::string cmd;
std::string name = "";
fm_db_util_build_sql_query(FM_SYSTEM_TABLE_NAME, NULL, cmd);
if (sess.query(cmd.c_str(), res)){
if (res.size() > 0){
std::map<std::string,std::string> entry = res[0];
name = FM_ENTITY_REGION_KEY + entry[FM_SYSTEM_REGION_COLUMN];
}
}
return name;
}
bool fm_db_util_get_row_counts(CFmDBSession &sess,
const char* db_table, int &counts){
fm_db_result_t res;
std::string cmd =
FM_DB_SELECT_ROW_COUNTS_FROM_TABLE(std::string(db_table));
res.clear();
if (sess.query(cmd.c_str(), res)){
if (res.size() > 0){
std::map<std::string,std::string> entry = res[0];
counts = fm_db_util_string_to_int(entry[FM_DB_TABLE_COUNT_COLUMN]);
FM_DEBUG_LOG("Table (%s) row counts: (%llu)",
db_table, counts);
return true;
}
}
return false;
}
bool fm_db_util_get_next_log_id(CFmDBSession &sess, int &id){
pthread_mutex_lock(&mutex);
static bool has_max_rows = false;
static int max = 0;
int active = 0;
if (max == 0){
max = fm_get_log_max_size();
}
if (!has_max_rows){
fm_db_util_get_row_counts(sess, FM_EVENT_LOG_TABLE_NAME, active);
FM_INFO_LOG("Active row accounts:(%d), max:(%d)\n", active, max);
if (active >= max) {
has_max_rows = true;
}
}
if (has_max_rows){
std::string sql;
id = get_oldest_id(sess, FM_EVENT_LOG_TABLE_NAME);
fm_db_util_build_sql_delete_row(FM_EVENT_LOG_TABLE_NAME, id, sql);
FM_DEBUG_LOG("Delete row (%s)\n", sql.c_str());
if (false == sess.cmd(sql.c_str())){
FM_INFO_LOG("Fail to delete the old event log: (%d)", id);
pthread_mutex_unlock(&mutex);
return false;
}
}
FM_DEBUG_LOG("Return next log id: (%d)\n", id);
pthread_mutex_unlock(&mutex);
return true;
}
bool fm_db_util_create_session(CFmDBSession **sess){
TFmAlarmSessionT handle;
const char *db_conn = NULL;
std::string val;
std::string key = FM_SQL_CONNECTION;
if (fm_db_util_get_config(key, val) != true){
FM_ERROR_LOG("Failed to get config for key: (%s)\n", key.c_str());
return false;
}
db_conn = val.c_str();
if (fm_snmp_util_create_session(&handle, db_conn)){
*sess = (CFmDBSession*)handle;
return true;
}
return false;
}
bool fm_db_util_sync_event_suppression(void){
bool return_value = true;
const char *db_conn = NULL;
std::string val;
std::string key = FM_SQL_CONNECTION;
if (fm_db_util_get_config(key, val) != true){
FM_ERROR_LOG("Failed to get config for key: (%s)\n", key.c_str());
return false;
}
db_conn = val.c_str();
FILE* file;
int argc;
char * argv[2];
FM_INFO_LOG("Starting event suppression synchronization...\n");
argc = 2;
argv[0] = (char*)FM_DB_SYNC_EVENT_SUPPRESSION;
argv[1] = (char*)db_conn;
Py_SetProgramName(argv[0]);
Py_Initialize();
PySys_SetArgv(argc, argv);
file = fopen(FM_DB_SYNC_EVENT_SUPPRESSION,"r");
PyRun_SimpleFile(file, FM_DB_SYNC_EVENT_SUPPRESSION);
fclose(file);
Py_Finalize();
FM_INFO_LOG("Completed event suppression synchronization.\n");
return return_value;
}

View File

@ -0,0 +1,94 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMDBUTILS_H_
#define FMDBUTILS_H_
#include "fmAPI.h"
#include "fmDbAlarm.h"
#include "fmDbEventLog.h"
#include "fmDb.h"
#include <string>
#include <memory>
#include <vector>
static inline const char *FM_DB_AND() { return "AND"; }
static inline const char *FM_DB_WHERE() { return "WHERE"; }
static inline const char *FM_DB_SELECT_FROM() { return "SELECT * FROM"; }
static inline const char *FM_DB_SELECT_COUNTS() {
return "SELECT COUNT(*) FROM";
}
static inline const char *FM_DB_ORDERBY_TIME() { return "order by timestamp desc"; }
static inline std::string FM_DB_SELECT_FROM_TABLE(const std::string &table){
return std::string(FM_DB_SELECT_FROM()) + " " +table;
}
static inline std::string FM_DB_SELECT_ROW_COUNTS_FROM_TABLE(
const std::string &table){
return std::string(FM_DB_SELECT_COUNTS()) + " " +table;
}
void FM_DB_UT_NAME_VAL( std::string &result,
const std::string &lhs, const std::string &rhs);
void FM_DB_UT_NAME_PARAM( std::string &result,
const std::string &lhs, const std::string &rhs);
std::string fm_db_util_replace_single_quote(std::string const& original);
void fm_db_util_make_timestamp_string(std::string &tstr,
FMTimeT tm=0, bool snmp=false);
bool fm_db_util_get_timestamp(const char *str, FMTimeT &ft);
bool fm_db_util_build_sql_query(const char* db_table,
const char* db_query, std::string &db_cmd);
bool fm_db_util_build_sql_insert(const char* db_table,
std::map<std::string,std::string> &map,
fm_db_util_sql_params &parms);
bool fm_db_util_event_log_build_sql_insert(std::map<std::string,std::string> &map,
fm_db_util_sql_params &params);
bool fm_db_util_build_sql_update(const char* db_table,
const std::string & id, std::map<std::string,std::string> &map,
fm_db_util_sql_params &parms, FMBoolTypeT masked=0);
bool fm_db_util_build_sql_delete(const char* db_table,
AlarmFilter *db_data, std::string &db_cmd);
bool fm_db_util_build_sql_delete_row(const char* db_table, int id,
std::string &db_cmd);
bool fm_db_util_build_sql_delete_all(const char* db_table,
const char *id, std::string &db_cmd);
bool fm_db_util_get_row_counts(CFmDBSession &sess, const char* db_table,
int &counts);
bool fm_db_util_create_session(CFmDBSession **sess);
std::string fm_db_util_get_system_name(CFmDBSession &sess);
std::string fm_db_util_get_region_name(CFmDBSession &sess);
void fm_db_util_set_conf_file(const char *fn);
bool fm_db_util_get_config(std::string &key, std::string &val);
bool fm_db_util_get_next_log_id(CFmDBSession &sess, int &id);
std::string fm_db_util_int_to_string(int val);
int fm_db_util_string_to_int(std::string val);
bool fm_db_util_sync_event_suppression(void);
#endif /* FMDBUTILS_H_ */

View File

@ -0,0 +1,104 @@
//
// Copyright (c) 2016 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <string>
#include "fmDbConstants.h"
#include "fmLog.h"
#include "fmDbAlarm.h"
#include "fmEventSuppression.h"
bool CFmEventSuppressionOperation::get_event_suppressed(CFmDBSession &sess, SFmAlarmDataT &data, bool &is_event_suppressed) {
fm_db_result_t result;
if (get_single_event_suppression(sess, data.alarm_id, result)) {
if (result.size() > 0){
fm_db_single_result_t event_suppression = result[0];
std::string db_suppression_status = event_suppression[FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS];
if (db_suppression_status.compare(FM_EVENT_SUPPRESSION_SUPPRESSED) == 0) {
is_event_suppressed = true;
} else {
is_event_suppressed = false;
}
} else
return false;
} else
return false;
return true;
}
bool CFmEventSuppressionOperation::get_single_event_suppression(CFmDBSession &sess, const char *alarm_id, fm_db_result_t & event_suppression) {
std::string sql;
std::string separator = ", ";
sql = "SELECT ";
sql += FM_EVENT_SUPPRESSION_COLUMN_CREATED_AT + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_UPDATED_AT + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_DELETED_AT + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_ID + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_UUID + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_DESCRIPTION + separator;
sql += FM_EVENT_SUPPRESSION_COLUMN_SUPPRESSION_STATUS;
sql += " FROM ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " WHERE ";
sql += FM_EVENT_SUPPRESSION_COLUMN_ALARM_ID;
sql += " = '";
sql += std::string(alarm_id);
sql += "'";
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
if ((sess.query(sql.c_str(), event_suppression)) != true){
return false;
}
return true;
}
bool CFmEventSuppressionOperation::set_table_notify_listen(CFmDBSession &sess){
std::string sql;
fm_db_result_t rule_name;
// Verify if rule already in table:
sql = "SELECT rulename FROM pg_rules WHERE rulename='watch_event_supression'";
if ((sess.query(sql.c_str(), rule_name)) != true){
return false;
}
if (rule_name.size() == 0 ) {
sql.clear();
sql = "CREATE RULE watch_event_supression AS ON UPDATE TO ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += " DO (NOTIFY ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
sql += ")";
if (sess.cmd(sql.c_str()) != true){
return false;
}
}
sql.clear();
sql = "LISTEN ";
sql += FM_EVENT_SUPPRESSION_TABLE_NAME;
FM_DEBUG_LOG("CMD:(%s)\n", sql.c_str());
sess.cmd(sql.c_str()); // TODO: sess.cmd() returns false since no row affected by LISTEN command
/* if (sess.cmd(sql.c_str()) != true){
return false;
} */
return true;
}

View File

@ -0,0 +1,35 @@
//
// Copyright (c) 2016 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMEVENTSUPPRESSION_H_
#define FMEVENTSUPPRESSION_H_
/*
#include <string>
#include <vector>
#include <stddef.h>
#include <map>
#include "fmAPI.h"
#include "fmDbConstants.h"
*/
#include "fmDb.h"
class CFmEventSuppressionOperation {
public:
bool get_event_suppressed(CFmDBSession &sess, SFmAlarmDataT &data, bool &is_event_suppressed);
bool get_single_event_suppression(CFmDBSession &sess, const char *alarm_id, fm_db_result_t & event_suppression);
bool set_table_notify_listen(CFmDBSession &sess);
};
#endif

View File

@ -0,0 +1,57 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <unistd.h>
#include <algorithm>
#include <string.h>
#include "fmFile.h"
#include "fmLog.h"
#define FM_FILE_MODE_MAX 10
#define FM_FILE_SIZE_MAX 2056
bool CfmFile::open(const char *path,eFileAccess a, bool binary) {
char attr[FM_FILE_MODE_MAX];
switch(a) {
case READ: strcpy(attr,"r");
break;
case READ_WRITE: strcpy(attr,"r+");
break;
case WRITE: strcpy(attr,"w");
break;
case APPEND: strcpy(attr,"a");
break;
}
if (binary) {
strcat(attr,"b");
}
fp = fopen(path,attr);
return fp!=NULL;
}
int is_return_char(int c) {
return (((char)c)=='\n' || ((char)c)=='\r') ? 1 : 0;
}
bool CfmFile::read_line(std::string &s) {
char st[MAX_LINE_LEN];
bool b = fgets(st,sizeof(st)-1,fp)!=NULL;
if (b) {
s = st;
s.erase(std::find_if(s.begin(), s.end(), std::ptr_fun<int, int>(is_return_char)),s.end());
} else s = "";
return b;
}
void CfmFile::close(){
fclose(fp);
}

View File

@ -0,0 +1,36 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef fmFILE_H_
#define fmFILE_H_
#include <stdio.h>
#include <string>
#include <vector>
class CfmFile {
enum {MAX_LINE_LEN = 4096 };
FILE * fp;
public:
enum eFileAccess {READ, READ_WRITE, WRITE, APPEND};
CfmFile() : fp(NULL) {}
virtual ~CfmFile() { if (fp!=NULL) fclose(fp); }
bool valid() { return fp!=NULL; }
bool open(const char *fn,eFileAccess a, bool binary=false);
void close();
virtual bool read_line(std::string &line);
};
#endif

169
fm-common/sources/fmLog.cpp Normal file
View File

@ -0,0 +1,169 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "fmLog.h"
#include "fmDbAlarm.h"
#include "fmDbEventLog.h"
#include <stdarg.h>
#include <syslog.h>
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static char * escape_json(const char * s, char * buffer, const int bufLen);
void fmLoggingInit() {
static bool has_inited=false;
if (!has_inited){
openlog(NULL,LOG_CONS | LOG_NDELAY,LOG_LOCAL1);
setlogmask(LOG_UPTO (LOG_INFO));
}
has_inited=true;
}
void fmLogMsg(int level, const char *data,...){
va_list ap;
va_start(ap, data);
vsyslog(level,data,ap);
va_end(ap);
}
bool fmLogFileInit(){
fmLoggingInit();
return true;
}
// formats event into json form for logging
static char * formattedEvent(CFmDbEventLog::data_type event_map, char * output, int outputSize) {
int bufLen = 1024;
char * buffer = (char *) malloc(bufLen);
int outputLen = 0;
snprintf(output + outputLen, outputSize - outputLen, "{ \"%s\" : \"%s\", ", "event_log_id", escape_json(event_map["event_log_id"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\", ", "reason_text", escape_json(event_map["reason_text"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\", ", "entity_instance_id", escape_json(event_map["entity_instance_id"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\", ", "severity", escape_json(event_map["severity"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\", ", "state", escape_json(event_map["state"].c_str(), buffer, bufLen));
outputLen = strlen(output);
snprintf(output + outputLen, outputSize - outputLen, "\"%s\" : \"%s\" }", "timestamp", escape_json(event_map["timestamp"].c_str(), buffer, bufLen));
free(buffer);
return output;
}
// logs event to syslog
void fmLogEVT(int level, CFmDbEventLog::data_type event_map) {
char * output = (char*) malloc(2048);
char * msg = formattedEvent(event_map, output, 2048);
fmLogMsg(level,msg);
free(output);
}
void fmLogAddEventLog(SFmAlarmDataT * data, bool is_event_suppressed){
pthread_mutex_lock(&mutex);
CFmDbEventLog event;
CFmDbEventLog::data_type event_map;
event.create_data(data);
event.export_data(event_map);
fmLogEVT(fmLogLevelInfo | LOG_LOCAL5, event_map);
pthread_mutex_unlock(&mutex);
}
// Converts a string (s) to be json safe. Special characters are escaped and written to buffer.
static char * escape_json(const char * s, char * buffer, const int bufLen) {
int sLen = -1;
int bufLeft = bufLen;
int s_i = 0;
int buf_i = 0;
int ch;
char tmp_buf[16];
char * escapedChrs = NULL;
int escapedChrsLen = -1;
if (s==NULL || buffer==NULL || bufLen<1) {
return buffer;
}
sLen = strlen(s);
buffer[0] = 0;
if (s == 0) {
return buffer;
}
while (s_i < sLen && bufLeft > 0) {
ch = s[s_i];
switch (ch) {
case '\"':
escapedChrs = (char *) "\\\"";
break;
case '\\':
escapedChrs = (char *) "\\\\";
break;
case '\b':
escapedChrs = (char *) "\\b";
break;
case '\f':
escapedChrs = (char *) "\\f";
break;
case '\n':
escapedChrs = (char *) "\\n";
break;
case '\r':
escapedChrs = (char *) "\\r";
break;
case '\t':
escapedChrs = (char *) "\\t";
break;
default:
if (ch < 0) {
ch = 0xFFFD; /* replacement character */
}
if (ch > 0xFFFF) {
/* beyond BMP (Basic Multilingual Plane); need a surrogate pair
* for reference, see: https://en.wikipedia.org/wiki/Plane_%28Unicode%29
*/
snprintf(tmp_buf, sizeof(tmp_buf), "\\u%04X\\u%04X",
0xD800 + ((ch - 0x10000) >> 10),
0xDC00 + ((ch - 0x10000) & 0x3FF));
} else if (ch < 0x20 || ch >= 0x7F) {
snprintf(tmp_buf, sizeof(tmp_buf), "\\u%04X", ch);
} else {
tmp_buf[0] = ch;
tmp_buf[1] = 0;
}
escapedChrs = tmp_buf;
}
escapedChrsLen = strlen(escapedChrs);
if (bufLeft <= escapedChrsLen) {
break;
}
strncpy(&buffer[buf_i], escapedChrs, bufLeft );
bufLeft -= escapedChrsLen;
buf_i += escapedChrsLen;
s_i++;
}
return buffer;
}

76
fm-common/sources/fmLog.h Normal file
View File

@ -0,0 +1,76 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMLOG_H_
#define FMLOG_H_
#include <stdio.h>
#include <syslog.h>
#include "fmAPI.h"
extern "C" {
}
enum {
fmLogLevelCritical=LOG_CRIT,
fmLogLevelError=LOG_ERR,
fmLogLevelWarning=LOG_WARNING,
fmLogLevelNotice=LOG_NOTICE,
fmLogLevelInfo = LOG_INFO,
fmLogLevelDebug=LOG_DEBUG,
};
#define FM_LOG_LINE_TO_STRING_impl(x) #x
#define FM_LOG_LINE_TO_STRING(x) FM_LOG_LINE_TO_STRING_impl(x)
#define PRINTF(data,...) printf(data,## __VA_ARGS__)
#define FM_TRACE_LOG(data,...) \
PRINTF(data,## __VA_ARGS__)
#define FM_LOG_MSG(level,data,...) \
fmLogMsg(level, __FILE__ "(" \
FM_LOG_LINE_TO_STRING(__LINE__) "): " \
data, ## __VA_ARGS__ )
#define FM_INFO_LOG(data,...) \
FM_LOG_MSG(fmLogLevelInfo,data,## __VA_ARGS__)
#define FM_DEBUG_LOG(data,...) \
FM_LOG_MSG(fmLogLevelDebug,data,## __VA_ARGS__)
#define FM_NOTICE_LOG(data,...) \
FM_LOG_MSG(fmLogLevelNotice,data,## __VA_ARGS__)
#define FM_WARNING_LOG(data,...) \
FM_LOG_MSG(fmLogLevelWarning,data,## __VA_ARGS__)
#define FM_ERROR_LOG(data,...) \
FM_LOG_MSG(fmLogLevelError,data,## __VA_ARGS__)
#define FM_CRITICAL_LOG(data,...) \
FM_LOG_MSG(fmLogLevelCritical,data,## __VA_ARGS__)
#define FM_MAX_LOG_LENGTH 992
void fmLoggingInit();
void fmLogMsg(int level, const char *data, ...);
bool fmLogFileInit();
void fmLogAddEventLog(SFmAlarmDataT * data, bool is_event_suppressed);
//void fmLogAddEventLog(SFmAlarmDataT * data);
#endif

69
fm-common/sources/fmMsg.h Normal file
View File

@ -0,0 +1,69 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef _FM_MSG_H
#define _FM_MSG_H
#include <vector>
#include "fmAPI.h"
#include <stdint.h>
#define FM_MSG_VAL_KEY (0x1a0ff11d)
#define FM_MSG_WAIT_FAIL (5)
#define FM_MSG_MAX_RET (2)
#define FM_MSG_INF_WAIT (0)
typedef enum {
EFmMsgV1= 1,
EFmMaxVersion
}EFmMsgVersionT;
typedef enum {
EFmMsgRx=0,
EFmMsgTx=1,
EFmMsgMax
}EFmMsgTypesT;
typedef enum {
EFmCreateFault = 0,
EFmUpdateFault,
EFmDeleteFault,
EFmDeleteFaults,
EFmGetFault,
EFmGetFaults,
EFmReturnUUID,
EFmGetFaultsById,
EFmActMax
}EFmMsgActionsT;
typedef struct {
EFmMsgVersionT version;
EFmMsgActionsT action;
uint32_t msg_size;
uint32_t msg_rc; //filled in by server
} SFmMsgHdrT;
typedef std::vector<char> fm_buff_t;
EFmErrorT fm_msg_utils_prep_requet_msg(fm_buff_t &buff,
EFmMsgActionsT act, const void * data, uint32_t len) ;
static inline void * ptr_to_data(fm_buff_t &buff) {
return &(buff[sizeof(SFmMsgHdrT)]);
}
static inline SFmMsgHdrT * ptr_to_hdr(fm_buff_t &buff) {
return (SFmMsgHdrT *)&(buff[0]);
}
static inline bool fm_valid_srv_msg(SFmMsgHdrT *msg, uint32_t exp_size) {
return (msg->msg_size==exp_size);
}
#endif /* _FM_MSG_H */

View File

@ -0,0 +1,735 @@
//
// Copyright (c) 2017 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdio.h>
#include <errno.h>
#include <list>
#include <new>
#include <vector>
#include <map>
#include <string>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <algorithm>
#include <functional>
#include <cctype>
#include <locale>
#include <signal.h>
#include <pthread.h>
#include <libpq-fe.h>
#include "fmMsgServer.h"
#include "fmThread.h"
#include "fmSocket.h"
#include "fmAPI.h"
#include "fmMsg.h"
#include "fmAlarmUtils.h"
#include "fmLog.h"
#include "fmMutex.h"
#include "fmDbAlarm.h"
#include "fmSnmpConstants.h"
#include "fmSnmpUtils.h"
#include "fmDbUtils.h"
#include "fmDbEventLog.h"
#include "fmDbConstants.h"
#include "fmEventSuppression.h"
#define FM_UUID_LENGTH 36
typedef struct{
int fd;
fm_buff_t data;
}sFmGetReq;
typedef struct{
int type;
bool set;
SFmAlarmDataT data;
}sFmJobReq;
typedef std::list<sFmGetReq> fmGetList;
typedef std::list<sFmJobReq> fmJobList;
CFmMutex & getJobMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
CFmMutex & getListMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
CFmMutex & getSockMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
// trim from end
static inline std::string &rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
return s;
}
fmJobList & getJobList(){
static fmJobList lst;
return lst;
}
fmGetList& getList(){
static fmGetList lst;
return lst;
}
static void enqueue_job(sFmJobReq &req){
CFmMutexGuard m(getJobMutex());
getJobList().push_back(req);
}
static bool dequeue_job(sFmJobReq &req){
if (getJobList().size() == 0){
//FM_DEBUG_LOG("Job queue is empty\n");
return false;
}
CFmMutexGuard m(getJobMutex());
fmJobList::iterator it = getJobList().begin();
req = (*it);
getJobList().pop_front();
return true;
}
static void enqueue_get(sFmGetReq &req){
CFmMutexGuard m(getListMutex());
getList().push_back(req);
}
static bool dequeue_get(sFmGetReq &req){
if (getList().size() == 0){
//FM_DEBUG_LOG("Job queue is empty\n");
return false;
}
CFmMutexGuard m(getListMutex());
fmGetList::iterator it = getList().begin();
req = (*it);
getList().pop_front();
return true;
}
void create_db_log(CFmDBSession &sess, sFmJobReq &req){
SFmAlarmDataT alarm = req.data;
if (alarm.alarm_state != FM_ALARM_STATE_MSG){
FM_ERROR_LOG("Unexpected request :(%d) (%s) (%s)", alarm.alarm_state,
alarm.alarm_id, alarm.entity_instance_id);
return;
}
fmLogAddEventLog(&alarm, false);
fm_snmp_util_gen_trap(sess, FM_ALARM_MESSAGE, alarm);
}
void get_db_alarm(CFmDBSession &sess, sFmGetReq &req, void *context){
fm_buff_t buff = req.data;
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
void * data = &buff[sizeof(SFmMsgHdrT)];
AlarmFilter *filter = (AlarmFilter *)data;
FmSocketServerProcessor *srv = (FmSocketServerProcessor *)context;
CFmDbAlarmOperation op;
fm_db_result_t res;
SFmAlarmDataT alarm;
memset(&alarm, 0, sizeof(alarm));
hdr->msg_rc = FM_ERR_OK;
res.clear();
if ((op.get_alarm(sess, *filter, res)) != true){
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}else if (res.size() > 0){
FM_INFO_LOG("Get alarm: (%s) (%s)\n", filter->alarm_id,
filter->entity_instance_id);
CFmDbAlarm::convert_to(res[0],&alarm);
}else{
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
}
if (hdr->msg_rc == FM_ERR_OK) {
FM_DEBUG_LOG("Send resp: uuid (%s), alarm_id (%s)\n",
alarm.uuid, alarm.alarm_id);
srv->send_response(req.fd,hdr,&alarm,sizeof(alarm));
}else{
std::string err = fm_error_from_int((EFmErrorT)hdr->msg_rc);
FM_DEBUG_LOG("Get alarm (%s) (%s) failed,send resp:(%s)\n",
filter->alarm_id, filter->entity_instance_id, err.c_str());
srv->send_response(req.fd,hdr,NULL,0);
}
}
void get_db_alarms(CFmDBSession &sess, sFmGetReq &req, void *context){
fm_buff_t buff = req.data;
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
void * data = &buff[sizeof(SFmMsgHdrT)];
fm_ent_inst_t *pid = (fm_ent_inst_t *)(data);
fm_ent_inst_t &id = *pid;
FmSocketServerProcessor *srv = (FmSocketServerProcessor *)context;
CFmDbAlarmOperation op;
fm_db_result_t res;
std::vector<SFmAlarmDataT> alarmv;
FM_DEBUG_LOG("handle get_db_alarms:%s\n", id);
hdr->msg_rc = FM_ERR_OK;
res.clear();
if (op.get_alarms(sess, id, res) != true){
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}else if (res.size() > 0){
int ix = 0;
int resp_len = res.size();
SFmAlarmDataT alarm;
alarmv.clear();
for ( ; ix < resp_len ; ++ix ) {
CFmDbAlarm::convert_to(res[ix],&alarm);
alarmv.push_back(alarm);
}
}else{
FM_DEBUG_LOG("No alarms found for entity_instance_id (%s)\n", id);
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
}
if ((hdr->msg_rc==FM_ERR_OK) && (alarmv.size() > 0)){
int found_num_alarms=alarmv.size();
int total_len =(found_num_alarms * sizeof(SFmAlarmDataT)) + sizeof(uint32_t);
void * buffer = malloc(total_len);
if (buffer==NULL) {
hdr->msg_rc =FM_ERR_SERVER_NO_MEM;
srv->send_response(req.fd,hdr,NULL,0);
return;
}
uint32_t *alen = (uint32_t*) buffer;
*alen =found_num_alarms;
SFmAlarmDataT * alarms = (SFmAlarmDataT*) ( ((char*)buffer)+sizeof(uint32_t));
memcpy(alarms,&(alarmv[0]),alarmv.size() * sizeof(SFmAlarmDataT));
srv->send_response(req.fd,hdr,buffer,total_len);
free(buffer);
} else {
srv->send_response(req.fd,hdr,NULL,0);
}
}
void get_db_alarms_by_id(CFmDBSession &sess, sFmGetReq &req, void *context){
fm_buff_t buff = req.data;
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
void * data = &buff[sizeof(SFmMsgHdrT)];
fm_alarm_id *aid = (fm_alarm_id *)(data);
fm_alarm_id &id = *aid;
FmSocketServerProcessor *srv = (FmSocketServerProcessor *)context;
CFmDbAlarmOperation op;
fm_db_result_t res;
std::vector<SFmAlarmDataT> alarmv;
FM_DEBUG_LOG("handle get_db_alarms_by_id:%s\n", id);
hdr->msg_rc = FM_ERR_OK;
res.clear();
if (op.get_alarms_by_id(sess, id, res) != true){
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}else if (res.size() > 0){
int ix = 0;
int resp_len = res.size();
CFmDbAlarm dbAlm;
SFmAlarmDataT alarm;
alarmv.clear();
for ( ; ix < resp_len ; ++ix ) {
CFmDbAlarm::convert_to(res[ix],&alarm);
alarmv.push_back(alarm);
}
}else{
FM_DEBUG_LOG("No alarms found for alarm_id (%s)\n", id);
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
}
if ((hdr->msg_rc==FM_ERR_OK) && (alarmv.size() > 0)){
int found_num_alarms=alarmv.size();
int total_len =(found_num_alarms * sizeof(SFmAlarmDataT)) + sizeof(uint32_t);
void * buffer = malloc(total_len);
if (buffer==NULL) {
hdr->msg_rc =FM_ERR_SERVER_NO_MEM;
srv->send_response(req.fd,hdr,NULL,0);
return;
}
uint32_t *alen = (uint32_t*) buffer;
*alen =found_num_alarms;
SFmAlarmDataT * alarms = (SFmAlarmDataT*) ( ((char*)buffer)+sizeof(uint32_t));
memcpy(alarms,&(alarmv[0]),alarmv.size() * sizeof(SFmAlarmDataT));
srv->send_response(req.fd,hdr,buffer,total_len);
free(buffer);
} else {
srv->send_response(req.fd,hdr,NULL,0);
}
}
void fm_handle_job_request(CFmDBSession &sess, sFmJobReq &req){
CFmDbAlarmOperation op;
CFmEventSuppressionOperation event_suppression_op;
//check if it is a customer log request
if (req.type == FM_CUSTOMER_LOG) {
return create_db_log(sess,req);
}
// check to see if there are any alarms need to be masked/unmasked
if (req.type != FM_ALARM_HIERARCHICAL_CLEAR){
if (req.data.inhibit_alarms){
FM_INFO_LOG("%s alarms: (%s)\n", req.set ? "Mask" : "Unmask",
req.data.entity_instance_id);
op.mask_unmask_alarms(sess, req.data, req.set);
}
}
if (!op.add_alarm_history(sess, req.data, req.set)){
FM_ERROR_LOG("Failed to add historical alarm to DB (%s) (%s",
req.data.alarm_id, req.data.entity_instance_id);
}
bool is_event_suppressed = false;
if ((req.type != FM_ALARM_HIERARCHICAL_CLEAR) &&
(!event_suppression_op.get_event_suppressed(sess, req.data, is_event_suppressed))) {
FM_ERROR_LOG("Failed to retrieve event suppression status in DB for (%s)",
req.data.alarm_id);
} else {
if (!is_event_suppressed)
fm_snmp_util_gen_trap(sess, req.type, req.data);
}
fmLogAddEventLog(&req.data, is_event_suppressed);
}
void fm_handle_get_request(CFmDBSession &sess, sFmGetReq &req,
void *context){
fm_buff_t buff = req.data;
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&buff[0];
switch(hdr->action) {
case EFmGetFault:get_db_alarm(sess,req,context); break;
case EFmGetFaults:get_db_alarms(sess,req,context); break;
case EFmGetFaultsById:get_db_alarms_by_id(sess,req,context); break;
default:
FM_ERROR_LOG("Unexpected job request, action:%u\n",hdr->action);
break;
}
}
inline void * prep_msg_buffer(std::vector<char> &buff, int reserved_size,
SFmMsgHdrT *&hdr) {
buff.resize(sizeof(SFmMsgHdrT) + reserved_size);
hdr = (SFmMsgHdrT*)&(buff[0]);
hdr->msg_size = reserved_size;
hdr->version = EFmMsgV1;
hdr->msg_rc = 0;
return &(buff[sizeof(SFmMsgHdrT)]);
}
#define is_request_valid(len,structdata) \
if (len != sizeof(structdata)) { \
hdr->msg_rc = FM_ERR_INVALID_REQ; \
send_response(fd,hdr,NULL,0); \
return; \
}
void FmSocketServerProcessor::send_response(int fd, SFmMsgHdrT *hdr, void *data, size_t len) {
fm_buff_t resp;
CFmMutexGuard m(getSockMutex());
if (fm_msg_utils_prep_requet_msg(resp,hdr->action,data,len)!=FM_ERR_OK) {
rm_socket(fd);
FM_INFO_LOG("Failed to prepare response, close fd:(%d)", fd);
::close(fd);
return;
}
ptr_to_hdr(resp)->msg_rc = hdr->msg_rc;
if (!write_packet(fd,resp)){
FM_INFO_LOG("Failed to send response, close fd:(%d)", fd);
rm_socket(fd);
::close(fd);
return;
}
}
void FmSocketServerProcessor::handle_create_fault(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata, CFmDBSession &sess) {
is_request_valid(hdr->msg_size,SFmAlarmDataT);
void * data = &(rdata[sizeof(SFmMsgHdrT)]);
CFmDbAlarmOperation op;
CFmDbEventLogOperation log_op;
CFmDbEventLog dbLog;
CFmDbAlarm a;
sFmJobReq req;
SFmAlarmDataT *alarm = (SFmAlarmDataT *)(data);
FM_DEBUG_LOG("Time stamp in the alarm message: (%lld)", alarm->timestamp);
if ((strlen(alarm->uuid)) != FM_UUID_LENGTH) {
fm_uuid_create(alarm->uuid);
}
hdr->msg_rc = FM_ERR_OK;
req.data = *alarm;
req.set = true;
FM_INFO_LOG("Raising Alarm/Log, (%s) (%s)", alarm->alarm_id, alarm->entity_instance_id);
//enqueue the customer log request after writing it the DB
if (alarm->alarm_state == FM_ALARM_STATE_MSG) {
alarm->alarm_state = FM_ALARM_STATE_LOG;
dbLog.create_data(alarm);
if (log_op.create_event_log(sess, dbLog)) {
FM_INFO_LOG("Log generated in DB: (%s) (%s) (%d)\n",
alarm->alarm_id, alarm->entity_instance_id, alarm->severity);
req.type = FM_CUSTOMER_LOG;
enqueue_job(req);
}else{
FM_ERROR_LOG("Fail to create customer log: (%s) (%s)\n",
alarm->alarm_id, alarm->entity_instance_id);
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}
FM_INFO_LOG("Send response for create log, uuid:(%s) (%u)\n",
alarm->uuid, hdr->msg_rc);
send_response(fd,hdr,alarm->uuid,sizeof(alarm->uuid));
} else {
a.create_data(alarm);
//a.print();
if (op.create_alarm(sess,a)){
FM_INFO_LOG("Alarm created/updated: (%s) (%s) (%d) (%s)\n",
alarm->alarm_id, alarm->entity_instance_id, alarm->severity, alarm->uuid);
req.type = alarm->severity;
enqueue_job(req);
}else{
FM_ERROR_LOG("Fail to created/updated alarm: (%s) (%s)\n",
alarm->alarm_id, alarm->entity_instance_id);
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}
FM_INFO_LOG("Send response for create fault, uuid:(%s) (%u)\n",
alarm->uuid, hdr->msg_rc);
send_response(fd,hdr,alarm->uuid,sizeof(alarm->uuid));
}
}
void FmSocketServerProcessor::handle_delete_faults(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata, CFmDBSession &sess) {
CFmDbAlarmOperation op;
sFmJobReq req;
is_request_valid(hdr->msg_size,fm_ent_inst_t);
void * data = &(rdata[sizeof(SFmMsgHdrT)]);
fm_ent_inst_t *pid = (fm_ent_inst_t *)(data);
fm_ent_inst_t &id = *pid;
hdr->msg_rc = FM_ERR_OK;
if (op.delete_alarms(sess,id)){
FM_DEBUG_LOG("Deleted alarms (%s)\n", id);
SFmAlarmDataT alarm;
memset(&alarm, 0, sizeof(alarm));
//only cares about entity_instance_id in hierarchical alarm clear trap
strncpy(alarm.entity_instance_id, id, sizeof(alarm.entity_instance_id)-1);
strncpy(alarm.reason_text,CLEAR_ALL_REASON_TEXT,
sizeof(alarm.reason_text)-1);
fm_uuid_create(alarm.uuid);
req.type = FM_ALARM_HIERARCHICAL_CLEAR;
req.set = false;
req.data = alarm;
enqueue_job(req);
}else{
FM_INFO_LOG("Fail to Delete alarms (%s)\n", id);
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}
send_response(fd,hdr,NULL,0);
}
void FmSocketServerProcessor::handle_delete_fault(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata, CFmDBSession &sess) {
CFmDbAlarmOperation op;
sFmJobReq req;
CFmDbAlarm dbAlm;
SFmAlarmDataT alarm;
fm_db_result_t res;
is_request_valid(hdr->msg_size,AlarmFilter);
void * data = &(rdata[sizeof(SFmMsgHdrT)]);
AlarmFilter *filter = (AlarmFilter *)(data);
hdr->msg_rc = FM_ERR_OK;
res.clear();
if ((op.get_alarm(sess, *filter, res)) != true){
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}else{
if (res.size() > 0){
if(op.delete_alarm(sess, *filter)){
FM_INFO_LOG("Deleted alarm: (%s) (%s)\n",
filter->alarm_id, filter->entity_instance_id);
CFmDbAlarm::convert_to(res[0],&alarm);
fm_uuid_create(alarm.uuid);
req.type = FM_ALARM_CLEAR;
req.set = false;
req.data = alarm;
enqueue_job(req);
}else{
hdr->msg_rc = FM_ERR_DB_OPERATION_FAILURE;
}
}else{
hdr->msg_rc = FM_ERR_ENTITY_NOT_FOUND;
FM_INFO_LOG("Deleted alarm failed: (%s) (%s) (%s)\n",
filter->alarm_id, filter->entity_instance_id,
fm_error_from_int((EFmErrorT)hdr->msg_rc).c_str());
}
}
FM_INFO_LOG("Response to delete fault: %u\n", hdr->msg_rc);
send_response(fd,hdr,NULL,0);
}
void FmSocketServerProcessor::handle_get_faults_by_id(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
is_request_valid(hdr->msg_size,fm_alarm_id);
sFmGetReq req;
req.fd = fd;
req.data = rdata;
enqueue_get(req);
}
void FmSocketServerProcessor::handle_get_faults(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
is_request_valid(hdr->msg_size,fm_ent_inst_t);
sFmGetReq req;
req.fd = fd;
req.data = rdata;
enqueue_get(req);
}
void FmSocketServerProcessor::handle_get_fault(int fd,
SFmMsgHdrT *hdr, std::vector<char> &rdata) {
is_request_valid(hdr->msg_size,AlarmFilter);
sFmGetReq req;
req.fd = fd;
req.data = rdata;
enqueue_get(req);
}
void FmSocketServerProcessor::handle_socket_data(int fd,
std::vector<char> &rdata, CFmDBSession &sess) {
SFmMsgHdrT *hdr = (SFmMsgHdrT *)&(rdata[0]);
FM_DEBUG_LOG("Processor: handler socket data, action:%u\n",hdr->action);
switch(hdr->action) {
case EFmCreateFault:handle_create_fault(fd,hdr,rdata, sess); break;
case EFmDeleteFault:handle_delete_fault(fd, hdr,rdata, sess); break;
case EFmDeleteFaults:handle_delete_faults(fd,hdr,rdata,sess); break;
case EFmGetFault:handle_get_fault(fd,hdr,rdata); break;
case EFmGetFaults:handle_get_faults(fd,hdr,rdata); break;
case EFmGetFaultsById:handle_get_faults_by_id(fd,hdr,rdata); break;
default:
FM_ERROR_LOG("Unexpected client request, action:%u\n",hdr->action);
break;
}
}
extern "C" {
EFmErrorT fm_server_create(const char *fn) {
signal(SIGPIPE,SIG_IGN);
FmSocketServerProcessor srv;
size_t retries = 5, count = 0, my_sleep = 2000;//2 seconds
const std::string host = "controller";
int rc = 0;
bool rt = false;
struct addrinfo hints;
struct addrinfo *result=NULL, *rp;
char addr[INET6_ADDRSTRLEN];
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */
hints.ai_socktype = SOCK_STREAM; /* Datagram socket */
hints.ai_flags = 0; /* For wildcard IP address */
hints.ai_protocol = 0; /* Any protocol */
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
fmLoggingInit();
if (!fmLogFileInit()){
exit(-1);
}
fm_db_util_set_conf_file(fn);
if (!fm_db_util_sync_event_suppression()){
exit(-1);
}
if (!fmCreateThread(fmJobHandlerThread,NULL)) {
exit(-1);
}
if (!fmCreateThread(fmRegHandlerThread,&srv)) {
exit(-1);
}
if (!fmCreateThread(fmEventSuppressionMonitorThread,NULL)) {
exit(-1);
}
FM_INFO_LOG("Starting fmManager...\n");
while (true) {
rc = getaddrinfo(host.c_str(),NULL, &hints,&result);
if (rc == 0){
for (rp = result; rp != NULL; rp = rp->ai_next) {
if (rp->ai_family==AF_INET||rp->ai_family==AF_INET6) {
if(rp->ai_family==AF_INET) {
inet_ntop(AF_INET, &(((sockaddr_in*)rp->ai_addr)->sin_addr), addr, sizeof(addr));
} else if (rp->ai_family==AF_INET6) {
inet_ntop(AF_INET6, &(((sockaddr_in6*)rp->ai_addr)->sin6_addr), addr, sizeof(addr));
}
rt = srv.server_sock(addr,8001,rp->ai_family);
if (rt == true) break;
if (count < retries){
FM_INFO_LOG("Bind (%s) (%s) address failed, error: (%d) (%s)",
host.c_str(), addr, errno, strerror(errno));
}
}
}
freeaddrinfo(result);
}else{
FM_INFO_LOG("(%s) address lookup failed, error: (%d) (%s)",
host.c_str(),errno, strerror(errno));
}
if (rt ==true) break;
if (count > retries){
FM_ERROR_LOG("Failed to bind to controller IP, exit...");
exit(-1);
}
fmThreadSleep(my_sleep);
count++;
}
if ( rt == false)
return (EFmErrorT)-1;
srv.run();
return FM_ERR_OK;
}
void fmJobHandlerThread(void *context){
CFmDBSession *sess;
if (fm_db_util_create_session(&sess) != true){
FM_ERROR_LOG("Fail to create DB session, exit ...\n");
exit (-1);
}
while (true){
sFmJobReq req;
while (dequeue_job(req)){
fm_handle_job_request(*sess,req);
}
fmThreadSleep(200);
}
}
void fmRegHandlerThread(void *context){
CFmDBSession *sess;
if (fm_db_util_create_session(&sess) != true){
FM_ERROR_LOG("Fail to create DB session, exit ...\n");
exit (-1);
}
while (true){
sFmGetReq req;
while (dequeue_get(req)){
fm_handle_get_request(*sess, req, context);
}
fmThreadSleep(100);
}
}
bool fm_handle_event_suppress_changes(CFmDBSession &sess){
int sock_fd;
fd_set readset;
PGconn *pgconn = NULL;
PGnotify *notify;
pgconn = sess.get_pgconn();
sock_fd = PQsocket(pgconn);
FD_ZERO(&readset);
FD_SET(sock_fd, &readset);
// Wait for event_suppression update to occur
if (select(sock_fd + 1, &readset, NULL, NULL, NULL) < 0)
{
FM_ERROR_LOG("select() failed: %s\n", strerror(errno));
if (errno!=EINTR)
return false;
}
// Now check for input. This will clear the queue
PQconsumeInput(pgconn);
while ((notify = PQnotifies(pgconn)) != NULL)
{
PQfreemem(notify);
}
SFmAlarmDataT *alarm = NULL;
fm_snmp_util_gen_trap(sess, FM_WARM_START, *alarm);
return true;
}
void fmEventSuppressionMonitorThread(void *context){
CFmDBSession *sess;
CFmEventSuppressionOperation event_suppression_op;
if (fm_db_util_create_session(&sess) != true){
FM_ERROR_LOG("Fail to create DB session, exit ...\n");
exit (-1);
}
if (event_suppression_op.set_table_notify_listen(*sess) != true){
FM_ERROR_LOG("Fail to set DB table notify and listen, exit ...\n");
exit (-1);
}
while (true){
fm_handle_event_suppress_changes(*sess);
fmThreadSleep(30000); // 30 second wait allows some time to buffer in multiple notify events
// and send only 1 Warm Start trap as a result
}
}
}

View File

@ -0,0 +1,38 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMMSGSERVER_H_
#define FMMSGSERVER_H_
#include <vector>
#include "fmSocket.h"
#include "fmMsg.h"
#include "fmDb.h"
class FmSocketServerProcessor : public FmSocketServer {
protected:
virtual void handle_socket_data(int fd,std::vector<char> &data,
CFmDBSession &sess);
virtual void handle_create_fault(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata, CFmDBSession &sess);
virtual void handle_delete_fault(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata, CFmDBSession &sess);
virtual void handle_delete_faults(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata,CFmDBSession &sess);
virtual void handle_get_fault(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata);
virtual void handle_get_faults(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata);
virtual void handle_get_faults_by_id(int fd, SFmMsgHdrT *hdr,
std::vector<char> &rdata);
public:
void send_response(int fd, SFmMsgHdrT *hdr, void *data, size_t len);
};
#endif /* FMMSGSERVER_H_ */

View File

@ -0,0 +1,48 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <pthread.h>
#include <stdio.h>
#include "fmLog.h"
#include "fmMutex.h"
bool CFmMutex::lock() {
//FM_DEBUG_LOG("lock %X",cntx);
return pthread_mutex_lock((pthread_mutex_t*)cntx)==0;
}
bool CFmMutex::unlock() {
//FM_DEBUG_LOG("unlock %X",cntx);
return pthread_mutex_unlock((pthread_mutex_t*)cntx)==0;
}
CFmMutex::CFmMutex() {
cntx = NULL;
//use recursive Mutex to allow one thread to lock it multiple times
pthread_mutex_t tmutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_mutex_t * pMutex = new pthread_mutex_t;
if (pMutex!=NULL) {
*pMutex = tmutex;
cntx = pMutex;
}
}
CFmMutex::~CFmMutex() {
pthread_mutex_destroy((pthread_mutex_t*)cntx);
delete ((pthread_mutex_t*)cntx); //safe if cntx is null
cntx = NULL;
}

View File

@ -0,0 +1,45 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FM_MUTEX_H_
#define FM_MUTEX_H_
class CFmMutex {
void * cntx;
public:
CFmMutex();
~CFmMutex();
bool lock();
bool unlock();
};
class CFmMutexGuard {
CFmMutex & m;
bool rc;
public:
CFmMutexGuard(CFmMutex & mu) : m(mu) {
rc = m.lock();
}
~CFmMutexGuard() {
m.unlock();
}
bool getRc() {
return rc;
}
};
#endif

View File

@ -0,0 +1,69 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <string>
#define FM_ALARM_CLEAR 6
#define FM_ALARM_HIERARCHICAL_CLEAR 7
#define FM_ALARM_MESSAGE 8
#define FM_WARM_START 9
#define FM_CUSTOMER_LOG 10
/* Trap Destination table name */
#define FM_TRAPDEST_TABLE_NAME "i_trap_destination"
#define FM_TRAPDEST_IP_COLUMN "ip_address"
#define FM_TRAPDEST_COMM_COLUMN "community"
/* MIB Trap definitions */
const std::string WRS_ALARM_MIB = "WRS-ALARM-MIB";
const std::string ALARM_CRITICAL = "wrsAlarmCritical";
const std::string ALARM_MAJOR = "wrsAlarmMajor";
const std::string ALARM_MINOR = "wrsAlarmMinor";
const std::string ALARM_WARNING = "wrsAlarmWarning";
const std::string ALARM_MSG = "wrsAlarmMessage";
const std::string ALARM_CLEAR = "wrsAlarmClear";
const std::string ALARM_HIERARCHICAL_CLEAR = "wrsAlarmHierarchicalClear";
const std::string ALARM_ID = "wrsAlarmActiveAlarmId";
const std::string ALARM_INSTANCE_ID = "wrsAlarmActiveEntityInstanceId";
const std::string ALARM_DATE_TIME = "wrsAlarmActiveDateAndTime";
const std::string ALARM_SEVERITY = "wrsAlarmActiveAlarmSeverity";
const std::string ALARM_REASON_TEXT = "wrsAlarmActiveReasonText";
const std::string ALARM_EVENT_TYPE = "wrsAlarmActiveEventType";
const std::string ALARM_CAUSE = "wrsAlarmActiveProbableCause";
const std::string ALARM_REPAIR_ACTION = "wrsAlarmActiveProposedRepairAction";
const std::string ALARM_SERVICE_AFFECTING = "wrsAlarmActiveServiceAffecting";
const std::string ALARM_SUPPRESSION = "wrsAlarmActiveSuppressionAllowed";
const std::string CUSTOMER_LOG_ID = "wrsCustomerLogId";
const std::string CUSTOMER_LOG_INSTANCE_ID = "wrsCustomerLogEntityInstanceId";
const std::string CUSTOMER_LOG_DATE_TIME = "wrsCustomerLogDateAndTime";
const std::string CUSTOMER_LOG_SEVERITY = "wrsCustomerLogSeverity";
const std::string CUSTOMER_LOG_REASON_TEXT = "wrsCustomerLogReasonText";
const std::string CUSTOMER_LOG_EVENT_TYPE = "wrsCustomerLogEventType";
const std::string CUSTOMER_LOG_CAUSE = "wrsCustomerLogProbableCause";
const std::string CUSTOMER_LOG_SERVICE_AFFECTING = "wrsCustomerLogServiceAffecting";
const std::string SNMPv2_MIB = "SNMPv2-MIB";
const std::string WARM_START = "warmStart";
const std::string TRAP_CMD = "/usr/bin/snmptrap -v 2c";
const std::string CLEAR_REASON_TEXT = "System initiated hierarchical alarm clear";
const std::string SEP = " ";
const std::string SCOPE = "::";
const std::string STR_TYPE = " s ";
const std::string INT_TYPE = " i ";
const std::string OPTION_COMM = " -c ";
const std::string DC_COMM_STR = "dcorchAlarmAggregator";
const std::string CONF_PATH_ENV = "SNMPCONFPATH=";
const std::string CONF_DIR = "/etc/snmp";

View File

@ -0,0 +1,290 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <assert.h>
#include <sstream>
#include "fmDbAPI.h"
#include "fmFile.h"
#include "fmAPI.h"
#include "fmMsg.h"
#include "fmLog.h"
#include "fmDb.h"
#include "fmDbUtils.h"
#include "fmSnmpConstants.h"
#include "fmSnmpUtils.h"
typedef std::map<int,std::string> int_to_objtype;
static int_to_objtype objtype_map;
static pthread_mutex_t mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
static void add_to_table(int t, std::string objtype, int_to_objtype &tbl) {
tbl[t]=objtype;
}
static void init_objtype_table() {
pthread_mutex_lock(&mutex);
static bool has_inited=false;
while (!has_inited){
add_to_table(FM_ALARM_SEVERITY_CLEAR, ALARM_MSG, objtype_map);
add_to_table(FM_ALARM_SEVERITY_WARNING, ALARM_WARNING, objtype_map);
add_to_table(FM_ALARM_SEVERITY_MINOR, ALARM_MINOR, objtype_map);
add_to_table(FM_ALARM_SEVERITY_MAJOR, ALARM_MAJOR, objtype_map);
add_to_table(FM_ALARM_SEVERITY_CRITICAL, ALARM_CRITICAL, objtype_map);
add_to_table(FM_ALARM_CLEAR, ALARM_CLEAR, objtype_map);
add_to_table(FM_ALARM_HIERARCHICAL_CLEAR, ALARM_HIERARCHICAL_CLEAR, objtype_map);
add_to_table(FM_ALARM_MESSAGE, ALARM_MSG, objtype_map);
add_to_table(FM_WARM_START, WARM_START, objtype_map);
has_inited=true;
}
pthread_mutex_unlock(&mutex);
}
static std::string add_time_val(std::string &str,
const std::string &objtype, FMTimeT time){
std::string time_str;
fm_db_util_make_timestamp_string(time_str, time, true);
return str + objtype + STR_TYPE + time_str + SEP;
}
static std::string add_str_val(std::string &str,
const std::string &objtype, const char *value){
std::string val(value);
return str + objtype + STR_TYPE + '"' + val + '"' + SEP;
}
static std::string add_int_val(std::string &str,
const std::string &objtype, int value){
return str + objtype + INT_TYPE + fm_db_util_int_to_string(value) + SEP;
}
static std::string get_trap_objtype(int type){
init_objtype_table();
return objtype_map[type];
}
static bool get_trap_dest_list(CFmDBSession &sess,fm_db_result_t & res){
std::string cmd;
fm_db_util_build_sql_query(FM_TRAPDEST_TABLE_NAME, NULL, cmd);
return sess.query(cmd.c_str(), res);
}
static std::string format_trap_cmd(CFmDBSession &sess, int type, SFmAlarmDataT &data,
std::string &ip, std::string &comm){
std::string cmd;
std::string objtype;
std::string mib;
std::string s = "\"\" ";
std::string env;
if (get_trap_objtype(type) == WARM_START)
mib = SNMPv2_MIB;
else
mib = WRS_ALARM_MIB;
objtype = mib + SCOPE + get_trap_objtype(type);
if (comm.compare(DC_COMM_STR) == 0){
env = CONF_PATH_ENV + CONF_DIR + SEP;
}
else {
env = "";
}
cmd = env + TRAP_CMD + OPTION_COMM + comm + SEP + ip + SEP + s + objtype + SEP;
std::string operation_type =get_trap_objtype(type);
if (operation_type == ALARM_CLEAR){
cmd = add_str_val(cmd,ALARM_ID, data.alarm_id);
cmd = add_str_val(cmd, ALARM_INSTANCE_ID, data.entity_instance_id);
cmd = add_time_val(cmd, ALARM_DATE_TIME, data.timestamp);
cmd = add_str_val(cmd, ALARM_REASON_TEXT, data.reason_text);
} else if (operation_type == ALARM_HIERARCHICAL_CLEAR){
cmd = add_str_val(cmd, ALARM_INSTANCE_ID, data.entity_instance_id);
cmd = add_time_val(cmd, ALARM_DATE_TIME, 0);
cmd = add_str_val(cmd, ALARM_REASON_TEXT, CLEAR_REASON_TEXT.c_str());
} else if (operation_type == ALARM_MSG){
cmd = add_str_val(cmd, CUSTOMER_LOG_ID, data.alarm_id);
cmd = add_str_val(cmd, CUSTOMER_LOG_INSTANCE_ID, data.entity_instance_id);
cmd = add_time_val(cmd, CUSTOMER_LOG_DATE_TIME, data.timestamp);
cmd = add_int_val(cmd, CUSTOMER_LOG_SEVERITY, data.severity);
cmd = add_str_val(cmd, CUSTOMER_LOG_REASON_TEXT, data.reason_text);
cmd = add_int_val(cmd, CUSTOMER_LOG_EVENT_TYPE, data.alarm_type);
cmd = add_int_val(cmd, CUSTOMER_LOG_CAUSE, data.probable_cause);
cmd = add_int_val(cmd, CUSTOMER_LOG_SERVICE_AFFECTING, data.service_affecting);
} else if (operation_type == WARM_START){
// nothing to add to cmd
} else {
cmd = add_str_val(cmd, ALARM_ID, data.alarm_id);
cmd = add_str_val(cmd, ALARM_INSTANCE_ID, data.entity_instance_id);
cmd = add_time_val(cmd, ALARM_DATE_TIME, data.timestamp);
cmd = add_int_val(cmd, ALARM_SEVERITY, data.severity);
cmd = add_str_val(cmd, ALARM_REASON_TEXT, data.reason_text);
cmd = add_int_val(cmd, ALARM_EVENT_TYPE, data.alarm_type);
cmd = add_int_val(cmd, ALARM_CAUSE, data.probable_cause);
cmd = add_str_val(cmd, ALARM_REPAIR_ACTION, data.proposed_repair_action);
cmd = add_int_val(cmd, ALARM_SERVICE_AFFECTING, data.service_affecting);
cmd = add_int_val(cmd, ALARM_SUPPRESSION, data.suppression);
}
return cmd;
}
bool fm_snmp_util_gen_trap(CFmDBSession &sess, int type, SFmAlarmDataT &data) {
bool rc = true;
fm_buff_t cmdbuff;
fm_db_result_t res;
std::string cmd, eid;
if (!get_trap_dest_list(sess,res)) return false;
if (&data != NULL) {
eid.assign(data.entity_instance_id);
std::string region_name = fm_db_util_get_region_name(sess);
std::string sys_name = fm_db_util_get_system_name(sess);
if (sys_name.length() != 0){
eid = sys_name + "."+ eid;
}
if (region_name.length() != 0){
eid = region_name + "."+ eid;
}
strncpy(data.entity_instance_id, eid.c_str(),
sizeof(data.entity_instance_id)-1);
}
fm_db_result_t::iterator it = res.begin();
fm_db_result_t::iterator end = res.end();
for (; it != end; ++it){
memset(&(cmdbuff[0]), 0, cmdbuff.size());
cmd.clear();
std::string ip = (*it)[FM_TRAPDEST_IP_COLUMN];
std::string comm = (*it)[FM_TRAPDEST_COMM_COLUMN];
cmd = format_trap_cmd(sess,type, data, ip, comm);
//FM_INFO_LOG("run cmd: %s\n", cmd.c_str());
char *pline = &(cmdbuff[0]);
FILE *op = popen(cmd.c_str(),"r");
if (op==NULL) {
FM_ERROR_LOG("popen() failed, errno: (%d) (%s)\n",
errno, strerror(errno));
rc = false;
}
while (fgets(pline,cmdbuff.size(),op)!=NULL) {
FM_ERROR_LOG("Trap error message: (%s)\n", pline);
}
fclose(op);
}
return rc;
}
static bool fm_snmp_get_db_connection(std::string &connection){
CfmFile f;
const char *fn = "/etc/fm.conf";
std::string sql_key = FM_SQL_CONNECTION;
std::string delimiter = "=";
std::string line, key, value;
size_t pos = 0;
if (!f.open(fn, CfmFile::READ, false)){
FM_ERROR_LOG("Failed to open config file: %s\n", fn);
exit (-1);
}
while (true){
if (!f.read_line(line)) break;
if (line.size() == 0) continue;
pos = line.find(delimiter);
key = line.substr(0, pos);
if (key == sql_key){
value = line.erase(0, pos + delimiter.length());
// Don't log sql_connection, as it has a password
//FM_DEBUG_LOG("Found it: (%s)\n", value.c_str());
connection = value;
return true;
}
}
return false;;
}
extern "C" {
bool fm_snmp_util_create_session(TFmAlarmSessionT *handle, const char* db_conn){
std::string key = FM_SQL_CONNECTION;
std::string conn;
CFmDBSession *sess = new CFmDBSession;
if (sess==NULL) return false;;
if (db_conn == NULL){
if (fm_snmp_get_db_connection(conn) != true){
FM_ERROR_LOG("Fail to get db connection uri\n");
delete sess;
return false;
}
db_conn = conn.c_str();
}
if (sess->connect(db_conn) != true){
FM_ERROR_LOG("Fail to connect to (%s)\n", db_conn);
delete sess;
return false;
}
*handle = sess;
return true;
}
void fm_snmp_util_destroy_session(TFmAlarmSessionT handle) {
CFmDBSession *sess = (CFmDBSession *)handle;
if (sess != NULL){
delete sess;
}
}
bool fm_snmp_util_get_all_alarms(TFmAlarmSessionT handle,
SFmAlarmQueryT *query) {
assert(handle!=NULL);
CFmDbAlarmOperation op;
fm_db_result_t res;
CFmDBSession &sess = *((CFmDBSession*)handle);
if (!op.get_all_alarms(sess, &(query->alarm), &(query->num))) return false;
return true;
}
bool fm_snmp_util_get_all_event_logs(TFmAlarmSessionT handle,
SFmAlarmQueryT *query) {
assert(handle!=NULL);
CFmDbEventLogOperation op;
fm_db_result_t res;
CFmDBSession &sess = *((CFmDBSession*)handle);
if (!op.get_all_event_logs(sess, &(query->alarm), &(query->num))) return false;
return true;
}
}

View File

@ -0,0 +1,17 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef __FM_SNMP_UTILS_H
#define __FM_SNMP_UTILS_H
#include <string>
#include "fmAPI.h"
#include "fmDb.h"
bool fm_snmp_util_gen_trap(CFmDBSession &sess, int type, SFmAlarmDataT &data);
#endif

View File

@ -0,0 +1,462 @@
//
// Copyright (c) 2017 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/select.h>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include "fmSocket.h"
#include "fmThread.h"
#include "fmMutex.h"
#include "fmLog.h"
#include "fmDbUtils.h"
CFmMutex & getConnectionMutex(){
static CFmMutex *m = new CFmMutex;
return *m;
}
void CFmSockAddr::set_type(socklen_t addr_len) {
if (addr_len==sizeof(address.ipv4)) {
type = AF_INET;
} else if (addr_len==sizeof(address.ipv6)) {
type = AF_INET6;
} else {
type = AF_UNIX;
}
}
CFmSocket::CFmSocket() {
m_fd = -1;
}
CFmSocket::~CFmSocket() {
close();
}
void CFmSocket::close() {
if (m_fd!=-1) {
//FM_INFO_LOG("close fd:(%d)", m_fd);
::close(m_fd);
}
m_fd = -1;
}
bool CFmSocket::create_socket() {
int optval = 1;
socklen_t optlen = sizeof(optval);
close();
m_fd = ::socket(address_family,SOCK_STREAM,0);
if (m_fd == -1){
FM_ERROR_LOG("Failed to create socket, error: (%d) (%s)", errno, strerror(errno));
return false;
}
/* Set the KEEPALIVE option active */
if(setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen) < 0) {
FM_ERROR_LOG("Failed to setsockopt, error: (%d) (%s)", errno, strerror(errno));
close();
return false;
}
//FM_DEBUG_LOG("SO_KEEPALIVE set on socket\n");
return true;
}
bool CFmSocket::connect(const char *host, int port, int address_family) {
this->address_family = address_family;
if (!create_socket()) {
return false;
}
switch (address_family) {
//When address is IPv4
case AF_INET:
{
struct sockaddr_in addr;
if (inet_aton(host,&(addr.sin_addr))==0) {
FM_INFO_LOG("inet_aton() failed\n");
return false;
}
addr.sin_port = htons(port);
addr.sin_family = AF_INET;
fd_set wset;
FD_ZERO(&wset);
FD_SET(m_fd,&wset);
return (::connect(m_fd,(const struct sockaddr *)&addr,sizeof(addr))==0);
}
//When address is IPv6
case AF_INET6:
{
struct sockaddr_in6 addr;
if (inet_pton(AF_INET6,host,&(addr.sin6_addr))<=0) {
FM_INFO_LOG("inet_aton() failed\n");
return false;
}
addr.sin6_port = htons(port);
addr.sin6_family = AF_INET6;
fd_set wset;
FD_ZERO(&wset);
FD_SET(m_fd,&wset);
return (::connect(m_fd,(const struct sockaddr *)&addr,sizeof(addr))==0);
}
//Should never get here, needed for completeness
default:
{
return false;
}
}
}
bool CFmSocket::write(int fd, const void *data, long len) {
int offset = 0;
while (offset!=len) {
int rc = ::write(fd, ((char*)data)+offset,len-offset);
if (rc==0 || (rc==-1 && errno!=EINTR)) {
FM_ERROR_LOG("Socket Error: Failed to write to fd:(%d), len:(%d), rc:(%d), error:(%s)",
fd, len, rc, strerror(errno));
return false;
}
if (rc==-1 && errno==EINTR) continue;
offset+=rc;
}
return true;
}
bool CFmSocket::write_packet(int fd, const void *data, long plen) {
uint32_t len = htonl(plen);
bool rc = write(fd,&len,sizeof(len));
if (!rc) return false;
return write(fd,data,plen);
}
bool CFmSocket::write_packet(int fd, const std::vector<char> &data) {
return write_packet(fd,&(data[0]),data.size());
}
bool CFmSocket::read_packet(int fd, std::vector<char> &data) {
int32_t len = 0;
long tlen = sizeof(len);
int i = 10;
for ( ; i > 0 ; --i) {
if (!read(fd,&len,tlen)) {
return false;
}
break;
}
if (tlen!=sizeof(len))
{
FM_ERROR_LOG("Socket Error: Length does not match the data size: (%ld), (%ld)", tlen, sizeof(len));
return false;
}
len=ntohl(len);
data.resize(len);
tlen = len;
if (!read(fd,&(data[0]),tlen)) return false;
return true;
}
bool CFmSocket::read(int fd,void *data, long &len) {
int offset = 0;
while (offset!=len) {
int rc = ::read(fd, ((char*)data)+offset,len-offset);
if (rc==0 || (rc==-1 && errno!=EINTR)) {
// return code 0 means graceful close of TCP socket
if (rc !=0 ){
FM_ERROR_LOG("Failed to read from fd:(%d), rc:(%d), error:(%s), len:(%d)",
fd, rc, strerror(errno), len);
}
len = offset;
return false;
}
if (rc==-1 && errno==EINTR) continue;
offset+=rc;
}
return true;
}
bool CFmSocket::read_packet(std::vector<char> &data) {
return read_packet(m_fd,data);
}
bool CFmSocket::read(void *data, long &len) {
return read(m_fd,data,len);
}
int CFmSocket::select(int *rfd, int rlen, int *wfds, int wlen,int timeout, int timeoutusec, bool &timedout) {
fd_set rset,wset;
FD_ZERO(&rset);
wset=rset;
int max_fd = -1;
int ix = 0;
for ( ; ix < rlen ; ++ix ) {
if (max_fd < rfd[ix]) max_fd = rfd[ix];
FD_SET(rfd[ix],&rset);
}
ix = 0;
for ( ; ix < wlen ; ++ix ) {
if (max_fd < wfds[ix]) max_fd = wfds[ix];
FD_SET(wfds[ix],&wset);
}
struct timeval to;
to.tv_sec = timeout;
to.tv_usec = timeoutusec;
timedout=false;
int rc = 0;
while (true) {
rc = ::select(max_fd+1,&rset,&wset,NULL,&to);
if (rc==-1 && errno!=EINTR) {
break;
}
if (rc==-1) continue;
if (rc==0) timedout = true;
break;
}
if (rc>0) {
ix = 0;
for ( ; ix < rlen ; ++ix ) {
if (!FD_ISSET(rfd[ix],&rset)) {
rfd[ix]=-1;
}
}
ix = 0;
for ( ; ix < wlen ; ++ix ) {
if (!FD_ISSET(wfds[ix],&wset)) {
wfds[ix] = -1;
}
}
}
return rc;
}
int CFmSocket::select_read(int fd,int timeout, bool &timedout){
return select(&fd,1,NULL,0,timeout,0,timedout);
}
bool CFmSocket::recvfrom(void *data, long &len, CFmSockAddr &addr) {
socklen_t addr_len = sizeof(addr.address);
int l = ::recvfrom(m_fd,data,len,0,addr.get_sockaddr(),&addr_len);
if (l==-1) { len = errno; return false; }
len = l;
addr.set_type(addr_len);
return true;
}
bool CFmSocket::write(const void *data, long len) {
return write(m_fd,data,len);
}
void FmSocketServer::rm_socket(int sock) {
CFmMutexGuard m(getConnectionMutex());
conn_map_t::iterator it = connections.find(sock);
if (it!=connections.end()) {
connections.erase(it);
}
}
void FmSocketServer::handle_socket_data(int fd, std::vector<char> &data,
CFmDBSession &sess) {
FM_INFO_LOG("Received data from sock:%d len %lu\n",fd,data.size());
}
bool FmSocketServer::good_socket(int sock) {
bool timedout=false;
int rc = select(&sock,1,NULL,0,0,0,timedout);
return (rc!=-1);
}
void FmSocketServer::find_bad_fd() {
if (!good_socket(m_fd)) {
server_reset();
}
std::vector<int> lsock;
to_sock_array(lsock);
int ix = 0;
int mx =lsock.size();
for ( ; ix < mx ; ++ix) {
if (!good_socket(lsock[ix])) {
FM_INFO_LOG("Found bad fd, close it:(%d)", lsock[ix]);
::close(lsock[ix]);
rm_socket(lsock[ix]);
}
}
}
bool FmSocketServer::run() {
CFmDBSession *sess;
if (fm_db_util_create_session(&sess) != true){
FM_ERROR_LOG("Fail to create DB session, exit ...\n");
exit (-1);
}
while (true) {
std::vector<int> lsock;
to_sock_array(lsock);
lsock.push_back(m_fd);
bool timedout =false;
int rc = select(&(lsock[0]),lsock.size(),NULL,0,1,0,timedout);
if (timedout) continue;
if (rc==-1) {
find_bad_fd();
continue;
}
//listening socket and close all current sockets..
int ix = 0;
int mx = lsock.size();
for ( ; ix < mx ; ++ix ) {
if (lsock[ix]==-1) continue;
if (lsock[ix]==m_fd) {
accept();
continue;
}
std::vector<char>buff;
buff.clear();
bool rc = read_packet(lsock[ix],buff);
if (!rc) {
::close(lsock[ix]);
rm_socket(lsock[ix]);
} else {
//FM_INFO_LOG("handle_socket_data\n");
handle_socket_data(lsock[ix],buff, *sess);
}
}
}
return false;
}
FmSocketServer::~FmSocketServer() {
conn_map_t::iterator it = connections.begin();
conn_map_t::iterator end = connections.end();
for (; it != end ; ++it) {
::close(it->first);
}
connections.clear();
}
void FmSocketServer::to_sock_array(std::vector<int> &socks) {
CFmMutexGuard m(getConnectionMutex());
conn_map_t::iterator it = connections.begin();
conn_map_t::iterator end = connections.end();
for (; it != end ; ++it) {
socks.push_back(it->first);
}
}
bool FmSocketServer::server_reset() {
if (!create_socket()) {
FM_INFO_LOG("Failed to create socket for port:(%d)\n", server_port);
return false;
}
switch (address_family) {
//When address is IPv4
case AF_INET:
{
int optval = 1;
setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(server_addr.c_str());
addr.sin_port = htons(server_port);
int ipAddr = addr.sin_addr.s_addr;
char str[INET_ADDRSTRLEN];
memset(str,0, sizeof(str));
inet_ntop( AF_INET, &ipAddr, str, INET_ADDRSTRLEN );
if (bind(m_fd,(const struct sockaddr *)&addr,sizeof(addr))!=0) {
return false;
}
FM_INFO_LOG("FM server socket binds the addr:(%s) port:(%d)\n",str, htons(server_port));
if (::listen(m_fd,10)==-1) {
FM_INFO_LOG("listen on fd:(%d) failed, errno: (%d) (%s)\n",
m_fd, errno, strerror(errno));
}
return true;
}
//When address is IPv6
case AF_INET6:
{
int optval = 1;
setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
struct sockaddr_in6 addr;
addr.sin6_family = AF_INET6;
inet_pton(AF_INET6,server_addr.c_str(),&(addr.sin6_addr));
addr.sin6_port = htons(server_port);
char str[INET6_ADDRSTRLEN];
memset(str,0, sizeof(str));
inet_ntop( AF_INET6, &addr.sin6_addr.s6_addr, str, INET6_ADDRSTRLEN );
if (bind(m_fd,(const struct sockaddr *)&addr,sizeof(addr))!=0) {
return false;
}
FM_INFO_LOG("FM server socket binds the addr:(%s) port:(%d)\n",str, htons(server_port));
if (::listen(m_fd,10)==-1) {
FM_INFO_LOG("listen on fd:(%d) failed, errno: (%d) (%s)\n",
m_fd, errno, strerror(errno));
}
return true;
}
//Should never get here, needed for completeness
default:
{
return false;
}
}
}
bool FmSocketServer::server_sock(const char *bindaddr, int port, int address_family) {
this->address_family = address_family;
server_addr = bindaddr;
server_port = port;
return server_reset();
}
bool FmSocketServer::accept() {
client_conn con;
socklen_t alen = sizeof(con.addr);
int fd = ::accept(m_fd,con.addr.get_sockaddr(),&alen);
if (fd==-1) {
FM_INFO_LOG("accept returns fd: (%d) errno: (%d) (%s)\n",
fd, errno, strerror(errno));
return false;
}
con.sock = fd;
CFmMutexGuard m(getConnectionMutex());
connections[fd] = con;
return true;
}

View File

@ -0,0 +1,109 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FMSOCKET_H_
#define FMSOCKET_H_
#include "fmMutex.h"
#include "fmDb.h"
#include <vector>
#include <unistd.h>
#include <string>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <map>
typedef struct CFmSockAddr_s {
int type;
union {
struct sockaddr_in ipv4;
struct sockaddr_in6 ipv6;
struct sockaddr_un un;
} address;
sockaddr * get_sockaddr() {
return (sockaddr*)(&address);
}
void set_type(socklen_t len);
} CFmSockAddr;
class CFmSocket {
protected:
int m_fd;
int address_family;
void close();
bool create_socket();
public:
CFmSocket();
~CFmSocket();
bool connect(const char *host, int port, int address_family);
static bool write(int fd, const void *data, long len);
static bool write_packet(int fd, const std::vector<char> &data);
static bool write_packet(int fd, const void *data, long len);
static bool read(int fd,void *data, long &len);
static bool read_packet(int fd, std::vector<char> &data);
// read length and then size of exact packet
bool read_packet(std::vector<char> &data);
bool write_packet(const std::vector<char> &data) {
return write_packet(m_fd,data);
}
bool write_packet(const void *data, long len) {
return write_packet(m_fd,data,len);
}
bool read(void *data, long &len);
bool write(const void *data, long len);
int get_fd() { return m_fd; }
bool recvfrom(void *data, long &len, CFmSockAddr &addr );
static int select(int *rfd, int rlen, int *wfds, int wlen,int timeout,int timeoutusec, bool &timedout);
static int select_read(int fd,int timeout, bool &timedout);
};
class FmSocketServer : public CFmSocket {
protected:
std::string server_addr;
int server_port;
typedef struct {
CFmSockAddr addr;
int sock;
} client_conn;
typedef std::map<int,client_conn> conn_map_t;
conn_map_t connections;
void to_sock_array(std::vector<int> &socks);
bool accept();
virtual void handle_socket_data(int fd,std::vector<char> &data,
CFmDBSession &sess);
void add_socket(int sock);
void rm_socket(int sock);
bool good_socket(int sock);
void find_bad_fd();
public:
bool server_sock(const char *bindaddr, int port, int address_family);
bool server_reset();
bool run();
virtual ~FmSocketServer();
};
#endif /* DMSOCKET_H_ */

View File

@ -0,0 +1,97 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include "fmThread.h"
#include "fmLog.h"
struct thread_struct {
FmThreadFunctionT fn;
void *cntx;
};
static void * ThreadProcL(void * lpParameter ) {
thread_struct * p = (thread_struct *) lpParameter;
p->fn(p->cntx);
delete p;
return 0;
}
#define FM_MSEC_PER_SEC 1000
#define FM_NSEC_PER_MILSEC 1000000
static void our_sleep(unsigned int msec) {
struct timespec req;
struct timespec left;
memset(&left,0,sizeof(left));
req.tv_sec = msec / FM_MSEC_PER_SEC;
req.tv_nsec = (msec % FM_MSEC_PER_SEC) * FM_NSEC_PER_MILSEC;
while (nanosleep(&req,&left)==-1 && errno==EINTR) {
req = left;
}
}
extern "C" {
bool fmCreateThread(FmThreadFunctionT fn, void *usrData) {
int rt = 0;
pthread_t p_thread;
pthread_attr_t attr;
//Initialize the thread attributes with the default values
rt =pthread_attr_init(&attr);
if (rt != 0){
FM_ERROR_LOG("Initialize the thread attributes failed:error=%d",rt);
return false;
}
// could change the default values here
rt =pthread_attr_setstacksize(&attr, FM_THREAD_STACK_SIZE);
if (rt != 0){
FM_ERROR_LOG("pthread_attr_setstacksize failed:error=%d",rt);
return false;
}
thread_struct * p = new thread_struct;
if (p == NULL){
FM_ERROR_LOG("Can't allocate the thread struct");
return false;
}
p->fn = fn;
p->cntx = usrData;
rt= pthread_create(&p_thread,&attr,ThreadProcL,p);
if (rt != 0){
FM_ERROR_LOG("Failed to create the thread:error=%d",rt);
delete p;
return false;
}
return true;
}
bool fmThreadSleep(unsigned int msec) {
our_sleep(msec);
return true;
}
}

View File

@ -0,0 +1,34 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FM_THREAD_H_
#define FM_THREAD_H_
#include <stdbool.h>
//Set stack size of 2M (rather than 8M default).
#define FM_THREAD_STACK_SIZE (2 * 1024 * 1024)
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*FmThreadFunctionT) (void * context);
bool fmCreateThread(FmThreadFunctionT fn, void *cntx) ;
bool fmThreadSleep(unsigned int msec) ;
void fmJobHandlerThread(void *context);
void fmRegHandlerThread(void *context);
void fmEventSuppressionMonitorThread(void *context);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,48 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include "fmTime.h"
#include "fmLog.h"
#include <string.h>
#include <errno.h>
#define FM_USEC_PER_SEC 1000000
static FMTimeT GetUptimeMicro() {
uint64_t thetm = 0;
struct timespec tv;
if (clock_gettime(CLOCK_MONOTONIC_RAW,&tv)==0) {
thetm = tv.tv_nsec/1000;
thetm = ((uint64_t)tv.tv_sec) * FM_USEC_PER_SEC;
} else {
FM_ERROR_LOG("clock_gettime() failed: error: (%d), (%s)", errno, strerror(errno));
}
return thetm;
}
FMTimeT fmGetCurrentTime() {
struct timeval tv;
memset(&tv,0,sizeof(tv));
if (gettimeofday(&tv, NULL) != 0){
FM_ERROR_LOG("gettimeofday failed (errno:%d)",errno);
return 0;
} else {
return (((FMTimeT)tv.tv_sec) * FM_USEC_PER_SEC) +
((FMTimeT)tv.tv_usec);
}
}
FMTimeT fmGetCurrentHrt() {
return GetUptimeMicro();
}
FMTimeT CFmTimer::gethrtime(){
return fmGetCurrentHrt();
}

View File

@ -0,0 +1,81 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#ifndef FM_TIME_H_
#define FM_TIME_H_
#include <time.h>
#include <sys/time.h>
#include <errno.h>
#include <stdio.h>
#include <stdint.h>
#include "fmAPI.h"
#include "fmLog.h"
// time in microseconds
FMTimeT fmGetCurrentTime();
// time in microseconds
FMTimeT fmGetCurrentHrt();
/**
* Create a passive timer in microseconds
*/
class CFmTimer {
FMTimeT m_start;
FMTimeT m_offset;
static bool isExpired(FMTimeT start, FMTimeT offset,
FMTimeT now) {
return (now-start) >= offset;
}
public:
static FMTimeT gethrtime();
unsigned long long getStartingTime() const { return m_start; }
void reset() {
m_start = gethrtime();
}
void setExpired() {
m_start = gethrtime() - m_offset;
}
void setExpiry(FMTimeT timeout) {
m_offset = timeout;
reset();
}
CFmTimer(FMTimeT timeout=0) {
setExpiry(timeout);
}
bool isExpired() const {
return isExpired(m_start,m_offset,gethrtime());
}
FMTimeT remaining() const {
FMTimeT now = gethrtime();
if (isExpired(m_start,m_offset,now)) {
return 0;
}
return m_offset - (now-m_start);
}
FMTimeT sec_to_micro(unsigned int t) {
return ((FMTimeT)(t)) * 10000000;
}
};
#endif

View File

@ -0,0 +1,188 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include "fmAPI.h"
#include "fmAlarmUtils.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <string>
void error(const char *add="") {
printf("%s\n",add);
exit(-1);
}
void ok(const char *s="") {
printf("Ok\n%s%s",s,strlen(s)!=0 ? "\n":"");
exit(0);
}
void ok(fm_uuid_t *uuid) {
return ok(*uuid);
}
void create_alarm(const char *al) {
SFmAlarmDataT alarm;
EFmErrorT rc;
memset(&alarm,0,sizeof(alarm));
if (!fm_alarm_from_string(al,&alarm)) {
error("Invalid alarm string..");
}
//clear uuid and let it be set by fm-mgr
memset(alarm.uuid, 0, sizeof(*alarm.uuid));
fm_uuid_t uuid;
if ((rc = fm_set_fault(&alarm,&uuid))!=FM_ERR_OK) {
std::string errstr = fm_error_from_int(rc);
error(errstr.c_str());
}
ok(&uuid);
}
void delete_alarms(const char *id) {
fm_ent_inst_t inst_id;
EFmErrorT rc;
memset(inst_id, 0 , sizeof(inst_id));
strncpy(inst_id, id ,sizeof(inst_id)-1);
if ((rc = fm_clear_all(&inst_id))!=FM_ERR_OK) {
std::string errstr = fm_error_from_int(rc);
error(errstr.c_str());
}
ok();
}
void delete_alarm(const char *f) {
AlarmFilter af;
EFmErrorT rc;
memset(&af,0,sizeof(af));
if (!fm_alarm_filter_from_string(f,&af)) {
error("Invalid alarm filter");
}
if ((rc = fm_clear_fault(&af))!=FM_ERR_OK) {
std::string errstr = fm_error_from_int(rc);
error(errstr.c_str());
}
ok();
}
void get_alarm(const char *f) {
AlarmFilter af;
EFmErrorT rc;
memset(&af, 0, sizeof(af));
if (!fm_alarm_filter_from_string(f,&af)) {
error("Invalid alarm filter");
}
SFmAlarmDataT ad;
memset(&ad, 0 , sizeof(ad));
if ((rc = fm_get_fault(&af,&ad))!=FM_ERR_OK) {
std::string errstr = fm_error_from_int(rc);
error(errstr.c_str());
}
std::string s;
fm_alarm_to_string(&ad,s);
ok(s.c_str());
}
void get_alarms(const char *id) {
fm_ent_inst_t inst_id;
EFmErrorT rc;
memset(inst_id, 0 , sizeof(inst_id));
strncpy(inst_id, id ,sizeof(inst_id)-1);
unsigned int max_alarms=500;
SFmAlarmDataT *p = (SFmAlarmDataT*)malloc(max_alarms*sizeof(SFmAlarmDataT));
if (p==NULL) error("Not enough memory...");
if ((rc=fm_get_faults(&inst_id,p,&max_alarms))!=FM_ERR_OK) {
free(p);
std::string errstr = fm_error_from_int(rc);
error(errstr.c_str());
}
printf("Ok\n");
size_t ix = 0;
for ( ; ix < max_alarms; ++ix ) {
std::string a;
fm_alarm_to_string(p+ix,a);
printf("%s\n",a.c_str());
}
free(p);
exit(0);
}
void get_alarms_by_id(const char *id) {
fm_alarm_id alm_id;
EFmErrorT rc;
memset(alm_id, 0 , sizeof(alm_id));
strncpy(alm_id, id ,sizeof(alm_id)-1);
unsigned int max_alarms=500;
SFmAlarmDataT *p = (SFmAlarmDataT*)malloc(max_alarms*sizeof(SFmAlarmDataT));
if (p==NULL) error("Not enough memory...");
if ((rc=fm_get_faults_by_id(&alm_id,p,&max_alarms))!=FM_ERR_OK) {
free(p);
std::string errstr = fm_error_from_int(rc);
error(errstr.c_str());
}
printf("Ok\n");
size_t ix = 0;
for ( ; ix < max_alarms; ++ix ) {
std::string a;
fm_alarm_to_string(p+ix,a);
printf("%s\n",a.c_str());
}
free(p);
exit(0);
}
int main(int argc, char**argv) {
int c;
if (argc < 3) {
error("Wrong arguments");
}
while ( (c=getopt(argc,argv,"c:d:D:g:G:A:"))) {
switch(c) {
case 'c':
create_alarm(optarg);
break;
case 'd':
delete_alarm(optarg);
break;
case 'D':
delete_alarms(optarg);
break;
case 'g':
get_alarm(optarg);
break;
case 'G':
get_alarms(optarg);
break;
case 'A':
get_alarms_by_id(optarg);
break;
default:
error("Invalid option...");
break;
}
}
return 0;
}

View File

@ -0,0 +1,195 @@
#!/usr/bin/env python
# Copyright (c) 2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import sys
import os
import json
import datetime
import uuid as uuid_gen
import socket
from inspect import getframeinfo
from inspect import stack
import yaml
import collections
import sqlalchemy
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Boolean, Integer, String, DateTime
FM_LOG_EVENT_LOG_FILE = "/var/log/platform.log"
Base = declarative_base()
class EventSuppression(Base):
__tablename__ = 'event_suppression'
created_at = Column('created_at', DateTime)
id = Column('id', Integer, primary_key=True, nullable=False)
uuid = Column('uuid', String(36), unique=True)
alarm_id = Column('alarm_id', String(255), unique=True)
description = Column('description', String(255))
suppression_status = Column('suppression_status', String(255))
set_for_deletion = Column('set_for_deletion', Boolean)
mgmt_affecting = Column('mgmt_affecting', String(255))
class ialarm(Base):
__tablename__ = 'i_alarm'
id = Column(Integer, primary_key=True, nullable=False)
alarm_id = Column('alarm_id', String(255), index=True)
class event_log(Base):
__tablename__ = 'i_event_log'
id = Column(Integer, primary_key=True, nullable=False)
event_log_id = Column('event_log_id', String(255), index=True)
state = Column(String(255))
def prettyDict(dict):
output = json.dumps(dict,sort_keys=True, indent=4)
return output
def logInfo(msg):
try:
timestamp = str(datetime.datetime.now())
host_name = socket.gethostname()
caller = getframeinfo(stack()[1][0])
line_no = str(caller.lineno)
output = "\n" + timestamp + " " + host_name + " fmManager: info " \
+ current_file_name + "(" + line_no + "):" + " " + msg+"\n"
with open(FM_LOG_EVENT_LOG_FILE,"a") as logFile:
logFile.write(output)
except Exception as e:
print e
def get_events_yaml_filename():
events_yaml_name = os.environ.get("EVENTS_YAML")
if events_yaml_name is not None and os.path.isfile(events_yaml_name):
return events_yaml_name
return "/etc/fm/events.yaml"
#
# Main
#
if len(sys.argv) < 2:
sys.exit("Postgres credentials required as argument.")
postgresql_credentials = str(sys.argv[1])
# Set up logging:
current_file_name = __file__
current_file_name = current_file_name[2:] # remove leading characters "./"
# Set up sqlalchemy:
meta = sqlalchemy.MetaData()
engine = sqlalchemy.create_engine(postgresql_credentials)
meta.bind = engine
Session = sessionmaker(bind=engine)
session = Session()
# Convert events.yaml to dict:
EVENT_TYPES_FILE = get_events_yaml_filename()
if not os.path.isfile(EVENT_TYPES_FILE):
exit (-1)
stream = file(EVENT_TYPES_FILE, 'r')
event_types = yaml.load(stream)
for alarm_id in event_types:
if isinstance(alarm_id, float):
# force 3 digits after the decimal point,
# to include trailing zero's (ex.: 200.010)
formatted_alarm_id = "{:.3f}".format(alarm_id)
event_types[formatted_alarm_id] = event_types.pop(alarm_id)
event_types = collections.OrderedDict(sorted(event_types.items()))
yaml_event_list = []
uneditable_descriptions = {'100.114', '200.007', '200.02', '200.021', '200.022', '800.002'}
# Parse events.yaml dict, and add any new alarm to event_suppression table:
for event_type in event_types:
if event_types.get(event_type).get('Type') == "Alarm":
event_created_at = datetime.datetime.now()
event_uuid = str(uuid_gen.uuid4())
string_event_type = str(event_type)
yaml_event_list.append(string_event_type)
if str(event_type) not in uneditable_descriptions:
event_description = (event_types.get(event_type) \
.get('Description'))
else:
event_description = event_types.get(event_type).get('Description')
event_description = str(event_description)
event_description = (event_description[:250] + ' ...') \
if len(event_description) > 250 else event_description
event_supp = session.query(EventSuppression) \
.filter_by(alarm_id=string_event_type).first()
event_mgmt_affecting = str(event_types.get(event_type).get(
'Management_Affecting_Severity', 'warning'))
if event_supp:
event_supp.description = event_description
event_supp.mgmt_affecting = event_mgmt_affecting
else:
event_supp = EventSuppression(created_at=event_created_at,
uuid=event_uuid,
alarm_id=string_event_type,
description=event_description,
suppression_status='unsuppressed',
set_for_deletion=False,
mgmt_affecting=event_mgmt_affecting)
session.add(event_supp)
logInfo("Created Event Type {} in event_suppression table.".format(string_event_type))
session.commit()
event_supp = session.query(EventSuppression)
alarms = session.query(ialarm)
events = session.query(event_log).filter(event_log.state != 'log')
alarm_ids_in_use = set()
for alarm in alarms:
alarm_ids_in_use.add(alarm.alarm_id)
for event in events:
alarm_ids_in_use.add(event.event_log_id)
for event_type in event_supp:
if event_type.alarm_id not in yaml_event_list:
if event_type.alarm_id not in alarm_ids_in_use:
event_supp = session.query(EventSuppression) \
.filter_by(alarm_id=event_type.alarm_id).first()
session.delete(event_supp)
logInfo("Deleted Event Type {} from event_suppression table.".format(event_type.alarm_id))
else:
event_supp.suppression_status='unsuppressed'
event_supp.set_for_deletion = True
logInfo("Event Type {} no longer in events.yaml, but still used by alarm in database.".format(event_type.alarm_id))
logInfo("Event Type {} marked as set for deletion in event_suppression table.".format(event_type.alarm_id))
session.commit()
session.close()

202
fm-doc/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,2 @@
SRC_DIR="fm_doc"
TIS_PATCH_VER=16

45
fm-doc/centos/fm-doc.spec Normal file
View File

@ -0,0 +1,45 @@
Summary: CGTS Platform Fault Management Documentation Package
Name: fm-doc
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
BuildRequires: fm-api-doc
BuildRequires: fm-common-doc
BuildRequires: python-yaml
Source0: %{name}-%{version}.tar.gz
%define cgcs_doc_deploy_dir /opt/deploy/cgcs_doc
%description
A yaml file description of the CGTS Alarms and Customer Logs generated by
the Titanium Cloud System. Also included and used at build time is a simple syntax
checker to ensure no duplicate IDs are used, and generally the correct
field values are documented.
%prep
%setup
%install
CGCS_DOC_DEPLOY=$RPM_BUILD_ROOT/%{cgcs_doc_deploy_dir}
install -d $CGCS_DOC_DEPLOY
mkdir -p $RPM_BUILD_ROOT/%{_sysconfdir}/fm/
install -m 744 events.yaml $RPM_BUILD_ROOT/%{_sysconfdir}/fm/
install -m 644 events.yaml $CGCS_DOC_DEPLOY
install -m 755 checkEventYaml $CGCS_DOC_DEPLOY
install -m 644 parseEventYaml.py $CGCS_DOC_DEPLOY
install -m 644 check_missing_alarms.py $CGCS_DOC_DEPLOY
pushd $CGCS_DOC_DEPLOY
cp %{cgcs_doc_deploy_dir}/constants.py %{cgcs_doc_deploy_dir}/fmAlarm.h .
./checkEventYaml
rm constants.py* fmAlarm.h*
popd
%files
%license LICENSE
%defattr(-,root,root,-)
%{cgcs_doc_deploy_dir}/*
%{_sysconfdir}/fm/events.yaml

202
fm-doc/fm_doc/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

33
fm-doc/fm_doc/checkEventYaml Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash -e
#
# Copyright (c) 2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
USAGE="usage: ${0##*/} [ <fmEventDoc.yaml> ]"
FMEVENTDOC_YAMLFILE="events.yaml"
if [ "$#" -gt 0 ]
then
FMEVENTDOC_YAMLFILE=$1
fi
echo "File: " ${FMEVENTDOC_YAMLFILE}
echo "Checking for duplicate records ..."
DUP_LINES=$(cat ${FMEVENTDOC_YAMLFILE} | egrep "^[0-9]" | cut --characters=1-7 | sort | uniq -d | wc -l)
if [ ${DUP_LINES} -gt 0 ]; then
echo "ERROR Duplicate records defined:"
cat ${FMEVENTDOC_YAMLFILE} | egrep "^[0-9]" | cut --characters=1-7 | sort | uniq -d
echo
echo "Done"
exit 1
fi
python parseEventYaml.py ${FMEVENTDOC_YAMLFILE}
python check_missing_alarms.py ${FMEVENTDOC_YAMLFILE}
exit $?

View File

@ -0,0 +1,113 @@
#!/usr/bin/env python
# Copyright (c) 2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import sys
import os
import yaml
import collections
import constants as fm_constants
FM_ALARM_H="fmAlarm.h"
def get_events_alarm_list(events):
for alarm_id in events:
if isinstance(alarm_id, float):
formatted_alarm_id = "{:.3f}".format(alarm_id) # force 3 digits after the point, to include trailing zero's (ex.: 200.010)
events[formatted_alarm_id] = events.pop(alarm_id)
events = collections.OrderedDict(sorted(events.items()))
events_alarm_list = []
for alarm_id in events:
if events.get(alarm_id).get('Type') == "Alarm":
events_alarm_list.append(str(alarm_id))
return events_alarm_list
def get_constants_alarms():
fm_constants_raw_dict = fm_constants.__dict__
fm_constants_alarms_dict = {k:v for k,v in fm_constants_raw_dict.iteritems() if 'FM_ALARM_ID' in k}
del fm_constants_alarms_dict['FM_ALARM_ID_INDEX'] # this is not an alarm
fm_constants_alarms = []
for alarm_constant_name in fm_constants_alarms_dict:
alarm_constant_full_name = 'fm_constants.' + alarm_constant_name
fm_constants_alarms.append(eval(alarm_constant_full_name))
return fm_constants_alarms
def get_fm_alarms():
fm_alarm_group_lines = []
fm_alarm_groups = {}
fm_alarms = []
with open(FM_ALARM_H) as f:
fm_alarms_file = f.readlines()
fm_alarm_group_lines = filter(lambda k: 'define ALARM_GROUP_' in k, fm_alarms_file)
for line in fm_alarm_group_lines:
group_name = line.split()[1]
group_value = line.split()[2]
group_value = group_value[1:-1] # remove quotes
fm_alarm_groups[group_name] = group_value
fm_alarm_lines = filter(lambda k: 'FM_ALARM_ID' in k, fm_alarms_file)
for line in fm_alarm_lines:
alarm_name = line.split()[1]
group_name = line.split()[2]
group_name = group_name[1:]
alarm_right_digits_value = line.split()[3]
alarm_right_digits_value = alarm_right_digits_value[1:-2]
alarm_left_digits_value = fm_alarm_groups[group_name]
alarm_value = alarm_left_digits_value + alarm_right_digits_value
fm_alarms.append(alarm_value)
return fm_alarms
#
# Main
#
if len(sys.argv) == 1:
print "Missing file argument.\n"
exit(1)
if not os.path.isfile(sys.argv[1]):
print "File \'%s\' does not exist.\n" % (sys.argv[1])
exit(1)
exitValue = 0
with open(sys.argv[1], 'r') as stream:
try:
events = yaml.load(stream)
events_alarm_list = get_events_alarm_list(events)
except yaml.YAMLError as exc:
print(exc)
constants_alarms = get_constants_alarms()
for alarm_id in constants_alarms:
if alarm_id not in events_alarm_list:
print "\n ERROR: constants.py alarm \'%s\' must be defined in file events.yaml.\n" % (alarm_id)
exitValue = 1
fm_alarms = get_fm_alarms()
for alarm_id in fm_alarms:
if alarm_id not in events_alarm_list:
print "\n ERROR: fmAlarm.h alarm \'%s\' must be defined in file events.yaml.\n" % (alarm_id)
exitValue = 1
exit (exitValue)

3098
fm-doc/fm_doc/events.yaml Executable file

File diff suppressed because it is too large Load Diff

196
fm-doc/fm_doc/parseEventYaml.py Executable file
View File

@ -0,0 +1,196 @@
#
# Copyright (c) 2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
import sys
import os
import yaml
import constants
# Record Format (for full description see events.yaml)
#
# 100.001:
# Type: Alarm
# Description: "Degrade: <hostname> is experiencing an intermittent 'Management Network' communication failure."
# Entity_Instance_ID: host=<hostname>
# Severity: critical
# Proposed_Repair_Action: "Check Host's board management configuration and connectivity."
# Maintenance_Action: auto recover
# Inhibit_Alarms: True
# Alarm_Type: operational-violation
# Probable_Cause: timing-problem
# Service_Affecting: False
# Suppression: True
# Management_Affecting_Severity: warning
#
type_FieldName = 'Type'
type_FieldValue_Alarm = 'Alarm'
type_FieldValues = [ type_FieldValue_Alarm, 'Log' ]
description_FieldName = 'Description'
description_FieldValues = [] # arbitrary string
entityInstanceId_FieldName = 'Entity_Instance_ID'
entityInstanceId_FieldValues = [] # arbitrary string
severity_FieldName = 'Severity'
severity_FieldValues = constants.ALARM_SEVERITY
proposedRepairAction_FieldName = 'Proposed_Repair_Action'
proposedRepairAction_FieldValues = [] # arbitrary string
maintenanceAction_FieldName = 'Maintenance_Action'
maintenanceAction_FieldValues = [] # arbitrary string
inhibitAlarms_FieldName = 'Inhibit_Alarms'
inhibitAlarms_FieldValues = [ True, False ]
alarmType_FieldName = 'Alarm_Type'
alarmType_FieldValues = constants.ALARM_TYPE
probableCause_FieldName = 'Probable_Cause'
probableCause_FieldValues = constants.ALARM_PROBABLE_CAUSE
serviceAffecting_FieldName = 'Service_Affecting'
serviceAffecting_FieldValues = [ True, False ]
suppression_FieldName = 'Suppression'
suppression_FieldValues = [ True, False ]
managementAffectingSeverity_FieldName = 'Management_Affecting_Severity'
managementAffectingSeverity_FieldValues = constants.ALARM_SEVERITY.append('none')
alarmFields = {
type_FieldName : type_FieldValues,
description_FieldName : description_FieldValues,
entityInstanceId_FieldName : entityInstanceId_FieldValues,
severity_FieldName : severity_FieldValues,
proposedRepairAction_FieldName : proposedRepairAction_FieldValues,
maintenanceAction_FieldName : maintenanceAction_FieldValues,
inhibitAlarms_FieldName : inhibitAlarms_FieldValues,
alarmType_FieldName : alarmType_FieldValues,
probableCause_FieldName : probableCause_FieldValues,
serviceAffecting_FieldName : serviceAffecting_FieldValues,
suppression_FieldName : suppression_FieldValues,
managementAffectingSeverity_FieldName : managementAffectingSeverity_FieldValues
}
logFields = {
type_FieldName : type_FieldValues,
description_FieldName : description_FieldValues,
entityInstanceId_FieldName : entityInstanceId_FieldValues,
severity_FieldName : severity_FieldValues,
alarmType_FieldName : alarmType_FieldValues,
probableCause_FieldName : probableCause_FieldValues,
serviceAffecting_FieldName : serviceAffecting_FieldValues
}
def checkField( fieldKey, fieldValues, key, event ):
if not event.has_key(fieldKey):
print "\n ERROR: %s missing \'%s\' field." % (key, fieldKey)
return False
# print "START: %s :END" % event[fieldKey]
if type(event[fieldKey]) is str:
if not fieldValues:
return True
if event[fieldKey] in fieldValues:
return True
else:
print "\n ERROR: \'%s\' is not a valid \'%s\' field value." % (event[fieldKey], fieldKey)
print " Valid values are:", fieldValues
return False
if type(event[fieldKey]) is list:
if not fieldValues:
return True
for listvalue in event[fieldKey]:
if not listvalue in fieldValues:
print "\n ERROR: \'%s\' is not a valid \'%s\' field value." % (listvalue, fieldKey)
print " Valid values are:", fieldValues
return False
if type(event[fieldKey]) is dict:
for dictKey, dictValue in event[fieldKey].iteritems():
if not dictKey in severity_FieldValues:
print "\n ERROR: \'%s\' is not a valid \'%s\' index value." % (dictKey, fieldKey)
print " Valid index values are:", severity_FieldValues
return False
if fieldValues:
if not dictValue in fieldValues:
print "\n ERROR: \'%s\' is not a valid \'%s\' field value." % (dictValue, fieldKey)
print " Valid values are:", fieldValues
return False
return True
def checkTypeField( key, event ):
if not event.has_key(type_FieldName):
print "\n ERROR: %s missing \'%s\' field." % (key, type_FieldName)
return False
if event[type_FieldName] in type_FieldValues:
return True
print "\n ERROR: \'%s\' is not a valid \'%s\' field value." % (event[type_FieldName], type_FieldName)
return False
def checkFields( key, event ):
isOk = True
if not checkTypeField(key, event) :
return False
isAlarm = (event[type_FieldName] == type_FieldValue_Alarm)
eventFields = alarmFields if isAlarm else logFields
for fieldKey, fieldValues in eventFields.iteritems():
if not checkField(fieldKey, fieldValues, key, event) :
isOk = False
for itemKey, itemValue in event.iteritems():
if not eventFields.has_key(itemKey):
print "\n ERROR: \'%s\' is not a valid \'%s\' field." % (itemKey, ("Alarm" if isAlarm else "Log") )
isOk = False
return isOk
#
# Main
#
if len(sys.argv) == 1:
print "Missing file argument.\n"
exit(1)
if not os.path.isfile(sys.argv[1]):
print "File \'%s\' does not exist.\n" % (sys.argv[1])
exit(1)
with open(sys.argv[1], 'r') as stream:
try:
events = yaml.load(stream)
exitValue = 0
for key in events:
print "%6.3f: checking ... " % key,
if not checkFields( key, events[key] ):
print
exitValue = 1
else:
print 'OK.'
print 'Done.'
except yaml.YAMLError as exc:
print(exc)
exit (exitValue)

2
fm-mgr/PKG-INFO Normal file
View File

@ -0,0 +1,2 @@
Name: fm-mgr
Version: 1.0

View File

@ -0,0 +1,2 @@
SRC_DIR="sources"
TIS_PATCH_VER=5

50
fm-mgr/centos/fm-mgr.spec Normal file
View File

@ -0,0 +1,50 @@
%define local_dir /usr/local
%define local_bindir %{local_dir}/bin
Summary: CGTS Platform Fault Manager Package
Name: fm-mgr
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
BuildRequires: fm-common-dev
BuildRequires: systemd-devel
BuildRequires: libuuid-devel
%description
CGTS platform Fault Manager that serves the client
application fault management requests and raise/clear/update
alarms in the active alarm database.
%prep
%setup
%build
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
make MAJOR=$MAJOR MINOR=$MINOR %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
make DEST_DIR=$RPM_BUILD_ROOT BIN_DIR=%{local_bindir} LIB_DIR=%{_libdir} INC_DIR=%{_includedir} MAJOR=$MAJOR MINOR=$MINOR install_non_bb
%clean
rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root,-)
%doc LICENSE
%{local_bindir}/fmManager
%config(noreplace) %{_sysconfdir}/fm.conf
%_sysconfdir/init.d/fminit
%{_unitdir}/fminit.service
%config(noreplace) %{_sysconfdir}/logrotate.d/fm.logrotate

202
fm-mgr/sources/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

30
fm-mgr/sources/Makefile Executable file
View File

@ -0,0 +1,30 @@
SRCS = fm_main.cpp
OBJS = fm_main.o
OBJS = $(SRCS:.cpp=.o)
INCLUDES = -I.
CCFLAGS = -g -O2 -Wall -Werror
build: fmManager
.cpp.o:
$(CXX) $(INCLUDES) $(CCFLAGS) $(EXTRACCFLAGS) -c $< -o $@
fmManager: $(OBJS)
$(CXX) -o $@ $(OBJS) $(LDFLAGS) -lfmcommon -lrt -lpthread -luuid
clean:
@rm -f $(OBJS)
install_non_bb:
mkdir -p $(DEST_DIR)/usr/lib/systemd/system
install -m 755 -d $(DEST_DIR)/etc
install -m 755 -d $(DEST_DIR)/etc/init.d
install -m 755 -d $(DEST_DIR)/etc/logrotate.d
install -m 755 -d $(DEST_DIR)/usr/local
install -m 755 -d $(DEST_DIR)/usr/local/bin
install -m 644 fm.conf $(DEST_DIR)/etc/fm.conf
install -m 755 fminit $(DEST_DIR)/etc/init.d/fminit
install -m 755 fmManager $(DEST_DIR)/usr/local/bin/fmManager
install -m 644 fm.logrotate $(DEST_DIR)/etc/logrotate.d/fm.logrotate
install -m 644 fminit.service $(DEST_DIR)/usr/lib/systemd/system/fminit.service

8
fm-mgr/sources/fm.conf Normal file
View File

@ -0,0 +1,8 @@
###################################################
#
# fm.conf
#
# The configuration file for the fmManager process.
#
###################################################
event_log_max_size=4000

View File

@ -0,0 +1,35 @@
#
# Copyright (c) 2014 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
nodateext
/var/log/fm-event.log
{
nodateext
size 200M
start 1
missingok
rotate 20
compress
sharedscripts
postrotate
systemctl reload syslog-ng > /dev/null 2>&1 || true
endscript
}
/var/log/fm-manager.log
{
nodateext
size 10M
start 1
rotate 20
missingok
notifempty
compress
sharedscripts
postrotate
systemctl reload syslog-ng > /dev/null 2>&1 || true
endscript
}

View File

@ -0,0 +1,59 @@
//
// Copyright (c) 2014 Wind River Systems, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
#include <stdio.h>
#include <stdlib.h>
#include <fmAPI.h>
#include <stdbool.h>
#include <unistd.h>
#include <signal.h>
#include <syslog.h>
void sig_handler(int signo) {
int result = 0;
if (signo == SIGHUP){
result = setlogmask(LOG_UPTO (LOG_DEBUG));
if (result == LOG_UPTO (LOG_DEBUG)){
result = setlogmask(LOG_UPTO (LOG_INFO));
syslog(LOG_INFO, "Received SIGHUP, set log level from %d to LOG_INFO", result);
}else{
syslog(LOG_INFO, "Received SIGHUP, set log level from %d to LOG_DEBUG", result);
}
}
}
int main(int argc, char *argv[]) {
int c;
const char *fn = NULL;
if (argc < 3) {
syslog(LOG_ERR, "Wrong arguments\n");
exit(-1);
}
while ((c=getopt(argc,argv,"c:")) != -1) {
switch(c) {
case 'c':
fn = optarg;
break;
default:
syslog(LOG_ERR, "Invalid option...\n");
exit(-1);
}
}
/* ignore SIGPIPE */
signal(SIGPIPE, SIG_IGN);
if (signal(SIGHUP, sig_handler) == SIG_ERR){
syslog(LOG_INFO, "Can't catch SIGHUP\n");
}
fm_server_create(fn);
exit(0);
}

111
fm-mgr/sources/fminit Executable file
View File

@ -0,0 +1,111 @@
#! /bin/sh
#
# Copyright (c) 2013-2014 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
#
# chkconfig: 2345 95 95
#
### BEGIN INIT INFO
# Provides: fminit
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: Fault Manager
### END INIT INFO
. /etc/init.d/functions
FMMGR_NAME="fmManager"
FMMGR="/usr/local/bin/${FMMGR_NAME}"
PIDFILE=/var/run/${FMMGR_NAME}.pid
CONFIGFILE=/etc/fm.conf
# Linux Standard Base (LSB) Error Codes
RETVAL=0
GENERIC_ERROR=1
INVALID_ARGS=2
NOT_RUNNING=3
NOT_INSTALLED=5
if [ ! -e "$FMMGR" ] ; then
logger "$FMMGR is missing"
exit ${NOT_INSTALLED}
fi
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
export PATH
case "$1" in
start)
# The FMMGR runs on controller only
echo -n "Starting ${FMMGR_NAME}: "
if [ -n "`pidof ${FMMGR_NAME}`" ] ; then
echo -n "is already running "
RETVAL=0
else
start-stop-daemon --start -b --make-pidfile --pidfile $PIDFILE --chuid fm -x ${FMMGR} -- -c ${CONFIGFILE}
RETVAL=$?
fi
if [ ${RETVAL} -eq 0 ] ; then
pid=`pidof ${FMMGR_NAME}`
echo "OK"
logger "${FMMGR} (${pid})"
else
echo "FAIL"
RETVAL=${GENERIC_ERROR}
fi
;;
stop)
status ${FMMGR_NAME} >/dev/null
if [ $? -ne 0 ]; then
echo "$FMMGR_NAME is not running"
RETVAL=0
else
echo -n "Stopping ${FMMGR_NAME}: "
killproc ${FMMGR_NAME}
if [ -n "`pidof ${FMMGR_NAME}`" ] ; then
logger "Going to SIGKILL ${FMMGR_NAME}"
killproc -KILL ${FMMGR_NAME}
fi
/bin/rm -rf $PIDFILE
status ${FMMGR_NAME} >/dev/null
if [ $? -ne 0 ]; then
echo "Stopped"
RETVAL=0
else
echo "Failed"
RETVAL=${GENERIC_ERROR}
fi
fi
;;
restart)
$0 stop
sleep 1
$0 start
;;
status)
status ${FMMGR_NAME} >/dev/null
RETVAL=$?
if [ ! ${RETVAL} -eq 0 ] ; then
RETVAL=${NOT_RUNNING}
fi
;;
condrestart)
$0 restart
;;
*)
echo "usage: $0 { start | stop | status | restart | condrestart | status }"
;;
esac
exit $RETVAL

View File

@ -0,0 +1,17 @@
[Unit]
Description=Titanium Cloud Fault Management Initialization
After=network.target syslog.target
[Service]
Type=forking
Restart=no
KillMode=process
RemainAfterExit=yes
ExecStart=/etc/rc.d/init.d/fminit start
ExecStop=/etc/rc.d/init.d/fminit stop
ExecReload=/etc/rc.d/init.d/fminit reload
PIDFile=/var/run/fmManager.pid
[Install]
WantedBy=multi-user.target

6
mwa-cleo.map Normal file
View File

@ -0,0 +1,6 @@
cgcs/middleware/fault/recipes-common/fm-api|fm-api
cgcs/middleware/fault/recipes-common/fm-common|fm-common
cgcs/middleware/fault/recipes-common/fm-doc|fm-doc
cgcs/middleware/fault/recipes-control/fm-mgr|fm-mgr
cgcs/middleware/fault/recipes-control/snmp-audittrail|snmp-audittrail
cgcs/middleware/fault/recipes-control/snmp-ext|snmp-ext

View File

@ -0,0 +1,2 @@
SRC_DIR="sources"
TIS_PATCH_VER=4

View File

@ -0,0 +1,56 @@
Summary: Titanium Cloud Platform SNMP Audit Trail
Name: snmp-audittrail
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
BuildRequires: net-snmp-devel
BuildRequires: fm-common-dev
BuildRequires: uuid-devel
BuildRequires: uuid
Requires: net-snmp
Requires: uuid
%description
Titanium Cloud platform SNMP Audit Trail provides audit trail support for incoming
SNMP requests.
%package -n snmp-audittrail-devel
Summary: Titanium Cloud Platform SNMP Audit Trail Package - Development files
Group: devel
Requires: snmp-audittrail = %{version}-%{release}
%description -n snmp-audittrail-devel
Titanium Cloud platform SNMP Audit Trail provides audit trail support for incoming
SNMP requests. This package contains symbolic links, header files, and related
items necessary for software development.
%prep
%setup
%build
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
PATCHVER=` echo %{release} | awk -F r '{print $2}' | awk -F . '{print $1}'`
make MAJOR=$MAJOR MINOR=$MINOR PATCH=$PATCHVER %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
PATCHVER=` echo %{release} | awk -F r '{print $2}' | awk -F . '{print $1}'`
make DEST_DIR=$RPM_BUILD_ROOT LIB_DIR=%{_libdir} MAJOR=$MAJOR MINOR=$MINOR PATCH=$PATCHVER install_non_bb
%files
%defattr(-,root,root,-)
%doc LICENSE
%{_libdir}/*.so.*
%files -n snmp-audittrail-devel
%defattr(-,root,root,-)
%{_libdir}/*.so

View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,25 @@
SRCS = snmpAuditPlugin.c
OBJS = $(SRCS:.c=.o)
LDLIBS = -lfmcommon -lnetsnmp -lnetsnmpagent -luuid
INCLUDES += -I./
CCFLAGS = -fPIC -g -O2 -Wall -Werror
LIBCGTSAGENT_SO := libsnmpAuditPlugin.so
build: lib
.c.o:
$(CXX) $(CCFLAGS) $(INCLUDES) -c $< -o $@
lib: $(OBJS)
$(CXX) $(OBJS) $(LDLIBS) -o $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) -shared
ln -sf $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(LIBCGTSAGENT_SO).$(MAJOR)
ln -sf $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(LIBCGTSAGENT_SO)
clean:
@rm -f $(OBJ) *.o *.so.*
install_non_bb:
install -m 755 -d $(DEST_DIR)$(LIB_DIR)
install -m 755 $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(DEST_DIR)$(LIB_DIR)
ln -s $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(DEST_DIR)$(LIB_DIR)/$(LIBCGTSAGENT_SO).$(MAJOR)
ln -s $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(DEST_DIR)$(LIB_DIR)/$(LIBCGTSAGENT_SO)

View File

@ -0,0 +1,422 @@
/*
* Copyright (c) 2017 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/library/callback.h>
#include <net-snmp/library/snmp_transport.h>
#include <net-snmp/library/snmp_api.h>
#include <net-snmp/library/mib.h>
#include <net-snmp/library/snmp.h>
#include <net-snmp/library/vacm.h>
#include <net-snmp/library/snmpUDPDomain.h>
#include <net-snmp/library/tools.h>
#include <net-snmp/agent/agent_callbacks.h>
#include <net-snmp/agent/agent_handler.h>
#include <net-snmp/agent/agent_registry.h>
#define LOG_BUF_STR (256)
#define AUDIT_TAG "snmp-auditor"
/* Used to keep track of the first handler call for a transaction */
typedef struct s_audit_req_t {
long transid;
long reqid;
} audit_req_t;
typedef struct s_enum_to_string_t {
const int enumval;
const char *str;
} enum_to_string_t;
/* Logs IP session information, in the format: "remote IP:port ==> local IP:port" */
static inline char* fmtaddr(const char *prefix, int af,
void *remote_addr, unsigned short remote_port,
char*buf, size_t buflen)
{
char remote_addr_str[LOG_BUF_STR+1];
if (NULL == inet_ntop(af, remote_addr, remote_addr_str, sizeof(remote_addr_str))) {
strncpy(remote_addr_str, "UNKNOWN", LOG_BUF_STR+1);
}
remote_addr_str[LOG_BUF_STR] = 0;
snprintf(buf, buflen, "transport:%s remote:%s", prefix, remote_addr_str);
return buf;
}
#ifdef NETSNMP_ENABLE_IPV6
static char* ipv6_fmtaddr(const char *prefix, netsnmp_addr_pair *addr_pair, char*buf, size_t buflen)
{
return fmtaddr(prefix, AF_INET6,
(void *)&addr_pair->remote_addr.sin6.sin6_addr, addr_pair->remote_addr.sin6.sin6_port,
buf, buflen);
}
#endif
static char* ipv4_fmtaddr(const char *prefix, netsnmp_addr_pair *addr_pair, char*buf, size_t buflen)
{
return fmtaddr(prefix, AF_INET,
(void *)&addr_pair->remote_addr.sin.sin_addr, addr_pair->remote_addr.sin.sin_port,
buf, buflen);
}
/* Logs IP session information */
static char* log_session_addresses(const oid* tDomain, netsnmp_addr_pair *addr_pair, char*buf, size_t buflen)
{
if (tDomain == netsnmpUDPDomain) {
return ipv4_fmtaddr("udp", addr_pair, buf, buflen);
}
if (tDomain == netsnmp_snmpTCPDomain) {
return ipv4_fmtaddr("tcp", addr_pair, buf, buflen);
}
#ifdef NETSNMP_ENABLE_IPV6
if (tDomain == netsnmp_UDPIPv6Domain) {
return ipv6_fmtaddr("udpv6", addr_pair, buf, buflen);
}
if (tDomain == netsnmp_TCPIPv6Domain) {
return ipv6_fmtaddr("tcpv6", addr_pair, buf, buflen);
}
#endif
strncpy(buf, "IP FMT ERROR", buflen);
buf[buflen-1] = 0;
return buf;
}
/* SNMP OID formatting (a wrapper around the 'standard' function */
static inline char* fmtoid(const oid * theoid, size_t len, int* no_overflow)
{
u_char *buf = NULL;
size_t buf_len = 0;
size_t out_len = 0;
*no_overflow = sprint_realloc_objid(&buf, &buf_len, &out_len, 1, theoid, len);
if (NULL == buf) {
*no_overflow = 0;
}
return (char*)buf;
}
/* SNMP var bind formatting (a convenience function) - formats the OID (variable name)
This function is always called with var != NULL */
static inline char* fmtmsg_var(netsnmp_variable_list * var, int* no_overflow)
{
return fmtoid(var->name, var->name_length, no_overflow);
}
static const char* get_version(long version)
{
switch (version) {
case 0: return "v1";
case 1: return "v2c";
case 2: return "v3";
}
return "error";
}
static const char *get_str_from_enum(int enumval, const enum_to_string_t* table, const char* defval)
{
const enum_to_string_t* ptr = table;
for ( ; ptr->str != NULL; ++ptr) {
if (ptr->enumval == enumval) {
return ptr->str;
}
}
if (NULL == defval) {
return "unknown";
}
return defval;
}
static const char *get_auth_error(int errorcode)
{
static enum_to_string_t errorcodes_str[] = {
{ VACM_SUCCESS, "Success", },
{ VACM_NOSECNAME, "InvalidCommunityName" },
{ VACM_NOGROUP, "NoGroup" },
{ VACM_NOACCESS, "NoAccess" },
{ VACM_NOVIEW, "NoViewAccess" },
{ VACM_NOTINVIEW, "NotInView" },
{ VACM_NOSUCHCONTEXT, "NoSuchContext" },
{ VACM_SUBTREE_UNKNOWN,"SubtreeUnknown" },
{0, NULL}
};
return get_str_from_enum(errorcode, errorcodes_str, "unknown err");
}
static const char *get_result_error(int errorcode)
{
static enum_to_string_t errorcodes_str[] = {
{ 0, "pass" },
{ SNMP_NOSUCHOBJECT, "NoSuchObject" },
{ SNMP_NOSUCHINSTANCE, "NoSuchInstance" },
{ SNMP_ENDOFMIBVIEW, "EndOfMIBView" },
{0, NULL}
};
return get_str_from_enum(errorcode, errorcodes_str, "pass");
}
/* Logs all var-binds in PDU (only variable names, aka OID's) */
static void log_var_list(netsnmp_pdu *pdu)
{
netsnmp_variable_list * var;
for (var = pdu->variables; var != NULL; var = var->next_variable) {
int no_overflow_var = 0;
char* var_str = fmtmsg_var(var, &no_overflow_var);
snmp_log(LOG_INFO, AUDIT_TAG" reqid:%ld oid:%s%s\n",
pdu->reqid,
(var_str != NULL) ? var_str : "INVALID",
(no_overflow_var) ? "" : " [TRUNCATED]");
free(var_str);
}
}
/* Logs the 'header' of a PDU/request (IP addresses, reqid, msg type, version) */
static void log_pdu_header(netsnmp_pdu *pdu, const char *status)
{
char buf[LOG_BUF_STR];
netsnmp_addr_pair *addr_pair = (netsnmp_addr_pair *)pdu->transport_data;
snmp_log(LOG_INFO, AUDIT_TAG" %s reqid:%ld msg-type:%s version:%s%s\n",
log_session_addresses(pdu->tDomain, addr_pair, buf, sizeof(buf)),
pdu->reqid, snmp_pdu_type(pdu->command), get_version(pdu->version), status);
}
/* Logs the results of a request, namely results obtained from actual processing handlers */
static void log_results(long reqid, netsnmp_request_info *requests)
{
netsnmp_request_info *req;
for (req = requests; req != NULL; req = req->next) {
netsnmp_variable_list *var = req->requestvb;
if (NULL == var) {
continue;
}
if (var->type != ASN_NULL) { /* NULL means no result, so skip */
int no_overflow_var = 0;
char* var_str = fmtmsg_var(var, &no_overflow_var);
/* Print only first variable: this is the request that we get a result for */
snmp_log(LOG_INFO, AUDIT_TAG" reqid:%ld oid:%s%s status:%s\n", reqid,
(var_str != NULL) ? var_str : "INVALID",
(no_overflow_var) ? "" : " [TRUNCATED]", get_result_error(var->type));
free(var_str);
}
}
}
static void log_invalid_oid_trees(netsnmp_pdu *pdu)
{
char buf[LOG_BUF_STR];
netsnmp_variable_list *var;
netsnmp_addr_pair *addr_pair = (netsnmp_addr_pair *)pdu->transport_data;
int first_time = 1;
for (var = pdu->variables; var != NULL; var = var->next_variable) {
netsnmp_subtree *tp = netsnmp_subtree_find(var->name, var->name_length,
NULL, pdu->contextName);
if (tp != NULL) {
int prefix_len = netsnmp_oid_find_prefix(tp->start_a,
tp->start_len,
tp->end_a, tp->end_len);
while (prefix_len < 1) {
tp = tp->next;
if (NULL == tp) {
break;
}
prefix_len = netsnmp_oid_find_prefix(tp->start_a,
tp->start_len,
tp->end_a, tp->end_len);
}
DEBUGMSGTL(("helper:snmpAudit", "var=%p tp=%p prefix_len=%d\n", var, tp, prefix_len ));
}
else {
DEBUGMSGTL(("helper:snmpAudit", "tp NOT found var=%p\n", var));
}
if (NULL == tp) {
int no_overflow_var = 0;
char* var_str = fmtmsg_var(var, &no_overflow_var);
if (first_time) {
first_time = 0;
snmp_log(LOG_INFO, AUDIT_TAG" %s reqid:%ld msg-type:%s version:%s\n",
log_session_addresses(pdu->tDomain, addr_pair, buf, sizeof(buf)), pdu->reqid,
snmp_pdu_type(pdu->command),
get_version(pdu->version));
log_var_list(pdu);
}
snmp_log(LOG_INFO, AUDIT_TAG" reqid:%ld oid:%s%s status:%s\n",
pdu->reqid,
(var_str != NULL) ? var_str : "INVALID",
(no_overflow_var) ? "" : " [TRUNCATED]",
get_result_error(SNMP_ENDOFMIBVIEW));
free(var_str);
}
}
}
/*
* Register with 'SNMPD_CALLBACK_ACM_CHECK_INITIAL == minorId'
* This function is used to log authorization errors and invalid OID's errors,
* for GET BULK and GET NEXT requests
*/
static int audit_callback_acm_check_initial(int majorID, int minorID, void *serverarg,
void *clientarg)
{
struct view_parameters *view_parms =
(struct view_parameters *) serverarg;
netsnmp_pdu *pdu = view_parms->pdu;
DEBUGMSGTL(("helper:snmpAudit", "%s msg-type: %s errcode=%d minorID=%d\n",
__FUNCTION__, snmp_pdu_type(pdu->command), view_parms->errorcode, minorID));
if (view_parms->errorcode != VACM_SUCCESS) {
/* Log Authentication errors */
char buf[LOG_BUF_STR];
netsnmp_addr_pair *addr_pair = (netsnmp_addr_pair *)pdu->transport_data;
snmp_log(LOG_INFO, AUDIT_TAG" %s reqid:%ld msg-type:%s version:%s status:%s\n",
log_session_addresses(pdu->tDomain, addr_pair, buf, sizeof(buf)), pdu->reqid,
snmp_pdu_type(pdu->command), get_version(pdu->version),
get_auth_error(view_parms->errorcode));
log_var_list(pdu);
return 0;
}
if (SNMP_MSG_GETBULK == pdu->command ||
SNMP_MSG_GETNEXT == pdu->command) {
/* Log possible invalid OID subtrees for GETNEXT and GETBULK request
* (e.g. "1.10" - outside the normal ISO MIB subtree)
*/
log_invalid_oid_trees(pdu);
}
return 0;
}
/*
* Register with 'SNMPD_CALLBACK_ACM_CHECK == minorId'
* This function is used to log SET requests (which are normally rejected)
*/
static int audit_callback_acm_check(int majorID, int minorID, void *serverarg,
void *clientarg)
{
struct view_parameters *view_parms =
(struct view_parameters *) serverarg;
netsnmp_pdu *pdu = view_parms->pdu;
DEBUGMSGTL(("helper:snmpAudit", "%s msg-type: %s errcode=%d minorID=%d\n",
__FUNCTION__, snmp_pdu_type(pdu->command), view_parms->errorcode, minorID));
if (SNMP_MSG_SET == pdu->command) {
char status_buf[LOG_BUF_STR];
snprintf(status_buf, LOG_BUF_STR,
" status:%s", get_auth_error(view_parms->errorcode));
log_pdu_header(pdu, status_buf);
log_var_list(pdu);
}
return 0;
}
/* Main log handler function: logs 'normal' requests:
* everything except SET operations, authentication errors and GETBULK/GETNEXT for invalid OIDs */
static int audit_log_handler(netsnmp_mib_handler *handler,
netsnmp_handler_registration *reginfo,
netsnmp_agent_request_info *reqinfo,
netsnmp_request_info *requests)
{
static audit_req_t req = {
.transid = 0,
.reqid = 0
};
netsnmp_pdu *orig_pdu = reqinfo->asp->orig_pdu;
int ret;
/* Note. Assumes single-threaded processing. */
if ((req.transid != orig_pdu->transid) &&
(req.reqid != orig_pdu->reqid)) {
/* New transaction */
req.transid = orig_pdu->transid;
req.reqid = orig_pdu->reqid;
/* Logs session information (e.g. IP addresses, version...) */
log_pdu_header(orig_pdu, "");
/* Logs the variables names in the request */
log_var_list(orig_pdu);
}
/* Calls the next handlers, to obtain processing results */
ret = netsnmp_call_next_handler(handler, reginfo, reqinfo, requests);
/* Logs the variables names in the results
* resulted from the calls to 'netsnmp_call_next_handler' above
* which invokes all other handlers in the chain.
*/
log_results(orig_pdu->reqid, requests);
return ret;
}
/*
* Initialization routine, automatically called by the agent
* (to get called, the function name must match init_FILENAME())
*/
extern "C" void init_snmpAuditPlugin(void) {
netsnmp_mib_handler *audit_handler = NULL;
snmp_log(LOG_INFO, "init_snmpAuditPlugin\n");
audit_handler = netsnmp_create_handler("snmpAudit",
audit_log_handler);
if (audit_handler != NULL) {
netsnmp_register_handler_by_name("snmpAudit", audit_handler);
}
netsnmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK,
audit_callback_acm_check,
NULL, NETSNMP_CALLBACK_LOWEST_PRIORITY );
netsnmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK_INITIAL,
audit_callback_acm_check_initial,
NULL, NETSNMP_CALLBACK_LOWEST_PRIORITY);
}
extern "C" void deinit_snmpAuditPlugin(void)
{
snmp_log(LOG_INFO, "deinit_snmpAuditPlugin\n");
snmp_unregister_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK,
audit_callback_acm_check, NULL, 1);
snmp_unregister_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK_INITIAL,
audit_callback_acm_check_initial, NULL, 1);
}

View File

@ -0,0 +1,3 @@
SRC_DIR="sources"
COPY_LIST="mibs/*"
TIS_PATCH_VER=1

View File

@ -0,0 +1,82 @@
Summary: CGTS Platform SNMP extension Package
Name: snmp-ext
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
BuildRequires: fm-common-dev
BuildRequires: net-snmp-devel
BuildRequires: libuuid-devel
Requires: fm-common
Requires: net-snmp
Source1: wrsAlarmMib.mib.txt
Source2: wrsEnterpriseReg.mib.txt
%define mib_ver 2.0
%define cgcs_sdk_deploy_dir /opt/deploy/cgcs_sdk
%description
Titanium Cloud platform SNMP extension provides Wind River enterprise MIBs support
and it serves as SNMP based alarm surveillance module for Network Manager
System.
%package -n snmp-ext-devel
Summary: Titanium Cloud Platform SNMP extension Package - Development files
Group: devel
Requires: snmp-ext = %{version}-%{release}
%description -n snmp-ext-devel
Titanium Cloud platform SNMP extension provides Wind River enterprise MIBs support
and it serves as SNMP based alarm surveillance module for Network Manager
System. This package contains symbolic links, header files, and related
items necessary for software development.
%package -n %{name}-cgts-sdk
Summary: Titanium Cloud Platform SNMP extension Package - SDK
Group: devel
%description -n %{name}-cgts-sdk
%prep
%setup
%build
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
PATCHVER=` echo %{release} | awk -F r '{print $2}' | awk -F . '{print $1}'`
make MAJOR=$MAJOR MINOR=$MINOR PATCH=$PATCHVER %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
VER=%{version}
MAJOR=`echo $VER | awk -F . '{print $1}'`
MINOR=`echo $VER | awk -F . '{print $2}'`
PATCHVER=` echo %{release} | awk -F r '{print $2}' | awk -F . '{print $1}'`
make DEST_DIR=$RPM_BUILD_ROOT LIB_DIR=%{_libdir} MAJOR=$MAJOR MINOR=$MINOR PATCH=$PATCHVER install_non_bb
MIBDIR=wrs-snmp-mib-${MAJOR}.%{mib_ver}
mkdir -p $RPM_BUILD_ROOT%{_datadir}/snmp/mibs
install -m 644 %{SOURCE1} $RPM_BUILD_ROOT%{_datadir}/snmp/mibs
install -m 644 %{SOURCE2} $RPM_BUILD_ROOT%{_datadir}/snmp/mibs
tar -zc --transform=s/^mibs/${MIBDIR}/ -f wrs-snmp-mib-${MAJOR}.%{mib_ver}.tgz -C $RPM_BUILD_ROOT%{_datadir}/snmp mibs
mkdir -p $RPM_BUILD_ROOT%{cgcs_sdk_deploy_dir}
install -m 644 wrs-snmp-mib-${MAJOR}.%{mib_ver}.tgz $RPM_BUILD_ROOT%{cgcs_sdk_deploy_dir}
%files
%defattr(-,root,root,-)
%doc LICENSE
%{_libdir}/*.so.*
%{_datadir}/snmp/mibs/*
%files -n snmp-ext-devel
%defattr(-,root,root,-)
%{_libdir}/*.so
%files -n %{name}-cgts-sdk
%{cgcs_sdk_deploy_dir}/wrs-snmp-mib-*.%{mib_ver}.tgz

View File

@ -0,0 +1,818 @@
WRS-ALARM-MIB
DEFINITIONS ::= BEGIN
IMPORTS
wrsAlarms, WrsUUID, WrsBoolean FROM WRS-ENTERPRISE-REG-MIB
NOTIFICATION-GROUP, OBJECT-GROUP, MODULE-COMPLIANCE
FROM SNMPv2-CONF
DateAndTime, DisplayString, TEXTUAL-CONVENTION
FROM SNMPv2-TC
MODULE-IDENTITY, OBJECT-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, Unsigned32
FROM SNMPv2-SMI;
wrsAlarmMIB MODULE-IDENTITY
LAST-UPDATED "201703310000Z"
ORGANIZATION "Wind River Systems, Inc."
CONTACT-INFO "Wind River Systems, Inc.
500 Wind River Way
Alameda, CA 94501, USA
Contact : Wind River Systems Support
E-mail: support@windriver.com
Phone : 510.748.4100"
DESCRIPTION "This module contains objects of the
Titanium Cloud Alarm MIB,
including notifications."
-- Revision history
REVISION "201703310000Z"
DESCRIPTION "Titanium Cloud Release 4 version, with new Event table and removal of deprecated customer and alarm history tables."
::= { wrsAlarms 1 }
wrsAlarmObjects OBJECT IDENTIFIER ::= { wrsAlarmMIB 1 }
wrsAlarmConformance OBJECT IDENTIFIER ::= { wrsAlarmMIB 2 }
wrsAlarmCompliances OBJECT IDENTIFIER ::= { wrsAlarmConformance 1 }
wrsAlarmGroups OBJECT IDENTIFIER ::= { wrsAlarmConformance 2 }
-- Textual Conventions
WrsAlarmSeverity ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION "The severity of the alarm."
SYNTAX INTEGER
{
not-applicable (0),
warning (1),
minor (2),
major (3),
critical (4)
}
WrsAlarmState ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION "The state of the alarm."
SYNTAX INTEGER
{
clear (0),
set (1),
log (3)
}
WrsAlarmId ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION "An ID identifying the particular Alarm condition.
Typically used as an index for looking up Alarm details
in a System's Alarm Document.
This will be a structured ID, in order to allow grouping of
Alarms into general categories and allow specific Alarms to
be independently added and numbered within the group.
e.g. <Alarm Group ID>.<Alarm Event ID>
where <Alarm Group ID> = 000 - 999
<Alarm Event ID> = 000 - 999
NOTE: the { alarm-id, entity-instance-id } uniquely identifies an ACTIVE Alarm.
e.g.
- an alarm is cleared based on the matching { alarm-id, entity-instance-id },
- consecutive sets of an alarm with matching { alarm-id, entity-instance-id }
updates the fields of the single ACTIVE Alarm.
E.g. updates severity for example. "
SYNTAX OCTET STRING (SIZE (0..7))
WrsAlarmEntityInstanceId ::= TEXTUAL-CONVENTION
DISPLAY-HINT "255a"
STATUS current
DESCRIPTION "This is a textual description of the resource under alarm.
A '.' separated list of sub-entity-type=instance-value pairs,
representing the containment structure of the overall entity
instance.
Can be larger than 256 bytes.
Note that this containment structure will be used for
processing hierarchical clears.
e.g
system=ironpass1-4
system=ironpass1-4 . host=compute-0
system=ironpass1-4 . host=compute-0 . port=eth0
system=ironpass1-4 . host=compute-0 . disk=/dev/sda
system=ironpass1-4 . instance=vyatta_rtr_0
system=ironpass1-4 . stack=vyatta_scaling_rtrs
NOTE: the { alarm-id, entity-instance-id } uniquely identifies an ACTIVE Alarm.
e.g.
- an alarm is cleared based on the matching { alarm-id, entity-instance-id },
- consecutive sets of an alarm with matching { alarm-id, entity-instance-id }
updates the fields of the single ACTIVE Alarm.
E.g. updates severity for example."
SYNTAX OCTET STRING
WrsAlarmText ::= TEXTUAL-CONVENTION
DISPLAY-HINT "255a"
STATUS current
DESCRIPTION "Variable length string to encapsulate alarm or message
information from the entity raising the trap.
Can be larger than 256 bytes."
SYNTAX OCTET STRING
WrsAlarmProbableCause ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION
"ITU-T probable cause values. Duplicate values defined in
X.733 are appended with X733 to ensure syntactic uniqueness.
Probable cause value 0 is reserved for special purposes.
The Internet Assigned Number Authority (IANA) is responsible
for the assignment of the enumerations in this TC.
IANAItuProbableCause value of 0 is reserved for special
purposes and MUST NOT be assigned.
Values of IANAItuProbableCause in the range 1 to 1023 are
reserved for causes that correspond to ITU-T probable cause.
All other requests for new causes will be handled on a
first-come, first served basis and will be assigned
enumeration values starting with 1025.
Request should come in the form of well-formed
SMI [RFC2578] for enumeration names that are unique and
sufficiently descriptive.
While some effort will be taken to ensure that new probable
causes do not conceptually duplicate existing probable
causes it is acknowledged that the existence of conceptual
duplicates in the starting probable cause list is an known
industry reality.
To aid IANA in the administration of probable cause names
and values, the OPS Area Director will appoint one or more
experts to help review requests.
See http://www.iana.org"
REFERENCE
"ITU Recommendation M.3100, 'Generic Network Information
Model', 1995
ITU Recommendation X.733, 'Information Technology - Open
Systems Interconnection - System Management: Alarm
Reporting Function', 1992
ITU Recommendation X.736, 'Information Technology - Open
Systems Interconnection - System Management: Security
Alarm Reporting Function', 1992"
SYNTAX INTEGER
{
not-applicable (0),
-- The following probable causes were defined in M.3100
adaptor-error (1),
application-subsystem-failure (2),
bandwidth-reduced (3),
call-establishment-error (4),
communication-protocol-error (5),
communication-subsystem-failure (6),
configuration-or-customization-error (7),
congestion (8),
corrupt-data (9),
cpu-cycles-limit-exceeded (10),
dataset-or-modem-error (11),
degraded-signal (12),
dte-dce-interface-error (13),
enclosure-door-open (14),
equipment-malfunction (15),
excessive-vibration (16),
file-error (17),
fire-detected (18),
flood-detected (19),
framing-error (20),
heating-ventilation-cooling-system-problem (21),
humidity-unacceptable (22),
io-device-error (23),
input-device-error (24),
lan-error (25),
leak-detected (26),
local-node-transmission-error (27),
loss-of-frame (28),
loss-of-signal (29),
material-supply-exhausted (30),
multiplexer-problem (31),
out-of-memory (32),
output-device-error (33),
performance-degraded (34),
power-problem (35),
processor-problem (36),
pump-failure (37),
queue-size-exceeded (38),
receive-failure (39),
receiver-failure (40),
remote-node-transmission-error (41),
resource-at-or-nearing-capacity (42),
response-time-excessive (43),
retransmission-rate-excessive (44),
software-error (45),
software-program-abnormally-terminated (46),
software-program-error (47),
storage-capacity-problem (48),
temperature-unacceptable (49),
threshold-crossed (50),
timing-problem (51),
toxic-leak-detected (52),
transmit-failure (53),
transmitter-failure (54),
underlying-resource-unavailable (55),
version-mismatch (56),
duplicate-information (57),
information-missing (58),
information-modification-detected (59),
information-out-of-sequence (60),
unexpected-information (61),
denial-of-service (62),
out-of-service (63),
procedural-error (64),
unspecified-reason (65),
cable-tamper (66),
intrusion-detection (67),
authentication-failure (68),
breach-of-confidentiality (69),
non-repudiation-failure (70),
unauthorized-access-attempt (71),
delayed-information (72),
key-expired (73),
out-of-hours-activity (74)
}
WrsAlarmEventType ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION
"The ITU event Type values.
The Internet Assigned Number Authority (IANA) is
responsible for the assignment of the enumerations
in this TC.
Request should come in the form of well-formed
SMI [RFC2578] for enumeration names that are unique
and sufficiently descriptive.
See http://www.iana.org "
REFERENCE
"ITU Recommendation X.736, 'Information Technology - Open
Systems Interconnection - System Management: Security
Alarm Reporting Function', 1992"
SYNTAX INTEGER
{
other (0),
communicationsAlarm (1),
qualityOfServiceAlarm (2),
processingErrorAlarm (3),
equipmentAlarm (4),
environmentalAlarm (5),
integrityViolation (6),
operationalViolation (7),
physicalViolation (8),
securityServiceOrMechanismViolation (9),
timeDomainViolation (10)
}
-- Wind River Systems Active Alarm Table
wrsAlarmActiveTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrsAlarmActiveEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "This table contains information about active alarms."
::= { wrsAlarmObjects 1 }
wrsAlarmActiveEntry OBJECT-TYPE
SYNTAX WrsAlarmActiveEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "An active alarm entry"
INDEX { wrsAlarmActiveIndex }
::= { wrsAlarmActiveTable 1 }
WrsAlarmActiveEntry ::= SEQUENCE {
wrsAlarmActiveIndex Unsigned32,
wrsAlarmActiveUuid DisplayString,
wrsAlarmActiveAlarmId WrsAlarmId,
wrsAlarmActiveEntityInstanceId WrsAlarmEntityInstanceId,
wrsAlarmActiveDateAndTime DateAndTime,
wrsAlarmActiveAlarmSeverity WrsAlarmSeverity,
wrsAlarmActiveReasonText WrsAlarmText,
wrsAlarmActiveEventType WrsAlarmEventType,
wrsAlarmActiveProbableCause WrsAlarmProbableCause,
wrsAlarmActiveProposedRepairAction WrsAlarmText,
wrsAlarmActiveServiceAffecting WrsBoolean,
wrsAlarmActiveSuppressionAllowed WrsBoolean
}
wrsAlarmActiveIndex OBJECT-TYPE
SYNTAX Unsigned32 (1..4294967295)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "The index of the Active Alarm in the Active Alarm Table."
::= { wrsAlarmActiveEntry 1 }
wrsAlarmActiveUuid OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION "An ID identifying the active alarm instance in the Active Alarm Table."
::= { wrsAlarmActiveEntry 2 }
wrsAlarmActiveAlarmId OBJECT-TYPE
SYNTAX WrsAlarmId
MAX-ACCESS read-only
STATUS current
DESCRIPTION "An ID identifying the particular Alarm condition.
Typically used as an index for looking up Alarm details
in a System's Alarm Document.
This will be a structured ID, in order to allow grouping of
Alarms into general categories and allow specific Alarms to
be independently added and numbered within the group.
e.g. <Alarm Group ID>.<Alarm Event ID>
where <Alarm Group ID> = 000 - 999
<Alarm Event ID> = 000 - 999
NOTE: the { alarm-id, entity-instance-id } uniquely identifies an ACTIVE Alarm.
e.g.
- an alarm is cleared based on the matching { alarm-id, entity-instance-id },
- consecutive sets of an alarm with matching { alarm-id, entity-instance-id }
updates the fields of the single ACTIVE Alarm.
E.g. updates severity for example. "
::= { wrsAlarmActiveEntry 3 }
wrsAlarmActiveEntityInstanceId OBJECT-TYPE
SYNTAX WrsAlarmEntityInstanceId
MAX-ACCESS read-only
STATUS current
DESCRIPTION "This is a textual description of the resource under alarm.
A '.' separated list of sub-entity-type=instance-value pairs,
representing the containment structure of the overall entity
instance.
Note that this containment structure will be used for
processing hierarchical clears.
e.g
system=ironpass1-4
system=ironpass1-4 . host=compute-0
system=ironpass1-4 . host=compute-0 . port=eth0
system=ironpass1-4 . host=compute-0 . disk=/dev/sda
system=ironpass1-4 . instance=vyatta_rtr_0
system=ironpass1-4 . stack=vyatta_scaling_rtrs
NOTE: the { alarm-id, entity-instance-id } uniquely identifies an ACTIVE Alarm.
e.g.
- an alarm is cleared based on the matching { alarm-id, entity-instance-id },
- consecutive sets of an alarm with matching { alarm-id, entity-instance-id }
updates the fields of the single ACTIVE Alarm.
E.g. updates severity for example."
::= { wrsAlarmActiveEntry 4 }
wrsAlarmActiveDateAndTime OBJECT-TYPE
SYNTAX DateAndTime
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Provided in this table as a convenience. It is a copy of the Date and Time of the alarm."
::= { wrsAlarmActiveEntry 5}
wrsAlarmActiveAlarmSeverity OBJECT-TYPE
SYNTAX WrsAlarmSeverity
MAX-ACCESS read-only
STATUS current
DESCRIPTION "The severity of the alarm."
::= { wrsAlarmActiveEntry 6}
wrsAlarmActiveReasonText OBJECT-TYPE
SYNTAX WrsAlarmText
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Represents the per active alarm instance additional text field."
REFERENCE "ITU Recommendation M.3100, 'Generic Network Information Model', 1995
ITU Recommendation X.733, 'Information Technology - Open
Systems Interconnection - System Management: Alarm Reporting Function', 1992"
::= { wrsAlarmActiveEntry 7}
wrsAlarmActiveEventType OBJECT-TYPE
SYNTAX WrsAlarmEventType
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Represents the per active alarm instance event type values."
REFERENCE "ITU Recommendation M.3100, 'Generic Network Information Model', 1995
ITU Recommendation X.733, 'Information Technology - Open
Systems Interconnection - System Management: Alarm Reporting Function', 1992
ITU Recommendation X.736, 'Information Technology - Open
Systems Interconnection - System Management: Security
Alarm Reporting Function', 1992"
::= { wrsAlarmActiveEntry 8 }
wrsAlarmActiveProbableCause OBJECT-TYPE
SYNTAX WrsAlarmProbableCause
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Per active alarm instance ITU probable cause values."
REFERENCE "ITU Recommendation M.3100, 'Generic Network Information Model', 1995
ITU Recommendation X.733, 'Information Technology - Open
Systems Interconnection - System Management: Alarm Reporting Function', 1992
ITU Recommendation X.736, 'Information Technology - Open
Systems Interconnection - System Management: Security
Alarm Reporting Function', 1992"
::= { wrsAlarmActiveEntry 9 }
wrsAlarmActiveProposedRepairAction OBJECT-TYPE
SYNTAX WrsAlarmText
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Represents more of the per active alarm instance additional text field."
::= { wrsAlarmActiveEntry 10}
wrsAlarmActiveServiceAffecting OBJECT-TYPE
SYNTAX WrsBoolean
MAX-ACCESS read-only
STATUS current
DESCRIPTION "This attribute indicates whether the alarm is service affecting or not."
::= { wrsAlarmActiveEntry 11 }
wrsAlarmActiveSuppressionAllowed OBJECT-TYPE
SYNTAX WrsBoolean
MAX-ACCESS read-only
STATUS current
DESCRIPTION "This attribute indicates whether the alarm can be manually suppressed or not."
::= { wrsAlarmActiveEntry 12 }
-- Wind River Event Table
wrsEventTable OBJECT-TYPE
SYNTAX SEQUENCE OF WrsEventEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "This table contains information about events."
::= { wrsAlarmObjects 4 }
wrsEventEntry OBJECT-TYPE
SYNTAX WrsEventEntry
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "An event entry"
INDEX { wrsEventIndex }
::= { wrsEventTable 1 }
WrsEventEntry ::= SEQUENCE {
wrsEventIndex Unsigned32,
wrsEventUuid DisplayString,
wrsEventEventId WrsAlarmId,
wrsEventState WrsAlarmState,
wrsEventEntityInstanceId WrsAlarmEntityInstanceId,
wrsEventDateAndTime DateAndTime,
wrsEventSeverity WrsAlarmSeverity,
wrsEventReasonText WrsAlarmText,
wrsEventEventType WrsAlarmEventType,
wrsEventProbableCause WrsAlarmProbableCause,
wrsEventProposedRepairAction WrsAlarmText,
wrsEventServiceAffecting WrsBoolean,
wrsEventSuppressionAllowed WrsBoolean
}
wrsEventIndex OBJECT-TYPE
SYNTAX Unsigned32 (1..4294967295)
MAX-ACCESS not-accessible
STATUS current
DESCRIPTION "The index of the event in the Event Table."
::= { wrsEventEntry 1 }
wrsEventUuid OBJECT-TYPE
SYNTAX DisplayString
MAX-ACCESS read-only
STATUS current
DESCRIPTION "An ID identifying the event instance in the Event Table."
::= { wrsEventEntry 2 }
wrsEventEventId OBJECT-TYPE
SYNTAX WrsAlarmId
MAX-ACCESS read-only
STATUS current
DESCRIPTION "An ID identifying the particular Event condition.
Typically used as an index for looking up Event details
in a System's Event Document.
This will be a structured ID, in order to allow grouping of
Events into general categories and allow specific Event to
be independently added and numbered within the group.
e.g. <Event Group ID>.<Event Event ID>
where <Event Group ID> = 000 - 999
<Event Event ID> = 000 - 999 "
::= { wrsEventEntry 3 }
wrsEventState OBJECT-TYPE
SYNTAX WrsAlarmState
MAX-ACCESS read-only
STATUS current
DESCRIPTION "The state of the event.
For Customer log events, this field is set to LOG. The attributes that are applicable for a LOG state are:
State, EventId, EntityInstanceId, DateAndTime, Severity, ReasonText, EventType, ProbableCause, ServiceAffecting
"
::= { wrsEventEntry 4 }
wrsEventEntityInstanceId OBJECT-TYPE
SYNTAX WrsAlarmEntityInstanceId
MAX-ACCESS read-only
STATUS current
DESCRIPTION "This is a textual description of the resource under event.
A '.' separated list of sub-entity-type=instance-value pairs,
representing the containment structure of the overall entity
instance.
e.g
system=ironpass1-4
system=ironpass1-4 . host=compute-0
system=ironpass1-4 . host=compute-0 . port=eth0
system=ironpass1-4 . host=compute-0 . disk=/dev/sda
system=ironpass1-4 . instance=vyatta_rtr_0
system=ironpass1-4 . stack=vyatta_scaling_rtrs"
::= { wrsEventEntry 5 }
wrsEventDateAndTime OBJECT-TYPE
SYNTAX DateAndTime
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Provided in this table as a convenience. It is the event last update Date and Time ."
::= { wrsEventEntry 6 }
wrsEventSeverity OBJECT-TYPE
SYNTAX WrsAlarmSeverity
MAX-ACCESS read-only
STATUS current
DESCRIPTION "The severity of the Event."
::= { wrsEventEntry 7 }
wrsEventReasonText OBJECT-TYPE
SYNTAX WrsAlarmText
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Represents the per Event instance additional text field."
REFERENCE "ITU Recommendation M.3100, 'Generic Network Information Model', 1995
ITU Recommendation X.733, 'Information Technology - Open
Systems Interconnection - System Management: Alarm Reporting Function', 1992"
::= { wrsEventEntry 8 }
wrsEventEventType OBJECT-TYPE
SYNTAX WrsAlarmEventType
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Represents the per Event instance event type values."
REFERENCE "ITU Recommendation M.3100, 'Generic Network Information Model', 1995
ITU Recommendation X.733, 'Information Technology - Open
Systems Interconnection - System Management: Alarm Reporting Function', 1992
ITU Recommendation X.736, 'Information Technology - Open
Systems Interconnection - System Management: Security
Alarm Reporting Function', 1992"
::= { wrsEventEntry 9 }
wrsEventProbableCause OBJECT-TYPE
SYNTAX WrsAlarmProbableCause
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Per Event instance ITU probable cause values."
REFERENCE "ITU Recommendation M.3100, 'Generic Network Information Model', 1995
ITU Recommendation X.733, 'Information Technology - Open
Systems Interconnection - System Management: Alarm Reporting Function', 1992
ITU Recommendation X.736, 'Information Technology - Open
Systems Interconnection - System Management: Security
Alarm Reporting Function', 1992"
::= { wrsEventEntry 10 }
wrsEventProposedRepairAction OBJECT-TYPE
SYNTAX WrsAlarmText
MAX-ACCESS read-only
STATUS current
DESCRIPTION "Represents more of the per historical alarm instance additional text field.
Applies to alarms only."
::= { wrsEventEntry 11}
wrsEventServiceAffecting OBJECT-TYPE
SYNTAX WrsBoolean
MAX-ACCESS read-only
STATUS current
DESCRIPTION "This attribute indicates whether the Event is service affecting or not."
::= { wrsEventEntry 12 }
wrsEventSuppressionAllowed OBJECT-TYPE
SYNTAX WrsBoolean
MAX-ACCESS read-only
STATUS current
DESCRIPTION "This attribute indicates whether the alarm can be manually suppressed or not.
Applies to alarms only."
::= { wrsEventEntry 13 }
-- All notification OIDs would be prefixed with a zero OID to facilitate snmp v1<->v2 conversion
wrsTrapPrefix OBJECT-IDENTITY
STATUS current
DESCRIPTION "This OID represents the prefix branch for all WIND RIVER ITU Alarm Trap.
The last but one sub identifier in the OID of any Notification must have the value
zero to facilitate v2<-->v1 conversion."
::= {wrsAlarmObjects 0 }
-- Generic Severity-based Traps / Alarms
wrsAlarmCritical NOTIFICATION-TYPE
OBJECTS {
wrsAlarmActiveAlarmId,
wrsAlarmActiveEntityInstanceId,
wrsAlarmActiveDateAndTime,
wrsAlarmActiveAlarmSeverity,
wrsAlarmActiveReasonText,
wrsAlarmActiveEventType,
wrsAlarmActiveProbableCause,
wrsAlarmActiveProposedRepairAction,
wrsAlarmActiveServiceAffecting,
wrsAlarmActiveSuppressionAllowed
}
STATUS current
DESCRIPTION "This notification indicates that an alarm of 'Critical' severity
has been raised on the system.
The varbinds include details of the alarm."
::= { wrsTrapPrefix 1 }
wrsAlarmMajor NOTIFICATION-TYPE
OBJECTS {
wrsAlarmActiveAlarmId,
wrsAlarmActiveEntityInstanceId,
wrsAlarmActiveDateAndTime,
wrsAlarmActiveAlarmSeverity,
wrsAlarmActiveReasonText,
wrsAlarmActiveEventType,
wrsAlarmActiveProbableCause,
wrsAlarmActiveProposedRepairAction,
wrsAlarmActiveServiceAffecting,
wrsAlarmActiveSuppressionAllowed
}
STATUS current
DESCRIPTION "This notification indicates that an alarm of 'Major' severity
has been raised on the system.
The varbinds include details of the alarm."
::= { wrsTrapPrefix 2 }
wrsAlarmMinor NOTIFICATION-TYPE
OBJECTS {
wrsAlarmActiveAlarmId,
wrsAlarmActiveEntityInstanceId,
wrsAlarmActiveDateAndTime,
wrsAlarmActiveAlarmSeverity,
wrsAlarmActiveReasonText,
wrsAlarmActiveEventType,
wrsAlarmActiveProbableCause,
wrsAlarmActiveProposedRepairAction,
wrsAlarmActiveServiceAffecting,
wrsAlarmActiveSuppressionAllowed
}
STATUS current
DESCRIPTION "This notification indicates that an alarm of 'Minor' severity
has been raised on the system.
The varbinds include details of the alarm."
::= { wrsTrapPrefix 3 }
wrsAlarmWarning NOTIFICATION-TYPE
OBJECTS {
wrsAlarmActiveAlarmId,
wrsAlarmActiveEntityInstanceId,
wrsAlarmActiveDateAndTime,
wrsAlarmActiveAlarmSeverity,
wrsAlarmActiveReasonText,
wrsAlarmActiveEventType,
wrsAlarmActiveProbableCause,
wrsAlarmActiveProposedRepairAction,
wrsAlarmActiveServiceAffecting,
wrsAlarmActiveSuppressionAllowed
}
STATUS current
DESCRIPTION "This notification indicates that an alarm of 'Warning' severity
has been raised on the system.
The varbinds include details of the alarm."
::= { wrsTrapPrefix 4 }
wrsAlarmMessage NOTIFICATION-TYPE
OBJECTS {
wrsAlarmActiveAlarmId,
wrsAlarmActiveEntityInstanceId,
wrsAlarmActiveDateAndTime,
wrsAlarmActiveAlarmSeverity,
wrsAlarmActiveReasonText,
wrsAlarmActiveEventType,
wrsAlarmActiveProbableCause,
wrsAlarmActiveProposedRepairAction,
wrsAlarmActiveServiceAffecting,
wrsAlarmActiveSuppressionAllowed
}
STATUS current
DESCRIPTION "This notification indicates that a stateless message alarm
event has occurred on the system.
The varbinds include details of the alarm.
Note that these events are stored in the Customer Log Table."
::= { wrsTrapPrefix 5 }
wrsAlarmClear NOTIFICATION-TYPE
OBJECTS {
wrsAlarmActiveAlarmId,
wrsAlarmActiveEntityInstanceId,
wrsAlarmActiveDateAndTime,
wrsAlarmActiveReasonText
}
STATUS current
DESCRIPTION "This notification indicates that a previously
reported alarm have been cleared.
The previously reported alarm is identified by the
{ AlarmId, EntityInstanceId } tuple."
::= { wrsTrapPrefix 9 }
wrsAlarmHierarchicalClear NOTIFICATION-TYPE
OBJECTS {
wrsAlarmActiveEntityInstanceId,
wrsAlarmActiveDateAndTime,
wrsAlarmActiveReasonText
}
STATUS current
DESCRIPTION "This notification indicates that one or more previously
reported alarms have been cleared.
The previously reported alarms are identified by the
EntityInstanceId attribute.
ALL alarms against EntityInstanceId and all of its children
have been cleared."
::= { wrsTrapPrefix 99 }
-- Notification group definitions
wrsAlarmNotificationsGroup NOTIFICATION-GROUP
NOTIFICATIONS {
wrsAlarmClear,
wrsAlarmHierarchicalClear,
wrsAlarmMessage,
wrsAlarmWarning,
wrsAlarmMinor,
wrsAlarmMajor,
wrsAlarmCritical
}
STATUS current
DESCRIPTION "Wind River alarm notification group."
::= { wrsAlarmGroups 1}
wrsAlarmGroup OBJECT-GROUP
OBJECTS {
wrsAlarmActiveUuid,
wrsAlarmActiveAlarmId,
wrsAlarmActiveEntityInstanceId,
wrsAlarmActiveDateAndTime,
wrsAlarmActiveAlarmSeverity,
wrsAlarmActiveReasonText,
wrsAlarmActiveEventType,
wrsAlarmActiveProbableCause,
wrsAlarmActiveProposedRepairAction,
wrsAlarmActiveServiceAffecting,
wrsAlarmActiveSuppressionAllowed
}
STATUS current
DESCRIPTION "Wind River alarm group."
::= { wrsAlarmGroups 2}
-- Compliance
wrsAlarmCompliance MODULE-COMPLIANCE
STATUS current
DESCRIPTION "The compliance statement for entities which implement
the Wind River Alarm MIB."
MODULE -- this module
MANDATORY-GROUPS { wrsAlarmGroup
}
::= { wrsAlarmCompliances 1}
END

View File

@ -0,0 +1,132 @@
------------------------------------------------------------------------------
--
-- File : wrsEnterpriseReg.mib
-- Description : Wind River Enterprise Registration Hierarchy MIB
-- Version : 1.2.0
-- Date : June 2, 2017
-- OBSOLETES : wrsMasterMib.mib v0.6 (August 29, 2000)
--
-- Copyright (c) 2014-2017 Wind River Systems, Inc. All Rights Reserved.
--
-- This module defines the Wind River Systems (WRS) registration hierarchy,
--
-- The Wind River Systems registration tree is administered with the following
-- hierarchy:
-- iso(1).org(3).dod(6).internet(1).private(4).enterprise(1)
-- .wrs(731)
-- .wrs(731).wrsCommon(1)
-- .wrs(731).wrsCommon(1).wrs<Module>(1-...) ... cont'd in wrsCommon<Module>.mib
-- .wrs(731).wrs<Product>(2-...) ... cont'd in wrs<Product>.mib
--
-- Reproduction of this document is authorized on condition that this
-- copyright notice is included. This Wind River Enterprise Registration MIB
-- embodies proprietary intellectual property of Wind River Systems (WRS).
-- WRS retains all title and ownership in the specification, including any
-- revisions.
--
-- It is the intent of WRS to encourage the widespread use of this
-- specification in connection with the management of Wind River products.
-- WRS grants vendors, end-users, and other interested parties a
-- non-exclusive license to use this specification in connection with the
-- management of Wind River products.
--
-- This specification is supplied "AS IS", and WRS makes no warranty,
-- either express or implied, as to the use, operations, condition,
-- or performance of this specification.
--
------------------------------------------------------------------------------
WRS-ENTERPRISE-REG-MIB DEFINITIONS ::= BEGIN
IMPORTS
TEXTUAL-CONVENTION FROM SNMPv2-TC
MODULE-IDENTITY, enterprises FROM SNMPv2-SMI;
wrs MODULE-IDENTITY
LAST-UPDATED "201407100000Z" -- July 10, 2014
ORGANIZATION "Wind River Systems, Inc."
CONTACT-INFO "Wind River Systems, Inc.
500 Wind River Way
Alameda, CA 94501, USA
Contact: Wind River Systems Support
E-mail : support@windriver.com
Phone : 510.748.4100"
DESCRIPTION "This module defines the Wind River Systems, Inc. Registration hierarchy."
-- Revision history
REVISION "201407100000Z" -- July 10, 2014
DESCRIPTION "Initial Version of MIB."
::= { enterprises 731 }
-- WRS Common Enterprise MIB Modules
wrsCommon OBJECT IDENTIFIER ::= { wrs 1 }
wrsAlarms OBJECT IDENTIFIER ::= { wrsCommon 1 } -- Common WRS Enterprise Alarm MIB
-- WRS Products
-- tms1_0 OBJECT IDENTIFIER ::= { wrs 1 } Obsolete
tms OBJECT IDENTIFIER ::= { wrs 2 }
wrsTs OBJECT IDENTIFIER ::= { wrs 3 } -- WRS Titanium Cloud specific Enterprise MIBs
---------------------------------------------------------------------------
-- TMS OID Definitions
--
-- TMS Major MIB Categories
idb OBJECT IDENTIFIER ::= { tms 1 } -- IDB MIBs
tmsGeneric OBJECT IDENTIFIER ::= { tms 2 } -- TMS Generic MIBs
oemSwapi OBJECT IDENTIFIER ::= { tms 3 } -- OEM swAPI MIBs
oemProd OBJECT IDENTIFIER ::= { tms 4 } -- OEM Product MIBs
-- TMS IDB Internal Module MIBs
rmonMib OBJECT IDENTIFIER ::= { idb 1 }
-- garpMib OBJECT IDENTIFIER ::= { idb 2 } SMIv2
-- stpMib OBJECT IDENTIFIER ::= { idb 3 } SMIv2
-- TMS Generic MIBs
-- tmsCommonMib OBJECT IDENTIFIER ::= { tmsGeneric 1 } SMIv2
-- tmsL3Mib OBJECT IDENTIFIER ::= { tmsGeneric 2 } SMIv2
-- OEM swAPI MIBs
-- pmSwapi OBJECT IDENTIFIER ::= { oemSwapi 1 } SMIv2
-- bcmSwapi OBJECT IDENTIFIER ::= { oemSwapi 2 } SMIv2
-- pcSwapi OBJECT IDENTIFIER ::= { oemSwapi 3 } SMIv2
-- OEM Product MIBs
-- pm3575 OBJECT IDENTIFIER ::= { oemProd 1 } SMIv2
-- bcm5600 OBJECT IDENTIFIER ::= { oemProd 2 } SMIv2
-- pcSwitch OBJECT IDENTIFIER ::= { oemProd 3 } SMIv2
---------------------------------------------------------------------------
-- General Textual Conventions
--
WrsUUID ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION "Universally Unique IDentifier;
format is typically XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX ,
where X is a hex-digit."
SYNTAX OCTET STRING (SIZE (0..36))
WrsBoolean ::= TEXTUAL-CONVENTION
STATUS current
DESCRIPTION "Boolean type."
SYNTAX INTEGER
{
false (0),
true (1)
}
--
-- END of WRS-ENTERPRISE-REG-MIB
--
END

202
snmp-ext/sources/LICENSE Normal file
View File

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

25
snmp-ext/sources/Makefile Normal file
View File

@ -0,0 +1,25 @@
SRCS = cgtsActiveAlarms.c cgtsAgentPlugin.c cgtsEventLogs.c
OBJS = $(SRCS:.c=.o)
LDLIBS = -lfmcommon -lnetsnmp -lnetsnmpagent -luuid
INCLUDES += -I./
CCFLAGS = -fPIC -g -O2 -Wall -Werror
LIBCGTSAGENT_SO := libcgtsAgentPlugin.so
build: lib
.c.o:
$(CXX) $(CCFLAGS) $(INCLUDES) -c $< -o $@
lib: $(OBJS)
$(CXX) $(OBJS) $(LDLIBS) -o $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) -shared
ln -sf $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(LIBCGTSAGENT_SO).$(MAJOR)
ln -sf $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(LIBCGTSAGENT_SO)
clean:
@rm -f $(OBJ) *.o *.so.*
install_non_bb:
install -m 755 -d $(DEST_DIR)$(LIB_DIR)
install -m 755 $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(DEST_DIR)$(LIB_DIR)
ln -s $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(DEST_DIR)$(LIB_DIR)/$(LIBCGTSAGENT_SO).$(MAJOR)
ln -s $(LIBCGTSAGENT_SO).$(MAJOR).$(MINOR).$(PATCH) $(DEST_DIR)$(LIB_DIR)/$(LIBCGTSAGENT_SO)

View File

@ -0,0 +1,266 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <fmDbAPI.h>
#include "cgtsAgentPlugin.h"
netsnmp_feature_require(date_n_time)
#define MINLOADFREQ 1 /* min reload frequency in seconds */
static long Active_Alarm_Count = 0;
static struct activealarm *alarm_list;
static struct activealarm *alarmaddr, savealarm, *savealarmaddr;
static int saveIndex = 0;
static char saveUuid[36];
static long LastLoad = 0; /* ET in secs at last table load */
extern long long_return;
int Active_Alarm_Get_Count(void);
static void
Alarm_Scan_Init()
{
struct timeval et; /* elapsed time */
struct activealarm **activealarm_ptr;
SFmAlarmQueryT aquery;
size_t i = 0;
saveIndex = 0;
netsnmp_get_monotonic_clock(&et);
if ( et.tv_sec < LastLoad + MINLOADFREQ ) {
DEBUGMSG(("cgtsAgentPlugin", "Skip reload" ));
alarmaddr = alarm_list;
return;
}
LastLoad = et.tv_sec;
/*
* free old list:
*/
while (alarm_list) {
struct activealarm *old = alarm_list;
alarm_list = alarm_list->next;
free(old);
}
alarmaddr = 0;
activealarm_ptr = &alarm_list;
/*
* query active alarm list from DB
*/
if (fm_snmp_util_get_all_alarms(getAlarmSession(), &aquery) != true){
DEBUGMSG(("cgtsAgentPlugin", "get_all_alarms from db failed\n"));
return;
}
DEBUGMSG(("cgtsAgentPlugin", "get_all_alarms returns %lu alarms\n", aquery.num));
for (i = 0; i < aquery.num; ++i){
struct activealarm *almnew;
/*populate alarm_list*/
almnew = (struct activealarm *) calloc(1, sizeof(struct activealarm));
if (almnew == NULL)
break; /* alloc error */
*activealarm_ptr = almnew;
activealarm_ptr = &almnew->next;
memset(&almnew->alarmdata, 0 , sizeof(almnew->alarmdata));
memcpy(&almnew->alarmdata, aquery.alarm + i, sizeof(almnew->alarmdata));
}
alarmaddr = alarm_list;
free(aquery.alarm);
}
static int
Alarm_Scan_NextAlarm(int *Index,
char *Name,
struct activealarm *Aalm)
{
struct activealarm alm;
while (alarmaddr) {
alm = *alarmaddr;
strlcpy(saveUuid, alm.alarmdata.uuid, sizeof(saveUuid));
if (Index)
*Index = ++saveIndex;
if (Aalm)
*Aalm = alm;
if (Name)
strcpy(Name, saveUuid);
savealarm = alm;
savealarmaddr = alarmaddr;
alarmaddr = alm.next;
return 1;
}
return 0;
}
static int
Alarm_Scan_By_Index(int Index,
char *Name,
struct activealarm *Aalm)
{
int i;
DEBUGMSGTL(("cgtsAgentPlugin","Alarm_Scan_By_Index"));
Alarm_Scan_Init();
while (Alarm_Scan_NextAlarm(&i, Name, Aalm)) {
if (i == Index)
break;
}
if (i != Index)
return (-1); /* Error, doesn't exist */
return (0); /* DONE */
}
static int
header_alarmEntry(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len,
WriteMethod ** write_method)
{
#define ALM_ENTRY_NAME_LENGTH 14
oid newname[MAX_OID_LEN];
register int index;
int result, count;
DEBUGMSGTL(("cgtsAgentPlugin", "header_alarmEntry: "));
DEBUGMSGOID(("cgtsAgentPlugin", name, *length));
DEBUGMSG(("cgtsAgentPlugin", "exact %d\n", exact));
memcpy((char *) newname, (char *) vp->name,
(int) vp->namelen * sizeof(oid));
/*
* find "next" alarm
*/
count = Active_Alarm_Get_Count();
DEBUGMSG(("cgtsAgentPlugin", "count %d\n", count));
for (index = 1; index <= count; index++) {
newname[ALM_ENTRY_NAME_LENGTH] = (oid) index;
result =
snmp_oid_compare(name, *length, newname,
(int) vp->namelen + 1);
if ((exact && (result == 0)) || (!exact && (result < 0)))
break;
}
if (index > count) {
DEBUGMSGTL(("cgtsAgentPlugin", "... index out of range\n"));
return MATCH_FAILED;
}
memcpy((char *) name, (char *) newname,
((int) vp->namelen + 1) * sizeof(oid));
*length = vp->namelen + 1;
*write_method = 0;
*var_len = sizeof(long); /* default to 'long' results */
DEBUGMSGTL(("cgtsAgentPlugin", "... get ALM data "));
DEBUGMSGOID(("cgtsAgentPlugin", name, *length));
DEBUGMSG(("cgtsAgentPlugin", "\n"));
DEBUGMSG(("cgtsAgentPlugin","Return index: %d\n", index));
return index;
}
int
Active_Alarm_Get_Count(void)
{
static time_t scan_time = 0;
time_t time_now = time(NULL);
if (!Active_Alarm_Count || (time_now > scan_time + 60)) {
scan_time = time_now;
Alarm_Scan_Init();
Active_Alarm_Count = 0;
while (Alarm_Scan_NextAlarm(NULL, NULL, NULL) != 0) {
Active_Alarm_Count++;
}
}
return (Active_Alarm_Count);
}
u_char *
var_alarms(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len,
WriteMethod ** write_method)
{
static struct activealarm alrm;
static char Name[36];
char *cp;
int index = 0;
DEBUGMSGTL(("cgtsAgentPlugin", "var_alarms"));
index = header_alarmEntry(vp, name, length, exact, var_len, write_method);
if (index == MATCH_FAILED)
return NULL;
Alarm_Scan_By_Index(index, Name, &alrm);
switch (vp->magic) {
case ALARM_INDEX:
long_return = index;
return (u_char *) & long_return;
case ALARM_UUID:
cp = Name;
*var_len = strlen(cp);
return (u_char *) cp;
case ALARM_ID:
cp = alrm.alarmdata.alarm_id;
*var_len = strlen(cp);
return (u_char *) cp;
case ALARM_INSTANCE_ID:
cp = alrm.alarmdata.entity_instance_id;
*var_len = strlen(cp);
return (u_char *) cp;
case ALARM_TIME:{
time_t when = alrm.alarmdata.timestamp/SECOND_PER_MICROSECOND;
cp = (char *) date_n_time(&when, var_len );
return (u_char *) cp;
}
case ALARM_SEVERITY:
long_return = alrm.alarmdata.severity;
return (u_char *) & long_return;
case ALARM_REASONTEXT:
cp = alrm.alarmdata.reason_text;
*var_len = strlen(cp);
return (u_char *) cp;
case ALARM_EVENTTYPE:
long_return = alrm.alarmdata.alarm_type;
return (u_char *) & long_return;
case ALARM_PROBABLECAUSE:
long_return = alrm.alarmdata.probable_cause;
return (u_char *) & long_return;
case ALARM_REPAIRACTION:
cp = alrm.alarmdata.proposed_repair_action;
*var_len = strlen(cp);
return (u_char *) cp;
case ALARM_SERVICEAFFECTING:
long_return = alrm.alarmdata.service_affecting;
return (u_char *) & long_return;
case ALARM_SUPPRESSION:
long_return = alrm.alarmdata.suppression;
return (u_char *) & long_return;
default:
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_alarms\n",
vp->magic));
}
return NULL;
}

View File

@ -0,0 +1,164 @@
/*
* Copyright (c) 2016 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <stdbool.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include "cgtsAgentPlugin.h"
#define CGTS_ALM_TABLE_NAME "wrsAlarmActiveTable"
#define CGTS_EVENT_TABLE_NAME "wrsEventTable"
#define _UNREGISTER_MIB(var, miboid) \
do{ \
size_t varsize = sizeof(struct variable2); \
struct variable2 *vp; \
oid myoid[MAX_OID_LEN]; \
size_t length; \
int i, result; \
int numvars = sizeof(var)/varsize; \
int miboidlen = sizeof(miboid)/sizeof(oid); \
for (i=0; i < numvars; i++) { \
vp = (struct variable2 *)((char *)var + varsize * i); \
memcpy(myoid, miboid, miboidlen * sizeof(oid)); \
memcpy(myoid+miboidlen, vp->name, vp->namelen * sizeof(oid)); \
length = miboidlen + vp->namelen; \
result = unregister_mib(myoid, length); \
DEBUGMSGOID(("cgtsAgentPlugin", myoid, length)); \
if (result != MIB_UNREGISTERED_OK) { \
snmp_log(LOG_ERR, "%s: Unregistering failed:%d\n", \
__FUNCTION__, result); \
} else { \
DEBUGMSGTL(("cgtsAgentPlugin", "Unregistering succeeded\n")); \
} \
} \
}while(0);
static TFmAlarmSessionT alm_handle;
/*
* * the OID we want to register our integer at. This should be the
* * OID node for the entire table. In our case this is the
* * wrsAlarmActiveTable oid definition
*/
oid cgtsAlarmTable_oid[] =
{ 1, 3, 6, 1, 4, 1, 731, 1, 1, 1, 1, 1};
oid cgtsEventLogTable_oid[] =
{ 1, 3, 6, 1, 4, 1, 731, 1, 1, 1, 1, 4};
struct variable2 alarm_variables[] = {
{ALARM_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 1}},
{ALARM_UUID, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 2}},
{ALARM_ID, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 3}},
{ALARM_INSTANCE_ID, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 4}},
{ALARM_TIME, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 5}},
{ALARM_SEVERITY, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 6}},
{ALARM_REASONTEXT, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 7}},
{ALARM_EVENTTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 8}},
{ALARM_PROBABLECAUSE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 9}},
{ALARM_REPAIRACTION , ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 10}},
{ALARM_SERVICEAFFECTING, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 11}},
{ALARM_SUPPRESSION, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_alarms, 2, {1, 12}},
};
struct variable2 event_log_variables[] = {
{EVENT_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 1}},
{EVENT_UUID, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 2}},
{EVENT_EVENT_ID, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 3}},
{EVENT_STATE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 4}},
{EVENT_INSTANCE_ID, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 5}},
{EVENT_TIME, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 6}},
{EVENT_SEVERITY, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 7}},
{EVENT_REASONTEXT, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 8}},
{EVENT_EVENTTYPE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 9}},
{EVENT_PROBABLECAUSE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 10}},
{EVENT_REPAIRACTION , ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 11}},
{EVENT_SERVICEAFFECTING, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 12}},
{EVENT_SUPPRESSION, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_events, 2, {1, 13}},
};
TFmAlarmSessionT getAlarmSession()
{
return alm_handle;
}
/*
* our initialization routine, automatically called by the agent
* (to get called, the function name must match init_FILENAME())
*/
void
init_cgtsAgentPlugin(void)
{
snmp_log(LOG_INFO,"init_cgtsAgentPlugin start");
snmp_log(LOG_INFO,"MIB registration: %s",CGTS_ALM_TABLE_NAME);
REGISTER_MIB(CGTS_ALM_TABLE_NAME, alarm_variables,
variable2, cgtsAlarmTable_oid);
snmp_log(LOG_INFO,"MIB registration: %s",CGTS_EVENT_TABLE_NAME);
REGISTER_MIB(CGTS_EVENT_TABLE_NAME, event_log_variables,
variable2, cgtsEventLogTable_oid);
snmp_log(LOG_INFO,"get alarm database handler");
if (fm_snmp_util_create_session(&alm_handle, NULL) != true){
snmp_log(LOG_ERR,"failed to get alarm database handler");
exit(-1);
}
/*
* a debugging statement. Run the agent with -DcgtsAgentPlugin to see
* the output of this debugging statement.
*/
DEBUGMSGTL(("cgtsAgentPlugin", "Done initializing.\n"));
}
void
deinit_cgtsAgentPlugin(void)
{
snmp_log(LOG_INFO,"deinit_cgtsAgentPlugin start");
_UNREGISTER_MIB(alarm_variables, cgtsAlarmTable_oid);
_UNREGISTER_MIB(event_log_variables, cgtsEventLogTable_oid);
fm_snmp_util_destroy_session(alm_handle);
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#ifndef CGTSAGENTPLUGIN_H
#define CGTSAGENTPLUGIN_H
#include <fmAPI.h>
#include <fmDbAPI.h>
#include <net-snmp/agent/snmp_vars.h>
extern FindVarMethod var_alarms;
extern FindVarMethod var_events;
/* Active alarm Table */
#define ALARM_INDEX 1
#define ALARM_UUID 2
#define ALARM_ID 3
#define ALARM_INSTANCE_ID 4
#define ALARM_TIME 5
#define ALARM_SEVERITY 6
#define ALARM_REASONTEXT 7
#define ALARM_EVENTTYPE 8
#define ALARM_PROBABLECAUSE 9
#define ALARM_REPAIRACTION 10
#define ALARM_SERVICEAFFECTING 11
#define ALARM_SUPPRESSION 12
/* Event Log Table */
#define EVENT_INDEX 1
#define EVENT_UUID 2
#define EVENT_EVENT_ID 3
#define EVENT_STATE 4
#define EVENT_INSTANCE_ID 5
#define EVENT_TIME 6
#define EVENT_SEVERITY 7
#define EVENT_REASONTEXT 8
#define EVENT_EVENTTYPE 9
#define EVENT_PROBABLECAUSE 10
#define EVENT_REPAIRACTION 11
#define EVENT_SERVICEAFFECTING 12
#define EVENT_SUPPRESSION 13
#define SECOND_PER_MICROSECOND 1000000
struct activealarm {
SFmAlarmDataT alarmdata;
struct activealarm *next;
};
/*
* function declarations
*/
#ifdef __cplusplus
extern "C" {
#endif
void init_cgtsAgentPlugin(void);
void deinit_cgtsAgentPlugin(void);
TFmAlarmSessionT getAlarmSession();
#ifdef __cplusplus
}
#endif
#endif /* CGTSAGENTPLUGIN_H */

View File

@ -0,0 +1,268 @@
/*
* Copyright (c) 2013-2016 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <fmDbAPI.h>
#include "cgtsAgentPlugin.h"
netsnmp_feature_require(date_n_time)
#define MINLOADFREQ 2 /* min reload frequency in seconds */
static long Event_Log_Count = 0;
static struct activealarm *alarm_list;
static struct activealarm *alarmaddr, savealarm, *savealarmaddr;
static int saveIndex = 0;
static char saveUuid[36];
static long LastLoad = 0; /* ET in secs at last table load */
extern long long_return;
int Event_Log_Get_Count(void);
static void
Event_Log_Scan_Init()
{
struct timeval et; /* elapsed time */
struct activealarm **activealarm_ptr;
SFmAlarmQueryT aquery;
size_t i = 0;
saveIndex = 0;
netsnmp_get_monotonic_clock(&et);
if ( et.tv_sec < LastLoad + MINLOADFREQ ) {
DEBUGMSG(("cgtsAgentPlugin", "Skip reload" ));
alarmaddr = alarm_list;
return;
}
LastLoad = et.tv_sec;
/*
* free old list:
*/
while (alarm_list) {
struct activealarm *old = alarm_list;
alarm_list = alarm_list->next;
free(old);
}
alarmaddr = 0;
activealarm_ptr = &alarm_list;
/*
* query event log list from DB
*/
if (fm_snmp_util_get_all_event_logs(getAlarmSession(), &aquery) != true){
DEBUGMSG(("cgtsAgentPlugin", "get_all_event_logs from db failed\n"));
return;
}
DEBUGMSG(("cgtsAgentPlugin", "get_all_event_logs returns %lu logs\n", aquery.num));
for (i = 0; i < aquery.num; ++i){
struct activealarm *almnew;
/*populate alarm_list*/
almnew = (struct activealarm *) calloc(1, sizeof(struct activealarm));
if (almnew == NULL)
break; /* alloc error */
*activealarm_ptr = almnew;
activealarm_ptr = &almnew->next;
memset(&almnew->alarmdata, 0 , sizeof(almnew->alarmdata));
memcpy(&almnew->alarmdata, aquery.alarm + i, sizeof(almnew->alarmdata));
}
alarmaddr = alarm_list;
free(aquery.alarm);
}
static int
Event_Log_Scan_NextLog(int *Index,
char *Name,
struct activealarm *Aalm)
{
struct activealarm alm;
while (alarmaddr) {
alm = *alarmaddr;
strlcpy(saveUuid, alm.alarmdata.uuid, sizeof(saveUuid));
if (Index)
*Index = ++saveIndex;
if (Aalm)
*Aalm = alm;
if (Name)
strcpy(Name, saveUuid);
savealarm = alm;
savealarmaddr = alarmaddr;
alarmaddr = alm.next;
return 1;
}
return 0;
}
static int
Event_Log_Scan_By_Index(int Index,
char *Name,
struct activealarm *Aalm)
{
int i;
DEBUGMSGTL(("cgtsAgentPlugin","Event_Log_Scan_By_Index"));
Event_Log_Scan_Init();
while (Event_Log_Scan_NextLog(&i, Name, Aalm)) {
if (i == Index)
break;
}
if (i != Index)
return (-1); /* Error, doesn't exist */
return (0); /* DONE */
}
static int
header_eventLogEntry(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len,
WriteMethod ** write_method)
{
#define ALM_ENTRY_NAME_LENGTH 14
oid newname[MAX_OID_LEN];
register int index;
int result, count;
DEBUGMSGTL(("cgtsAgentPlugin", "header_eventLogEntry: "));
DEBUGMSGOID(("cgtsAgentPlugin", name, *length));
DEBUGMSG(("cgtsAgentPlugin", "exact %d\n", exact));
memcpy((char *) newname, (char *) vp->name,
(int) vp->namelen * sizeof(oid));
/*
* find "next" log
*/
count = Event_Log_Get_Count();
DEBUGMSG(("cgtsAgentPlugin", "count %d\n", count));
for (index = 1; index <= count; index++) {
newname[ALM_ENTRY_NAME_LENGTH] = (oid) index;
result =
snmp_oid_compare(name, *length, newname,
(int) vp->namelen + 1);
if ((exact && (result == 0)) || (!exact && (result < 0)))
break;
}
if (index > count) {
DEBUGMSGTL(("cgtsAgentPlugin", "... index out of range\n"));
return MATCH_FAILED;
}
memcpy((char *) name, (char *) newname,
((int) vp->namelen + 1) * sizeof(oid));
*length = vp->namelen + 1;
*write_method = 0;
*var_len = sizeof(long); /* default to 'long' results */
DEBUGMSGTL(("cgtsAgentPlugin", "... get ALM data "));
DEBUGMSGOID(("cgtsAgentPlugin", name, *length));
DEBUGMSG(("cgtsAgentPlugin", "\n"));
DEBUGMSG(("cgtsAgentPlugin","Return index: %d\n", index));
return index;
}
int
Event_Log_Get_Count(void)
{
static time_t scan_time = 0;
time_t time_now = time(NULL);
if (!Event_Log_Count || (time_now > scan_time + 60)) {
scan_time = time_now;
Event_Log_Scan_Init();
Event_Log_Count = 0;
while (Event_Log_Scan_NextLog(NULL, NULL, NULL) != 0) {
Event_Log_Count++;
}
}
return (Event_Log_Count);
}
u_char *
var_events(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len,
WriteMethod ** write_method)
{
static struct activealarm alrm;
static char Name[36];
char *cp;
int index = 0;
DEBUGMSGTL(("cgtsAgentPlugin", "var_events"));
index = header_eventLogEntry(vp, name, length, exact, var_len, write_method);
if (index == MATCH_FAILED)
return NULL;
Event_Log_Scan_By_Index(index, Name, &alrm);
switch (vp->magic) {
case EVENT_INDEX:
long_return = index;
return (u_char *) & long_return;
case EVENT_UUID:
cp = Name;
*var_len = strlen(cp);
return (u_char *) cp;
case EVENT_EVENT_ID:
cp = alrm.alarmdata.alarm_id;
*var_len = strlen(cp);
return (u_char *) cp;
case EVENT_STATE:
long_return = alrm.alarmdata.alarm_state;
return (u_char *) & long_return;
case EVENT_INSTANCE_ID:
cp = alrm.alarmdata.entity_instance_id;
*var_len = strlen(cp);
return (u_char *) cp;
case EVENT_TIME:{
time_t when = alrm.alarmdata.timestamp/SECOND_PER_MICROSECOND;
cp = (char *) date_n_time(&when, var_len );
return (u_char *) cp;
}
case EVENT_SEVERITY:
long_return = alrm.alarmdata.severity;
return (u_char *) & long_return;
case EVENT_REASONTEXT:
cp = alrm.alarmdata.reason_text;
*var_len = strlen(cp);
return (u_char *) cp;
case EVENT_EVENTTYPE:
long_return = alrm.alarmdata.alarm_type;
return (u_char *) & long_return;
case EVENT_PROBABLECAUSE:
long_return = alrm.alarmdata.probable_cause;
return (u_char *) & long_return;
case EVENT_REPAIRACTION:
cp = alrm.alarmdata.proposed_repair_action;
*var_len = strlen(cp);
return (u_char *) cp;
case EVENT_SERVICEAFFECTING:
long_return = alrm.alarmdata.service_affecting;
return (u_char *) & long_return;
case EVENT_SUPPRESSION:
long_return = alrm.alarmdata.suppression;
return (u_char *) & long_return;
default:
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_events\n",
vp->magic));
}
return NULL;
}