Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests(Gorgone): test action module to retrieve result of command #1619

Merged
merged 6 commits into from
Aug 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/gorgone.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,15 +222,15 @@ jobs:

- name: Create databases
run: |
mysql -h mariadb -u root -ppassword -e "CREATE DATABASE \`centreon${{ matrix.distrib }}\`"
mysql -h mariadb -u root -ppassword -e "CREATE DATABASE \`centreon-storage${{ matrix.distrib }}\`"
mysql -h mariadb -u root -ppassword -e "GRANT ALL PRIVILEGES ON centreon${{ matrix.distrib }}.* TO 'centreon'@'%'"
mysql -h mariadb -u root -ppassword -e "GRANT ALL PRIVILEGES ON \`centreon-storage${{ matrix.distrib }}\`.* TO 'centreon'@'%'"
mysql -h mariadb -u root -ppassword 'centreon${{ matrix.distrib }}' < centreon/centreon/www/install/createTables.sql
mysql -h mariadb -u root -ppassword 'centreon-storage${{ matrix.distrib }}' < centreon/centreon/www/install/createTablesCentstorage.sql
mysql -h mariadb -u root -ppassword -e "CREATE DATABASE \`centreon\`"
mysql -h mariadb -u root -ppassword -e "CREATE DATABASE \`centreon-storage\`"
mysql -h mariadb -u root -ppassword -e "GRANT ALL PRIVILEGES ON centreon.* TO 'centreon'@'%'"
mysql -h mariadb -u root -ppassword -e "GRANT ALL PRIVILEGES ON \`centreon-storage\`.* TO 'centreon'@'%'"
mysql -h mariadb -u root -ppassword 'centreon' < centreon/centreon/www/install/createTables.sql
mysql -h mariadb -u root -ppassword 'centreon-storage' < centreon/centreon/www/install/createTablesCentstorage.sql

- name: Run tests
run: robot -v 'DBHOST:mariadb' -v 'DBNAME:centreon${{ matrix.distrib }}' -v 'DBNAME_STORAGE:centreon-storage${{ matrix.distrib }}' -v 'DBUSER:centreon' gorgone/tests
run: robot -v 'DBHOST:mariadb' -v 'DBNAME:centreon' -v 'DBNAME_STORAGE:centreon-storage' -v 'DBUSER:centreon' gorgone/tests

- name: Upload gorgone and robot debug artifacts
if: failure()
Expand Down
64 changes: 33 additions & 31 deletions gorgone/docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ Centreon Gorgone provides a RestAPI through its HTTP server module.

### Get Nodes Connection Status

| Endpoint | Method |
| :- | :- |
| /internal/constatus | `GET` |
| Endpoint | Method |
|:--------------------|:-------|
| /internal/constatus | `GET` |

#### Headers

| Header | Value |
| :- | :- |
| Header | Value |
|:-------|:-----------------|
| Accept | application/json |

#### Example
Expand Down Expand Up @@ -42,14 +42,14 @@ curl --request GET "https://hostname:8443/api/internal/constatus" \

### Get Public Key Thumbprint

| Endpoint | Method |
| :- | :- |
| /internal/thumbprint | `GET` |
| Endpoint | Method |
|:---------------------|:-------|
| /internal/thumbprint | `GET` |

#### Headers

| Header | Value |
| :- | :- |
| Header | Value |
|:-------|:-----------------|
| Accept | application/json |

#### Example
Expand All @@ -73,14 +73,14 @@ curl --request GET "https://hostname:8443/api/internal/thumbprint" \

### Get Runtime Informations And Statistics

| Endpoint | Method |
| :- | :- |
| /internal/information | `GET` |
| Endpoint | Method |
|:----------------------|:-------|
| /internal/information | `GET` |

#### Headers

| Header | Value |
| :- | :- |
| Header | Value |
|:-------|:-----------------|
| Accept | application/json |

