# OpenStack Nova by HTTP ## Overview This template is designed for the effortless deployment of OpenStack Nova monitoring by Zabbix via HTTP and doesn't require any external scripts. ## Requirements Zabbix version: 7.0 and higher. ## Tested versions This template has been tested on: - OpenStack Yoga release and OpenStack built from sources (27568ea3): * Compute API v2.1 ## Configuration > Zabbix should be configured according to the instructions in the [Templates out of the box](https://www.zabbix.com/documentation/7.0/manual/config/templates_out_of_the_box) section. ## Setup This template is not meant to be used independently. A host with the __OpenStack by HTTP__ template will discover the __Nova__ service automatically and create a host prototype with this template assigned to it. If needed, you can specify an HTTP proxy for the template to use by changing the value of `{$OPENSTACK.NOVA.HTTP.PROXY}` user macro. For tenant usage statistics, it is possible to choose a custom time period for which the data will be queried. This can be set with the `{$OPENSTACK.NOVA.TENANT.PERIOD}` macro value. The value can be one of the following: * `y` - current year until now; * `m` - current month until now (default value); * `w` - current week until now; * `d` - current day until now; This template discovers servers (instances) present in the project and monitors their statuses, but, depending on different use cases, most likely it is not necessary to monitor all servers. To filter which servers to monitor, set the `{$OPENSTACK.SERVER.DISCOVERY.NAME.MATCHES}` and `{$OPENSTACK.SERVER.DISCOVERY.NAME.NOT_MATCHES}` macro values accordingly. This logic also applies to other low-level discovery rules. **OpenStack configuration** For the OpenStack monitoring user to be able to access the API resources used in this template, it is needed to configure the policy file for OpenStack Nova. On the OpenStack server, open the `/etc/nova/policy.json` file in your favorite text editor. In this file, assign the following target resources to the role that the monitoring user uses: ``` { "os_compute_api:servers:index": "role:monitoring", "os_compute_api:servers:show": "role:monitoring", "os_compute_api:os-services:list": "role:monitoring", "os_compute_api:os-hypervisors:list-detail": "role:monitoring", "os_compute_api:os-availability-zone:detail": "role:monitoring", "os_compute_api:os-simple-tenant-usage:list": "role:monitoring" } ``` If some role is already assigned to the target, it is possible to add another role with `or`, for example, `role:firstRole or role:monitoring`. Note that a restart of OpenStack Nova services might be needed for these new changes to be applied. ### Macros used |Name|Description|Default| |----|-----------|-------| |{$OPENSTACK.NOVA.SERVICE.URL}|
API endpoint for Nova Service, e.g., https://local.openstack:8774/v2.1.
|| |{$OPENSTACK.TOKEN}|API token for the monitoring user.
|| |{$OPENSTACK.HTTP.PROXY}|Sets the HTTP proxy for script and HTTP agent items. If this parameter is empty, then no proxy is used.
|| |{$OPENSTACK.NOVA.TENANT.PERIOD}|Period for which tenant usage statistics will be queried. Possible values are:
'y' - current year until now,
'm' - current month until now,
'w' - current week until now,
'd' - current day until now.
|`m`| |{$OPENSTACK.NOVA.INTERVAL.LIMITS}|Interval for absolute limit HTTP agent item query.
|`3m`| |{$OPENSTACK.NOVA.INTERVAL.SERVERS}|Interval for server HTTP agent item queries.
|`3m`| |{$OPENSTACK.NOVA.INTERVAL.SERVICES}|Interval for service HTTP agent item query.
|`3m`| |{$OPENSTACK.NOVA.INTERVAL.HYPERVISOR}|Interval for hypervisor HTTP agent item query.
|`3m`| |{$OPENSTACK.NOVA.INTERVAL.AVAILABILITY_ZONE}|Interval for availability zone HTTP agent item query.
|`3m`| |{$OPENSTACK.NOVA.INTERVAL.TENANTS}|Interval for tenant HTTP agent item query.
|`3m`| |{$OPENSTACK.NOVA.INSTANCES.UTIL.WARN}|Sets the percentage threshold for creating a warning severity event about instances resource count.
|`75`| |{$OPENSTACK.NOVA.INSTANCES.UTIL.HIGH}|Sets the percentage threshold for creating a high severity event about instances resource count.
|`90`| |{$OPENSTACK.NOVA.CPU.UTIL.WARN}|Sets the percentage threshold for creating a warning severity event about vCPU resource usage.
|`75`| |{$OPENSTACK.NOVA.CPU.UTIL.HIGH}|Sets the percentage threshold for creating a high severity event about vCPU resource usage.
|`90`| |{$OPENSTACK.NOVA.RAM.UTIL.WARN}|Sets the percentage threshold for creating a warning severity event about RAM resource usage.
|`75`| |{$OPENSTACK.NOVA.RAM.UTIL.HIGH}|Sets the percentage threshold for creating a high severity event about RAM resource usage.
|`90`| |{$OPENSTACK.SERVER.DISCOVERY.NAME.MATCHES}|Sets the server name regex filter to use in server discovery for including.
|`.*`| |{$OPENSTACK.SERVER.DISCOVERY.NAME.NOT_MATCHES}|Sets the server name regex filter to use in server discovery for excluding.
|`CHANGE_IF_NEEDED`| |{$OPENSTACK.SERVICES.DISCOVERY.HOST.MATCHES}|Sets the host name regex filter to use in compute services discovery for including.
|`.*`| |{$OPENSTACK.SERVICES.DISCOVERY.HOST.NOT_MATCHES}|Sets the host name regex filter to use in compute services discovery for excluding.
|`CHANGE_IF_NEEDED`| |{$OPENSTACK.SERVICES.DISCOVERY.BINARY.MATCHES}|Sets the binary name regex filter to use in compute services discovery for including.
|`.*`| |{$OPENSTACK.SERVICES.DISCOVERY.BINARY.NOT_MATCHES}|Sets the binary name regex filter to use in compute services discovery for excluding.
|`CHANGE_IF_NEEDED`| |{$OPENSTACK.HYPERVISOR.DISCOVERY.HOSTNAME.MATCHES}|Sets the hostname regex filter to use in hypervisor discovery for including.
|`.*`| |{$OPENSTACK.HYPERVISOR.DISCOVERY.HOSTNAME.NOT_MATCHES}|Sets the hostname regex filter to use in hypervisor discovery for excluding.
|`CHANGE_IF_NEEDED`| |{$OPENSTACK.HYPERVISOR.DISCOVERY.TYPE.MATCHES}|Sets the type regex filter to use in hypervisor discovery for including.
|`.*`| |{$OPENSTACK.HYPERVISOR.DISCOVERY.TYPE.NOT_MATCHES}|Sets the type regex filter to use in hypervisor discovery for excluding.
|`CHANGE_IF_NEEDED`| |{$OPENSTACK.HYPERVISOR.DISCOVERY.IP.MATCHES}|Sets the host IP address regex filter to use in hypervisor discovery for including.
|`.*`| |{$OPENSTACK.HYPERVISOR.DISCOVERY.IP.NOT_MATCHES}|Sets the host IP address regex filter to use in hypervisor discovery for excluding.
|`CHANGE_IF_NEEDED`| |{$OPENSTACK.AVAILABILITY_ZONE.DISCOVERY.NAME.MATCHES}|Sets the zone name regex filter to use in availability zone discovery for including.
|`.*`| |{$OPENSTACK.AVAILABILITY_ZONE.DISCOVERY.NAME.NOT_MATCHES}|Sets the zone name regex filter to use in availability zone discovery for excluding.
|`CHANGE_IF_NEEDED`| ### Items |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Nova: Get absolute limits|Gets absolute limits for the project.
|HTTP agent|openstack.nova.limits.get**Preprocessing**
JSON Path: `$.limits.absolute`
⛔️Custom on fail: Set error to: `Could not get absolute project limits`
Gets a list of servers.
|HTTP agent|openstack.nova.servers.get**Preprocessing**
JSON Path: `$.servers`
⛔️Custom on fail: Set error to: `Could not get servers list`
Gets a list of compute services and its data.
|HTTP agent|openstack.nova.services.get**Preprocessing**
JSON Path: `$.services`
⛔️Custom on fail: Set error to: `Could not get compute services list`
Gets a list of hypervisors and its data.
|HTTP agent|openstack.nova.hypervisors.get**Preprocessing**
JSON Path: `$.hypervisors`
⛔️Custom on fail: Set error to: `Could not get hypervisors list`
Gets a list of availability zones and its data.
|HTTP agent|openstack.nova.availability_zone.get**Preprocessing**
JSON Path: `$.availabilityZoneInfo`
⛔️Custom on fail: Set error to: `Could not get availability zones list`
Gets a list of tenants and its data.
|Script|openstack.nova.tenant.get**Preprocessing**
JSON Path: `$.tenant_usages`
⛔️Custom on fail: Set error to: `Could not get tenant list`
Number of servers in each tenant.
|Dependent item|openstack.nova.limits.instances.current**Preprocessing**
JSON Path: `$.totalInstancesUsed`
Number of allowed servers for each tenant.
|Dependent item|openstack.nova.limits.instances.max**Preprocessing**
JSON Path: `$.maxTotalInstances`
Number of available servers for each tenant.
|Calculated|openstack.nova.limits.instances.free**Preprocessing**
Discard unchanged with heartbeat: `1h`
Number of used server cores in each tenant.
|Dependent item|openstack.nova.limits.vcpu.current**Preprocessing**
JSON Path: `$.totalCoresUsed`
Number of allowed server cores for each tenant.
|Dependent item|openstack.nova.limits.vcpu.max**Preprocessing**
JSON Path: `$.maxTotalCores`
Number of available server cores for each tenant.
|Calculated|openstack.nova.limits.vcpu.free**Preprocessing**
Discard unchanged with heartbeat: `1h`
Amount of used server RAM.
|Dependent item|openstack.nova.limits.ram.current**Preprocessing**
JSON Path: `$.totalRAMUsed`
Custom multiplier: `1048576`
Amount of allowed server RAM.
|Dependent item|openstack.nova.limits.ram.max**Preprocessing**
JSON Path: `$.maxTotalRAMSize`
Custom multiplier: `1048576`
Amount of available server RAM.
|Calculated|openstack.nova.limits.ram.free**Preprocessing**
Discard unchanged with heartbeat: `1h`
Current instances count has exceeded {$OPENSTACK.NOVA.INSTANCES.UTIL.HIGH}% of the max available instances count.
|`last(/OpenStack Nova by HTTP/openstack.nova.limits.instances.current) >= ({$OPENSTACK.NOVA.INSTANCES.UTIL.HIGH} / 100 * last(/OpenStack Nova by HTTP/openstack.nova.limits.instances.max))`|High|| |Nova: Current instances count is high|Current instances count has exceeded {$OPENSTACK.NOVA.INSTANCES.UTIL.WARN}% of the max available instances count.
|`last(/OpenStack Nova by HTTP/openstack.nova.limits.instances.current) >= ({$OPENSTACK.NOVA.INSTANCES.UTIL.WARN} / 100 * last(/OpenStack Nova by HTTP/openstack.nova.limits.instances.max))`|Warning|**Depends on**:Current vCPU usage has exceeded {$OPENSTACK.NOVA.CPU.UTIL.HIGH}% of the max available vCPU usage.
|`last(/OpenStack Nova by HTTP/openstack.nova.limits.vcpu.current) >= ({$OPENSTACK.NOVA.CPU.UTIL.HIGH} / 100 * last(/OpenStack Nova by HTTP/openstack.nova.limits.vcpu.max))`|High|| |Nova: Current vCPU usage is high|Current vCPU usage has exceeded {$OPENSTACK.NOVA.CPU.UTIL.WARN}% of the max available vCPU usage.
|`last(/OpenStack Nova by HTTP/openstack.nova.limits.vcpu.current) >= ({$OPENSTACK.NOVA.CPU.UTIL.WARN} / 100 * last(/OpenStack Nova by HTTP/openstack.nova.limits.vcpu.max))`|Warning|**Depends on**:Current RAM usage has exceeded {$OPENSTACK.NOVA.RAM.UTIL.HIGH}% of the max available RAM usage.
|`last(/OpenStack Nova by HTTP/openstack.nova.limits.ram.current) >= ({$OPENSTACK.NOVA.RAM.UTIL.HIGH} / 100 * last(/OpenStack Nova by HTTP/openstack.nova.limits.ram.max))`|High|| |Nova: Current RAM usage is high|Current RAM usage has exceeded {$OPENSTACK.NOVA.RAM.UTIL.WARN}% of the max available RAM usage.
|`last(/OpenStack Nova by HTTP/openstack.nova.limits.ram.current) >= ({$OPENSTACK.NOVA.RAM.UTIL.WARN} / 100 * last(/OpenStack Nova by HTTP/openstack.nova.limits.ram.max))`|Warning|**Depends on**:Discovers OpenStack Nova servers.
|Dependent item|openstack.nova.server.discovery**Preprocessing**
Discard unchanged with heartbeat: `1h`
Server status.
|HTTP agent|openstack.nova.server.status.get[{#SERVER_ID}]**Preprocessing**
JSON Path: `$.server.status`
⛔️Custom on fail: Set error to: `Could not parse the detailed server report`
JavaScript: `The text is too long. Please see the template.`
Discard unchanged with heartbeat: `1h`
Server is in "ERROR" status.
|`last(/OpenStack Nova by HTTP/openstack.nova.server.status.get[{#SERVER_ID}])=5`|High|**Manual close**: Yes| |Server [{#SERVER_ID}]:[{#SERVER_NAME}]: Status has changed|Status of the server has changed. Acknowledge to close the problem manually.
|`last(/OpenStack Nova by HTTP/openstack.nova.server.status.get[{#SERVER_ID}])<>last(/OpenStack Nova by HTTP/openstack.nova.server.status.get[{#SERVER_ID}],#2) and length(last(/OpenStack Nova by HTTP/openstack.nova.server.status.get[{#SERVER_ID}]))>0`|Info|**Manual close**: YesDiscovers OpenStack compute services.
|Dependent item|openstack.nova.services.discovery**Preprocessing**
Discard unchanged with heartbeat: `1h`
Raw data of the service.
|Dependent item|openstack.nova.services.raw[{#ID}]**Preprocessing**
JSON Path: `$[?(@.id == "{#ID}")].first()`
⛔️Custom on fail: Set error to: `Could not parse the detailed services report`
State of the service.
|Dependent item|openstack.nova.services.state[{#ID}]**Preprocessing**
JSON Path: `$.state`
⛔️Custom on fail: Set error to: `Could not parse the detailed services report`
JavaScript: `The text is too long. Please see the template.`
Discard unchanged with heartbeat: `1h`
Status of the service.
|Dependent item|openstack.nova.services.status[{#ID}]**Preprocessing**
JSON Path: `$.status`
⛔️Custom on fail: Set error to: `Could not parse the detailed services report`
JavaScript: `The text is too long. Please see the template.`
Discard unchanged with heartbeat: `1h`
Reason for disabling a service.
|Dependent item|openstack.nova.services.disabled.reason[{#ID}]**Preprocessing**
JSON Path: `$.disabled_reason`
⛔️Custom on fail: Set error to: `Could not parse the detailed services report`
Discard unchanged with heartbeat: `1h`
State of the service is "down".
|`last(/OpenStack Nova by HTTP/openstack.nova.services.state[{#ID}])=0`|Warning|**Manual close**: Yes| |Compute service [{#HOST}]:[{#BINARY}]:[{#ID}]: Status is "disabled"|Status of the server is disabled. Acknowledge to close the problem manually.
|`last(/OpenStack Nova by HTTP/openstack.nova.services.status[{#ID}])=0 and length(last(/OpenStack Nova by HTTP/openstack.nova.services.disabled.reason[{#ID}]))>=0`|Info|**Manual close**: Yes| ### LLD rule Nova: Hypervisor discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Nova: Hypervisor discovery|Discovers OpenStack Nova hypervisors.
|Dependent item|openstack.nova.hypervisors.discovery**Preprocessing**
Discard unchanged with heartbeat: `1h`
Raw data of the hypervisor.
|Dependent item|openstack.nova.hypervisors.raw[{#ID}]**Preprocessing**
JSON Path: `$[?(@.id == "{#ID}")].first()`
⛔️Custom on fail: Set error to: `Could not parse the detailed hypervisor report`
State of the hypervisor.
|Dependent item|openstack.nova.hypervisors.state[{#ID}]**Preprocessing**
JSON Path: `$.state`
⛔️Custom on fail: Set error to: `Could not parse the detailed hypervisor report`
JavaScript: `The text is too long. Please see the template.`
Discard unchanged with heartbeat: `1h`
Status of the hypervisor.
|Dependent item|openstack.nova.hypervisors.status[{#ID}]**Preprocessing**
JSON Path: `$.status`
⛔️Custom on fail: Set error to: `Could not parse the detailed hypervisor report`
JavaScript: `The text is too long. Please see the template.`
Discard unchanged with heartbeat: `1h`
Hypervisor version.
|Dependent item|openstack.nova.hypervisors.version[{#ID}]**Preprocessing**
JSON Path: `$.hypervisor_version`
⛔️Custom on fail: Set error to: `Could not parse the detailed hypervisor report`
Discard unchanged with heartbeat: `1h`
State of the hypervisor is "down".
|`last(/OpenStack Nova by HTTP/openstack.nova.hypervisors.state[{#ID}])=0`|Warning|**Manual close**: Yes| |Hypervisor [{#ID}]:[{#HOSTNAME}]: Status is "disabled"|Status of the hypervisor is disabled.
|`last(/OpenStack Nova by HTTP/openstack.nova.hypervisors.status[{#ID}])=0`|Info|**Manual close**: Yes| |Hypervisor [{#ID}]:[{#HOSTNAME}]: Version has changed|Version of the hypervisor has changed. Acknowledge to close the problem manually.
|`last(/OpenStack Nova by HTTP/openstack.nova.hypervisors.version[{#ID}])<>last(/OpenStack Nova by HTTP/openstack.nova.hypervisors.version[{#ID}],#2) and length(last(/OpenStack Nova by HTTP/openstack.nova.hypervisors.version[{#ID}]))>0`|Info|**Manual close**: Yes| ### LLD rule Nova: Availability zones discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Nova: Availability zones discovery|Discovers OpenStack Nova availability zones.
|Dependent item|openstack.nova.availability_zone.discovery**Preprocessing**
Discard unchanged with heartbeat: `1h`
Raw data of the availability zone.
|Dependent item|openstack.nova.availability_zone.raw[{#ZONE_NAME}]**Preprocessing**
JSON Path: `$[?(@.zoneName == "{#ZONE_NAME}")].first()`
⛔️Custom on fail: Set error to: `Could not parse the detailed availability zone report`
Current state of the availability zone.
|Dependent item|openstack.nova.availability_zone.state[{#ZONE_NAME}]**Preprocessing**
JSON Path: `$.zoneState.available`
⛔️Custom on fail: Set error to: `Could not parse the detailed availability zone report`
Discard unchanged with heartbeat: `1h`
Count of hosts and service objects under single availability zone.
|Dependent item|openstack.nova.availability_zone.host_count[{#ZONE_NAME}]**Preprocessing**
JSON Path: `$['hosts'].[*].[*].length()`
⛔️Custom on fail: Set error to: `Could not parse the detailed availability zone report`
Discard unchanged with heartbeat: `1h`
Availability zone is not available.
|`last(/OpenStack Nova by HTTP/openstack.nova.availability_zone.state[{#ZONE_NAME}])=0`|Warning|**Manual close**: Yes| ### LLD rule Nova: Tenant discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |Nova: Tenant discovery|Discovers tenants and their usage data.
|Dependent item|openstack.nova.tenant.discovery**Preprocessing**
Discard unchanged with heartbeat: `1h`
Raw data of the tenant.
|Dependent item|openstack.nova.tenant.raw[{#TENANT_ID}]**Preprocessing**
JSON Path: `$[?(@.tenant_id == "{#TENANT_ID}")].first()`
⛔️Custom on fail: Set error to: `Could not parse the tenant report`
Total duration that the servers exist (in hours).
|Dependent item|openstack.nova.tenant.total_hours[{#TENANT_ID}]**Preprocessing**
JSON Path: `$.total_hours`
⛔️Custom on fail: Set error to: `Could not parse the detailed tenant report`
JavaScript: `return Math.round(value * 100) / 100;`
Discard unchanged with heartbeat: `1h`
Total vCPU usage hours for the current tenant (project).
Multiplying the number of virtual CPUs of the server by hours the server exists, and then adding that all together for each server.
|Dependent item|openstack.nova.tenant.total_vcpu[{#TENANT_ID}]**Preprocessing**
JSON Path: `$.total_vcpus_usage`
⛔️Custom on fail: Set error to: `Could not parse the detailed tenant report`
JavaScript: `return Math.round(value * 100) / 100;`
Discard unchanged with heartbeat: `1h`
Total disk usage hours for the current tenant (project).
Multiplying the server disk size (in GiB) by hours the server exists, and then adding that all together for each server.
|Dependent item|openstack.nova.tenant.disk_usage[{#TENANT_ID}]**Preprocessing**
JSON Path: `$.total_local_gb_usage`
⛔️Custom on fail: Set error to: `Could not parse the detailed tenant report`
JavaScript: `return Math.round(value * 100) / 100;`
Discard unchanged with heartbeat: `1h`
Total memory usage hours for the current tenant (project).
Multiplying the server memory size (in MiB) by hours the server exists, and then adding that all together for each server.
|Dependent item|openstack.nova.tenant.total_memory_mb_usage[{#TENANT_ID}]**Preprocessing**
JSON Path: `$.total_memory_mb_usage`
⛔️Custom on fail: Set error to: `Could not parse the detailed tenant report`
JavaScript: `return Math.round(value * 100) / 100;`
Discard unchanged with heartbeat: `1h`
API endpoint for Identity Service, e.g., https://local.openstack:5000.
|| |{$OPENSTACK.AUTH.INTERVAL}|API token regeneration interval, in minutes. By default, OpenStack API tokens expire after 60m.
|`50m`| |{$OPENSTACK.HTTP.PROXY}|Sets the HTTP proxy for the authorization item. Host prototypes will also use this value for HTTP proxy. If this parameter is empty, then no proxy is used.
|| |{$OPENSTACK.APP.CRED.ID}|Application credential ID for monitoring user access.
|| |{$OPENSTACK.APP.CRED.SECRET}|Application credential password for monitoring user access.
|| ### Items |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |OpenStack: Get access token and service catalog|Authorizes user on the OpenStack Identity service and gets the service catalog.
|Script|openstack.identity.auth| ### LLD rule OpenStack: Nova discovery |Name|Description|Type|Key and additional info| |----|-----------|----|-----------------------| |OpenStack: Nova discovery|Discovers OpenStack services from the monitoring user's services catalog.
|Dependent item|openstack.services.nova.discovery| ## Feedback Please report any issues with the template at [`https://support.zabbix.com`](https://support.zabbix.com) You can also provide feedback, discuss the template, or ask for help at [`ZABBIX forums`](https://www.zabbix.com/forum/zabbix-suggestions-and-feedback)