From 2467ebde1b2cc58ab1d9efacc1249bffaaaa9f15 Mon Sep 17 00:00:00 2001 From: victorvassilev <19683390+victorvassilev@users.noreply.github.com> Date: Fri, 6 Mar 2020 14:52:32 +0200 Subject: [PATCH] feat(api): add eventlog listing (#8381) * Adapt font regexp path for Windows (#8375) * enh(apiv2): add event listing for hosts and services Resolves: MON-4866, MON-4867 * enh(apiv2): add event listing for hosts and services Resolves: MON-4866, MON-4867 * fix(doc): regenerate html for doc * feat(ui): Implement Resources listing (#8371) * fix(tests): update error message on unit test * Fix the search parameter 'IN' (#8380) * fix(doc): fix scrollbar issue in API documentation (#8378) * feat(build): stash git sources for Sonar analysis. * feat(ui): Implement Unified view search (#8382) * feat(build): fail build on front-end style errors. * enh(doc): update docblock in interface * fix: fix ESLint warnings * doc(api): document how to use search parameter with API (#8376) * fix(test): improve unit test SqlRequestParametersTranslatorTest::testTranslateSortParameterToSql * fix(configuration): export hosts geo_coords to remote server (#8390) * fix(ldap): use define user member_attribute var (#8287) * fix(ldap): use define user member_attribute var * fix(code): use PSR2 * feat(ui): Implement Unified view downtime and acknowledge tooltips (#8385) * fix(code): Clean switch case service monitoring (#8285) * fix(code): dedicated meta event console does not exist anymore * fix(code): scheduling queue console does not exist anymore * fix(code): merge some cases Co-authored-by: Colin Gagnaire * fix(remote-server): fix import with strict mode (#7944) Refs: MON-7944 * doc(api): document how to generate html api documentation (#8394) * feat(doc): update the API documentation (#8393) * feat(doc): update the API documentation Resolve MON-4887 * fix(doc): apply feedback from PR Resolve MON-4887 * fix(doc): remove again api html documentation * Update src/Centreon/Domain/Monitoring/Entity/DowntimeEventObject.php Co-Authored-By: Kevin Duret * Update src/Centreon/Domain/Monitoring/Interfaces/TimelineRepositoryInterface.php Co-Authored-By: Kevin Duret * Update src/Centreon/Domain/Monitoring/Interfaces/EventObjectInterface.php Co-Authored-By: Kevin Duret * Update package-lock * enh(apiv2): add event listing for hosts and services Resolves: MON-4866, MON-4867 * fix(doc): regenerate html for doc * fix(tests): update error message on unit test * enh(doc): update docblock in interface * Update src/Centreon/Domain/Monitoring/Entity/DowntimeEventObject.php Co-Authored-By: Kevin Duret * Update src/Centreon/Domain/Monitoring/Interfaces/TimelineRepositoryInterface.php Co-Authored-By: Kevin Duret * Update src/Centreon/Domain/Monitoring/Interfaces/EventObjectInterface.php Co-Authored-By: Kevin Duret * resolve conflict with html doc Co-authored-by: Tom Darneix Co-authored-by: Bruno d'Auria Co-authored-by: Laurent Calvet Co-authored-by: Kevin Duret Co-authored-by: Matthieu Kermagoret Co-authored-by: Valentin Hristov Co-authored-by: Colin Gagnaire --- config/Modules/Centreon.yaml | 7 + .../Acknowledgement.Acknowledgement.yml | 10 +- .../serializer/Centreon/Downtime.Downtime.yml | 14 +- .../Monitoring.Entity.AckEventObject.yml | 10 + .../Monitoring.Entity.CommentEventObject.yml | 7 + .../Monitoring.Entity.DowntimeEventObject.yml | 10 + .../Monitoring.Entity.LogEventObject.yml | 7 + .../Centreon/Monitoring.Model.Comment.yml | 27 + .../Centreon/Monitoring.Model.Log.yml | 46 + .../Centreon/Monitoring.TimelineEvent.yml | 18 + config/routes/Centreon/monitoring.yaml | 12 + doc/API/centreon-api-v2.html | 842 ++++++++++++++++++ doc/API/centreon-api-v2.yaml | 56 ++ .../Controller/MonitoringHostsController.php | 44 + .../MonitoringServicesController.php | 48 + .../Acknowledgement/Acknowledgement.php | 10 +- src/Centreon/Domain/Entity/EntityCreator.php | 2 +- .../Monitoring/Entity/AckEventObject.php | 100 +++ .../Monitoring/Entity/CommentEventObject.php | 79 ++ .../Monitoring/Entity/DowntimeEventObject.php | 126 +++ .../Monitoring/Entity/LogEventObject.php | 129 +++ .../Interfaces/EventObjectInterface.php | 44 + .../Interfaces/MonitoringServiceInterface.php | 12 + .../TimelineRepositoryInterface.php | 55 ++ .../Domain/Monitoring/Model/Comment.php | 341 +++++++ src/Centreon/Domain/Monitoring/Model/Log.php | 344 +++++++ .../Domain/Monitoring/MonitoringService.php | 22 +- .../Domain/Monitoring/TimelineEvent.php | 88 ++ .../Monitoring/TimelineRepositoryRDB.php | 430 +++++++++ .../Monitoring/MonitoringServiceTest.php | 31 + 30 files changed, 2962 insertions(+), 9 deletions(-) create mode 100644 config/packages/serializer/Centreon/Monitoring.Entity.AckEventObject.yml create mode 100644 config/packages/serializer/Centreon/Monitoring.Entity.CommentEventObject.yml create mode 100644 config/packages/serializer/Centreon/Monitoring.Entity.DowntimeEventObject.yml create mode 100644 config/packages/serializer/Centreon/Monitoring.Entity.LogEventObject.yml create mode 100644 config/packages/serializer/Centreon/Monitoring.Model.Comment.yml create mode 100644 config/packages/serializer/Centreon/Monitoring.Model.Log.yml create mode 100644 config/packages/serializer/Centreon/Monitoring.TimelineEvent.yml create mode 100644 doc/API/centreon-api-v2.html create mode 100644 src/Centreon/Domain/Monitoring/Entity/AckEventObject.php create mode 100644 src/Centreon/Domain/Monitoring/Entity/CommentEventObject.php create mode 100644 src/Centreon/Domain/Monitoring/Entity/DowntimeEventObject.php create mode 100644 src/Centreon/Domain/Monitoring/Entity/LogEventObject.php create mode 100644 src/Centreon/Domain/Monitoring/Interfaces/EventObjectInterface.php create mode 100644 src/Centreon/Domain/Monitoring/Interfaces/TimelineRepositoryInterface.php create mode 100644 src/Centreon/Domain/Monitoring/Model/Comment.php create mode 100644 src/Centreon/Domain/Monitoring/Model/Log.php create mode 100644 src/Centreon/Domain/Monitoring/TimelineEvent.php create mode 100644 src/Centreon/Infrastructure/Monitoring/TimelineRepositoryRDB.php diff --git a/config/Modules/Centreon.yaml b/config/Modules/Centreon.yaml index 485e0e2bf67..01d67416a89 100644 --- a/config/Modules/Centreon.yaml +++ b/config/Modules/Centreon.yaml @@ -133,3 +133,10 @@ services: calls: - method: setSqlRequestTranslator arguments: ['@sqlRequestTranslator'] + + # Monitoring Timeline + Centreon\Domain\Monitoring\Interfaces\TimelineRepositoryInterface: + class: Centreon\Infrastructure\Monitoring\TimelineRepositoryRDB + calls: + - method: setSqlRequestTranslator + arguments: ['@sqlRequestTranslator'] \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Acknowledgement.Acknowledgement.yml b/config/packages/serializer/Centreon/Acknowledgement.Acknowledgement.yml index e666fb39c55..34a430e4ef1 100644 --- a/config/packages/serializer/Centreon/Acknowledgement.Acknowledgement.yml +++ b/config/packages/serializer/Centreon/Acknowledgement.Acknowledgement.yml @@ -4,6 +4,7 @@ Centreon\Domain\Acknowledgement\Acknowledgement: type: int groups: - 'ack_main' + - 'ack_event_list' authorId: type: int groups: @@ -12,14 +13,17 @@ Centreon\Domain\Acknowledgement\Acknowledgement: type: string groups: - 'ack_main' + - 'ack_event_list' deletionTime: type: DateTime groups: - 'ack_main' + - 'ack_event_list' entryTime: type: DateTime groups: - 'ack_main' + - 'ack_event_list' hostId: type: int groups: @@ -32,14 +36,17 @@ Centreon\Domain\Acknowledgement\Acknowledgement: type: bool groups: - 'ack_main' + - 'ack_event_list' isPersistentComment: type: bool groups: - 'ack_main' + - 'ack_event_list' isSticky: type: bool groups: - 'ack_main' + - 'ack_event_list' serviceId: type: int groups: @@ -47,4 +54,5 @@ Centreon\Domain\Acknowledgement\Acknowledgement: state: type: int groups: - - 'ack_main' \ No newline at end of file + - 'ack_main' + - 'ack_event_list' \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Downtime.Downtime.yml b/config/packages/serializer/Centreon/Downtime.Downtime.yml index f1a044fe09d..90ff947408e 100644 --- a/config/packages/serializer/Centreon/Downtime.Downtime.yml +++ b/config/packages/serializer/Centreon/Downtime.Downtime.yml @@ -4,10 +4,12 @@ Centreon\Domain\Downtime\Downtime: type: int groups: - 'downtime_main' + - 'downtime_event_list' entryTime: type: DateTime groups: - 'downtime_main' + - 'downtime_event_list' authorId: type: int groups: @@ -24,28 +26,34 @@ Centreon\Domain\Downtime\Downtime: type: bool groups: - 'downtime_main' + - 'downtime_event_list' comment: type: string groups: - 'downtime_main' + - 'downtime_event_list' deletionTime: type: DateTime groups: - 'downtime_main' + - 'downtime_event_list' duration: type: int groups: - 'downtime_main' + - 'downtime_event_list' endTime: type: DateTime<'Y-m-d\TH:i:sP'> groups: - 'downtime_main' + - 'downtime_event_list' internalId: type: int isFixed: type: bool groups: - 'downtime_main' + - 'downtime_event_list' pollerId: type: int groups: @@ -54,15 +62,19 @@ Centreon\Domain\Downtime\Downtime: type: DateTime<'Y-m-d\TH:i:sP'> groups: - 'downtime_main' + - 'downtime_event_list' actualStartTime: type: DateTime groups: - 'downtime_main' + - 'downtime_event_list' actualEndTime: type: DateTime groups: - 'downtime_main' + - 'downtime_event_list' isStarted: type: bool groups: - - 'downtime_main' \ No newline at end of file + - 'downtime_main' + - 'downtime_event_list' \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Monitoring.Entity.AckEventObject.yml b/config/packages/serializer/Centreon/Monitoring.Entity.AckEventObject.yml new file mode 100644 index 00000000000..b944c78923d --- /dev/null +++ b/config/packages/serializer/Centreon/Monitoring.Entity.AckEventObject.yml @@ -0,0 +1,10 @@ +Centreon\Domain\Monitoring\Entity\AckEventObject: + properties: + id: + type: int + groups: + - 'ack_event_list' + author: + type: string + groups: + - 'ack_event_list' \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Monitoring.Entity.CommentEventObject.yml b/config/packages/serializer/Centreon/Monitoring.Entity.CommentEventObject.yml new file mode 100644 index 00000000000..a68e0aea5e4 --- /dev/null +++ b/config/packages/serializer/Centreon/Monitoring.Entity.CommentEventObject.yml @@ -0,0 +1,7 @@ +Centreon\Domain\Monitoring\Entity\CommentEventObject: + properties: + id: + type: int + groups: + - 'comment_event_list' + - 'comment_event_full' \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Monitoring.Entity.DowntimeEventObject.yml b/config/packages/serializer/Centreon/Monitoring.Entity.DowntimeEventObject.yml new file mode 100644 index 00000000000..bcbd4c56d55 --- /dev/null +++ b/config/packages/serializer/Centreon/Monitoring.Entity.DowntimeEventObject.yml @@ -0,0 +1,10 @@ +Centreon\Domain\Monitoring\Entity\DowntimeEventObject: + properties: + id: + type: int + groups: + - 'downtime_event_list' + author: + type: string + groups: + - 'downtime_event_list' \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Monitoring.Entity.LogEventObject.yml b/config/packages/serializer/Centreon/Monitoring.Entity.LogEventObject.yml new file mode 100644 index 00000000000..9760919c8f9 --- /dev/null +++ b/config/packages/serializer/Centreon/Monitoring.Entity.LogEventObject.yml @@ -0,0 +1,7 @@ +Centreon\Domain\Monitoring\Entity\LogEventObject: + properties: + id: + type: int + groups: + - 'log_event_list' + - 'log_event_full' \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Monitoring.Model.Comment.yml b/config/packages/serializer/Centreon/Monitoring.Model.Comment.yml new file mode 100644 index 00000000000..ca3bf7042bb --- /dev/null +++ b/config/packages/serializer/Centreon/Monitoring.Model.Comment.yml @@ -0,0 +1,27 @@ +Centreon\Domain\Monitoring\Model\Comment: + properties: + id: + type: int + groups: + - 'comment_event_list' + - 'comment_event_full' + entryTime: + type: DateTime<'Y-m-d\TH:i:sP'> + groups: + - 'comment_event_list' + - 'comment_event_full' + data: + type: string + groups: + - 'comment_event_list' + - 'comment_event_full' + author: + type: string + groups: + - 'comment_event_list' + - 'comment_event_full' + persistent: + type: int + groups: + - 'comment_event_list' + - 'comment_event_full' \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Monitoring.Model.Log.yml b/config/packages/serializer/Centreon/Monitoring.Model.Log.yml new file mode 100644 index 00000000000..721f266fe68 --- /dev/null +++ b/config/packages/serializer/Centreon/Monitoring.Model.Log.yml @@ -0,0 +1,46 @@ +Centreon\Domain\Monitoring\Model\Log: + properties: + id: + type: int + groups: + - 'log_event_list' + - 'log_event_full' + output: + type: string + groups: + - 'log_event_list' + - 'log_event_full' + createTime: + type: DateTime<'Y-m-d\TH:i:sP'> + groups: + - 'log_event_list' + - 'log_event_full' + status: + type: string + accessor: + getter: getStatusText + groups: + - 'log_event_list' + - 'log_event_full' + type: + type: string + accessor: + getter: getTypeText + groups: + - 'log_event_list' + - 'log_event_full' + retry: + type: int + groups: + - 'log_event_list' + - 'log_event_full' + contact: + type: string + groups: + - 'log_event_list' + - 'log_event_full' + command: + type: string + groups: + - 'log_event_list' + - 'log_event_full' \ No newline at end of file diff --git a/config/packages/serializer/Centreon/Monitoring.TimelineEvent.yml b/config/packages/serializer/Centreon/Monitoring.TimelineEvent.yml new file mode 100644 index 00000000000..d5de094ec19 --- /dev/null +++ b/config/packages/serializer/Centreon/Monitoring.TimelineEvent.yml @@ -0,0 +1,18 @@ +Centreon\Domain\Monitoring\TimelineEvent: + virtual_properties: + getType: + serialized_name: type + groups: + - 'timeline_list' + getId: + serialized_name: id + groups: + - 'timeline_list' + getTimestamp: + serialized_name: date + groups: + - 'timeline_list' + properties: + object: + groups: + - 'timeline_list' \ No newline at end of file diff --git a/config/routes/Centreon/monitoring.yaml b/config/routes/Centreon/monitoring.yaml index c8e277882cd..1d3ac95fb74 100644 --- a/config/routes/Centreon/monitoring.yaml +++ b/config/routes/Centreon/monitoring.yaml @@ -52,4 +52,16 @@ centreon_application_monitoring_gethostgroupsbyhost: methods: GET path: /monitoring/hosts/{hostId}/hostgroups controller: 'Centreon\Application\Controller\MonitoringHostsController::getHostGroupsByHost' + condition: "request.attributes.get('version.is_beta') == true" + +centreon_application_monitoring_gettimelinebyhostandservice: + methods: GET + path: /monitoring/hosts/{hostId}/services/{serviceId}/timeline + controller: 'Centreon\Application\Controller\MonitoringServicesController::getServiceTimeline' + condition: "request.attributes.get('version.is_beta') == true" + +centreon_application_monitoring_gettimelinebyhost: + methods: GET + path: /monitoring/hosts/{hostId}/timeline + controller: 'Centreon\Application\Controller\MonitoringHostsController::getHostTimeline' condition: "request.attributes.get('version.is_beta') == true" \ No newline at end of file diff --git a/doc/API/centreon-api-v2.html b/doc/API/centreon-api-v2.html new file mode 100644 index 00000000000..09816c9f72e --- /dev/null +++ b/doc/API/centreon-api-v2.html @@ -0,0 +1,842 @@ + + + + + + Centreon Web RestAPI + + + + + + + + + +

New features

    +
  • Added real-time monitoring for hosts and services
  • +
  • Added acknowledgement for hosts and services
  • +
  • Added downtimes for hosts and services
  • +
  • Added the list of monitoring server configurations
  • +
  • Added the proxy configuration
  • +
+

Information

All dates are in ISO 8601 format

+

Authentication

There are two modes of authentication:

+
    +
  • By token: after identification with your login credentials
  • +
  • By cookie: by reusing a valid session ID
  • +
+

Token

The use of the API requires a security token.

+

To retrieve it, you will need to authenticate yourself with your login credentials.

+

The token will be deleted if it has not been used for more than one hour.

+
Security Scheme Type API Key
Header parameter name: X-AUTH-TOKEN

Cookie

If you have already connected on the Centreon web application, you can reused the PHPSESSID cookie.

+

The cookie will be valid as long as the connection to Centreon is maintained.

+
Security Scheme Type API Key
Cookie parameter name: PHPSESSID

Authentication

Login and logout endpoints to retrieve authentication token

+

Login

Entry point to retrieve an authentication token.

+
Request Body schema: application/json

Authentication schema

+
security
object

Responses

200

OK

+
401

Unauthorized

+
post /login
{protocol}://{server}:{port}/centreon/api/{version}/login

Request samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "security":
    {
    }
}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "contact":
    {
    },
  • "security":
    {
    }
}