#### Example
Expand Down Expand Up @@ -158,6 +158,7 @@ The available endpoints depend on which modules are loaded.
Endpoints are basically built from:

* API root,
* optional target node, local if not present ( `/nodes/:nodeid/` )
* Module's namespace,
* Module's name,
* Action
Expand All @@ -175,7 +176,7 @@ curl --request POST "https://hostname:8443/api/core/action/command" \
]"
```

Find more informations directly from modules documentations [here](../docs/modules.md).
Find more informations directly from modules documentations [here](./modules.md).

As Centreon Gorgone is asynchronous, those endpoints will return a token corresponding to the action.

Expand All @@ -187,7 +188,7 @@ As Centreon Gorgone is asynchronous, those endpoints will return a token corresp
}
```

That being said, its possible to make Gorgone work synchronously by providing two parameters.
That being said, it is possible to make Gorgone work synchronously by providing two parameters.

First one is `log_wait` with a numeric value in microseconds: this value defines the amount of time the API will wait before trying to retrieve log results.

Expand All @@ -202,7 +203,7 @@ Note: the `sync_wait` parameter is induced if you ask for a log directly specify
Using the `/core/action/command` endpoint with `log_wait` parameter set to 100000:

```bash
curl --request POST "https://hostname:8443/api/core/action/command&log_wait=100000" \
curl --request POST "https://hostname:8443/api/core/action/command?log_wait=100000" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "[
Expand All @@ -219,12 +220,12 @@ This call will ask for the API to execute an action and will give a result after

Note: there is no need for logs synchronisation when dealing with local actions.

##### Launch a command remotly and wait for the result
##### Launch a command remotely and wait for the result

Using the `/nodes/:id/core/action/command` endpoint with `log_wait` parameter set to 100000:

```bash
curl --request POST "https://hostname:8443/api/nodes/2/core/action/command&log_wait=100000&sync_wait=200000" \
curl --request POST "https://hostname:8443/api/nodes/2/core/action/command?log_wait=100000&sync_wait=200000" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "[
Expand All @@ -241,23 +242,24 @@ This call will ask for the API to execute an action on the node with ID 2, will

## Log endpoint

To retrieve the logs, a specific endpoint can be called as follow.
To retrieve the logs, a specific endpoint can be called as follows.

| Endpoint | Method |
| :- | :- |
| /log/:token | `GET` |
| Endpoint | Method |
|:------------------------------|:-------|
| /api/nodes/:nodeid/log/:token | `GET` |

#### Headers

| Header | Value |
| :- | :- |
| Accept | application/json |
| Header | Value |
|:-------|:------------------|
| Accept | application/json |

#### Path variables

| Variable | Description |
| :- | :- |
| token | Token of the action |
| Variable | Description |
|:---------|:---------------------------|
| token | Token of the action |
| nodeid | node id to search log into |

#### Examples

Expand All @@ -271,7 +273,7 @@ curl --request GET "https://hostname:8443/api/nodes/2/log/3f25bc3a797fe989d1fb05
--header "Accept: application/json"
```

This second example will force logs synchonisation before looking for results to retrieve. Default temporisation is 10ms and can be changed by providing `sync_wait` parameter.
This second example will force logs synchronisation before looking for results to retrieve. Default wait time is 10ms and can be changed by providing `sync_wait` parameter.

#### Response example

Expand Down
18 changes: 13 additions & 5 deletions gorgone/docs/modules/core/action.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ This module aims to execute actions on the server running the Gorgone daemon or
## Configuration

| Directive | Description | Default value |
| :--------------- | :------------------------------------------------------------- | :------------ |
|:-----------------|:---------------------------------------------------------------|:--------------|
| command_timeout | Time in seconds before a command is considered timed out | `30` |
| whitelist_cmds | Boolean to enable commands whitelist | `false` |
| allowed_cmds | Regexp list of allowed commands | |
Expand Down Expand Up @@ -38,7 +38,7 @@ allowed_cmds:
## Events

| Event | Description |
| :---------- | :-------------------------------------------------------------------------------------- |
|:------------|:----------------------------------------------------------------------------------------|
| ACTIONREADY | Internal event to notify the core |
| PROCESSCOPY | Process file or archive received from another daemon |
| COMMAND | Execute a shell command on the server running the daemon or on another server using SSH |
Expand All @@ -48,20 +48,20 @@ allowed_cmds:
### Execute a command line

| Endpoint | Method |
| :------------------- | :----- |
|:---------------------|:-------|
| /core/action/command | `POST` |

#### Headers

| Header | Value |
| :----------- | :--------------- |
|:-------------|:-----------------|
| Accept | application/json |
| Content-Type | application/json |

#### Body

| Key | Value |
| :---------------- | :------------------------------------------------------- |
|:------------------|:---------------------------------------------------------|
| command | Command to execute |
| timeout | Time in seconds before a command is considered timed out |
| continue_on_error | Behaviour in case of execution issue |
Expand All @@ -76,8 +76,11 @@ allowed_cmds:
]
```


