Merge "Zabbix Plugin for Application Monitoring in Tacker VNF Manager"
This commit is contained in:
commit
80b08ee08f
193
doc/source/contributor/zabbix-plugin.rst
Normal file
193
doc/source/contributor/zabbix-plugin.rst
Normal file
@ -0,0 +1,193 @@
|
||||
..
|
||||
Copyright 2014-2017 OpenStack Foundation
|
||||
All Rights Reserved.
|
||||
|
||||
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.
|
||||
|
||||
========================
|
||||
How to use Zabbix Plugin
|
||||
========================
|
||||
|
||||
This document explains how Tacker VNFM's Zabbix-plugin works with Zabbix
|
||||
monitoring tool to provide application monitoring for VNF.
|
||||
|
||||
VNF application monitoring requires three pre-installation or configuration
|
||||
settings. You do not have to do a lot of work or complex settings.
|
||||
|
||||
1. Zabbix-agent Installation and Setting in VNF.
|
||||
|
||||
Zabbix-Agent must be installed in the VNF. And you need to set it up. The
|
||||
necessary settings must be made in /etc/zabbix/zabbix_agentd.conf in the
|
||||
VNF. Installation and The setting method is as follows.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade
|
||||
sudo apt-get install zabbix-agent
|
||||
sudo echo 'zabbix ALL=NOPASSWD: ALL' >> /etc/sudoers
|
||||
|
||||
Then open the /etc/zabbix/zabbix_agentd.conf file and write for Server,
|
||||
ServerActive Hostname, EnableRemoteCommands. However, this approach is
|
||||
more difficult to manage as the number of VNFs increases.
|
||||
|
||||
Therefore, to solve this problem, the method presented in this document
|
||||
are as follows. After creating the VNF based on the TOSCA template,
|
||||
the USER_DATA parameter is executed on the assumption that the VNF
|
||||
is initialized. We can install and make the necessary settings
|
||||
automatically. Here is an example of a User-data script.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
user_data: |
|
||||
#!/bin/bash
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y upgrade
|
||||
sudo apt-get -y install zabbix-agent
|
||||
sudo sed -i "2s/.*/`ifconfig [Interface name in VNF] | grep ""\"inet addr:\"""| cut -d: -f2 | awk ""\"{ print $1 }\"""`/g" "/etc/hosts"
|
||||
sudo sed -i "s/Bcast/`cat /etc/hostname`/g" "/etc/hosts"
|
||||
sudo sed -i "3s/.*/[Zabbix Host IP Address]\tmonitor/g" "/etc/hosts"
|
||||
sudo /etc/init.d/networking restart
|
||||
sudo echo 'zabbix ALL=NOPASSWD: ALL' >> /etc/sudoers
|
||||
sudo sed -i "s/# EnableRemoteCommands=0/EnableRemoteCommands=1/" "/etc/zabbix/zabbix_agentd.conf"
|
||||
sudo sed -i "s/Server=127.0.0.1/Server=[Zabbix server's IP Address]/" "/etc/zabbix/zabbix_agentd.conf"
|
||||
sudo sed -i "s/ServerActive=127.0.0.1/ServerActive=[Zabbix server's IP Address:Port]/" "/etc/zabbix/zabbix_agentd.conf"
|
||||
sudo sed -i "s/Hostname=Zabbix server/Hostname=`cat /etc/hostname`/" "/etc/zabbix/zabbix_agentd.conf"
|
||||
sudo service zabbix-agent restart
|
||||
|
||||
Use the sed command to modify the information in the conf file.
|
||||
The basic network interface finds the IP address for ens3, sets it,
|
||||
and sets the hostname. The zabbix user also needs permissions to run
|
||||
the monitoring script. EnablRemoteCommands can be set to 1 to enable
|
||||
execution of action commands created by Zabbix-Server.
|
||||
|
||||
2. Installing Zabbix Server
|
||||
|
||||
Because Zabbix Server requires a lot of processes for monitoring
|
||||
projects, it is recommended to build it as a separate physical
|
||||
node if performance stability is required. Installation instructions
|
||||
for Zabbix Server are detailed in the manual provided by Zabbix.
|
||||
Examples of installation procedures are based on Ubuntu16.04
|
||||
and zabbix 3.2.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get upgrade
|
||||
sudo apt-get install php7.0* libapache2-mod-php7.0
|
||||
sudo wget http://repo.zabbix.com/zabbix/3.2/ubuntu/pool/main/z/zabbix-release/zabbix-release_3.2-1+xenial_all.deb
|
||||
sudo dpkg -i zabbix-release_3.2-1+xenial_all.deb
|
||||
sudo apt-get install zabbix-server-mysql zabbix-frontend-php
|
||||
|
||||
Install mysql to store Zabbix-server and monitoring data and
|
||||
necessary information, and install Zabbix-frotend-php to
|
||||
provide web pages. Database creation is as follows.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
shell> mysql -uroot -p[ROOT_PASSWORD]
|
||||
mysql> create database zabbix character set utf8 collate utf8_bin;
|
||||
mysql> grant all privileges on zabbix.* to zabbix@localhost identified by '[PASSWORD]';
|
||||
FLUSH PRIVILEGES;
|
||||
mysql> quit;
|
||||
cd /usr/share/doc/zabbix-server-mysql
|
||||
zcat create.sql.gz | mysql -u root -p zabbix
|
||||
|
||||
We must modify the vi /etc/zabbix/zabbix_server.conf file to
|
||||
provide the Zabbix-server.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
DBHost=localhost
|
||||
DBName=[DBName]
|
||||
DBUser=[DBUser]
|
||||
DBPassword=[PASSWORD]
|
||||
|
||||
At the end of the next operation, we are now ready to use the
|
||||
Zabbix-server to complete the finish operation.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
service zabbix-server start
|
||||
update-rc.d zabbix-server enable
|
||||
vi /etc/zabbix/apache.conf
|
||||
=>php_value date.timezone [location/city]
|
||||
service zabbix-server restart
|
||||
service apache2 restart
|
||||
|
||||
This installation method is based on manual, but it includes
|
||||
additional explanation and installation part of dependency
|
||||
file installation.
|
||||
|
||||
3. Template
|
||||
|
||||
The following templates are used for application monitoring.
|
||||
If we create a VNFD by creating the template below and use it
|
||||
to create a VNF, we can monitor the application without any
|
||||
additional steps. If we want automatic configuration, it is
|
||||
recommended to use USER_DATA parameter.
|
||||
|
||||
If we enter Zabbix-related information in the template, you will
|
||||
get a Token according to the internal workflow of Zabbix-plugin.
|
||||
It it used to configure varitous monitoring functions.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
app_monitoring_policy:
|
||||
name: zabbix
|
||||
zabbix_username: [Zabbix user ID]
|
||||
zabbix_password: [Zabbix user Password]
|
||||
zabbix_server_ip: [Zabbix server IP]
|
||||
zabbix_server_port: [Zabbix server Port]
|
||||
parameters:
|
||||
application:
|
||||
app_name: [application-name]
|
||||
app_port: [application-port]
|
||||
ssh_username: [ssh username in VNF OS]
|
||||
ssh_password: [ssh password in VNF OS]
|
||||
app_status:
|
||||
condition: [comparison,value]
|
||||
actionname: [action name]
|
||||
cmd-action: [Command to be executed in VNF]
|
||||
app_memory:
|
||||
condition: [comparison,value]
|
||||
actionname: [action name]
|
||||
cmd-action: [Command to be executed in VNF]
|
||||
OS:
|
||||
os_agent_info:
|
||||
condition: [comparison,value]
|
||||
actionname: [action name]
|
||||
cmd-action: [Command to be executed in VNF]
|
||||
os_proc_value:
|
||||
condition: [comparison,value]
|
||||
actionname: [action name]
|
||||
cmd-action: [Command to be executed in VNF]
|
||||
os_cpu_load:
|
||||
condition: [comparison,value]
|
||||
actionname: [action name]
|
||||
cmd-action: [Command to be executed in VNF]
|
||||
os_cpu_usage:
|
||||
condition: [comparison,value]
|
||||
actionname: [action name]
|
||||
cmd-action: [Command to be executed in VNF]
|
||||
|
||||
4. Actions
|
||||
Currently, only cmd is supported as an action function.
|
||||
Respawn and Scale Action will be updated with additional
|
||||
proposals and corresponding functionality as more template
|
||||
definitions and corresponding additional functions are required.
|
||||
|
||||
References
|
||||
==========
|
||||
.. [#first] https://www.zabbix.com/documentation/3.2/manual
|
||||
|
4
releasenotes/notes/zabbix-plugin-da2f8867acafd405.yaml
Normal file
4
releasenotes/notes/zabbix-plugin-da2f8867acafd405.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
features:
|
||||
- Added zabbix-pugin to monitor applications within VNF.
|
||||
|
136
samples/tosca-templates/vnfd/tosca-vnfd-zabbix-monitor.yaml
Normal file
136
samples/tosca-templates/vnfd/tosca-vnfd-zabbix-monitor.yaml
Normal file
@ -0,0 +1,136 @@
|
||||
tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0
|
||||
|
||||
description: Monitoring for multiple vdus
|
||||
|
||||
metadata:
|
||||
template_name: tosca-vnfd-monitoir-multi-vdu
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
VDU1:
|
||||
type: tosca.nodes.nfv.VDU.Tacker
|
||||
capabilities:
|
||||
nfv_compute:
|
||||
properties:
|
||||
num_cpus: 2
|
||||
mem_size: 2048 MB
|
||||
disk_size: 15 GB
|
||||
properties:
|
||||
name: VDU1
|
||||
image: ubuntu16.04
|
||||
availability_zone: nova
|
||||
mgmt_driver: noop
|
||||
config: |
|
||||
param0: key1
|
||||
param1: key2
|
||||
user_data_format: RAW
|
||||
user_data: |
|
||||
#!/bin/bash
|
||||
sudo apt-get -y update
|
||||
sudo apt-get -y upgrade
|
||||
sudo apt-get -y install zabbix-agent
|
||||
sudo apt-get -y install apache2
|
||||
|
||||
sudo sed -i "2s/.*/`ifconfig [Interface name in VNF] | grep ""\"inet addr:\"""| cut -d: -f2 | awk ""\"{ print $1 }\"""`/g" "/etc/hosts"
|
||||
sudo sed -i "s/Bcast/`cat /etc/hostname`/g" "/etc/hosts"
|
||||
sudo sed -i "3s/.*/[Zabbix Host IP Address]\tmonitor/g" "/etc/hosts"
|
||||
sudo /etc/init.d/networking restart
|
||||
sudo echo 'zabbix ALL=NOPASSWD: ALL' >> /etc/sudoers
|
||||
|
||||
sudo sed -i "s/# EnableRemoteCommands=0/EnableRemoteCommands=1/" "/etc/zabbix/zabbix_agentd.conf"
|
||||
sudo sed -i "s/Server=127.0.0.1/Server=[Zabbix server's IP Address]/" "/etc/zabbix/zabbix_agentd.conf"
|
||||
sudo sed -i "s/ServerActive=127.0.0.1/ServerActive=[Zabbix server's IP Address:Port]/" "/etc/zabbix/zabbix_agentd.conf"
|
||||
sudo sed -i "s/Hostname=Zabbix server/Hostname=`cat /etc/hostname`/" "/etc/zabbix/zabbix_agentd.conf"
|
||||
|
||||
sudo service apache2 restart
|
||||
sudo service zabbix-agent restart
|
||||
sudo echo 'ubuntu:ubuntu' | chpasswd
|
||||
sudo echo 'root:root' | chpasswd
|
||||
app_monitoring_policy:
|
||||
name: zabbix
|
||||
zabbix_username: Admin
|
||||
zabbix_password: zabbix
|
||||
zabbix_server_ip: 192.168.11.53
|
||||
zabbix_server_port: 80
|
||||
parameters:
|
||||
application:
|
||||
app_name: apache2
|
||||
app_port: 80
|
||||
ssh_username: ubuntu
|
||||
ssh_password: ubuntu
|
||||
app_status:
|
||||
condition: [down]
|
||||
actionname: cmd
|
||||
cmd-action: sudo service apache2 restart
|
||||
app_memory:
|
||||
condition: [greater,22]
|
||||
actionname: cmd
|
||||
cmd-action: sudo service apache2 stop
|
||||
OS:
|
||||
os_agent_info:
|
||||
condition: [down]
|
||||
actionname: cmd
|
||||
cmd-action: sudo service zabbix-agent restart
|
||||
os_proc_value:
|
||||
condition: [and less,22]
|
||||
actionname: cmd
|
||||
cmd-action: sudo reboot
|
||||
os_cpu_load:
|
||||
condition: [and greater,30]
|
||||
actionname: cmd
|
||||
cmd-action: sudo reboot
|
||||
os_cpu_usage:
|
||||
condition: [less,30]
|
||||
actionname: cmd
|
||||
cmd-action: sudo reboot
|
||||
|
||||
CP11:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
management: true
|
||||
order: 0
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL1
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
|
||||
CP12:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
order: 1
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL2
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
|
||||
CP13:
|
||||
type: tosca.nodes.nfv.CP.Tacker
|
||||
properties:
|
||||
order: 2
|
||||
anti_spoofing_protection: false
|
||||
requirements:
|
||||
- virtualLink:
|
||||
node: VL3
|
||||
- virtualBinding:
|
||||
node: VDU1
|
||||
VL1:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net_mgmt
|
||||
vendor: Tacker
|
||||
|
||||
VL2:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net0
|
||||
vendor: Tacker
|
||||
|
||||
VL3:
|
||||
type: tosca.nodes.nfv.VL
|
||||
properties:
|
||||
network_name: net1
|
||||
vendor: Tacker
|
@ -59,6 +59,8 @@ tacker.tacker.mgmt.drivers =
|
||||
tacker.tacker.monitor.drivers =
|
||||
ping = tacker.vnfm.monitor_drivers.ping.ping:VNFMonitorPing
|
||||
http_ping = tacker.vnfm.monitor_drivers.http_ping.http_ping:VNFMonitorHTTPPing
|
||||
tacker.tacker.app_monitor.drivers =
|
||||
zabbix = tacker.vnfm.monitor_drivers.zabbix.zabbix:VNFMonitorZabbix
|
||||
tacker.tacker.alarm_monitor.drivers =
|
||||
ceilometer = tacker.vnfm.monitor_drivers.ceilometer.ceilometer:VNFMonitorCeilometer
|
||||
tacker.tacker.policy.actions =
|
||||
@ -81,6 +83,7 @@ oslo.config.opts =
|
||||
tacker.vnfm.monitor_drivers.http_ping.http_ping = tacker.vnfm.monitor_drivers.http_ping.http_ping:config_opts
|
||||
tacker.vnfm.monitor_drivers.ping.ping = tacker.vnfm.monitor_drivers.ping.ping:config_opts
|
||||
tacker.vnfm.monitor_drivers.ceilometer.ceilometer = tacker.vnfm.monitor_drivers.ceilometer.ceilometer:config_opts
|
||||
tacker.vnfm.monitor_drivers.zabbix.zabbix = tacker.vnfm.monitor_drivers.zabbix.zabbix:config_opts
|
||||
tacker.alarm_receiver = tacker.alarm_receiver:config_opts
|
||||
mistral.actions =
|
||||
tacker.vim_ping_action = tacker.nfvo.workflows.vim_monitor.vim_ping_action:PingVimAction
|
||||
|
54
tacker/tests/unit/vnfm/monitor_drivers/zabbix/test_zabbix.py
Normal file
54
tacker/tests/unit/vnfm/monitor_drivers/zabbix/test_zabbix.py
Normal file
@ -0,0 +1,54 @@
|
||||
#
|
||||
# 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 mock
|
||||
from tacker.vnfm.monitor_drivers.zabbix import zabbix
|
||||
import testtools
|
||||
|
||||
|
||||
class TestVNFMonitorZabbix(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestVNFMonitorZabbix, self).setUp()
|
||||
zabbix.VNFMonitorZabbix.tacker_token = 'a1b2c3d4e5'
|
||||
self.monitor_zabbix = zabbix.VNFMonitorZabbix()
|
||||
|
||||
@mock.patch('tacker.vnfm.monitor_drivers.zabbix.zabbix.'
|
||||
'VNFMonitorZabbix.add_to_appmonitor')
|
||||
def test_add_to_appmonitor(self, mock_ac):
|
||||
mock_ac.return_value = None
|
||||
|
||||
test_vnf = {'vnfd': {'tenant_id': u'd1e6919c73074d18ab6cd49a02e08391'},
|
||||
'id': 'b9af3cb5-6e43-4b2c-a056-67bda3f71e1a'}
|
||||
test_kwargs = {'vdus': {'VDU1':
|
||||
{'parameters':
|
||||
{'application':
|
||||
{'app_name': 'apache2',
|
||||
'app_status': {'actionname': 'cmd',
|
||||
'cmd-action': 'sudo service \
|
||||
apache2 restart',
|
||||
'condition': ['down']},
|
||||
'ssh_username': 'ubuntu',
|
||||
'app_port': 80,
|
||||
'ssh_password': 'ubuntu'}},
|
||||
'name': 'zabbix',
|
||||
'zabbix_username': 'Admin',
|
||||
'zabbix_password': 'zabbix',
|
||||
'zabbix_server_ip': '192.168.11.53',
|
||||
'zabbix_server_port': 80,
|
||||
'mgmt_ip': '192.168.11.206'}}}
|
||||
|
||||
monitor_return = self.monitor_zabbix.\
|
||||
add_to_appmonitor(test_kwargs, test_vnf)
|
||||
self.assertEqual(None, monitor_return)
|
@ -13,6 +13,89 @@ data_types:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
tosca.datatypes.tacker.AppActionMap:
|
||||
properties:
|
||||
condition:
|
||||
type: map
|
||||
entry_schema:
|
||||
type: string
|
||||
required: false
|
||||
actionname:
|
||||
type: string
|
||||
required: false
|
||||
cmd-action:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
tosca.datatypes.tacker.AppInfoParams:
|
||||
properties:
|
||||
app_name:
|
||||
type: string
|
||||
required: true
|
||||
app_port:
|
||||
type: string
|
||||
required: true
|
||||
ssh_username:
|
||||
type: string
|
||||
required: false
|
||||
ssh_password:
|
||||
type: string
|
||||
required: false
|
||||
app_status:
|
||||
type: tosca.dataypes.tacker.AppActionMap
|
||||
required: false
|
||||
app_memory:
|
||||
type: tosca.dataypes.tacker.AppActionMap
|
||||
required: false
|
||||
|
||||
tosca.datatypes.tacker.OSInfoParams:
|
||||
properties:
|
||||
os_agent_info:
|
||||
type: tosca.dataypes.tacker.AppActionMap
|
||||
required: false
|
||||
os_proc_value:
|
||||
type: tosca.datatypes.tacker.AppActionMap
|
||||
required: false
|
||||
os_cpu_load:
|
||||
type: tosca.datatypes.tacker.AppActionMap
|
||||
required: false
|
||||
os_cpu_usage:
|
||||
type: tosca.datatypes.tacker.AppActionMap
|
||||
required: false
|
||||
|
||||
|
||||
tosca.datatypes.tacker.AppMonitoringParams:
|
||||
properties:
|
||||
application:
|
||||
type: tosca.datatypes.tacker.AppInfoParams
|
||||
required: false
|
||||
OS:
|
||||
type: tosca.datatypes.tacker.OSInfoParams
|
||||
required: false
|
||||
|
||||
tosca.datatypes.tacker.AppMonitoringType:
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
required: true
|
||||
zabbix_username:
|
||||
type: string
|
||||
required: true
|
||||
zabbix_password:
|
||||
type: string
|
||||
required: true
|
||||
zabbix_server_ip:
|
||||
type: string
|
||||
required: true
|
||||
zabbix_server_port:
|
||||
type: int
|
||||
required: true
|
||||
parameters:
|
||||
type: tosca.datatypes.tacker.AppMonitoringParams
|
||||
required: false
|
||||
|
||||
|
||||
|
||||
tosca.datatypes.tacker.MonitoringParams:
|
||||
properties:
|
||||
monitoring_delay:
|
||||
@ -46,6 +129,8 @@ data_types:
|
||||
type: tosca.datatypes.tacker.MonitoringParams
|
||||
required: false
|
||||
|
||||
|
||||
|
||||
tosca.datatypes.compute_properties:
|
||||
properties:
|
||||
num_cpus:
|
||||
@ -83,6 +168,7 @@ data_types:
|
||||
required: false
|
||||
description: The mac address allowed to be paired with specific virtual IP.
|
||||
|
||||
|
||||
policy_types:
|
||||
tosca.policies.tacker.Placement:
|
||||
derived_from: tosca.policies.Root
|
||||
@ -121,6 +207,20 @@ policy_types:
|
||||
type: string
|
||||
required: true
|
||||
|
||||
tosca.policies.tacker.AppMonitoring:
|
||||
derived_from: tosca.policies.Root
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
required: true
|
||||
parameters:
|
||||
type: map
|
||||
entry_schema:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
|
||||
|
||||
tosca.policies.tacker.Monitoring.NoOp:
|
||||
derived_from: tosca.policies.tacker.Monitoring
|
||||
properties:
|
||||
@ -136,6 +236,12 @@ policy_types:
|
||||
properties:
|
||||
name: http-ping
|
||||
|
||||
tosca.policies.tacker.Monitoring.Zabbix:
|
||||
derived_from: tosca.policies.tacker.Appmonitoring
|
||||
properties:
|
||||
name: zabbix
|
||||
|
||||
|
||||
tosca.policies.tacker.Alarming:
|
||||
derived_from: tosca.policies.Monitoring
|
||||
triggers:
|
||||
|
@ -163,7 +163,7 @@ node_types:
|
||||
type: string
|
||||
required: false
|
||||
image:
|
||||
# type: tosca.artifacts.Deployment.Image.VM
|
||||
# type: tosca.artifacts.Deployment.Image.VM
|
||||
type: string
|
||||
required: false
|
||||
flavor:
|
||||
@ -186,6 +186,13 @@ node_types:
|
||||
# type: tosca.policies.tacker.Placement
|
||||
type: string
|
||||
required: false
|
||||
app_monitoring_policy:
|
||||
# type: tosca.policies.tacker.AppMonitoring
|
||||
# type: tosca.datatypes.tacker.AppMonitoringType
|
||||
type: map
|
||||
required: false
|
||||
|
||||
|
||||
|
||||
monitoring_policy:
|
||||
# type: tosca.policies.tacker.Monitoring
|
||||
|
@ -17,15 +17,14 @@ import re
|
||||
import sys
|
||||
import yaml
|
||||
|
||||
from collections import OrderedDict
|
||||
from oslo_log import log as logging
|
||||
from toscaparser import properties
|
||||
from toscaparser.utils import yamlparser
|
||||
|
||||
from tacker.common import log
|
||||
from tacker.common import utils
|
||||
from tacker.extensions import vnfm
|
||||
from toscaparser import properties
|
||||
from toscaparser.utils import yamlparser
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
FAILURE = 'tosca.policies.tacker.Failure'
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -160,6 +159,28 @@ def get_vdu_monitoring(template):
|
||||
return monitoring_dict
|
||||
|
||||
|
||||
def get_vdu_applicationmonitoring(template):
|
||||
tpl_temp = "topology_template"
|
||||
n_temp = "node_templates"
|
||||
poly = "app_monitoring_policy"
|
||||
monitoring_dict = dict()
|
||||
policy_dict = dict()
|
||||
policy_dict['vdus'] = collections.OrderedDict()
|
||||
node_list = template[tpl_temp][n_temp].keys()
|
||||
for node in node_list:
|
||||
nt = template[tpl_temp][n_temp][node]
|
||||
if nt['type'] == TACKERVDU:
|
||||
if poly in nt['properties'].keys():
|
||||
mon_policy = nt['properties'][poly]
|
||||
if mon_policy != 'noop':
|
||||
policy_dict['vdus'][node] = {}
|
||||
policy_dict['vdus'][node] = mon_policy
|
||||
del template[tpl_temp][n_temp][node]['properties'][poly]
|
||||
if policy_dict.get('vdus'):
|
||||
monitoring_dict = policy_dict
|
||||
return monitoring_dict
|
||||
|
||||
|
||||
@log.log
|
||||
def get_vdu_metadata(template):
|
||||
metadata = dict()
|
||||
|
@ -60,6 +60,7 @@ class TOSCAToHOT(object):
|
||||
self.nested_resources = dict()
|
||||
self.fields = None
|
||||
self.STACK_FLAVOR_EXTRA = cfg.CONF.openstack_vim.flavor_extra_specs
|
||||
self.appmonitoring_dict = None
|
||||
|
||||
@log.log
|
||||
def generate_hot(self):
|
||||
@ -78,6 +79,9 @@ class TOSCAToHOT(object):
|
||||
if self.monitoring_dict:
|
||||
self.vnf['attributes']['monitoring_policy'] = jsonutils.dumps(
|
||||
self.monitoring_dict)
|
||||
if self.appmonitoring_dict:
|
||||
self.vnf['attributes']['app_monitoring_policy'] = \
|
||||
jsonutils.dumps(self.appmonitoring_dict)
|
||||
|
||||
@log.log
|
||||
def _get_vnfd(self):
|
||||
@ -250,11 +254,17 @@ class TOSCAToHOT(object):
|
||||
LOG.debug("Params not Well Formed: %s", str(e))
|
||||
raise vnfm.ParamYAMLNotWellFormed(error_msg_details=str(e))
|
||||
|
||||
block_storage_details = toscautils.get_block_storage_details(vnfd_dict)
|
||||
appmonitoring_dict = \
|
||||
toscautils.get_vdu_applicationmonitoring(vnfd_dict)
|
||||
|
||||
block_storage_details = toscautils.get_block_storage_details(
|
||||
vnfd_dict)
|
||||
toscautils.updateimports(vnfd_dict)
|
||||
if 'substitution_mappings' in str(vnfd_dict):
|
||||
toscautils.check_for_substitution_mappings(vnfd_dict,
|
||||
parsed_params)
|
||||
toscautils.check_for_substitution_mappings(
|
||||
vnfd_dict,
|
||||
parsed_params
|
||||
)
|
||||
|
||||
try:
|
||||
tosca = tosca_template.ToscaTemplate(parsed_params=parsed_params,
|
||||
@ -314,6 +324,7 @@ class TOSCAToHOT(object):
|
||||
self.heat_template_yaml = heat_template_yaml
|
||||
self.monitoring_dict = monitoring_dict
|
||||
self.metadata = metadata
|
||||
self.appmonitoring_dict = appmonitoring_dict
|
||||
|
||||
@log.log
|
||||
def represent_odict(self, dump, tag, mapping, flow_style=None):
|
||||
|
@ -14,7 +14,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
import ast
|
||||
import inspect
|
||||
import threading
|
||||
import time
|
||||
@ -24,7 +24,6 @@ from oslo_log import log as logging
|
||||
from oslo_serialization import jsonutils
|
||||
from oslo_utils import timeutils
|
||||
|
||||
|
||||
from tacker.common import driver_manager
|
||||
from tacker import context as t_context
|
||||
from tacker.db.common_services import common_services_db_plugin
|
||||
@ -43,7 +42,8 @@ CONF.register_opts(OPTS, group='monitor')
|
||||
def config_opts():
|
||||
return [('monitor', OPTS),
|
||||
('tacker', VNFMonitor.OPTS),
|
||||
('tacker', VNFAlarmMonitor.OPTS), ]
|
||||
('tacker', VNFAlarmMonitor.OPTS),
|
||||
('tacker', VNFAppMonitor.OPTS)]
|
||||
|
||||
|
||||
def _log_monitor_events(context, vnf_dict, evt_details):
|
||||
@ -195,6 +195,49 @@ class VNFMonitor(object):
|
||||
vnf=vnf_dict, kwargs=kwargs)
|
||||
|
||||
|
||||
class VNFAppMonitor(object):
|
||||
"""VNF App monitor"""
|
||||
OPTS = [
|
||||
cfg.ListOpt(
|
||||
'app_monitor_driver', default=['zabbix'],
|
||||
help=_('App monitoring driver to communicate with '
|
||||
'Hosting VNF/logical service '
|
||||
'instance tacker plugin will use')),
|
||||
]
|
||||
cfg.CONF.register_opts(OPTS, 'tacker')
|
||||
|
||||
def __init__(self):
|
||||
self._application_monitor_manager = driver_manager.DriverManager(
|
||||
'tacker.tacker.app_monitor.drivers',
|
||||
cfg.CONF.tacker.app_monitor_driver)
|
||||
|
||||
def _create_app_monitoring_dict(self, dev_attrs, mgmt_url):
|
||||
app_policy = 'app_monitoring_policy'
|
||||
appmonitoring_dict = ast.literal_eval(dev_attrs[app_policy])
|
||||
vdulist = appmonitoring_dict['vdus'].keys()
|
||||
|
||||
for vduname in vdulist:
|
||||
temp = ast.literal_eval(mgmt_url)
|
||||
appmonitoring_dict['vdus'][vduname]['mgmt_ip'] = temp[vduname]
|
||||
return appmonitoring_dict
|
||||
|
||||
def create_app_dict(self, context, vnf_dict):
|
||||
dev_attrs = vnf_dict['attributes']
|
||||
mgmt_url = vnf_dict['mgmt_url']
|
||||
return self._create_app_monitoring_dict(dev_attrs, mgmt_url)
|
||||
|
||||
def _invoke(self, driver, **kwargs):
|
||||
method = inspect.stack()[1][3]
|
||||
return self._application_monitor_manager.\
|
||||
invoke(driver, method, **kwargs)
|
||||
|
||||
def add_to_appmonitor(self, applicationvnfdict, vnf_dict):
|
||||
vdunode = applicationvnfdict['vdus'].keys()
|
||||
driver = applicationvnfdict['vdus'][vdunode[0]]['name']
|
||||
kwargs = applicationvnfdict
|
||||
return self._invoke(driver, vnf=vnf_dict, kwargs=kwargs)
|
||||
|
||||
|
||||
class VNFAlarmMonitor(object):
|
||||
"""VNF Alarm monitor"""
|
||||
OPTS = [
|
||||
@ -262,7 +305,7 @@ class VNFAlarmMonitor(object):
|
||||
return alarm_url
|
||||
|
||||
def process_alarm_for_vnf(self, vnf, trigger):
|
||||
'''call in plugin'''
|
||||
"""call in plugin"""
|
||||
params = trigger['params']
|
||||
mon_prop = trigger['trigger']
|
||||
alarm_dict = dict()
|
||||
|
0
tacker/vnfm/monitor_drivers/zabbix/__init__.py
Normal file
0
tacker/vnfm/monitor_drivers/zabbix/__init__.py
Normal file
416
tacker/vnfm/monitor_drivers/zabbix/zabbix.py
Normal file
416
tacker/vnfm/monitor_drivers/zabbix/zabbix.py
Normal file
@ -0,0 +1,416 @@
|
||||
# All Rights Reserved.
|
||||
#
|
||||
#
|
||||
# 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 json
|
||||
import requests
|
||||
import time
|
||||
|
||||
import copy
|
||||
from oslo_log import log as logging
|
||||
from tacker.vnfm.monitor_drivers import abstract_driver
|
||||
from tacker.vnfm.monitor_drivers.zabbix import zabbix_api as zapi
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class VNFMonitorZabbix(abstract_driver.VNFMonitorAbstractDriver):
|
||||
params = ['application', 'OS']
|
||||
|
||||
def __init__(self):
|
||||
self.kwargs = None
|
||||
self.vnf = None
|
||||
self.vduname = []
|
||||
self.URL = None
|
||||
self.hostinfo = {}
|
||||
self.tenant_id = None
|
||||
|
||||
def get_type(self):
|
||||
"""Return one of predefined type of the hosting vnf drivers."""
|
||||
plugin_type = 'zabbix'
|
||||
return plugin_type
|
||||
|
||||
def get_name(self):
|
||||
"""Return a symbolic name for the VNF Monitor plugin."""
|
||||
plugin_name = 'zabbix'
|
||||
return plugin_name
|
||||
|
||||
def get_description(self):
|
||||
"""Return description of VNF Monitor plugin."""
|
||||
plugin_descript = 'Tacker VNFMonitor Zabbix Driver'
|
||||
return plugin_descript
|
||||
|
||||
def monitor_get_config(self, plugin, context, vnf):
|
||||
|
||||
"""Return dict of monitor configuration data.
|
||||
|
||||
:param plugin:
|
||||
:param context:
|
||||
:param vnf:
|
||||
:returns: dict
|
||||
:returns: dict of monitor configuration data
|
||||
"""
|
||||
return {}
|
||||
|
||||
def monitor_url(self, plugin, context, vnf):
|
||||
"""Return the url of vnf to monitor.
|
||||
|
||||
:param plugin:
|
||||
:param context:
|
||||
:param vnf:
|
||||
:returns: string
|
||||
:returns: url of vnf to monitor
|
||||
"""
|
||||
pass
|
||||
|
||||
def send_post(self, query):
|
||||
response = requests.post(self.URL, headers=zapi.HEADERS,
|
||||
data=json.dumps(query))
|
||||
return dict(response.json())
|
||||
|
||||
@staticmethod
|
||||
def check_error(response):
|
||||
try:
|
||||
if 'result' not in response:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
LOG.error('Cannot request error : %s', response['error']['data'])
|
||||
|
||||
def create_graph(self, itemid, name, nodename):
|
||||
temp_graph_api = copy.deepcopy(zapi.dGRAPH_CREATE_API)
|
||||
gitems = [{'itemid': itemid, 'color': '00AA00'}]
|
||||
temp_graph_api['auth'] = \
|
||||
self.hostinfo[nodename]['zbx_info']['zabbix_token']
|
||||
temp_graph_api['params']['gitems'] = gitems
|
||||
temp_graph_api['params']['name'] = name
|
||||
response = self.send_post(temp_graph_api)
|
||||
VNFMonitorZabbix.check_error(response)
|
||||
|
||||
def create_action(self):
|
||||
for vdu in self.vduname:
|
||||
temp_action_api = copy.deepcopy(zapi.dACTION_CREATE_API)
|
||||
temp_action_api['auth'] = \
|
||||
self.hostinfo[vdu]['zbx_info']['zabbix_token']
|
||||
tempname_api = temp_action_api['params']['operations'][0]
|
||||
temp_filter = temp_action_api['params']['filter']
|
||||
for info in (self.hostinfo[vdu]['actioninfo']):
|
||||
tempname_api['opcommand_hst'][0]['hostid'] = \
|
||||
self.hostinfo[vdu]['hostid']
|
||||
now = time.localtime()
|
||||
rtime = str(now.tm_hour) + str(now.tm_min) + str(now.tm_sec)
|
||||
temp_name = "Trigger Action " + \
|
||||
str(
|
||||
vdu + rtime + " " +
|
||||
info['item'] + " " + info['action']
|
||||
)
|
||||
temp_action_api['params']['name'] = temp_name
|
||||
|
||||
if (info['action'] == 'cmd') and \
|
||||
(info['item'] != 'os_agent_info'):
|
||||
|
||||
tempname_api['opcommand']['command'] = info['cmd-action']
|
||||
|
||||
elif (info['item'] == 'os_agent_info') \
|
||||
and (info['action'] == 'cmd'):
|
||||
|
||||
tempname_api['opcommand']['authtype'] = 0
|
||||
tempname_api['opcommand']['username'] = \
|
||||
self.hostinfo[vdu]['appinfo']['ssh_username']
|
||||
tempname_api['opcommand']['password'] = \
|
||||
self.hostinfo[vdu]['appinfo']['ssh_password']
|
||||
tempname_api['opcommand']['type'] = 2
|
||||
tempname_api['opcommand']['command'] = info['cmd-action']
|
||||
tempname_api['opcommand']['port'] = 22
|
||||
|
||||
temp_filter['conditions'][0]['value'] = info['trigger_id']
|
||||
response = self.send_post(temp_action_api)
|
||||
VNFMonitorZabbix.check_error(response)
|
||||
continue
|
||||
|
||||
temp_filter['conditions'][0]['value'] = info['trigger_id']
|
||||
response = self.send_post(temp_action_api)
|
||||
VNFMonitorZabbix.check_error(response)
|
||||
|
||||
def create_vdu_host(self):
|
||||
for vdu in self.vduname:
|
||||
temp_host_api = zapi.dHOST_CREATE_API
|
||||
temp_group_api = zapi.dGROUP_GET_API
|
||||
temp_host_api['auth'] = \
|
||||
self.hostinfo[vdu]['zbx_info']['zabbix_token']
|
||||
temp_group_api['auth'] = \
|
||||
self.hostinfo[vdu]['zbx_info']['zabbix_token']
|
||||
response = self.send_post(temp_group_api)
|
||||
gid = response['result'][0]['groupid']
|
||||
temp_host_api['params']['host'] = str(vdu)
|
||||
if type(self.hostinfo[vdu]['mgmt_ip']) is list:
|
||||
for vduip in (self.hostinfo[vdu]['mgmt_ip']):
|
||||
temp_host_api['params']['interfaces'][0]['ip'] = vduip
|
||||
temp_host_api['params']['templates'][0]['templateid'] = \
|
||||
self.hostinfo[vdu]['template_id'][0]
|
||||
temp_host_api['params']['groups'][0]['groupid'] = gid
|
||||
response = self.send_post(temp_host_api)
|
||||
else:
|
||||
temp_host_api['params']['interfaces'][0]['ip'] = \
|
||||
self.hostinfo[vdu]['mgmt_ip']
|
||||
temp_host_api['params']['templates'][0]['templateid'] = \
|
||||
self.hostinfo[vdu]['template_id'][0]
|
||||
temp_host_api['params']['groups'][0]['groupid'] = gid
|
||||
response = self.send_post(temp_host_api)
|
||||
if 'error' in response:
|
||||
now = time.localtime()
|
||||
rtime = str(now.tm_hour) + str(now.tm_min) + str(now.tm_sec)
|
||||
temp_host_api['params']['host'] = str(vdu) + rtime
|
||||
response = self.send_post(temp_host_api)
|
||||
self.hostinfo[vdu]['hostid'] = response['result']['hostids'][0]
|
||||
|
||||
def create_trigger(self, trigger_params, vduname):
|
||||
temp_trigger_api = copy.deepcopy(zapi.dTRIGGER_CREATE_API)
|
||||
temp_trigger_api['auth'] = \
|
||||
self.hostinfo[vduname]['zbx_info']['zabbix_token']
|
||||
temp_trigger_api['params'] = trigger_params
|
||||
temp_trigger_api['templateid'] = \
|
||||
str(
|
||||
self.hostinfo[vduname]['template_id'][0])
|
||||
response = self.send_post(temp_trigger_api)
|
||||
VNFMonitorZabbix.check_error(response)
|
||||
return response['result']
|
||||
|
||||
def _create_trigger(self):
|
||||
|
||||
trigger_params = []
|
||||
trig_act_pa = []
|
||||
for vdu in self.vduname:
|
||||
temp_trigger_list = copy.deepcopy(zapi.dTRIGGER_LIST)
|
||||
|
||||
temp_vdu_name = self.hostinfo[vdu]['appinfo']['app_name']
|
||||
temp_vdu_port = self.hostinfo[vdu]['appinfo']['app_port']
|
||||
for para in VNFMonitorZabbix.params:
|
||||
for item in self.hostinfo[vdu]['parameters'][para].keys():
|
||||
action_list = copy.deepcopy(zapi.dACTION_LIST)
|
||||
temp_item = self.hostinfo[vdu]['parameters'][para][item]
|
||||
|
||||
if ('app_name' != item)\
|
||||
and ('app_port' != item) \
|
||||
and ('ssh_username' != item) \
|
||||
and ('ssh_password' != item):
|
||||
|
||||
if 'condition' \
|
||||
in temp_item.keys():
|
||||
temp_con = temp_item['condition']
|
||||
|
||||
if len(temp_con) == 2:
|
||||
temp_comparrision = temp_con[0]
|
||||
temp_comparrision_value = temp_con[1]
|
||||
temp_trigger_list[item][0]['expression'] += \
|
||||
self.hostinfo[vdu]['template_name'] + ':'\
|
||||
+ str(
|
||||
zapi.dITEM_KEY_COMP[item].replace(
|
||||
'*', str(temp_vdu_name))) \
|
||||
+ str(
|
||||
zapi.COMP_VALUE[temp_comparrision]) \
|
||||
+ str(
|
||||
temp_comparrision_value)
|
||||
|
||||
else:
|
||||
temp_comparrision = temp_con[0]
|
||||
if 'os_agent_info' == item:
|
||||
temp_trigger_list[item][0]['expression'] += \
|
||||
self.hostinfo[vdu]['template_name'] + ':' \
|
||||
+ str(zapi.dITEM_KEY_COMP[item])
|
||||
|
||||
else:
|
||||
temp_trigger_list[item][0]['expression'] += \
|
||||
self.hostinfo[vdu]['template_name'] + ':' \
|
||||
+ str(
|
||||
zapi.dITEM_KEY_COMP[item].replace(
|
||||
'*', str(temp_vdu_port))) \
|
||||
+ str(
|
||||
zapi.COMP_VALUE[temp_comparrision])
|
||||
if 'actionname' in \
|
||||
temp_item.keys():
|
||||
|
||||
trig_act_pa.append(temp_trigger_list[item][0])
|
||||
response = self.create_trigger(trig_act_pa, vdu)
|
||||
del trig_act_pa[:]
|
||||
action_list['action'] = \
|
||||
temp_item['actionname']
|
||||
action_list['trigger_id'] = \
|
||||
response['triggerids'][0]
|
||||
action_list['item'] = item
|
||||
if 'cmd' == \
|
||||
temp_item['actionname']:
|
||||
|
||||
action_list['cmd-action'] = \
|
||||
temp_item['cmd-action']
|
||||
self.hostinfo[vdu]['actioninfo'].append(
|
||||
action_list)
|
||||
|
||||
else:
|
||||
trigger_params.append(
|
||||
temp_trigger_list[item][0])
|
||||
|
||||
if len(trigger_params) != 0:
|
||||
self.create_trigger(trigger_params, vdu)
|
||||
del trigger_params[:]
|
||||
|
||||
def create_item(self):
|
||||
# Create _ITEM
|
||||
for vdu in self.vduname:
|
||||
temp_item_api = copy.deepcopy(zapi.dITEM_CREATE_API)
|
||||
temp_item_api['auth'] = \
|
||||
self.hostinfo[vdu]['zbx_info']['zabbix_token']
|
||||
self.hostinfo[vdu]['appinfo'] = \
|
||||
copy.deepcopy(zapi.dAPP_INFO)
|
||||
temp_app = self.hostinfo[vdu]['parameters']['application']
|
||||
temp_item_api['params']['hostid'] = \
|
||||
self.hostinfo[vdu]['template_id'][0]
|
||||
|
||||
for para in VNFMonitorZabbix.params:
|
||||
if 'application' == para:
|
||||
for app_info in \
|
||||
temp_app.keys():
|
||||
self.hostinfo[vdu]['appinfo'][app_info] = \
|
||||
temp_app[app_info]
|
||||
|
||||
for item in (self.hostinfo[vdu]['parameters'][para].keys()):
|
||||
if ('app_name' != item) and ('app_port' != item) \
|
||||
and ('ssh_username' != item) \
|
||||
and ('ssh_password' != item):
|
||||
|
||||
temp_item_api['params']['name'] = \
|
||||
zapi.dITEM_KEY_INFO[item]['name']
|
||||
temp_item_api['params']['value_type'] = \
|
||||
zapi.dITEM_KEY_INFO[item]['value_type']
|
||||
|
||||
if item == 'app_status':
|
||||
temp = zapi.dITEM_KEY_INFO[item]['key_']
|
||||
temp_item_api['params']['key_'] = temp.replace(
|
||||
'*', str(
|
||||
self.hostinfo[vdu]['appinfo']['app_port']))
|
||||
|
||||
elif item == 'app_memory':
|
||||
temp = zapi.dITEM_KEY_INFO[item]['key_']
|
||||
temp_item_api['params']['key_'] = temp.replace(
|
||||
'*',
|
||||
str(
|
||||
self.hostinfo[vdu]['appinfo']['app_name']))
|
||||
|
||||
else:
|
||||
temp_item_api['params']['key_'] = \
|
||||
zapi.dITEM_KEY_INFO[item]['key_']
|
||||
response = self.send_post(temp_item_api)
|
||||
self.create_graph(
|
||||
response['result']['itemids'][0],
|
||||
temp_item_api['params']['name'], vdu)
|
||||
VNFMonitorZabbix.check_error(response)
|
||||
|
||||
def create_template(self):
|
||||
temp_template_api = copy.deepcopy(zapi.dTEMPLATE_CREATE_API)
|
||||
|
||||
for vdu in self.vduname:
|
||||
temp_template_api['params']['host'] = "Tacker Template " + str(vdu)
|
||||
temp_template_api['auth'] = \
|
||||
self.hostinfo[vdu]['zbx_info']['zabbix_token']
|
||||
response = self.send_post(temp_template_api)
|
||||
|
||||
if 'error' in response:
|
||||
if "already exists." in response['error']['data']:
|
||||
now = time.localtime()
|
||||
rtime = str(now.tm_hour) + str(now.tm_min) + str(
|
||||
now.tm_sec)
|
||||
temp_template_api['params']['host'] = \
|
||||
"Tacker Template " + str(vdu) + rtime
|
||||
response = self.send_post(temp_template_api)
|
||||
VNFMonitorZabbix.check_error(response)
|
||||
self.hostinfo[vdu]['template_id'] = \
|
||||
response['result']['templateids']
|
||||
self.hostinfo[vdu]['template_name'] =\
|
||||
temp_template_api['params']['host']
|
||||
|
||||
def add_host_to_zabbix(self):
|
||||
|
||||
self.create_template()
|
||||
self.create_item()
|
||||
self._create_trigger()
|
||||
self.create_vdu_host()
|
||||
self.create_action()
|
||||
|
||||
def get_token_from_zbxserver(self, node):
|
||||
|
||||
temp_auth_api = copy.deepcopy(zapi.dAUTH_API)
|
||||
temp_auth_api['params']['user'] = \
|
||||
self.hostinfo[node]['zbx_info']['zabbix_user']
|
||||
temp_auth_api['params']['password'] = \
|
||||
self.hostinfo[node]['zbx_info']['zabbix_pass']
|
||||
zabbixip = \
|
||||
self.hostinfo[node]['zbx_info']['zabbix_ip']
|
||||
zabbixport = \
|
||||
self.hostinfo[node]['zbx_info']['zabbix_port']
|
||||
self.URL = "http://" + zabbixip + ":" + \
|
||||
str(zabbixport) + zapi.URL_
|
||||
response = requests.post(
|
||||
self.URL,
|
||||
headers=zapi.HEADERS,
|
||||
data=json.dumps(temp_auth_api)
|
||||
)
|
||||
response_dict = dict(response.json())
|
||||
VNFMonitorZabbix.check_error(response_dict)
|
||||
LOG.info('Success Connect Zabbix Server')
|
||||
return response_dict['result']
|
||||
|
||||
def set_zbx_info(self, node):
|
||||
self.hostinfo[node]['zbx_info'] = \
|
||||
copy.deepcopy(zapi.dZBX_INFO)
|
||||
self.hostinfo[node]['zbx_info']['zabbix_user'] = \
|
||||
self.kwargs['vdus'][node]['zabbix_username']
|
||||
self.hostinfo[node]['zbx_info']['zabbix_pass'] = \
|
||||
self.kwargs['vdus'][node]['zabbix_password']
|
||||
self.hostinfo[node]['zbx_info']['zabbix_ip'] = \
|
||||
self.kwargs['vdus'][node]['zabbix_server_ip']
|
||||
self.hostinfo[node]['zbx_info']['zabbix_port'] = \
|
||||
self.kwargs['vdus'][node]['zabbix_server_port']
|
||||
self.hostinfo[node]['zbx_info']['zabbix_token'] = \
|
||||
self.get_token_from_zbxserver(node)
|
||||
|
||||
def set_vdu_info(self):
|
||||
temp_vduname = self.kwargs['vdus'].keys()
|
||||
for node in temp_vduname:
|
||||
if 'application' in \
|
||||
self.kwargs['vdus'][node]['parameters'].keys() \
|
||||
and 'OS'\
|
||||
in self.kwargs['vdus'][node]['parameters'].keys():
|
||||
self.vduname.append(node)
|
||||
self.hostinfo[node] = copy.deepcopy(zapi.dVDU_INFO)
|
||||
self.set_zbx_info(node)
|
||||
self.hostinfo[node]['mgmt_ip'] = \
|
||||
self.kwargs['vdus'][node]['mgmt_ip']
|
||||
self.hostinfo[node]['parameters'] = \
|
||||
self.kwargs['vdus'][node]['parameters']
|
||||
self.hostinfo[node]['vdu_id'] = self.vnf['id']
|
||||
|
||||
def add_to_appmonitor(self, vnf, kwargs):
|
||||
|
||||
self.__init__()
|
||||
self.kwargs = kwargs
|
||||
self.vnf = vnf
|
||||
self.set_vdu_info()
|
||||
self.tenant_id = self.vnf['vnfd']['tenant_id']
|
||||
self.add_host_to_zabbix()
|
||||
|
||||
def monitor_call(self, vnf, kwargs):
|
||||
pass
|
||||
|
||||
def monitor_app_driver(self, plugin, context, vnf, service_instance):
|
||||
return self.get_name()
|
214
tacker/vnfm/monitor_drivers/zabbix/zabbix_api.py
Normal file
214
tacker/vnfm/monitor_drivers/zabbix/zabbix_api.py
Normal file
@ -0,0 +1,214 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
URL_ = "/zabbix/api_jsonrpc.php"
|
||||
|
||||
HEADERS = {'Content-Type': 'application/json-rpc'}
|
||||
dAUTH_API = {'jsonrpc': "2.0",
|
||||
'method': 'user.login',
|
||||
'params': {'user': None,
|
||||
'password': None},
|
||||
'id': 1,
|
||||
'auth': None}
|
||||
|
||||
COMP_VALUE = {'greater': '>',
|
||||
'less': '<',
|
||||
'and greater': '>=',
|
||||
'and less': '<=',
|
||||
'down': '=0'}
|
||||
|
||||
|
||||
dTEMPLATE_CREATE_API = {'jsonrpc': "2.0", 'method': "template.create",
|
||||
'params': {'host': "", 'groups': {'groupid': 1},
|
||||
'hosts': []},
|
||||
'id': 1004, 'auth': None}
|
||||
|
||||
dITEM_CREATE_API = {'jsonrpc': "2.0",
|
||||
'method': "item.create",
|
||||
'params': {'hostid': None,
|
||||
'interfaceid': 'NULL',
|
||||
'name': "",
|
||||
'key_': "",
|
||||
'type': 0,
|
||||
'value_type': 3,
|
||||
'delay': 1},
|
||||
'id': 1,
|
||||
'auth': None}
|
||||
|
||||
|
||||
dITEM_KEY_VALUE = {'os_agent_info': 'agent.ping',
|
||||
'os_cpu_usage': 'system.cpu.util[,iowait]',
|
||||
'os_cpu_load': 'system.cpu.load[percpu,avg1]',
|
||||
'os_proc_value': 'proc.num[,,run]',
|
||||
'app_status': 'net.tcp.port[ ,*]',
|
||||
'app_memory': 'proc.mem[*,root]'}
|
||||
|
||||
dITEM_KEY_COMP = {'os_agent_info': str(
|
||||
dITEM_KEY_VALUE['os_agent_info'] + '.nodata(15s)}=1'),
|
||||
'os_cpu_usage': str(
|
||||
dITEM_KEY_VALUE['os_cpu_usage'] + '.avg(5s)}'),
|
||||
'os_cpu_load': str(
|
||||
dITEM_KEY_VALUE['os_cpu_load'] + '.avg(5s)}'),
|
||||
'os_proc_value': str(
|
||||
dITEM_KEY_VALUE['os_proc_value'] + '.avg(5s)}'),
|
||||
'app_status': str(
|
||||
dITEM_KEY_VALUE['app_status'] + '.last(,5)}'),
|
||||
'app_memory': str(
|
||||
dITEM_KEY_VALUE['app_memory'] + '.avg(5s)}')}
|
||||
|
||||
dITEM_KEY_INFO = {'os_proc_value': {'name': 'process number',
|
||||
'key_': str(
|
||||
dITEM_KEY_VALUE['os_proc_value']),
|
||||
'value_type': 3},
|
||||
'os_cpu_load': {'name': 'cpu load',
|
||||
'key_': str(
|
||||
dITEM_KEY_VALUE['os_cpu_load']),
|
||||
'value_type': 0},
|
||||
'os_cpu_usage': {'name': 'cpu util usage',
|
||||
'key_': str(
|
||||
dITEM_KEY_VALUE['os_cpu_usage']),
|
||||
'value_type': 0},
|
||||
'os_agent_info': {'name': 'Zabbix agent status check',
|
||||
'key_': str(
|
||||
dITEM_KEY_VALUE['os_agent_info']),
|
||||
'value_type': 0},
|
||||
'app_status': {'name': ' service status check',
|
||||
'key_': str(
|
||||
dITEM_KEY_VALUE['app_status']),
|
||||
'value_type': 3},
|
||||
'app_memory': {'name': ' service memory usage',
|
||||
'key_': str(
|
||||
dITEM_KEY_VALUE['app_memory']),
|
||||
'value_type': 3}}
|
||||
|
||||
|
||||
dTRIGGER_CREATE_API = {'jsonrpc': "2.0",
|
||||
'method': "trigger.create",
|
||||
'templateid': None,
|
||||
'auth': None,
|
||||
'id': 1004}
|
||||
|
||||
dTRIGGER_INFO = {'itemname': None,
|
||||
'cmdname': None,
|
||||
'cmd-action': None}
|
||||
|
||||
dTRIGGER_LIST = {'os_agent_info': [{'description': 'Zabbix agent on '
|
||||
'{HOST.NAME} is '
|
||||
'unreachable '
|
||||
'for 15 seconds',
|
||||
'expression': '{', 'priority': 3}],
|
||||
'app_status': [{'description': 'Service is down '
|
||||
'on {HOST.NAME}',
|
||||
'expression': '{', 'priority': 3}],
|
||||
'app_memory': [{'description': 'Process Memory '
|
||||
'is lacking '
|
||||
'on {HOST.NAME}',
|
||||
'expression': '{', 'priority': 3}],
|
||||
'os_cpu_usage': [{'description': 'Disk I/O is '
|
||||
'overloaded '
|
||||
'on {HOST.NAME}',
|
||||
'expression': '{', 'priority': 3}],
|
||||
'os_cpu_load': [{'description': 'Processor load '
|
||||
'is too high '
|
||||
'on {HOST.NAME}',
|
||||
'expression': '{', 'priority': 3}],
|
||||
'os_proc_value': [{'description': 'Too many '
|
||||
'processes running '
|
||||
'on {HOST.NAME}',
|
||||
'expression': '{', 'priority': 3}]}
|
||||
|
||||
dACTION_CREATE_API = {'jsonrpc': "2.0",
|
||||
'method': "action.create",
|
||||
'params': {'name': '',
|
||||
'eventsource': 0,
|
||||
'status': 0,
|
||||
'esc_period': 120,
|
||||
'def_shortdata': "{TRIGGER.NAME}:"
|
||||
"{TRIGGER.STATUS}",
|
||||
'def_longdata': "{TRIGGER.NAME}: "
|
||||
"{TR`IGGER.STATUS}\r\n"
|
||||
"Last value: "
|
||||
"{ITEM.LASTVALUE]"
|
||||
"\r\n\r\n{TRIGGER.URL}",
|
||||
"filter": {"evaltype": 0,
|
||||
"conditions": [{'conditiontype': 2,
|
||||
'operator': 0,
|
||||
'value': None}]},
|
||||
'operations': [{'operationtype': 1,
|
||||
'esc_period': 0,
|
||||
'esc_step_from': 1,
|
||||
'esc_step_to': 2,
|
||||
'evaltype': 0,
|
||||
'opcommand': {
|
||||
'command': None,
|
||||
'type': 0,
|
||||
'execute_on': 0},
|
||||
'opcommand_hst': [
|
||||
{'hostid': None}]
|
||||
}]},
|
||||
'auth': None, 'id': 1}
|
||||
|
||||
dHOST_CREATE_API = {'jsonrpc': "2.0",
|
||||
'method': "host.create",
|
||||
'params': {'host': 'ubuntu',
|
||||
'interfaces': [
|
||||
{'type': 1,
|
||||
'main': 1,
|
||||
'useip': 1,
|
||||
'dns': "",
|
||||
'ip': None,
|
||||
'port': "10050"}],
|
||||
'templates': [{'templateid': None}],
|
||||
'groups': [{'groupid': None}]},
|
||||
'id': 4, 'auth': None}
|
||||
|
||||
dGROUP_GET_API = {'jsonrpc': "2.0", 'method': "hostgroup.get",
|
||||
'params': {'output': 'extend',
|
||||
'filter': {'name': ["Zabbix servers", ]}},
|
||||
'id': 1, 'auth': None}
|
||||
|
||||
dGRAPH_CREATE_API = {'jsonrpc': '2.0', 'method': 'graph.create',
|
||||
'params': {'name': None,
|
||||
'width': 900,
|
||||
'height': 200,
|
||||
'gitems': []},
|
||||
'auth': None, 'id': 1004}
|
||||
|
||||
dAPP_INFO = {'app_port': None,
|
||||
'app_name': None,
|
||||
'ssh_username': None,
|
||||
'ssh_password': None}
|
||||
|
||||
dZBX_INFO = {'zabbix_user': None,
|
||||
'zabbix_pass': None,
|
||||
'zabbix_ip': None,
|
||||
'zabbix_port': None,
|
||||
'zabbix_token': None
|
||||
}
|
||||
|
||||
dACTION_LIST = {'item': None,
|
||||
'action': None,
|
||||
'trigger_id': None,
|
||||
'cmd-action': None}
|
||||
|
||||
dVDU_INFO = {'template_id': None,
|
||||
'template_name': None,
|
||||
'hostid': None,
|
||||
'group_id': None,
|
||||
'mgmt_ip': None,
|
||||
'vdu_id': None,
|
||||
'parameters': None,
|
||||
'actioninfo': [],
|
||||
'appinfo': None,
|
||||
'zbx_info': None
|
||||
}
|
@ -32,11 +32,11 @@ from tacker.common import utils
|
||||
from tacker.db.vnfm import vnfm_db
|
||||
from tacker.extensions import vnfm
|
||||
from tacker.plugins.common import constants
|
||||
from tacker.tosca import utils as toscautils
|
||||
from tacker.vnfm.mgmt_drivers import constants as mgmt_constants
|
||||
from tacker.vnfm import monitor
|
||||
from tacker.vnfm import vim_client
|
||||
|
||||
from tacker.tosca import utils as toscautils
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
@ -143,6 +143,7 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
||||
cfg.CONF.tacker.policy_action)
|
||||
self._vnf_monitor = monitor.VNFMonitor(self.boot_wait)
|
||||
self._vnf_alarm_monitor = monitor.VNFAlarmMonitor()
|
||||
self._vnf_app_monitor = monitor.VNFAppMonitor()
|
||||
|
||||
def spawn_n(self, function, *args, **kwargs):
|
||||
self._pool.spawn_n(function, *args, **kwargs)
|
||||
@ -247,6 +248,10 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
||||
vnf_dict['attributes'].update(alarm_url)
|
||||
break
|
||||
|
||||
def add_vnf_to_appmonitor(self, context, vnf_dict):
|
||||
appmonitor = self._vnf_app_monitor.create_app_dict(context, vnf_dict)
|
||||
self._vnf_app_monitor.add_to_appmonitor(appmonitor, vnf_dict)
|
||||
|
||||
def config_vnf(self, context, vnf_dict):
|
||||
config = vnf_dict['attributes'].get('config')
|
||||
if not config:
|
||||
@ -392,6 +397,10 @@ class VNFMPlugin(vnfm_db.VNFMPluginDb, VNFMMgmtMixin):
|
||||
|
||||
def create_vnf_wait():
|
||||
self._create_vnf_wait(context, vnf_dict, vim_auth, infra_driver)
|
||||
|
||||
if 'app_monitoring_policy' in vnf_dict['attributes']:
|
||||
self.add_vnf_to_appmonitor(context, vnf_dict)
|
||||
|
||||
if vnf_dict['status'] is not constants.ERROR:
|
||||
self.add_vnf_to_monitor(context, vnf_dict)
|
||||
self.config_vnf(context, vnf_dict)
|
||||
|
Loading…
Reference in New Issue
Block a user