Logout

Entry point to delete an existing authentication token.

+
Authorizations:

Responses

200

OK

+
403

Forbidden

+
get /logout
{protocol}://{server}:{port}/centreon/api/{version}/logout

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "message": "Successful logout"
}

Proxy

Display the default configuration of the Centreon proxy

Authorizations:

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /configuration/proxy
{protocol}://{server}:{port}/centreon/api/{version}/configuration/proxy

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "url": "proxy.internal.company.org",
  • "port": 3128,
  • "user": "proxy-user",
  • "password": "proxy-pass"
}

Update the default configuration of the Centreon proxy

Authorizations:
Request Body schema: application/json
url
required
string

URL of the proxy

+
port
required
integer [ 0 .. 65535 ]

Port of the proxy

+
user
required
string

Login used to connect to proxy

+
password
required
string

Password used to connect to proxy

+

Responses

204

Command Sent

+
403

Forbidden

+
500

Internal Server Error

+
put /configuration/proxy
{protocol}://{server}:{port}/centreon/api/{version}/configuration/proxy

Request samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "url": "proxy.internal.company.org",
  • "port": 3128,
  • "user": "proxy-user",
  • "password": "proxy-pass"
}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

Monitoring Server

List all monitoring servers configurations

List all monitoring servers configurations.

+

The available parameters to search / sort_by are:

+
    +
  • id
  • +
  • name
  • +
  • is_localhost
  • +
  • address
  • +
  • is_activate
  • +