#### Example

See a complete exemple of this endpoint in the [api documentation](../../api.md)

```bash
curl --request POST "https://hostname:8443/api/core/action/command" \
--header "Accept: application/json" \
Expand All @@ -88,3 +91,8 @@ curl --request POST "https://hostname:8443/api/core/action/command" \
}
]"
```
Output :
```bash
{"token":"b3f825f87d64764316d872c59e4bae69299b0003f6e5d27bbc7de4e27c50eb65fc17440baf218578343eff7f4d67f7e98ab6da40b050a2635bb735c7cec276bd"}
```

60 changes: 58 additions & 2 deletions gorgone/tests/robot/resources/LogResearch.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,69 @@
#
# Copyright 2024 Centreon
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# For more information : [email protected]
#

from robot.api import logger
import re
import time
from dateutil import parser
from datetime import datetime, timedelta
from robot.libraries.BuiltIn import BuiltIn
import requests


def ctn_get_api_log_with_timeout(token: str, node_path='', host='http://127.0.0.1:8085', timeout=15):
"""! Query gorgone log API until the response contains a log with code 2 (success) or 1 (failure)
@param token: token to search in the API
@param node_path: part of the API URL defining if we use the local gorgone or another one, ex node/2/
@param timeout: timeout in seconds
@param host: gorgone API URL with the port
@return True(when output of the command is found)/False(on failure or timeout),
and a json object containing the incriminated log for failure or success.
"""
limit_date = time.time() + timeout
api_json = []
while time.time() < limit_date:
time.sleep(1)
uri = host + "/api/" + node_path + "log/" + token
response = requests.get(uri)
(status, output) = parse_json_response(response)
if status == '':
continue
return status, output

return False, api_json["data"]


def parse_json_response(response):
api_json = response.json()
# http code should either be 200 for success or 404 for no log found if we are too early.
# as the time of writing, status code is always 200 because webapp autodiscovery module always expect a 200.
if response.status_code != 200 and response.status_code != 404:
return False, api_json

TIMEOUT = 30
if 'error' in api_json and api_json['error'] == "no_log":
return '', ''
for log_detail in api_json["data"]:
if log_detail["code"] == 2:
return False, log_detail
if log_detail["code"] == 100:
return True, log_detail


# these function search log in the gorgone log file
def ctn_find_in_log_with_timeout(log: str, content, timeout=20, date=-1, regex=False):
"""! search a pattern in log from date param
@param log: path of the log file
Expand Down
1 change: 1 addition & 0 deletions gorgone/tests/robot/resources/resources.resource
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ Setup Two Gorgone Instances
Start Gorgone debug ${poller_name}
Start Gorgone debug ${central_name}
Wait Until Port Is Bind 5556

Check Poller Is Connected port=5556 expected_nb=2
Check Poller Communicate 2
END
Expand Down
Loading