+
Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /configuration/monitoring-servers
{protocol}://{server}:{port}/centreon/api/{version}/configuration/monitoring-servers

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Host

List all hosts

List all the hosts in real-time monitoring.

+

The available parameters to search / sort_by are:

+
    +
  • host.id
  • +
  • host.name
  • +
  • host.alias
  • +
  • host.address
  • +
  • host.state
  • +
  • poller.id
  • +
  • service.display_name
  • +
  • host_group.id
  • +
  • host.is_acknowledged
  • +
  • host.downtime
  • +
  • host.criticality
  • +
+
Authorizations:
query Parameters
show_service
boolean
Default: false
Example: show_service=true

Allows to display services belonging to items

+
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hosts
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Get a host

Return a single host with full details and some details about its services.

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+

Responses

200

OK

+
403

Forbidden

+
404

Not Found

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "id": 12,
  • "alias": "Central",
  • "display_name": "Central",
  • "name": "Central",
  • "state": 0,
  • "services":
    [
    ],
  • "poller_id": 1,
  • "acknowledged": false,
  • "address_ip": "127.0.0.1",
  • "check_attempt": 1,
  • "checked": true,
  • "execution_time": 0.070906,
  • "icon_image": "ppm/operatingsystems-linux-snmp-linux-128.png",
  • "icon_image_alt": "",
  • "last_check": "2020-03-06T12:41:44Z",
  • "last_hard_state_change": "2020-03-06T12:41:44Z",
  • "last_state_change": "2020-03-06T12:41:44Z",
  • "last_time_down": "2020-03-06T12:41:44Z",
  • "last_time_unreachable": "2020-03-06T12:41:44Z",
  • "last_time_up": "2020-03-06T12:41:44Z",
  • "last_update": "2020-03-06T12:41:44Z",
  • "max_check_attempts": 3,
  • "output": "OK - 127.0.0.1 rta 0.100ms lost 0%\n",
  • "passive_checks": false,
  • "state_type": 0,
  • "timezone": ":Europe/Paris",
  • "scheduled_downtime_depth": 0,
  • "criticality": 10,
  • "active_checks": true,
  • "check_command": "base_host_alive",
  • "check_interval": 5,
  • "check_period": "24x7",
  • "check_type": 0,
  • "last_hard_state": "2020-03-06T12:41:44Z",
  • "last_notification": "2020-03-06T12:41:44Z",
  • "latency": 0.005,
  • "next_check": "2020-03-06T12:41:44Z",
  • "next_host_notification": 0,
  • "notification_interval": 30,
  • "notification_number": 3,
  • "notify": true,
  • "notify_on_down": true,
  • "notify_on_downtime": false,
  • "notify_on_flapping": false,
  • "notify_on_recovery": true,
  • "notify_on_unreachable": false
}

Service

List all services

List all the services in real-time monitoring.

+

The available parameters to search / sort_by are:

+
    +
  • host.id
  • +
  • host.name
  • +
  • host.alias
  • +
  • host.address
  • +
  • host.state
  • +
  • host_group.id
  • +
  • service.display_name
  • +
  • service.description
  • +
  • service.is_acknowledged
  • +
  • service.output
  • +
  • service.state
  • +
  • service_group.id
  • +
  • poller.id
  • +
  • service.downtime
  • +
  • service.criticality
  • +
+
Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/services
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/services

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

List services related to a host

List all services related to a host in real-time monitoring.

+

The available parameters to search / sort_by are:

+
    +
  • service.id
  • +
  • service.description
  • +
  • service.display_name
  • +
  • service_group.id
  • +
  • service.is_acknowledged
  • +
  • service.state
  • +
+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
404

Not Found

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/services
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Get a service

Return a single service with full details.

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+

Responses

200

OK

+
403

Forbidden

+
404

Not Found

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/services/{service_id}
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "id": 5,
  • "description": "Ping",
  • "display_name": "Ping",
  • "state": 0,
  • "check_attempt": 1,
  • "icon_image": "",
  • "icon_image_alt": "",
  • "last_check": "2020-03-06T12:41:44Z",
  • "last_state_change": "2020-03-06T12:41:44Z",
  • "max_check_attempts": 3,
  • "output": "OK - 127.0.0.1 rta 0.025ms lost 0%\n",
  • "state_type": 1,
  • "criticality": 10,
  • "check_command": "base_centreon_ping",
  • "check_interval": 5,
  • "check_period": "24x7",
  • "check_type": 0,
  • "command_line": "/usr/lib64/nagios/plugins/check_icmp -H 127.0.0.1 -n 5 -w 200,20% -c 400,50%",
  • "execution_time": 0.179335,
  • "is_acknowledged": false,
  • "is_active_check": true,
  • "is_checked": true,
  • "last_hard_state_change": "2020-03-06T12:41:44Z",
  • "last_notification": "2020-03-06T12:41:44Z",
  • "last_time_critical": "2020-03-06T12:41:44Z",
  • "last_time_ok": "2020-03-06T12:41:44Z",
  • "last_time_unknown": "2020-03-06T12:41:44Z",
  • "last_time_warning": "2020-03-06T12:41:44Z",
  • "last_update": "2020-03-06T12:41:44Z",
  • "latency": 0.031,
  • "next_check": "2020-03-06T12:41:44Z",
  • "performance_data": "rta=0.025ms;200.000;400.000;0; rtmax=0.061ms;;;; rtmin=0.015ms;;;; pl=0%;20;50;0;100 ",
  • "scheduled_downtime_depth": 0
}

Host Group

List all host groups by host id

List all the host groups in real-time monitoring by host id

+
Authorizations:
query Parameters
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/hostgroups
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/hostgroups

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

List all host groups

List all the host groups in real-time monitoring.

+

The available parameters to search / sort_by are:

+
    +
  • host.id
  • +
  • host.name
  • +
  • host.alias
  • +
  • host.address
  • +
  • host.state
  • +
  • poller.id
  • +
  • service.display_name
  • +
  • host_group.id
  • +
+
Authorizations:
query Parameters
show_host
boolean
Default: false
Example: show_host=true

Allows to display hosts belonging to items

+
show_service
boolean
Default: false
Example: show_service=true

Allows to display services belonging to items

+
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hostgroups
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hostgroups

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Service Group

Get service groups by host id and service id

Return a list of service groups for host-service pair.

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+

Responses

200

OK

+
403

Forbidden

+
404

Not Found

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/services/{service_id}/servicegroups
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/servicegroups

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "id": 13,
  • "name": "MySG",
  • "host":
    {
    }
}

List all service groups

List all the service groups in real-time monitoring.

+

The available parameters to search / sort_by are:

+
    +
  • host.id
  • +
  • host.name
  • +
  • host.alias
  • +
  • host.address
  • +
  • host.state
  • +
  • poller.id
  • +
  • service.display_name
  • +
  • service_group.id
  • +
  • service_group.name
  • +
+
Authorizations:
query Parameters
show_service
boolean
Default: false
Example: show_service=true

Allows to display services belonging to items

+
show_host
boolean
Default: false
Example: show_host=true

Allows to display hosts belonging to items

+
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/servicegroups
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/servicegroups

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Acknowledgement

List all acknowledgements

Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/acknowledgements

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Display one acknowledgement

Display one acknowledgement.

+
Authorizations:
path Parameters
acknowledgement_id
required
integer <int64>
Example: 227

ID of the acknowledgement

+

Responses

200

OK

+
403

Forbidden

+
404

Not Found

+
500

Internal Server Error

+
get /monitoring/acknowledgements/{acknowledgement_id}
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/acknowledgements/{acknowledgement_id}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "id": 34,
  • "author_id": 3,
  • "comment": "Acknowledged by admin",
  • "deletion_time": "2020-03-06T12:41:44Z",
  • "entry_time": "2020-03-06T12:41:44Z",
  • "host_id": 12,
  • "poller_id": 1,
  • "is_notify_contacts": false,
  • "is_persistent_comment": true,
  • "is_sticky": true,
  • "state": 1,
  • "service_id": 5
}

List all hosts acknowledgements

Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hosts/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/acknowledgements

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

List all services acknowledgements

Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/services/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/services/acknowledgements

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

List all acknowledgements of a host

Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/acknowledgements

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Add an acknowledgement on chosen host

Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
Request Body schema: application/json
comment
string

Short description of the acknowledgement

+
is_notify_contacts
boolean

Indicates whether notification is sent to the contacts linked to the host or service

+
is_persistent_comment
boolean

Indicates whether acknowledgement is maintained in the case of a restart of the scheduler

+
is_sticky
boolean

Indicates whether acknowledgement is maintained in the case of a change of status

+

Responses

204

Command Sent

+
403

Forbidden

+
500

Internal Server Error

+
post /monitoring/hosts/{host_id}/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/acknowledgements

Request samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "comment": "Acknowledged by admin",
  • "is_notify_contacts": false,
  • "is_persistent_comment": true,
  • "is_sticky": true
}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

Cancel an acknowledgement on a host

Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+

Responses

204

Command Sent

+
403

Forbidden

+
500

Internal Server Error

+
delete /monitoring/hosts/{host_id}/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/acknowledgements

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

List all acknowledgements of a service

Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/services/{service_id}/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/acknowledgements

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Add an acknowledgement on chosen service

Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+
Request Body schema: application/json
comment
string

Short description of the acknowledgement

+
is_notify_contacts
boolean

Indicates whether notification is sent to the contacts linked to the host or service

+
is_persistent_comment
boolean

Indicates whether acknowledgement is maintained in the case of a restart of the scheduler

+
is_sticky
boolean

Indicates whether acknowledgement is maintained in the case of a change of status

+

Responses

204

Command Sent

+
403

Forbidden

+
500

Internal Server Error

+
post /monitoring/hosts/{host_id}/services/{service_id}/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/acknowledgements

Request samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "comment": "Acknowledged by admin",
  • "is_notify_contacts": false,
  • "is_persistent_comment": true,
  • "is_sticky": true
}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

Cancel an acknowledgement on a service

Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+

Responses

204

Command Sent

+
403

Forbidden

+
500

Internal Server Error

+
delete /monitoring/hosts/{host_id}/services/{service_id}/acknowledgements
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/acknowledgements

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

Downtime

List all downtimes

List all downtimes

+

The available parameters to search / sort_by are:

+
    +
  • id
  • +
  • entry_time
  • +
  • is_cancelled
  • +
  • comment
  • +
  • deletion_time
  • +
  • duration
  • +
  • end_time
  • +
  • is_fixed
  • +
  • start_time
  • +
  • host.id
  • +
  • host.name
  • +
  • host.alias
  • +
  • host.address
  • +
  • host.display_name
  • +
  • host.state
  • +
  • poller.id
  • +
  • contact.id
  • +
  • contact.name
  • +
+
Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/downtimes
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/downtimes

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Display one downtime

Display one downtime.

+
Authorizations:
path Parameters
downtime_id
required
integer <int64>
Example: 329

ID of the downtime

+

Responses

200

OK

+
403

Forbidden

+
404

Not Found

+
500

Internal Server Error

+
get /monitoring/downtimes/{downtime_id}
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/downtimes/{downtime_id}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "id": 329,
  • "author_id": 3,
  • "host_id": 12,
  • "comment": "Downtime set by admin",
  • "duration": 7200,
  • "entry_time": "2020-03-06T12:41:45Z",
  • "start_time": "2020-03-06T12:41:45Z",
  • "end_time": "2020-03-06T12:41:45Z",
  • "deletion_time": null,
  • "actual_start_time": "2020-03-06T12:41:45Z",
  • "actual_end_time": null,
  • "is_started": true,
  • "is_cancelled": false,
  • "is_fixed": true,
  • "service_id": 5
}

Cancel a downtime

Cancel a downtime.

+
Authorizations:
path Parameters
downtime_id
required
integer <int64>
Example: 329

ID of the downtime

+

Responses

204

Command Sent

+
403

Forbidden

+
404

Not Found

+
500

Internal Server Error

+
delete /monitoring/downtimes/{downtime_id}
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/downtimes/{downtime_id}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

List all hosts downtimes

List all downtimes of hosts

+

The available parameters to search / sort_by are:

+
    +
  • id
  • +
  • entry_time
  • +
  • is_cancelled
  • +
  • comment
  • +
  • deletion_time
  • +
  • duration
  • +
  • end_time
  • +
  • is_fixed
  • +
  • start_time
  • +
  • host.id
  • +
  • host.name
  • +
  • host.alias
  • +
  • host.address
  • +
  • host.display_name
  • +
  • host.state
  • +
  • poller.id
  • +
  • contact.id
  • +
  • contact.name
  • +
+
Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hosts/downtimes
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/downtimes

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

List all services downtimes

List all downtimes of services

+

The available parameters to search / sort_by are:

+
    +
  • id
  • +
  • entry_time
  • +
  • is_cancelled
  • +
  • comment
  • +
  • deletion_time
  • +
  • duration
  • +
  • end_time
  • +
  • is_fixed
  • +
  • start_time
  • +
  • host.id
  • +
  • host.name
  • +
  • host.alias
  • +
  • host.address
  • +
  • host.display_name
  • +
  • host.state
  • +
  • poller.id
  • +
  • contact.id
  • +
  • contact.name
  • +
+
Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/services/downtimes
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/services/downtimes

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

List all downtimes of a host

List all downtimes of a host.

+

The available parameters to search / sort_by are:

+
    +
  • id
  • +
  • entry_time
  • +
  • is_cancelled
  • +
  • comment
  • +
  • deletion_time
  • +
  • duration
  • +
  • end_time
  • +
  • is_fixed
  • +
  • start_time
  • +
  • contact.id
  • +
  • contact.name
  • +
+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
query Parameters
show_service
boolean
Default: false
Example: show_service=true

Allows to display services belonging to items

+
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/downtimes
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/downtimes

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Add a downtime on a host

Add a downtime on a host.

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
Request Body schema: application/json
start_time
string <date-time>

Scheduled start date of the downtime (ISO8601)

+
end_time
string <date-time>

Scheduled end date of the downtime (ISO8601)

+
is_fixed
boolean

Indicates whether the downtime is fixed

+
duration
integer

Downtime duration in seconds

+
author_id
integer

ID of the contact who requested the downtime

+
comment
string

Comment of the downtime

+
with_services
boolean

Indicates whether we should add the downtime on the host-related services

+

Responses

204

Command Sent

+
403

Forbidden

+
500

Internal Server Error

+
post /monitoring/hosts/{host_id}/downtimes
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/downtimes

Request samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "start_time": "2020-03-06T12:41:44Z",
  • "end_time": "2020-03-06T12:41:44Z",
  • "is_fixed": true,
  • "duration": 3600,
  • "author_id": 3,
  • "comment": "Downtime set by admin",
  • "with_services": true
}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

List all downtimes of a service

List all downtimes of a service.

+

The available parameters to search / sort_by are:

+
    +
  • id
  • +
  • entry_time
  • +
  • is_cancelled
  • +
  • comment
  • +
  • deletion_time
  • +
  • duration
  • +
  • end_time
  • +
  • is_fixed
  • +
  • start_time
  • +
  • contact.id
  • +
  • contact.name
  • +
+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/services/{service_id}/downtimes
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/downtimes

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Add a downtime on a service

Add a downtime on a service.

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+
Request Body schema: application/json
start_time
string <date-time>

Scheduled start date of the downtime (ISO8601)

+
end_time
string <date-time>

Scheduled end date of the downtime (ISO8601)

+
is_fixed
boolean

Indicates whether the downtime is fixed

+
duration
integer

Downtime duration in seconds

+
author_id
integer

ID of the contact who requested the downtime

+
comment
string

Comment of the downtime

+

Responses

204

Command Sent

+
403

Forbidden

+
500

Internal Server Error

+
post /monitoring/hosts/{host_id}/services/{service_id}/downtimes
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/downtimes

Request samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "start_time": "2020-03-06T12:41:44Z",
  • "end_time": "2020-03-06T12:41:44Z",
  • "is_fixed": true,
  • "duration": 3600,
  • "author_id": 3,
  • "comment": "Downtime set by admin"
}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

Resource

List all resources including hosts and services

List all the resources in real-time monitoring : hosts and services.

+

The available parameters to search / sort_by are:

+
    +
  • id
  • +
  • name
  • +
  • type
  • +
  • status_code
  • +
  • status
  • +
  • action_url
  • +
  • details_url
  • +
  • parent_name
  • +
  • parent_status
  • +
  • severity_level
  • +
  • in_downtime
  • +
  • acknowledged
  • +
  • impacted_resources_count
  • +
  • last_status_change
  • +
  • tries
  • +
  • last_check
  • +
  • information
  • +
+

Only for searching:

+
+
    +
  • host.group
  • +
  • host.group.id
  • +
  • host.name
  • +
  • host.alias
  • +
  • host.address
  • +
  • service.description
  • +
  • service.group
  • +
  • service.group.id
  • +
+
Authorizations:
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+
types
Array of strings
Items Enum: "service" "host"
Example: types=["host"]

Filter the resources by type

+
states
Array of strings
Items Enum: "unhandled_problems" "resources_problems" "in_downtime" "acknowledged" "all"
Example: states=["in_downtime", "acknowledged"]

Filter the resources by state

+
statuses
Array of strings
Items Enum: "OK" "UP" "WARNING" "DOWN" "CRITICAL" "UNREACHABLE" "UNKNOWN" "PENDING"
Example: statuses=["OK", "UP", "PENDING"]

Filter the resources by status

+
hostgroup_ids
Array of int <int64>
Example: hostgroup_ids=[13, 22, 31]

Filter the resources by host group ID

+
hostgroup_ids
Array of int <int64>
Example: hostgroup_ids=[2033]

Filter the resources by host group ID

+

Responses

200

OK

+
403

Forbidden

+
500

Internal Server Error

+
get /monitoring/resources
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/resources

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}

Check

Check host

Schedule immediate check on chosen host

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
Request Body schema: application/json
is_forced
boolean

Indicates whether the check is forced (do not take into account the check timeperiod)

+

Responses

204

Command Sent

+
403

Forbidden

+
404

Host not found

+
500

Internal Server Error

+
post /monitoring/hosts/{host_id}/check
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/check

Request samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "is_forced": true
}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

Check service

Schedule immediate check on chosen service

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+
Request Body schema: application/json
is_forced
boolean

Indicates whether the check is forced (do not take into account the check timeperiod)

+

Responses

204

Command Sent

+
403

Forbidden

+
404

Host or service not found

+
500

Internal Server Error

+
post /monitoring/hosts/{host_id}/services/{service_id}/check
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/check

Request samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "is_forced": true
}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "code": 403,
  • "message": "You are not authorized to access this resource"
}

Metrics

Get service metrics data

Get metrics data from a service between given interval

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+
start
required
string <date-time>
Example: 2020-02-18T00:00:00

start of the interval (ISO8601)

+
end
required
string <date-time>
Example: 2020-02-18T12:00:00

end of the interval (ISO8601)

+

Responses

200

OK

+
403

Forbidden

+
404

Host or service not found

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/services/{service_id}/metrics/start/{start}/end/{end}
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/metrics/start/{start}/end/{end}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "global":
    {
    },
  • "metrics":
    [
    ],
  • "times":
    [
    ]
}

Get service status data

Get status data from a service between given interval

+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
service_id
required
integer <int64>
Example: 5

ID of the service

+
start
required
string <date-time>
Example: 2020-02-18T00:00:00

start of the interval (ISO8601)

+
end
required
string <date-time>
Example: 2020-02-18T12:00:00

end of the interval (ISO8601)

+

Responses

200

OK

+
403

Forbidden

+
404

Host or service not found

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/services/{service_id}/status/start/{start}/end/{end}
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/services/{service_id}/status/start/{start}/end/{end}

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "critical":
    [
    ],
  • "warning":
    [
    ],
  • "ok":
    [
    ],
  • "unknown":
    [
    ]
}

Timeline

List events related to a host

List all events for a given host

+

The available parameters to search / sort_by are:

+
    +
  • date
  • +
+
Authorizations:
path Parameters
host_id
required
integer <int64>
Example: 12

ID of the host

+
query Parameters
search
object
limit
integer >= 1
Default: 10
Example: limit=20

Number of items per pages

+
page
integer >= 1
Default: 1
Example: page=4

Number of the requested page

+
sort_by
object
Example: sort_by={"host.name":"ASC"}

Sort the resulted data by its properties

+

Responses

200

OK

+
403

Forbidden

+
404

Not Found

+
500

Internal Server Error

+
get /monitoring/hosts/{host_id}/timeline
{protocol}://{server}:{port}/centreon/api/{version}/monitoring/hosts/{host_id}/timeline

Response samples

Content type
application/json
Copy
Expand all Collapse all
{
  • "result":
    [
    ],
  • "meta":
    {
    }
}
+ + + + \ No newline at end of file diff --git a/doc/API/centreon-api-v2.yaml b/doc/API/centreon-api-v2.yaml index ac39cca6fd4..508f63b2582 100644 --- a/doc/API/centreon-api-v2.yaml +++ b/doc/API/centreon-api-v2.yaml @@ -1503,6 +1503,44 @@ paths: description: "Host or service not found" '500': $ref: '#/components/responses/InternalServerError' + + /monitoring/hosts/{host_id}/timeline: + get: + tags: + - Timeline + summary: "List events related to a host" + description: | + List all events for a given host + + The available parameters to **search** / **sort_by** are: + + * date + parameters: + - $ref: '#/components/parameters/HostId' + - $ref: '#/components/parameters/Search' + - $ref: '#/components/parameters/Limit' + - $ref: '#/components/parameters/Page' + - $ref: '#/components/parameters/SortBy' + responses: + '200': + description: "OK" + content: + application/json: + schema: + type: object + properties: + result: + type: array + items: + $ref: '#/components/schemas/Monitoring.TimelineEvent' + meta: + $ref: '#/components/schemas/Meta' + '403': + $ref: '#/components/responses/Forbidden' + '404': + $ref: '#/components/responses/NotFound' + '500': + $ref: '#/components/responses/InternalServerError' components: securitySchemes: Token: @@ -2779,3 +2817,21 @@ components: - port - user - password + Monitoring.TimelineEvent: + type: object + properties: + type: + type: string + description: "Type of Event (L - log, C - Comment, A - Acknowledgement, D - Downtime" + example: "C" + id: + type: string + description: "Concatinated ID of Type + Object ID" + example: "C25" + date: + type: string + format: date-time + description: "The date the event was created (ISO8601)" + object: + type: object + description: "The detailed object properties of above types" \ No newline at end of file diff --git a/src/Centreon/Application/Controller/MonitoringHostsController.php b/src/Centreon/Application/Controller/MonitoringHostsController.php index 41f662f994c..f3f0871f568 100644 --- a/src/Centreon/Application/Controller/MonitoringHostsController.php +++ b/src/Centreon/Application/Controller/MonitoringHostsController.php @@ -21,7 +21,12 @@ namespace Centreon\Application\Controller; +use Centreon\Domain\Monitoring\Entity\AckEventObject; +use Centreon\Domain\Monitoring\Entity\CommentEventObject; +use Centreon\Domain\Monitoring\Entity\DowntimeEventObject; +use Centreon\Domain\Monitoring\Entity\LogEventObject; use Centreon\Domain\Monitoring\Interfaces\MonitoringServiceInterface; +use Centreon\Domain\Monitoring\TimelineEvent; use Centreon\Domain\RequestParameters\Interfaces\RequestParametersInterface; use FOS\RestBundle\Context\Context; use FOS\RestBundle\View\View; @@ -327,4 +332,43 @@ public function getHostGroupsByHost(int $hostId, RequestParametersInterface $req 'meta' => $requestParameters->toArray() ])->setContext($context); } + + + /** + * Entry point to get timeline for a host + * @param int $hostId id of host + * @param RequestParametersInterface $requestParameters Request parameters used to filter the request + * @return View + * @throws \Exception + */ + public function getHostTimeline( + int $hostId, + RequestParametersInterface $requestParameters + ): View { + + $this->monitoring->filterByContact($this->getUser()); + + if ($this->monitoring->isHostExists($hostId)) { + $timeline = $this->monitoring->findTimelineEvents($hostId, 0); + + $context = (new Context()) + ->setGroups([ + LogEventObject::SERIALIZER_GROUP_LIST, + CommentEventObject::SERIALIZER_GROUP_LIST, + DowntimeEventObject::SERIALIZER_GROUP_LIST, + AckEventObject::SERIALIZER_GROUP_LIST, + TimelineEvent::SERIALIZER_GROUP_LIST, + ]) + ->enableMaxDepth(); + + return $this->view( + [ + 'result' => $timeline, + 'meta' => $requestParameters->toArray() + ] + )->setContext($context); + } else { + return View::create(null, Response::HTTP_NOT_FOUND, []); + } + } } diff --git a/src/Centreon/Application/Controller/MonitoringServicesController.php b/src/Centreon/Application/Controller/MonitoringServicesController.php index 0edb256d490..5f73b7891ac 100644 --- a/src/Centreon/Application/Controller/MonitoringServicesController.php +++ b/src/Centreon/Application/Controller/MonitoringServicesController.php @@ -22,10 +22,18 @@ namespace Centreon\Application\Controller; +use Centreon\Domain\Acknowledgement\Acknowledgement; +use Centreon\Domain\Downtime\Downtime; +use Centreon\Domain\Monitoring\Entity\AckEventObject; +use Centreon\Domain\Monitoring\Entity\CommentEventObject; +use Centreon\Domain\Monitoring\Entity\DowntimeEventObject; +use Centreon\Domain\Monitoring\Entity\LogEventObject; use Centreon\Domain\Monitoring\Host; use Centreon\Domain\Monitoring\Interfaces\MonitoringServiceInterface; +use Centreon\Domain\Monitoring\Model\Log; use Centreon\Domain\Monitoring\Service; use Centreon\Domain\Monitoring\ServiceGroup; +use Centreon\Domain\Monitoring\TimelineEvent; use Centreon\Domain\RequestParameters\Interfaces\RequestParametersInterface; use FOS\RestBundle\Context\Context; use FOS\RestBundle\View\View; @@ -151,4 +159,44 @@ public function getServiceGroupsByHostAndService( return View::create(null, Response::HTTP_NOT_FOUND, []); } } + + /** + * Entry point to get timeline for a host-service + * @param int $hostId id of host + * @param int $serviceId id of service + * @param RequestParametersInterface $requestParameters Request parameters used to filter the request + * @return View + * @throws \Exception + */ + public function getServiceTimeline( + int $hostId, + int $serviceId, + RequestParametersInterface $requestParameters + ): View { + + $this->monitoring->filterByContact($this->getUser()); + + if ($this->monitoring->isServiceExists($hostId, $serviceId)) { + $timeline = $this->monitoring->findTimelineEvents($hostId, $serviceId); + + $context = (new Context()) + ->setGroups([ + LogEventObject::SERIALIZER_GROUP_LIST, + CommentEventObject::SERIALIZER_GROUP_LIST, + DowntimeEventObject::SERIALIZER_GROUP_LIST, + AckEventObject::SERIALIZER_GROUP_LIST, + TimelineEvent::SERIALIZER_GROUP_LIST, + ]) + ->enableMaxDepth(); + + return $this->view( + [ + 'result' => $timeline, + 'meta' => $requestParameters->toArray() + ] + )->setContext($context); + } else { + return View::create(null, Response::HTTP_NOT_FOUND, []); + } + } } diff --git a/src/Centreon/Domain/Acknowledgement/Acknowledgement.php b/src/Centreon/Domain/Acknowledgement/Acknowledgement.php index da649d46816..86e8719ca6f 100644 --- a/src/Centreon/Domain/Acknowledgement/Acknowledgement.php +++ b/src/Centreon/Domain/Acknowledgement/Acknowledgement.php @@ -55,7 +55,7 @@ class Acknowledgement implements EntityDescriptorMetadataInterface private $deletionTime; /** - * @var \DateTime + * @var \DateTime|null */ private $entryTime; @@ -187,18 +187,18 @@ public function setDeletionTime(?\DateTime $deletionTime): Acknowledgement } /** - * @return \DateTime + * @return \DateTime|null */ - public function getEntryTime(): \DateTime + public function getEntryTime(): ?\DateTime { return $this->entryTime; } /** - * @param \DateTime $entryTime + * @param \DateTime|null $entryTime * @return Acknowledgement */ - public function setEntryTime(\DateTime $entryTime): Acknowledgement + public function setEntryTime(?\DateTime $entryTime): Acknowledgement { $this->entryTime = $entryTime; return $this; diff --git a/src/Centreon/Domain/Entity/EntityCreator.php b/src/Centreon/Domain/Entity/EntityCreator.php index 490bef43b3b..a69708ed53e 100644 --- a/src/Centreon/Domain/Entity/EntityCreator.php +++ b/src/Centreon/Domain/Entity/EntityCreator.php @@ -237,7 +237,7 @@ private function readAnnotations(): void if ($reflectionClass->isSubclassOf(EntityDescriptorMetadataInterface::class)) { foreach ($this->className::loadEntityDescriptorMetadata() as $column => $modifier) { $descriptor = new EntityDescriptor; - $descriptor->column = $key; + $descriptor->column = $column; $descriptor->modifier = $modifier; $this->entityDescriptors[$column] = $descriptor; diff --git a/src/Centreon/Domain/Monitoring/Entity/AckEventObject.php b/src/Centreon/Domain/Monitoring/Entity/AckEventObject.php new file mode 100644 index 00000000000..a3d220966cd --- /dev/null +++ b/src/Centreon/Domain/Monitoring/Entity/AckEventObject.php @@ -0,0 +1,100 @@ +author; + } + + /** + * @param null|string $author + */ + public function setAuthor(?string $author): void + { + $this->author = $author; + } + + /** + * @inheritdoc + */ + public function getTimestamp(): ?\DateTime + { + return $this->getEntryTime(); + } + + /** + * @inheritdoc + */ + public function getEventType(): string + { + return self::EVENTTYPE; + } + + /** + * @inheritdoc + */ + public function getEventId(): string + { + return self::EVENTTYPE . $this->getId(); + } + + /** + * {@inheritdoc} + */ + public static function loadEntityDescriptorMetadata(): array + { + return [ + 'id' => 'setId', + 'output' => 'setComment', + 'status' => 'setState', + 'notify_contacts' => 'setNotifyContacts', + 'type' => 'setType', + 'persistent' => 'setPersistentComment', + 'deletion_time' => 'setDeletionTime', + 'sticky' => 'setSticky', + 'timestamp' => 'setEntryTime', + 'contact' => 'setAuthor', + ]; + } +} diff --git a/src/Centreon/Domain/Monitoring/Entity/CommentEventObject.php b/src/Centreon/Domain/Monitoring/Entity/CommentEventObject.php new file mode 100644 index 00000000000..6b51680872e --- /dev/null +++ b/src/Centreon/Domain/Monitoring/Entity/CommentEventObject.php @@ -0,0 +1,79 @@ +getEntryTime(); + } + + /** + * @inheritdoc + */ + public function getEventType(): string + { + return self::EVENTTYPE; + } + + /** + * @inheritdoc + */ + public function getEventId(): string + { + return self::EVENTTYPE . $this->getId(); + } + + /** + * {@inheritdoc} + */ + public static function loadEntityDescriptorMetadata(): array + { + return [ + 'id' => 'setId', + 'timestamp' => 'setEntryTime', + 'output' => 'setData', + 'type' => 'setType', + 'contact' => 'setAuthor', + 'persistent' => 'setPersistent', + ]; + } +} diff --git a/src/Centreon/Domain/Monitoring/Entity/DowntimeEventObject.php b/src/Centreon/Domain/Monitoring/Entity/DowntimeEventObject.php new file mode 100644 index 00000000000..d62d8066b92 --- /dev/null +++ b/src/Centreon/Domain/Monitoring/Entity/DowntimeEventObject.php @@ -0,0 +1,126 @@ +type; + } + + /** + * @param int|null $type + */ + public function setType(?int $type): void + { + $this->type = $type; + } + + /** + * @return null|string + */ + public function getAuthor(): ?string + { + return $this->author; + } + + /** + * @param null|string $author + */ + public function setAuthor(?string $author): void + { + $this->author = $author; + } + + /** + * @inheritdoc + */ + public function getTimestamp(): ?\DateTime + { + return $this->getEntryTime(); + } + + /** + * @inheritdoc + */ + public function getEventType(): string + { + return self::EVENTTYPE; + } + + /** + * @inheritdoc + */ + public function getEventId(): string + { + return self::EVENTTYPE . $this->getId(); + } + + /** + * {@inheritdoc} + */ + public static function loadEntityDescriptorMetadata(): array + { + return [ + 'id' => 'setId', + 'output' => 'setComment', + 'timestamp' => 'setEntryTime', + 'type' => 'setType', + 'contact' => 'setAuthor', + 'start_time' => 'setStartTime', + 'end_time' => 'setEndTime', + 'actual_start_time' => 'setActualStartTime', + 'actual_end_time' => 'setActualEndTime', + 'duration' => 'setDuration', + 'started' => 'setStarted', + 'cancelled' => 'setCancelled', + 'fixed' => 'setFixed', + 'deletion_time' => 'setDeletionTime', + ]; + } +} diff --git a/src/Centreon/Domain/Monitoring/Entity/LogEventObject.php b/src/Centreon/Domain/Monitoring/Entity/LogEventObject.php new file mode 100644 index 00000000000..a0b67aa74cd --- /dev/null +++ b/src/Centreon/Domain/Monitoring/Entity/LogEventObject.php @@ -0,0 +1,129 @@ +getCreateTime(); + } + + /** + * @inheritdoc + */ + public function getEventType(): string + { + return self::EVENTTYPE; + } + + /** + * @inheritdoc + */ + public function getEventId(): string + { + return self::EVENTTYPE . $this->getId(); + } + + /** + * {@inheritdoc} + */ + public static function loadEntityDescriptorMetadata(): array + { + return [ + 'id' => 'setId', + 'output' => 'setOutput', + 'timestamp' => 'setCreateTime', + 'status' => 'setStatus', + 'type' => 'setType', + 'retry' => 'setRetry', + 'contact' => 'setNotificationContact', + 'command' => 'setNotificationCmd' + ]; + } + + /** + * Convert integer status to text + * @return null|string + */ + public function getStatusText(): ?string + { + switch ($this->getStatus()) { + case 0: + $textValue = 'OK'; + break; + case 1: + $textValue = 'WARNING'; + break; + case 2: + $textValue = 'CRITICAL'; + break; + case 3: + $textValue = 'UNKNOWN'; + break; + default: + $textValue = null; + break; + } + + return $textValue; + } + + /** + * Convert integer type to text + * @return null|string + */ + public function getTypeText(): ?string + { + switch ($this->getType()) { + case 0: + $textValue = 'SOFT'; + break; + case 1: + $textValue = 'HARD'; + break; + default: + $textValue = null; + break; + } + + return $textValue; + } +} diff --git a/src/Centreon/Domain/Monitoring/Interfaces/EventObjectInterface.php b/src/Centreon/Domain/Monitoring/Interfaces/EventObjectInterface.php new file mode 100644 index 00000000000..872aae8a207 --- /dev/null +++ b/src/Centreon/Domain/Monitoring/Interfaces/EventObjectInterface.php @@ -0,0 +1,44 @@ +id; + } + + /** + * @param int|null $id + */ + public function setId(?int $id): void + { + $this->id = $id; + } + + /** + * @return \DateTime|null + */ + public function getEntryTime(): ?\DateTime + { + return $this->entryTime; + } + + /** + * @param \DateTime|null $entryTime + */ + public function setEntryTime(?\DateTime $entryTime): void + { + $this->entryTime = $entryTime; + } + + /** + * @return int|null + */ + public function getHostId(): ?int + { + return $this->hostId; + } + + /** + * @param int|null $hostId + */ + public function setHostId(?int $hostId): void + { + $this->hostId = $hostId; + } + + /** + * @return int|null + */ + public function getServiceId(): ?int + { + return $this->serviceId; + } + + /** + * @param int|null $serviceId + */ + public function setServiceId(?int $serviceId): void + { + $this->serviceId = $serviceId; + } + + /** + * @return null|string + */ + public function getAuthor(): ?string + { + return $this->author; + } + + /** + * @param null|string $author + */ + public function setAuthor(?string $author): void + { + $this->author = $author; + } + + /** + * @return null|string + */ + public function getData(): ?string + { + return $this->data; + } + + /** + * @param null|string $data + */ + public function setData(?string $data): void + { + $this->data = $data; + } + + /** + * @return \DateTime|null + */ + public function getDeletionTime(): ?\DateTime + { + return $this->deletionTime; + } + + /** + * @param \DateTime|null $deletionTime + */ + public function setDeletionTime(?\DateTime $deletionTime): void + { + $this->deletionTime = $deletionTime; + } + + /** + * @return int|null + */ + public function getEntryType(): ?int + { + return $this->entryType; + } + + /** + * @param int|null $entryType + */ + public function setEntryType(?int $entryType): void + { + $this->entryType = $entryType; + } + + /** + * @return \DateTime|null + */ + public function getExpireTime(): ?\DateTime + { + return $this->expireTime; + } + + /** + * @param \DateTime|null $expireTime + */ + public function setExpireTime(?\DateTime $expireTime): void + { + $this->expireTime = $expireTime; + } + + /** + * @return int|null + */ + public function getExpires(): ?int + { + return $this->expires; + } + + /** + * @param int|null $expires + */ + public function setExpires(?int $expires): void + { + $this->expires = $expires; + } + + /** + * @return int|null + */ + public function getInstanceId(): ?int + { + return $this->instanceId; + } + + /** + * @param int|null $instanceId + */ + public function setInstanceId(?int $instanceId): void + { + $this->instanceId = $instanceId; + } + + /** + * @return int|null + */ + public function getInternalId(): ?int + { + return $this->internalId; + } + + /** + * @param int|null $internalId + */ + public function setInternalId(?int $internalId): void + { + $this->internalId = $internalId; + } + + /** + * @return int|null + */ + public function getPersistent(): ?int + { + return $this->persistent; + } + + /** + * @param int|null $persistent + */ + public function setPersistent(?int $persistent): void + { + $this->persistent = $persistent; + } + + /** + * @return int|null + */ + public function getSource(): ?int + { + return $this->source; + } + + /** + * @param int|null $source + */ + public function setSource(?int $source): void + { + $this->source = $source; + } + + /** + * @return int|null + */ + public function getType(): ?int + { + return $this->type; + } + + /** + * @param int|null $type + */ + public function setType(?int $type): void + { + $this->type = $type; + } +} diff --git a/src/Centreon/Domain/Monitoring/Model/Log.php b/src/Centreon/Domain/Monitoring/Model/Log.php new file mode 100644 index 00000000000..b7d0b9b4992 --- /dev/null +++ b/src/Centreon/Domain/Monitoring/Model/Log.php @@ -0,0 +1,344 @@ +id; + } + + /** + * @param int $id + */ + public function setId(int $id): void + { + $this->id = $id; + } + + /** + * @return \DateTime|null + */ + public function getCreateTime(): ?\DateTime + { + return $this->createTime; + } + + /** + * @param \DateTime|null $createTime + */ + public function setCreateTime(?\DateTime $createTime): void + { + $this->createTime = $createTime; + } + + /** + * @return int|null + */ + public function getHostId(): ?int + { + return $this->hostId; + } + + /** + * @param int|null $hostId + */ + public function setHostId(?int $hostId): void + { + $this->hostId = $hostId; + } + + /** + * @return null|string + */ + public function getHostName(): ?string + { + return $this->hostName; + } + + /** + * @param null|string $hostName + */ + public function setHostName(?string $hostName): void + { + $this->hostName = $hostName; + } + + /** + * @return null|string + */ + public function getInstanceName(): ?string + { + return $this->instanceName; + } + + /** + * @param string $instanceName + */ + public function setInstanceName(?string $instanceName): void + { + $this->instanceName = $instanceName; + } + + /** + * @return int|null + */ + public function getIssueId(): ?int + { + return $this->issueId; + } + + /** + * @param int|null $issueId + */ + public function setIssueId(?int $issueId): void + { + $this->issueId = $issueId; + } + + /** + * @return int|null + */ + public function getMsgType(): ?int + { + return $this->msgType; + } + + /** + * @param int|null $msgType + */ + public function setMsgType(?int $msgType): void + { + $this->msgType = $msgType; + } + + /** + * @return null|string + */ + public function getNotificationCmd(): ?string + { + return $this->notificationCmd; + } + + /** + * @param null|string $notificationCmd + */ + public function setNotificationCmd(?string $notificationCmd): void + { + $this->notificationCmd = $notificationCmd; + } + + /** + * @return null|string + */ + public function getNotificationContact(): ?string + { + return $this->notificationContact; + } + + /** + * @param null|string $notificationContact + */ + public function setNotificationContact(?string $notificationContact): void + { + $this->notificationContact = $notificationContact; + } + + /** + * @return null|string + */ + public function getOutput(): ?string + { + return $this->output; + } + + /** + * @param null|string $output + */ + public function setOutput(?string $output): void + { + $this->output = $output; + } + + /** + * @return int|null + */ + public function getRetry(): ?int + { + return $this->retry; + } + + /** + * @param int|null $retry + */ + public function setRetry(?int $retry): void + { + $this->retry = $retry; + } + + /** + * @return null|string + */ + public function getServiceDescription(): ?string + { + return $this->serviceDescription; + } + + /** + * @param null|string $serviceDescription + */ + public function setServiceDescription(?string $serviceDescription): void + { + $this->serviceDescription = $serviceDescription; + } + + /** + * @return int|null + */ + public function getServiceId(): ?int + { + return $this->serviceId; + } + + /** + * @param int|null $serviceId + */ + public function setServiceId(?int $serviceId): void + { + $this->serviceId = $serviceId; + } + + /** + * @return int|null + */ + public function getStatus(): ?int + { + return $this->status; + } + + /** + * @param int|null $status + */ + public function setStatus(?int $status): void + { + $this->status = $status; + } + + /** + * @return int|null + */ + public function getType(): ?int + { + return $this->type; + } + + /** + * @param int|null $type + */ + public function setType(?int $type): void + { + $this->type = $type; + } +} diff --git a/src/Centreon/Domain/Monitoring/MonitoringService.php b/src/Centreon/Domain/Monitoring/MonitoringService.php index a6ef35549a2..a7f2e3661b1 100644 --- a/src/Centreon/Domain/Monitoring/MonitoringService.php +++ b/src/Centreon/Domain/Monitoring/MonitoringService.php @@ -25,6 +25,7 @@ use Centreon\Domain\Contact\Contact; use Centreon\Domain\Monitoring\Interfaces\MonitoringServiceInterface; use Centreon\Domain\Monitoring\Interfaces\MonitoringRepositoryInterface; +use Centreon\Domain\Monitoring\Interfaces\TimelineRepositoryInterface; use Centreon\Domain\Security\Interfaces\AccessGroupRepositoryInterface; use Centreon\Domain\Service\AbstractCentreonService; @@ -45,16 +46,23 @@ class MonitoringService extends AbstractCentreonService implements MonitoringSer */ private $accessGroupRepository; + /** + * @var TimelineRepositoryInterface + */ + private $timelineRepository; + /** * @param MonitoringRepositoryInterface $monitoringRepository * @param AccessGroupRepositoryInterface $accessGroupRepository */ public function __construct( MonitoringRepositoryInterface $monitoringRepository, - AccessGroupRepositoryInterface $accessGroupRepository + AccessGroupRepositoryInterface $accessGroupRepository, + TimelineRepositoryInterface $timelineRepository = null ) { $this->monitoringRepository = $monitoringRepository; $this->accessGroupRepository = $accessGroupRepository; + $this->timelineRepository = $timelineRepository; } /** @@ -72,6 +80,10 @@ public function filterByContact($contact): self ->setContact($this->contact) ->filterByAccessGroups($accessGroups); + $this->timelineRepository + ->setContact($this->contact) + ->filterByAccessGroups($accessGroups); + return $this; } @@ -260,6 +272,14 @@ public function findServiceGroupsByHostAndService(int $hostId, int $serviceId): return $this->monitoringRepository->findServiceGroupsByHostAndService($hostId, $serviceId); } + /** + * @inheritDoc + */ + public function findTimelineEvents(int $hostid, int $serviceId): array + { + return $this->timelineRepository->findTimelineEventsByHostAndService($hostid, $serviceId); + } + /** * Completes hosts with their services. * diff --git a/src/Centreon/Domain/Monitoring/TimelineEvent.php b/src/Centreon/Domain/Monitoring/TimelineEvent.php new file mode 100644 index 00000000000..c5261cd3912 --- /dev/null +++ b/src/Centreon/Domain/Monitoring/TimelineEvent.php @@ -0,0 +1,88 @@ +setObject($object); + } + + /** + * @return string $id + */ + public function getId(): string + { + return $this->getObject()->getEventType() . $this->getObject()->getEventId(); + } + + /** + * @return \DateTime + */ + public function getTimestamp(): ?\DateTime + { + return $this->getObject()->getTimestamp(); + } + + /** + * @return string + */ + public function getType(): string + { + return $this->getObject()->getEventType(); + } + + /** + * @return EventObjectInterface + */ + public function getObject(): EventObjectInterface + { + return $this->object; + } + + /** + * @param EventObjectInterface $object + * @return TimelineEvent + */ + public function setObject(EventObjectInterface $object): void + { + $this->object = $object; + } +} diff --git a/src/Centreon/Infrastructure/Monitoring/TimelineRepositoryRDB.php b/src/Centreon/Infrastructure/Monitoring/TimelineRepositoryRDB.php new file mode 100644 index 00000000000..19eb36c6a67 --- /dev/null +++ b/src/Centreon/Infrastructure/Monitoring/TimelineRepositoryRDB.php @@ -0,0 +1,430 @@ +db = $pdo; + } + + /** + * Initialized by the dependency injector. + * + * @param SqlRequestParametersTranslator $sqlRequestTranslator + */ + public function setSqlRequestTranslator(SqlRequestParametersTranslator $sqlRequestTranslator): void + { + $this->sqlRequestTranslator = $sqlRequestTranslator; + $this->sqlRequestTranslator + ->getRequestParameters() + ->setConcordanceStrictMode( + RequestParameters::CONCORDANCE_MODE_STRICT + ); + } + + /** + * @inheritDoc + */ + public function filterByAccessGroups(?array $accessGroups): TimelineRepositoryInterface + { + $this->accessGroups = $accessGroups; + + return $this; + } + + /** + * @inheritDoc + */ + public function findTimelineEventsByHostAndService(int $hostId, int $serviceId = null): array + { + $timelineEvents = []; + + if ($this->hasNotEnoughRightsToContinue()) { + return $timelineEvents; + } + + $this->sqlRequestTranslator->setConcordanceArray([ + 'date' => 'event.timestamp' + ]); + + $collector = new StatementCollector(); + $request = $this->translateDbName('SELECT SQL_CALC_FOUND_ROWS ' + . 'event.* ' + . 'FROM ((' + . $this->generateLogsQuery($collector, $hostId, $serviceId) + . ') UNION ALL (' + . $this->generateCommentsQuery($collector, $hostId, $serviceId) + . ') UNION ALL (' + . $this->generateAcknowledgementsQuery($collector, $hostId, $serviceId) + . ') UNION ALL (' + . $this->generateDowntimesQuery($collector, $hostId, $serviceId) + . ')) AS `event`'); + + // Search + $searchRequest = $this->sqlRequestTranslator->translateSearchParameterToSql(); + + foreach ($this->sqlRequestTranslator->getSearchValues() as $key => $data) { + // @todo update when date parameter converter is available + $collector->addValue($key, strtotime(current($data)), key($data)); + } + $request .= $searchRequest ? $searchRequest : ''; + + // Group + $request .= ' GROUP BY event.eventId'; + + // Sort + $request .= $this->sqlRequestTranslator->translateSortParameterToSql() + ?: ' ORDER BY event.timestamp DESC'; + + // Pagination + $request .= $this->sqlRequestTranslator->translatePaginationToSql(); + + $statement = $this->db->prepare($request); + $collector->bind($statement); + + $statement->execute(); + + $result = $this->db->query('SELECT FOUND_ROWS()'); + $this->sqlRequestTranslator->getRequestParameters()->setTotal( + (int)$result->fetchColumn() + ); + + while (false !== ($result = $statement->fetch(\PDO::FETCH_ASSOC))) { + $newEvent = EntityCreator::createEntityByArray( + $this->detectClass($result['eventType']), + $result + ); + $timelineEvents[] = new TimelineEvent($newEvent); + } + + return $timelineEvents; + } + + private function isAdmin(): bool + { + return ($this->contact !== null) + ? $this->contact->isAdmin() + : false; + } + + /** + * {@inheritDoc} + */ + public function setContact(ContactInterface $contact): TimelineRepositoryInterface + { + $this->contact = $contact; + + return $this; + } + + /** + * @return bool Return FALSE if the contact is an admin or has at least one access group. + */ + private function hasNotEnoughRightsToContinue(): bool + { + return ($this->contact !== null) + ? !($this->contact->isAdmin() || count($this->accessGroups) > 0) + : count($this->accessGroups) == 0; + } + + /** + * Generate SQL query for logs + * + * @param \Centreon\Infrastructure\CentreonLegacyDB\StatementCollector $collector + * @param int $hostId + * @param int $serviceId + * @return string + */ + protected function generateLogsQuery(StatementCollector $collector, int $hostId, int $serviceId = null): string + { + $sql = "SELECT + CONCAT('L', l.log_id) AS `eventId`, + '". LogEventObject::EVENTTYPE ."' AS `eventType`, + l.log_id AS `id`, + l.output AS `output`, + l.ctime AS `timestamp`, + l.status AS `status`, + l.type AS `type`, + l.retry AS `retry`, + l.notification_contact AS `contact`, + l.notification_cmd AS `command`, + NULL AS `persistent`, + NULL as `deletion_time`, + NULL AS `start_time`, + NULL AS `end_time`, + NULL AS `actual_start_time`, + NULL AS `actual_end_time`, + NULL AS `duration`, + NULL AS `started`, + NULL AS `cancelled`, + NULL AS `fixed`, + NULL AS `sticky`, + NULL AS `notify_contacts` + FROM `:dbstg`.`logs` l + WHERE l.host_id = :hostId AND l.service_id = :serviceId"; + + $collector->addValue(":hostId", $hostId); + $collector->addValue(":serviceId", (int) $serviceId); + + // set ACL limitations + if (!$this->isAdmin()) { + $sql .= " INNER JOIN `:dbstg`.`centreon_acl` AS service_acl ON service_acl.host_id = s.host_id + AND service_acl.service_id = s.service_id + AND service_acl.group_id IN (" . $this->accessGroupIdToString($this->accessGroups) . ")"; + } + + //Group to avoid duplicate entries + $sql .= ' GROUP BY l.log_id'; + + return $sql; + } + + /** + * Generate SQL query for comments + * + * @param \Centreon\Infrastructure\CentreonLegacyDB\StatementCollector $collector + * @param int $hostId + * @param int $serviceId + * @return string + */ + protected function generateCommentsQuery(StatementCollector $collector, int $hostId, int $serviceId = null): string + { + $sql = "SELECT + CONCAT('C', c.comment_id) AS `eventId`, + '". CommentEventObject::EVENTTYPE ."' AS `eventType`, + c.comment_id AS `id`, + c.data AS `output`, + c.entry_time AS `timestamp`, + NULL AS `status`, + c.type AS `type`, + NULL AS `retry`, + c.author AS `contact`, + NULL AS `command`, + c.persistent AS `persistent`, + NULL as `deletion_time`, + NULL AS `start_time`, + NULL AS `end_time`, + NULL AS `actual_start_time`, + NULL AS `actual_end_time`, + NULL AS `duration`, + NULL AS `started`, + NULL AS `cancelled`, + NULL AS `fixed`, + NULL AS `sticky`, + NULL AS `notify_contacts` + FROM `:dbstg`.`comments` c + WHERE c.host_id = :hostId AND c.service_id = :serviceId"; + + $collector->addValue(":hostId", $hostId); + $collector->addValue(":serviceId", (int) $serviceId); + + // set ACL limitations + if (!$this->isAdmin()) { + $sql .= " INNER JOIN `:dbstg`.`centreon_acl` AS service_acl ON service_acl.host_id = s.host_id + AND service_acl.service_id = s.service_id + AND service_acl.group_id IN (" . $this->accessGroupIdToString($this->accessGroups) . ")"; + } + + //Group to avoid duplicate entries + $sql .= ' GROUP BY c.comment_id'; + + return $sql; + } + + /** + * Generate SQL query for downtimes + * + * @param \Centreon\Infrastructure\CentreonLegacyDB\StatementCollector $collector + * @param int $hostId + * @param int $serviceId + * @return string + */ + protected function generateDowntimesQuery(StatementCollector $collector, int $hostId, int $serviceId = null): string + { + $sql = "SELECT + CONCAT('D', d.downtime_id) AS `eventId`, + '". DowntimeEventObject::EVENTTYPE ."' AS `eventType`, + d.downtime_id AS `id`, + d.comment_data AS `output`, + d.entry_time AS `timestamp`, + NULL AS `status`, + d.type AS `type`, + NULL AS `retry`, + d.author AS `contact`, + NULL AS `command`, + NULL AS `persistent`, + d.deletion_time as `deletion_time`, + d.start_time AS `start_time`, + d.end_time AS `end_time`, + d.actual_start_time AS `actual_start_time`, + d.actual_end_time AS `actual_end_time`, + d.duration AS `duration`, + d.started AS `started`, + d.cancelled AS `cancelled`, + d.fixed AS `fixed`, + NULL AS `sticky`, + NULL AS `notify_contacts` + FROM `:dbstg`.`downtimes` d + WHERE d.host_id = :hostId AND d.service_id = :serviceId"; + + $collector->addValue(":hostId", $hostId); + $collector->addValue(":serviceId", (int) $serviceId); + + // set ACL limitations + if (!$this->isAdmin()) { + $sql .= " INNER JOIN `:dbstg`.`centreon_acl` AS service_acl ON service_acl.host_id = s.host_id + AND service_acl.service_id = s.service_id + AND service_acl.group_id IN (" . $this->accessGroupIdToString($this->accessGroups) . ")"; + } + + //Group to avoid duplicate entries + $sql .= ' GROUP BY d.downtime_id'; + + return $sql; + } + + /** + * Generate SQL query for ack + * + * @param \Centreon\Infrastructure\CentreonLegacyDB\StatementCollector $collector + * @param int $hostId + * @param int $serviceId + * @return string + */ + protected function generateAcknowledgementsQuery( + StatementCollector $collector, + int $hostId, + int $serviceId = null + ): string { + + $sql = "SELECT + CONCAT('A', a.acknowledgement_id) AS `eventId`, + '". AckEventObject::EVENTTYPE ."' AS `eventType`, + a.acknowledgement_id AS `id`, + a.comment_data AS `output`, + a.entry_time AS `timestamp`, + a.state AS `status`, + a.type AS `type`, + NULL AS `retry`, + a.author AS `contact`, + NULL AS `command`, + a.persistent_comment AS `persistent`, + a.deletion_time as `deletion_time`, + NULL AS `start_time`, + NULL AS `end_time`, + NULL AS `actual_start_time`, + NULL AS `actual_end_time`, + NULL AS `duration`, + NULL AS `started`, + NULL AS `cancelled`, + NULL AS `fixed`, + a.sticky AS `sticky`, + a.notify_contacts AS `notify_contacts` + FROM `:dbstg`.`acknowledgements` a + WHERE a.host_id = :hostId AND a.service_id = :serviceId"; + + $collector->addValue(":hostId", $hostId); + $collector->addValue(":serviceId", (int) $serviceId); + + // set ACL limitations + if (!$this->isAdmin()) { + $sql .= " INNER JOIN `:dbstg`.`centreon_acl` AS service_acl ON service_acl.host_id = s.host_id + AND service_acl.service_id = s.service_id + AND service_acl.group_id IN (" . $this->accessGroupIdToString($this->accessGroups) . ")"; + } + + //Group to avoid duplicate entries + $sql .= ' GROUP BY a.acknowledgement_id'; + + return $sql; + } + + + /** + * Generate Objects by database result row + * @param string $eventType + * @throws \Exception + * @return string + */ + private function detectClass(string $eventType): string + { + switch ($eventType) { + case 'L': + $eventClass = LogEventObject::class; + break; + case 'A': + $eventClass = AckEventObject::class; + break; + case 'C': + $eventClass = CommentEventObject::class; + break; + case 'D': + $eventClass = DowntimeEventObject::class; + break; + default: + throw new \Exception('Incorrect Event Type'); + break; + } + + return $eventClass; + } +} diff --git a/tests/php/Centreon/Domain/Monitoring/MonitoringServiceTest.php b/tests/php/Centreon/Domain/Monitoring/MonitoringServiceTest.php index 0c5614fcb47..dc75262f294 100644 --- a/tests/php/Centreon/Domain/Monitoring/MonitoringServiceTest.php +++ b/tests/php/Centreon/Domain/Monitoring/MonitoringServiceTest.php @@ -22,12 +22,15 @@ namespace Tests\Centreon\Domain\Monitoring; use Centreon\Domain\Contact\Interfaces\ContactInterface; +use Centreon\Domain\Monitoring\Entity\CommentEventObject; use Centreon\Domain\Monitoring\Host; use Centreon\Domain\Monitoring\HostGroup; use Centreon\Domain\Monitoring\Interfaces\MonitoringRepositoryInterface; +use Centreon\Domain\Monitoring\Interfaces\TimelineRepositoryInterface; use Centreon\Domain\Monitoring\MonitoringService; use Centreon\Domain\Monitoring\Service; use Centreon\Domain\Monitoring\ServiceGroup; +use Centreon\Domain\Monitoring\TimelineEvent; use Centreon\Domain\Security\Interfaces\AccessGroupRepositoryInterface; use PHPUnit\Framework\TestCase; @@ -380,4 +383,32 @@ public function findServiceGroupsByHostAndService() $this->assertEquals($host->getId(), $serviceGroup->getHosts()[0]->getId()); $this->assertEquals($service->getId(), $serviceGroup->getHosts()[0]->getServices()[0]->getId()); } + + /** + * @throws \Exception + */ + public function findTimelineEvents() + { + $commentObject = new CommentEventObject(); + $timelineEvent = new TimelineEvent($commentObject); + $repository = $this->createMock(TimelineRepositoryInterface::class); + + $repository->expects(self::any()) + ->method('findTimelineEvents') + ->with(2, 2) + ->willReturn([$timelineEvent]); // values returned for the all next tests + + $accessGroup = $this->createMock(AccessGroupRepositoryInterface::class); + + $monitoringService = new MonitoringService($repository, $accessGroup); + /** + * @var TimelineEvent[] $timelineEventsFound + */ + $timelineEventsFound = $monitoringService->findTimelineEvents(2, 2); + $this->assertCount( + 1, + $timelineEventsFound, + "Error, this method must relay the 'findTimelineEvents' method of the timeline repository" + ); + } }