Merge branch 'genesis' into 'development'
feat: new role See merge request nofusscomputing/projects/ansible/nfc_glpi!1
This commit is contained in:
7
.cz.yaml
Normal file
7
.cz.yaml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
commitizen:
|
||||||
|
bump_message: "build(version): bump version $current_version \u2192 $new_version"
|
||||||
|
changelog_incremental: false
|
||||||
|
name: cz_conventional_commits
|
||||||
|
tag_format: $major.$minor.$patch$prerelease
|
||||||
|
update_changelog_on_bump: true
|
||||||
|
version: 0.0.1
|
15
.gitlab-ci.yml
Normal file
15
.gitlab-ci.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
include:
|
||||||
|
- project: nofusscomputing/projects/gitlab-ci
|
||||||
|
ref: development
|
||||||
|
file:
|
||||||
|
- .gitlab-ci_common.yaml
|
||||||
|
- template/automagic.gitlab-ci.yaml
|
||||||
|
|
||||||
|
|
||||||
|
variables:
|
||||||
|
MY_PROJECT_ID: "48046854"
|
||||||
|
GIT_SYNC_URL: "https://$GITHUB_USERNAME_ROBOT:$GITHUB_TOKEN_ROBOT@github.com/NoFussComputing/ansible_role_glpi.git"
|
||||||
|
PAGES_ENVIRONMENT_PATH: projects/nfc_glpi/
|
||||||
|
|
8
.gitmodules
vendored
Normal file
8
.gitmodules
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[submodule "gitlab-ci"]
|
||||||
|
path = gitlab-ci
|
||||||
|
url = https://gitlab.com/nofusscomputing/projects/gitlab-ci.git
|
||||||
|
branch = development
|
||||||
|
[submodule "website-template"]
|
||||||
|
path = website-template
|
||||||
|
url = https://gitlab.com/nofusscomputing/infrastructure/website-template.git
|
||||||
|
branch = development
|
8
.nfc_automation.yaml
Normal file
8
.nfc_automation.yaml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
role_git_conf:
|
||||||
|
gitlab:
|
||||||
|
submodule_branch: "development"
|
||||||
|
default_branch: development
|
||||||
|
mr_labels: ~"type::automation" ~"impact::0" ~"priority::0"
|
||||||
|
auto_merge: true
|
51
defaults/main.yaml
Normal file
51
defaults/main.yaml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
# directory_logrotate_config: /etc/logrotate.d
|
||||||
|
install_glpi: 'true'
|
||||||
|
glpi_installed: false
|
||||||
|
# logfile_max_size: 10 # must be specified in MB (Mega Bytes)
|
||||||
|
# logrotate_configuration: [] # Global var for usage within group/host vars
|
||||||
|
|
||||||
|
docker_image_name_glpi: nofusscomputing/docker-glpi
|
||||||
|
docker_image_tag_glpi: dev
|
||||||
|
|
||||||
|
docker_container_name_glpi: glpi
|
||||||
|
# mysql_unix_socket: /run/mysql/mariadb/mysqld.sock
|
||||||
|
mysql_unix_socket: /var/lib/docker/volumes/socket-mysql/_data/mysqld.sock
|
||||||
|
mysql_login_user: root
|
||||||
|
mysql_login_password: admin
|
||||||
|
|
||||||
|
glpi_plugins:
|
||||||
|
- filename: fail2ban_1.0.2-1.upstream1_all.deb
|
||||||
|
#url: https://github.com/pluginsGLPI/formcreator/releases/download/2.13.6/glpi-formcreator-2.13.6.tar.bz2
|
||||||
|
url: https://api.github.com/repos/pluginsGLPI/formcreator/releases/tags/2.13.6
|
||||||
|
|
||||||
|
- filename: glpi-glpiinventory-1.2.3.tar.bz2
|
||||||
|
#url: https://github.com/glpi-project/glpi-inventory-plugin/releases/download/1.2.3/glpi-glpiinventory-1.2.3.tar.bz2
|
||||||
|
url: https://api.github.com/repos/glpi-project/glpi-inventory-plugin/releases/tags/1.2.3
|
||||||
|
|
||||||
|
# - filename: glpi-actualtime-2.1.0.tar.tgz
|
||||||
|
# url: https://api.github.com/repos/ticgal/actualtime/releases/tags/2.1.0/glpi-actualtime-2.1.0.tar.tgz
|
||||||
|
|
||||||
|
|
||||||
|
mysql_database_glpi: glpi
|
||||||
|
|
||||||
|
# Configuration Example
|
||||||
|
# logrotate:
|
||||||
|
# - name: docker # Mandatory, used as logrotate difinition file name
|
||||||
|
# path: '/var/lib/docker/containers/*/*.log' # Mandatory, path to the logfile
|
||||||
|
# su: ingress ingress # Optional,, string user and group for log permissions
|
||||||
|
# interval: daily # optional example daily, weekly, monthly default=daily
|
||||||
|
# keep: # Optional, int, How many logs to keep default=7
|
||||||
|
# size: 10 # Optional, max size of logfile in Mega Bytes. DONT specify unit. default={{}}
|
||||||
|
# compress: # Optional, bool default=true
|
||||||
|
# delaycompress: # Optional, bool, delay logfile compression default=true
|
||||||
|
# postrotate: 'docker restart $(docker ps -q)' # Optional, Command to run post rotate default=not defined
|
||||||
|
# create: # Optional, default=not defined
|
||||||
|
# mode: 640 # Mandatory, filemode
|
||||||
|
# owner: root # Mandatory, logfile owner
|
||||||
|
# group: adm # Mandatory, logfile group owner
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glpi_config_as_code_json: []
|
||||||
|
search_items: []
|
0
docs/articles/index.md
Normal file
0
docs/articles/index.md
Normal file
0
docs/contact.md
Normal file
0
docs/contact.md
Normal file
0
docs/index.md
Normal file
0
docs/index.md
Normal file
0
docs/operations/index.md
Normal file
0
docs/operations/index.md
Normal file
0
docs/projects/index.md
Normal file
0
docs/projects/index.md
Normal file
170
docs/projects/nfc_glpi/config_from_code.md
Normal file
170
docs/projects/nfc_glpi/config_from_code.md
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
---
|
||||||
|
title: GLPI Config as code
|
||||||
|
description: How to use No Fuss Computings Ansible role to configure GLPI from configuration as code.
|
||||||
|
date: 2023-07-28
|
||||||
|
template: project.html
|
||||||
|
about: https://gitlab.com/nofusscomputing/projects/ansible/nfc_glpi
|
||||||
|
---
|
||||||
|
|
||||||
|
To configure GLPI using this role, the config/settings are saved as json files. The workflow to create the json files, is to (preferably within a test environment) make the required setting changes in GLPI using the GUI. once the changes have been made, conduct an API `GET` query to GLPI for the item you changed. The JSON body that is returned, is placed within the Config file (detailed below) under path `.body`. You must however, remove any fields that are not required, for example dynamic fields (fields that update themselves or are auto created) for example date fields. it's also recommended to remove the items `id` entry from the body, this option enables the updating and creation of the item by the name field.
|
||||||
|
|
||||||
|
As the export process is manual to create the json files, it is possible that errors could occur. another side effect is that when updating an item, when checking it into an SCM (git for example), that the commit may contain more than the item that changed. This is planned to be rectified in [gitlab-#1](https://gitlab.com/nofusscomputing/projects/ansible/nfc_glpi/-/issues/1).
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
To utilise the config from json files, it's important that any configurable item from json files, that it's name is unique for that item type within GLPI. This is due to the feature "find item_id by name" i.e. you can't have two items named `my name` and `my name` of type `x`, even if in different entities.
|
||||||
|
|
||||||
|
|
||||||
|
## Config files Example
|
||||||
|
|
||||||
|
Each tab provides an example of the JSON file layout, including any additional variables. Variable listed at path `.`, with the exception of `api_path`, `body` or have asuffix of `_` are provided to use that items name. These fields are used to fetch the item_id of the field by name. available fields are:
|
||||||
|
|
||||||
|
- entities_id
|
||||||
|
|
||||||
|
- groups_id
|
||||||
|
|
||||||
|
- item_id
|
||||||
|
|
||||||
|
- itilcategories_id
|
||||||
|
|
||||||
|
- tickettemplates_id_demand
|
||||||
|
|
||||||
|
- tickettemplates_id
|
||||||
|
|
||||||
|
- users_id
|
||||||
|
|
||||||
|
|
||||||
|
For example, to have an item placed in the entity `NoFussComputing` provided value would be `"entities_id": "NoFussComputing"`. As part of the item workflow a search for an entity named `NoFussComputing` is conducted, and if found, adds it's `entity_id` to path `.body.entities_id: {entity_id}`.
|
||||||
|
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
If you leave the item ID in the config file under path `.body.id`, the item that matches this ID, will be updated, not the item matching the name.
|
||||||
|
|
||||||
|
=== "AuthLDAP"
|
||||||
|
|
||||||
|
``` json title="example.json" linenums="1"
|
||||||
|
|
||||||
|
{
|
||||||
|
"api_path": "AuthLDAP",
|
||||||
|
"body": {
|
||||||
|
// JSON from API Query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Config (GLPI General Settings)"
|
||||||
|
|
||||||
|
This config file contains the settings found in `General Settings`. The full API JSON response is added to the body. When this file is processed, each individual item is added via the API without using the `id` as found in the JSON file. This is done as the ID's can change, so the workflow includes a step that matches the config item name to the found id in the database, then patches with the values from the JSON file.
|
||||||
|
|
||||||
|
``` json title="example.json" linenums="1"
|
||||||
|
{
|
||||||
|
"api_path": "Config",
|
||||||
|
"body": [
|
||||||
|
// JSON from API Query the full response (see note below)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
The structure of this JSON file is different than the rest. The body is a **list** of **ALL** of the Config options. This includes the item ID. it was done this way, so that only one API query is required to export all config options.
|
||||||
|
|
||||||
|
!!! info "Further Information"
|
||||||
|
Any config item that does not contain a value field, is excluded from being added or updated. In addition, the following items by name, are excluded
|
||||||
|
|
||||||
|
``` yaml title="tasks/api/excluded_config.yaml" linenums="1"
|
||||||
|
|
||||||
|
--8<-- "tasks/api/excluded_config.yaml"
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Entity"
|
||||||
|
|
||||||
|
``` json title="example.json" linenums="1"
|
||||||
|
|
||||||
|
{
|
||||||
|
"api_path": "Entity",
|
||||||
|
"entities_id": "",
|
||||||
|
"body": {
|
||||||
|
// JSON from API Query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "ITILCategory"
|
||||||
|
|
||||||
|
``` json title="example.json" linenums="1"
|
||||||
|
|
||||||
|
{
|
||||||
|
"api_path": "ITILCategory",
|
||||||
|
"users_id": "",
|
||||||
|
"itilcategories_id": "",
|
||||||
|
"entities_id": "",
|
||||||
|
"tickettemplates_id_demand": "",
|
||||||
|
"body": {
|
||||||
|
// JSON from API Query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "Profile"
|
||||||
|
|
||||||
|
``` json title="example.json" linenums="1"
|
||||||
|
|
||||||
|
{
|
||||||
|
"api_path": "Profile",
|
||||||
|
"body": {
|
||||||
|
// JSON from API Query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
=== "TicketTemplate"
|
||||||
|
|
||||||
|
This config file covers all parts of a ticket template. with this template you can create and update an existing ticket template.
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
Assosiated Items do not get updated or removed. They will be added if they don't exist. No checks are done for more assosiated items then are specified in the template.
|
||||||
|
|
||||||
|
``` json title="example.json" linenums="1"
|
||||||
|
|
||||||
|
{
|
||||||
|
"api_path": "TicketTemplate",
|
||||||
|
"entities_id": "",
|
||||||
|
"body": {
|
||||||
|
// JSON from API Query
|
||||||
|
},
|
||||||
|
"_TicketTemplateMandatoryField": [
|
||||||
|
|
||||||
|
// JSON from API Query path TicketTemplate/{ticket_template_id}/TicketTemplateMandatoryField
|
||||||
|
],
|
||||||
|
"_TicketTemplatePredefinedField": [
|
||||||
|
|
||||||
|
// JSON from API Query path TicketTemplate/{ticket_template_id}/TicketTemplatePredefinedField
|
||||||
|
|
||||||
|
],
|
||||||
|
"_TicketTemplateHiddenField": [
|
||||||
|
|
||||||
|
// JSON from API Query path TicketTemplate/{ticket_template_id}/TicketTemplateHiddenField
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Sub-items to the ticket are `TicketTemplateMandatoryField`, `TicketTemplatePredefinedField` and `TicketTemplateHiddenField` and are at json path `._{sub-item}`. These items are a **list of dicts** and can contain the `id` of the item, however it is ignored as the update is base off of `tickettemplates_id`, `num` for all and `tickettemplates_id`, `num` and `value` for `num=13` which is an assosiated item. With the exception of the latter, all of these values will be updated if they exist.
|
||||||
|
|
||||||
|
|
||||||
|
With the config files structured as per the examples, within your playbook(s), load the json files in a list of json objects using variable `glpi_config_as_code_json`
|
||||||
|
|
||||||
|
example
|
||||||
|
|
||||||
|
``` yaml title="my_vars.yaml" linenums="1"
|
||||||
|
|
||||||
|
glpi_config_as_code_json:
|
||||||
|
- "{{ lookup('file', '/workdir/files/glpi/ITILCategory-new-ldap-user.json') | from_json }}"
|
||||||
|
- "{{ lookup('file', '/workdir/files/glpi/LDAPAuth-local_ldap.json') | from_json }}"
|
||||||
|
|
||||||
|
```
|
25
docs/projects/nfc_glpi/index.md
Normal file
25
docs/projects/nfc_glpi/index.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
title: nfc_glpi - Ansible Role
|
||||||
|
description: How to use No Fuss Computings Ansible role to manage GLPI from configuration as code.
|
||||||
|
date: 2023-07-28
|
||||||
|
template: project.html
|
||||||
|
about: https://gitlab.com/nofusscomputing/projects/ansible/nfc_glpi
|
||||||
|
---
|
||||||
|
|
||||||
|
This Ansible role is designed to manage GLPI specifically installation and configuration.
|
||||||
|
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- install GLPI using our [docker container](https://gitlab.com/nofusscomputing/projects/docker-glpi)
|
||||||
|
|
||||||
|
- [Configure using Config from Code](config_from_code.md)
|
||||||
|
|
||||||
|
|
||||||
|
## Default Variables
|
||||||
|
|
||||||
|
``` yaml title="defaults/main.yaml" linenums="1"
|
||||||
|
|
||||||
|
--8<-- "defaults/main.yaml"
|
||||||
|
|
||||||
|
```
|
1
gitlab-ci
Submodule
1
gitlab-ci
Submodule
Submodule gitlab-ci added at 975de7aca2
29
handlers/main.yaml
Normal file
29
handlers/main.yaml
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
---
|
||||||
|
# - name: Log Rotate Configuration files
|
||||||
|
# ansible.builtin.template:
|
||||||
|
# src: definition.j2
|
||||||
|
# dest: "{{ directory_logrotate_config }}/{{ item.name }}"
|
||||||
|
# owner: root
|
||||||
|
# mode: '0644'
|
||||||
|
# force: true
|
||||||
|
# loop: "{{ logrotate_configuration }}"
|
||||||
|
# listen: 'configure_logrotate'
|
||||||
|
# notify: restart_logrotate
|
||||||
|
# when: logrotate_installed | bool
|
||||||
|
|
||||||
|
|
||||||
|
# - name: Restart logrotate
|
||||||
|
# ansible.builtin.service:
|
||||||
|
# name: logrotate
|
||||||
|
# state: restarted
|
||||||
|
# listen: restart_logrotate
|
||||||
|
# when: logrotate_installed | bool
|
||||||
|
|
||||||
|
- name: Restart GLPI
|
||||||
|
community.docker.docker_container:
|
||||||
|
name: "{{ docker_container_name_glpi }}"
|
||||||
|
state: started
|
||||||
|
restart: true
|
||||||
|
listen: restart_glpi
|
||||||
|
when: >
|
||||||
|
glpi_installed | bool
|
13
meta/main.yaml
Normal file
13
meta/main.yaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
galaxy_info:
|
||||||
|
role_name: nfc_glpi
|
||||||
|
author: No Fuss Computing
|
||||||
|
description: |-
|
||||||
|
A universal role to install and configure a glpi.
|
||||||
|
|
||||||
|
This role is also desiged so that it can be included within other roles.
|
||||||
|
|
||||||
|
issue_tracker_url: https://gitlab.com/nofusscomputing/projects/ansible/nfc_glpi
|
||||||
|
|
||||||
|
license: https://gitlab.com/nofusscomputing/projects/ansible/nfc_glpi/-/blob/master/LICENSE
|
||||||
|
|
||||||
|
min_ansible_version: '1.2'
|
33
mkdocs.yml
Normal file
33
mkdocs.yml
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
INHERIT: website-template/mkdocs.yml
|
||||||
|
|
||||||
|
docs_dir: 'docs'
|
||||||
|
|
||||||
|
repo_name: nfc_glpi
|
||||||
|
repo_url: https://gitlab.com/nofusscomputing/projects/ansible/nfc_glpi
|
||||||
|
edit_uri: '/-/ide/project/nofusscomputing/projects/ansible/nfc_glpi/edit/development/-/docs/'
|
||||||
|
|
||||||
|
nav:
|
||||||
|
- Home: index.md
|
||||||
|
|
||||||
|
- Articles:
|
||||||
|
|
||||||
|
- articles/index.md
|
||||||
|
|
||||||
|
- Projects:
|
||||||
|
|
||||||
|
- projects/index.md
|
||||||
|
|
||||||
|
- Ansible Roles:
|
||||||
|
|
||||||
|
- GLPI:
|
||||||
|
|
||||||
|
- projects/nfc_glpi/index.md
|
||||||
|
|
||||||
|
- projects/nfc_glpi/config_from_code.md
|
||||||
|
|
||||||
|
- Operations:
|
||||||
|
|
||||||
|
- operations/index.md
|
||||||
|
|
||||||
|
- Contact Us: contact.md
|
||||||
|
|
24
tasks/api/api.yaml
Normal file
24
tasks/api/api.yaml
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
---
|
||||||
|
- name: Always End Session
|
||||||
|
block:
|
||||||
|
|
||||||
|
|
||||||
|
- name: Start Session
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/session-create.yaml
|
||||||
|
when: glpi.api.session | default('') == ''
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append/Create Item
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: search-add.yaml
|
||||||
|
loop: "{{ glpi_config_as_code_json }}"
|
||||||
|
|
||||||
|
|
||||||
|
always:
|
||||||
|
|
||||||
|
|
||||||
|
- name: End Session
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/session-end.yaml
|
||||||
|
when: glpi_session_get.status | default(0) | int == 200
|
73
tasks/api/append-create-item.yaml
Normal file
73
tasks/api/append-create-item.yaml
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Show item
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "{{ item }}"
|
||||||
|
|
||||||
|
- name: Create item_body
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: "{{ item.body }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Search for item IDs
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search.yaml
|
||||||
|
|
||||||
|
|
||||||
|
- name: Show Body
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "{{ item_body }}"
|
||||||
|
when: item_body is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Create Item
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/{{ item.api_path }}{% if item.sub_path is defined %}/{{ item.sub_path }}{% endif %}"
|
||||||
|
method: "POST"
|
||||||
|
return_content: true
|
||||||
|
body: "{\"input\": {{ item_body | from_yaml | to_json }} }"
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
no_log: true
|
||||||
|
register: create_item
|
||||||
|
when: >
|
||||||
|
not item_body.id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Update Item
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/{{ item.api_path }}{% if item.sub_path is defined %}/{{ item.sub_path }}{% else %}{% if item.api_path != 'Config' %}/{{ item_body.id | default('') }}{% endif %}{% endif %}"
|
||||||
|
method: "PATCH"
|
||||||
|
return_content: true
|
||||||
|
body: "{\"input\": {{ item_body | from_yaml | to_json }} }"
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
no_log: true
|
||||||
|
register: update_item
|
||||||
|
when: item_body.id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Fail on no action
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: No action carried out, stop.
|
||||||
|
when: >
|
||||||
|
update_item.skipped | default(false) | bool
|
||||||
|
and
|
||||||
|
create_item.skipped | default(false) | bool
|
||||||
|
|
||||||
|
|
||||||
|
- name: Clear temp vars
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: {}
|
||||||
|
create_item: {}
|
||||||
|
update_item: {}
|
||||||
|
no_log: true
|
100
tasks/api/config.yaml
Normal file
100
tasks/api/config.yaml
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Fetch ID for {{ list_item.body.name }}
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/{{ item.api_path }}?searchText[name]={{ list_item.body.name | urlencode }}"
|
||||||
|
method: "GET"
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
no_log: true
|
||||||
|
register: glpi_search
|
||||||
|
|
||||||
|
|
||||||
|
- name: Build API Body for {{ list_item.body.name }}
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
config_item:
|
||||||
|
api_path: "{{ list_item.api_path }}"
|
||||||
|
body:
|
||||||
|
context: "{{ list_item.body.context }}"
|
||||||
|
name: "{{ list_item.body.name }}"
|
||||||
|
value: "{{ list_item.body.value }}"
|
||||||
|
when: glpi_search.json | length | int == 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Build API Body (with ID) for {{ list_item.body.name }}
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
config_item:
|
||||||
|
api_path: "{{ list_item.api_path }}"
|
||||||
|
body:
|
||||||
|
id: "{% for found_id in glpi_search.json %}{%if list_item.body.name == found_id.name %}{{ found_id.id }}{% endif %}{% endfor %}"
|
||||||
|
context: "{{ list_item.body.context }}"
|
||||||
|
name: "{{ list_item.body.name }}"
|
||||||
|
value: "{{ list_item.body.value }}"
|
||||||
|
when: glpi_search.json | length | int > 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Remove Empty ID from body
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
config_item:
|
||||||
|
api_path: "{{ list_item.api_path }}"
|
||||||
|
body:
|
||||||
|
context: "{{ list_item.body.context }}"
|
||||||
|
name: "{{ list_item.body.name }}"
|
||||||
|
value: "{{ list_item.body.value }}"
|
||||||
|
when: config_item.body.id | default('0') == ''
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: "Item [{{ config_item.body.id + ']: ' + config_item.body.name }}"
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "{{ config_item }}"
|
||||||
|
when: config_item is defined
|
||||||
|
|
||||||
|
|
||||||
|
# ToDo: figure out why cant create item?????
|
||||||
|
|
||||||
|
# - name: Create Config Item
|
||||||
|
# ansible.builtin.uri:
|
||||||
|
# url: "http://{{ glpi.host }}/apirest.php/{{ config_item.api_path }}"
|
||||||
|
# method: "POST"
|
||||||
|
# return_content: true
|
||||||
|
# body: "{\"input\": {{ config_item.body | from_yaml | to_json }} }"
|
||||||
|
# status_code: [200, 201]
|
||||||
|
# headers:
|
||||||
|
# App-Token: "{{ glpi.app_token }}"
|
||||||
|
# Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
# body_format: json
|
||||||
|
# # no_log: true
|
||||||
|
# when: not config_item.body.id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Update Config Item
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/{{ item.api_path }}/{{ config_item.body.id }}"
|
||||||
|
method: "PATCH"
|
||||||
|
return_content: true
|
||||||
|
body: "{\"input\": {{ config_item.body | from_yaml | to_json }} }"
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
no_log: true
|
||||||
|
when: config_item.body.id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Clear temp vars
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
config_item: {}
|
||||||
|
glpi_search: {}
|
||||||
|
list_item: {}
|
||||||
|
no_log: true
|
21
tasks/api/excluded_config.yaml
Normal file
21
tasks/api/excluded_config.yaml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
#
|
||||||
|
# Config items excluded from Adding/Updating.
|
||||||
|
#
|
||||||
|
# Each list item is the name of the config item.
|
||||||
|
#
|
||||||
|
- name: Config Items to skip
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
skip_config:
|
||||||
|
- cas_version
|
||||||
|
- dbversion
|
||||||
|
- _dbslave_status
|
||||||
|
- init_all
|
||||||
|
- instance_uuid
|
||||||
|
- notification_uuid
|
||||||
|
- proxy_passwd
|
||||||
|
- registration_uuid
|
||||||
|
- schema_version
|
||||||
|
- smtp_passwd
|
||||||
|
- version
|
||||||
|
when: item.api_path == 'Config'
|
45
tasks/api/search-add.yaml
Normal file
45
tasks/api/search-add.yaml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Ticket Template
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/ticket_template.yaml
|
||||||
|
when: item.api_path == 'TicketTemplate'
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append/Create Item
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/append-create-item.yaml
|
||||||
|
when: >
|
||||||
|
not item.api_path == 'Config'
|
||||||
|
and
|
||||||
|
not item.api_path == 'TicketTemplate'
|
||||||
|
|
||||||
|
|
||||||
|
- name: Config Items to skip
|
||||||
|
ansible.builtin.import_tasks:
|
||||||
|
file: api/excluded_config.yaml
|
||||||
|
|
||||||
|
|
||||||
|
- name: Add/Update GLPI Config
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/config.yaml
|
||||||
|
when: >
|
||||||
|
not sub_item.name in skip_config
|
||||||
|
and
|
||||||
|
sub_item.value is defined
|
||||||
|
loop: "{% if item.api_path == 'Config' %}{{ item.body }}{% else %}{{ [] }}{% endif %}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: sub_item
|
||||||
|
vars:
|
||||||
|
list_item:
|
||||||
|
api_path: "{{ item.api_path }}"
|
||||||
|
body:
|
||||||
|
context: "{{ sub_item.context }}"
|
||||||
|
name: "{{ sub_item.name }}"
|
||||||
|
value: "{{ sub_item.value }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Clear temp vars
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: {}
|
||||||
|
no_log: true
|
42
tasks/api/search.yaml
Normal file
42
tasks/api/search.yaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Search item_id
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search/item_id.yaml
|
||||||
|
when: not item.body.id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Search entities_id
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search/entities_id.yaml
|
||||||
|
when: item.entities_id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Search groups_id
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search/groups_id.yaml
|
||||||
|
when: item.groups_id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Search itilcategories_id
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search/itilcategories_id.yaml
|
||||||
|
when: item.itilcategories_id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Search tickettemplates_id_demand
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search/tickettemplates_id_demand.yaml
|
||||||
|
when: item.tickettemplates_id_demand is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Search tickettemplates_id
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search/tickettemplates_id.yaml
|
||||||
|
when: item.tickettemplates_id is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Search users_id
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search/users_id.yaml
|
||||||
|
when: item.users_id is defined
|
54
tasks/api/search/entities_id.yaml
Normal file
54
tasks/api/search/entities_id.yaml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch entities_id
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/Entity?searchText[name]={{ item.entities_id | urlencode }}"
|
||||||
|
method: "GET"
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
# status_code: "{{ item.status_code | from_yaml | list }}"
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
register: glpi_search
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Iterate over results for ID search
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: |
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
{%- for json in glpi_search.json -%}
|
||||||
|
|
||||||
|
{%- if json.name | string == item.entities_id | string -%}
|
||||||
|
"entities_id": {{ json.id | int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- endfor -%}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
|
register: itarate_id
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
when: >
|
||||||
|
glpi_search.json | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set entities_id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data: "{{ itarate_id.stdout | from_yaml }}"
|
||||||
|
when: itarate_id.stdout | default({}) | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append entities_id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: "{{ item_body | ansible.builtin.combine(new_data | default({})) }}"
|
||||||
|
glpi_search: {}
|
||||||
|
itarate_id: {}
|
||||||
|
new_data: {}
|
||||||
|
no_log: true
|
54
tasks/api/search/groups_id.yaml
Normal file
54
tasks/api/search/groups_id.yaml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Fetch users_id
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/Group?searchText[name]={{ item.groups_id | urlencode }}"
|
||||||
|
method: "GET"
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
register: glpi_search
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Iterate over results for ID search
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: |
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
{%- for json in glpi_search.json -%}
|
||||||
|
|
||||||
|
{%- if json.name | string == item.groups_id | string -%}
|
||||||
|
"groups_id": {{ json.id | int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- endfor -%}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
|
register: itarate_id
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
when: >
|
||||||
|
glpi_search.json | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set groups_id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data: "{{ itarate_id.stdout | from_yaml }}"
|
||||||
|
when: itarate_id.stdout | default({}) | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append groups (have item_body)
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: "{{ item_body | ansible.builtin.combine(new_data | default({})) }}"
|
||||||
|
glpi_search: {}
|
||||||
|
itarate_id: {}
|
||||||
|
new_data: {}
|
||||||
|
no_log: true
|
122
tasks/api/search/item_id.yaml
Normal file
122
tasks/api/search/item_id.yaml
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
---
|
||||||
|
- name: Find Item ID
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/{{ item.api_path }}{% if item.sub_path is defined %}/{{ item.sub_path }}{% endif%}{% if search_items | length | int > 0%}?{% for search in search_items %}searchText[{{ search.name }}]={{ search.value | urlencode }}&{% endfor %}{% else%}?searchText[name]={{ item.body.name | urlencode }}{% endif %}"
|
||||||
|
method: "GET"
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
# status_code: "{{ item.status_code | from_yaml | list }}"
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
register: glpi_search
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data:
|
||||||
|
id: "{{ glpi_search.json[0].id | int }}"
|
||||||
|
when: glpi_search.json | length | int == 1
|
||||||
|
|
||||||
|
|
||||||
|
- name: Iterate over results for TicketTemplateMandatoryField id/TicketTemplateHiddenField
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: |
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
{%- for json in glpi_search.json -%}
|
||||||
|
|
||||||
|
{%- if
|
||||||
|
json.tickettemplates_id | int == item_body.tickettemplates_id | int
|
||||||
|
and
|
||||||
|
json.num | int == item_body.num | int
|
||||||
|
-%}
|
||||||
|
"id": {{ json.id | int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- endfor -%}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
|
register: itarate_id
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
when: >
|
||||||
|
glpi_search.json | length | int > 1
|
||||||
|
and
|
||||||
|
(
|
||||||
|
'TicketTemplateMandatoryField' in item.sub_path | default('')
|
||||||
|
or
|
||||||
|
'TicketTemplateHiddenField' in item.sub_path | default('')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set iterate id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data: "{{ itarate_id.stdout | from_yaml }}"
|
||||||
|
when: itarate_id.stdout is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Iterate over results for TicketTemplatePredefinedField id
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: |
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
{%- for json in glpi_search.json -%}
|
||||||
|
|
||||||
|
{%- if
|
||||||
|
json.num | int == 13
|
||||||
|
and
|
||||||
|
json.tickettemplates_id | int == item_body.tickettemplates_id | int
|
||||||
|
and
|
||||||
|
json.num | int == item_body.num | int
|
||||||
|
and
|
||||||
|
json.value == item_body.value
|
||||||
|
-%}
|
||||||
|
|
||||||
|
"id": {{ json.id | int }}
|
||||||
|
|
||||||
|
|
||||||
|
{%- elif
|
||||||
|
json.num | int != 13
|
||||||
|
and
|
||||||
|
json.tickettemplates_id | int == item_body.tickettemplates_id | int
|
||||||
|
and
|
||||||
|
json.num | int == item_body.num | int
|
||||||
|
-%}
|
||||||
|
"id": {{ json.id | int }}
|
||||||
|
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- endfor -%}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
|
register: itarate_id
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
when: >
|
||||||
|
glpi_search.json | length | int > 1
|
||||||
|
and
|
||||||
|
'TicketTemplatePredefinedField' in item.sub_path | default('')
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set iterate id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data: "{{ itarate_id.stdout | from_yaml }}"
|
||||||
|
when: itarate_id.stdout is defined
|
||||||
|
|
||||||
|
|
||||||
|
- name: Item_id fact Cleanup
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: "{{ item_body | ansible.builtin.combine(new_data | default({})) }}"
|
||||||
|
glpi_search: {}
|
||||||
|
itarate_id: {}
|
||||||
|
new_data: {}
|
||||||
|
no_log: true
|
54
tasks/api/search/itilcategories_id.yaml
Normal file
54
tasks/api/search/itilcategories_id.yaml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch itilcategories_id
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/ITILCategory?searchText[name]={{ item.itilcategories_id | urlencode }}"
|
||||||
|
method: "GET"
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
# status_code: "{{ item.status_code | from_yaml | list }}"
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
register: glpi_search
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Iterate over results for ID search
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: |
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
{%- for json in glpi_search.json -%}
|
||||||
|
|
||||||
|
{%- if json.name | string == item.itilcategories_id | string -%}
|
||||||
|
"itilcategories_id": {{ json.id | int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- endfor -%}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
|
register: itarate_id
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
when: >
|
||||||
|
glpi_search.json | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set itilcategories_id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data: "{{ itarate_id.stdout | from_yaml }}"
|
||||||
|
when: itarate_id.stdout | default({}) | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append itilcategories_id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: "{{ item_body | ansible.builtin.combine(new_data | default({})) }}"
|
||||||
|
glpi_search: {}
|
||||||
|
itarate_id: {}
|
||||||
|
new_data: {}
|
||||||
|
no_log: true
|
54
tasks/api/search/tickettemplates_id.yaml
Normal file
54
tasks/api/search/tickettemplates_id.yaml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch tickettemplates_id
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/TicketTemplate?searchText[name]={{ item.tickettemplates_id | urlencode }}"
|
||||||
|
method: "GET"
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
register: glpi_search
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Iterate over results for ID search
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: |
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
{%- for json in glpi_search.json -%}
|
||||||
|
|
||||||
|
{%- if json.name | string == item.tickettemplates_id | string -%}
|
||||||
|
"tickettemplates_id": {{ json.id | int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- endfor -%}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
|
register: itarate_id
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
when: >
|
||||||
|
glpi_search.json | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set tickettemplates_id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data: "{{ itarate_id.stdout | from_yaml }}"
|
||||||
|
when: itarate_id.stdout | default({}) | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append tickettemplates_id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: "{{ item_body | ansible.builtin.combine(new_data | default({})) }}"
|
||||||
|
tickettemplates_id: "{{ new_data.tickettemplates_id | default(omit) | int }}"
|
||||||
|
glpi_search: {}
|
||||||
|
itarate_id: {}
|
||||||
|
new_data: {}
|
||||||
|
no_log: true
|
54
tasks/api/search/tickettemplates_id_demand.yaml
Normal file
54
tasks/api/search/tickettemplates_id_demand.yaml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch tickettemplates_id_demand
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/TicketTemplate?searchText[name]={{ item.tickettemplates_id_demand | urlencode }}"
|
||||||
|
method: "GET"
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
# status_code: "{{ item.status_code | from_yaml | list }}"
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
register: glpi_search
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Iterate over results for ID search
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: |
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
{%- for json in glpi_search.json -%}
|
||||||
|
|
||||||
|
{%- if json.name | string == item.tickettemplates_id_demand | string -%}
|
||||||
|
"tickettemplates_id_demand": {{ json.id | int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- endfor -%}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
|
register: itarate_id
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
when: >
|
||||||
|
glpi_search.json | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set tickettemplates_id_demand
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data: "{{ itarate_id.stdout | from_yaml }}"
|
||||||
|
when: itarate_id.stdout | default({}) | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append tickettemplates_id_demand
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: "{{ item_body | ansible.builtin.combine(new_data | default({})) }}"
|
||||||
|
glpi_search: {}
|
||||||
|
itarate_id: {}
|
||||||
|
new_data: {}
|
||||||
|
no_log: true
|
55
tasks/api/search/users_id.yaml
Normal file
55
tasks/api/search/users_id.yaml
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Fetch users_id
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/User?searchText[name]={{ item.users_id | urlencode }}"
|
||||||
|
method: "GET"
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
# status_code: "{{ item.status_code | from_yaml | list }}"
|
||||||
|
status_code: [200, 201]
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
register: glpi_search
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Iterate over results for ID search
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: |
|
||||||
|
cat <<EOF
|
||||||
|
{
|
||||||
|
{%- for json in glpi_search.json -%}
|
||||||
|
|
||||||
|
{%- if json.name | string == item.users_id | string -%}
|
||||||
|
"users_id": {{ json.id | int }}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
|
{%- endfor -%}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
args:
|
||||||
|
executable: bash
|
||||||
|
register: itarate_id
|
||||||
|
changed_when: false
|
||||||
|
no_log: true
|
||||||
|
when: >
|
||||||
|
glpi_search.json | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Set users_id
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
new_data: "{{ itarate_id.stdout | from_yaml }}"
|
||||||
|
when: itarate_id.stdout | default({}) | length | int > 0
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append users_id (have item_body)
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
item_body: "{{ item_body | ansible.builtin.combine(new_data | default({})) }}"
|
||||||
|
glpi_search: {}
|
||||||
|
itarate_id: {}
|
||||||
|
new_data: {}
|
||||||
|
no_log: true
|
30
tasks/api/session-create.yaml
Normal file
30
tasks/api/session-create.yaml
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
- name: Fetch API Session Token
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/initSession?get_full_session=true"
|
||||||
|
method: GET
|
||||||
|
return_content: true
|
||||||
|
body: ""
|
||||||
|
status_code: 200
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Authorization: "user_token {{ glpi.user_token }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
register: glpi_session_get
|
||||||
|
no_log: true
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
|
||||||
|
|
||||||
|
- name: Session Data
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
glpi_session:
|
||||||
|
session: "{{ glpi_session_get.json.session }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
|
||||||
|
- name: Session fact
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
glpi: "{{ glpi | ansible.builtin.combine(glpi_session) }}"
|
||||||
|
no_log: true
|
14
tasks/api/session-end.yaml
Normal file
14
tasks/api/session-end.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
- name: End API Session
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ http_protocol | default('https') | string }}://{{ glpi.host }}/apirest.php/killSession"
|
||||||
|
method: GET
|
||||||
|
return_content: true
|
||||||
|
body: ''
|
||||||
|
status_code: 200
|
||||||
|
headers:
|
||||||
|
App-Token: "{{ glpi.app_token }}"
|
||||||
|
Session-Token: "{{ glpi_session_get.json.session.valid_id }}"
|
||||||
|
body_format: json
|
||||||
|
validate_certs: "{{ glpi.validate_certs | default(true) | bool }}"
|
||||||
|
no_log: true
|
103
tasks/api/ticket_template.yaml
Normal file
103
tasks/api/ticket_template.yaml
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Template item
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
template_item: "{{ item }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append/Create TicketTemplate
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/append-create-item.yaml
|
||||||
|
when: item.api_path == 'TicketTemplate'
|
||||||
|
vars:
|
||||||
|
item:
|
||||||
|
api_path: TicketTemplate
|
||||||
|
entities_id: "{{ template_item.entities_id }}"
|
||||||
|
body: "{{ template_item.body }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Search tickettemplates_id
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/search/tickettemplates_id.yaml
|
||||||
|
vars:
|
||||||
|
item:
|
||||||
|
tickettemplates_id: "{{ template_item.body.name }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append/Create Ticket Template Mandatory Fields
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/append-create-item.yaml
|
||||||
|
when: >
|
||||||
|
template_item._TicketTemplateMandatoryField is defined
|
||||||
|
and
|
||||||
|
template_item._TicketTemplateMandatoryField | length | int > 0
|
||||||
|
loop: "{{ template_item._TicketTemplateMandatoryField }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: sub_item
|
||||||
|
vars:
|
||||||
|
search_items:
|
||||||
|
- name: tickettemplates_id
|
||||||
|
value: "{{ tickettemplates_id }}"
|
||||||
|
- name: num
|
||||||
|
value: "{{ sub_item.num }}"
|
||||||
|
item:
|
||||||
|
api_path: TicketTemplate
|
||||||
|
sub_path: "{{ tickettemplates_id }}/TicketTemplateMandatoryField"
|
||||||
|
body:
|
||||||
|
num: "{{ sub_item.num }}"
|
||||||
|
tickettemplates_id: "{{ tickettemplates_id | int }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append/Create Ticket Template Predefined Fields
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/append-create-item.yaml
|
||||||
|
when: >
|
||||||
|
template_item._TicketTemplatePredefinedField is defined
|
||||||
|
and
|
||||||
|
template_item._TicketTemplatePredefinedField | length | int > 0
|
||||||
|
loop: "{{ template_item._TicketTemplatePredefinedField }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: sub_item
|
||||||
|
vars:
|
||||||
|
search_items:
|
||||||
|
- name: tickettemplates_id
|
||||||
|
value: "{{ tickettemplates_id }}"
|
||||||
|
- name: num
|
||||||
|
value: "{{ sub_item.num }}"
|
||||||
|
item:
|
||||||
|
api_path: TicketTemplate
|
||||||
|
sub_path: "{{ tickettemplates_id }}/TicketTemplatePredefinedField"
|
||||||
|
body:
|
||||||
|
num: "{{ sub_item.num | int }}"
|
||||||
|
tickettemplates_id: "{{ tickettemplates_id | int }}"
|
||||||
|
value: "{{ sub_item.value | string }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Append/Create Ticket Template Hidden Fields
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/append-create-item.yaml
|
||||||
|
when: >
|
||||||
|
template_item._TicketTemplateHiddenField is defined
|
||||||
|
and
|
||||||
|
template_item._TicketTemplateHiddenField | length | int > 0
|
||||||
|
loop: "{{ template_item._TicketTemplateHiddenField }}"
|
||||||
|
loop_control:
|
||||||
|
loop_var: sub_item
|
||||||
|
vars:
|
||||||
|
search_items:
|
||||||
|
- name: tickettemplates_id
|
||||||
|
value: "{{ tickettemplates_id }}"
|
||||||
|
- name: num
|
||||||
|
value: "{{ sub_item.num }}"
|
||||||
|
item:
|
||||||
|
api_path: TicketTemplate
|
||||||
|
sub_path: "{{ tickettemplates_id }}/TicketTemplateHiddenField"
|
||||||
|
body:
|
||||||
|
num: "{{ sub_item.num | int }}"
|
||||||
|
tickettemplates_id: "{{ tickettemplates_id | int }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Clear temp vars
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
template_item: {}
|
||||||
|
no_log: true
|
111
tasks/configure.yaml
Normal file
111
tasks/configure.yaml
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
---
|
||||||
|
- name: Clear Any downloaded files
|
||||||
|
ansible.builtin.file:
|
||||||
|
name: "/tmp/ansible"
|
||||||
|
state: absent
|
||||||
|
#loop: "{{ glpi_plugins }}"
|
||||||
|
|
||||||
|
- name: Clear Any downloaded files
|
||||||
|
ansible.builtin.file:
|
||||||
|
name: "/tmp/ansible"
|
||||||
|
state: directory
|
||||||
|
#loop: "{{ glpi_plugins }}"
|
||||||
|
|
||||||
|
# - name: Download Plugins
|
||||||
|
# ansible.builtin.get_url:
|
||||||
|
# url: "{{ item.url }}"
|
||||||
|
# dest: "/tmp/{{ item.filename }}"
|
||||||
|
# loop: "{{ glpi_plugins }}"
|
||||||
|
|
||||||
|
# - name: Download plugins
|
||||||
|
# ansible.builtin.command:
|
||||||
|
# cmd: "bash -c echo $({{ item.url }})"
|
||||||
|
# loop: "{{ glpi_plugins }}"
|
||||||
|
|
||||||
|
# wget https://github.com/pluginsGLPI/formcreator/releases/download/2.13.6/glpi-formcreator-2.13.6.tar.bz2 -O /tmp/plugin-form-creator.tar.bz2
|
||||||
|
# tar -xjf /tmp/plugin-form-creator.tar.bz2 -C /var/lib/docker/volumes/glpi_glpi_plugins/_data/
|
||||||
|
|
||||||
|
# wget https://github.com/glpi-project/glpi-inventory-plugin/releases/download/1.2.3/glpi-glpiinventory-1.2.3.tar.bz2 -O /tmp/glpi-glpiinventory-1.2.3.tar.bz2
|
||||||
|
# tar -xjf /tmp/glpi-glpiinventory-1.2.3.tar.bz2 -C /var/lib/docker/volumes/glpi_glpi_plugins/_data/
|
||||||
|
# chown www-data:www-data -R /var/lib/docker/volumes/glpi_glpi_plugins/_data/
|
||||||
|
|
||||||
|
- name: Install bzip
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
loop: "{{ apps }}"
|
||||||
|
vars:
|
||||||
|
apps:
|
||||||
|
- bzip2
|
||||||
|
- jq
|
||||||
|
- wget
|
||||||
|
|
||||||
|
|
||||||
|
# - name: Example clone of a single branch
|
||||||
|
# ansible.builtin.git:
|
||||||
|
# repo: "{{ item.repo }}.git"
|
||||||
|
# dest: "/var/lib/docker/volumes/plugins_glpi/_data/{{ item.name }}"
|
||||||
|
# single_branch: true
|
||||||
|
# version: "{{ item.version }}"
|
||||||
|
# depth: 1
|
||||||
|
# force: true
|
||||||
|
# loop: "{{ plugins }}"
|
||||||
|
# vars:
|
||||||
|
# plugins:
|
||||||
|
# - name: actualtime
|
||||||
|
# repo: https://github.com/ticgal/actualtime
|
||||||
|
# version: 2.1.0
|
||||||
|
|
||||||
|
# - name: glpiinventory
|
||||||
|
# repo: https://github.com/glpi-project/glpi-inventory-plugin
|
||||||
|
# version: 1.2.3
|
||||||
|
# # for creator doesnt work
|
||||||
|
# # - name: formcreator
|
||||||
|
# # repo: https://github.com/pluginsGLPI/formcreator
|
||||||
|
# # version: 2.13.6
|
||||||
|
|
||||||
|
# - name: geninventorynumber
|
||||||
|
# repo: https://github.com/pluginsGLPI/geninventorynumber
|
||||||
|
# version: 2.8.3
|
||||||
|
|
||||||
|
# - name: releases
|
||||||
|
# repo: https://github.com/InfotelGLPI/releases
|
||||||
|
# version: 2.0.3
|
||||||
|
|
||||||
|
# - name: phpsaml
|
||||||
|
# repo: https://github.com/DonutsNL/phpsaml
|
||||||
|
# # version: e7357a49ca9f0b612bc28879a0c703cdbfc4463b
|
||||||
|
# version: master
|
||||||
|
|
||||||
|
# - name: Download and Extract the plugins
|
||||||
|
# ansible.builtin.shell:
|
||||||
|
# cmd: |
|
||||||
|
# export URL=$(curl -s {{ item.url }} | jq .assets[0].browser_download_url | tr -d \");
|
||||||
|
# wget $URL -O /tmp/ansible/$(basename ${URL});
|
||||||
|
# tar -xjf /tmp/ansible/$(basename ${URL}) -C /var/lib/docker/volumes/plugins_glpi/_data/;
|
||||||
|
# loop: "{{ glpi_plugins }}"
|
||||||
|
# changed_when: false
|
||||||
|
|
||||||
|
|
||||||
|
- name: Fix file perms
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: chown www-data:www-data -R /var/lib/docker/volumes/plugins_glpi/_data/
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
# - name: Unarchive a file that needs to be downloaded (added in 2.0)
|
||||||
|
# ansible.builtin.unarchive:
|
||||||
|
# src: /tmp/{{ item.filename }}
|
||||||
|
# dest: /var/lib/docker/volumes/plugins_glpi/_data/
|
||||||
|
# remote_src: true
|
||||||
|
# extra_opts:
|
||||||
|
# - -j
|
||||||
|
# loop: "{{ glpi_plugins }}"
|
||||||
|
|
||||||
|
- name: Clear Any downloaded files
|
||||||
|
ansible.builtin.file:
|
||||||
|
name: "{{ item.filename }}"
|
||||||
|
state: absent
|
||||||
|
loop: "{{ glpi_plugins }}"
|
||||||
|
|
||||||
|
- name: Reload logroate if required
|
||||||
|
ansible.builtin.meta: flush_handlers
|
150
tasks/install.yaml
Normal file
150
tasks/install.yaml
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
---
|
||||||
|
- name: GPLI Docker Container
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: docker_management
|
||||||
|
vars:
|
||||||
|
docker_images:
|
||||||
|
- name: "{{ docker_image_name_glpi }}"
|
||||||
|
tag: "{{ docker_image_tag_glpi }}"
|
||||||
|
|
||||||
|
docker_networks:
|
||||||
|
- name: "{{ docker_container_name_glpi }}-access"
|
||||||
|
internal: false # this needs to be added to the docker role
|
||||||
|
- name: "{{ docker_container_name_glpi }}-smtp-access"
|
||||||
|
internal: true
|
||||||
|
|
||||||
|
docker_containers:
|
||||||
|
- name: "{{ docker_container_name_glpi }}"
|
||||||
|
image: "{{ docker_image_name_glpi }}:{{ docker_image_tag_glpi }}"
|
||||||
|
env:
|
||||||
|
TIMEZONE: UTC
|
||||||
|
networks:
|
||||||
|
- name: "{{ docker_container_name_glpi }}-access"
|
||||||
|
- name: "ingress-access"
|
||||||
|
- name: "{{ docker_container_name_glpi }}-smtp-access"
|
||||||
|
- name: ldap-access
|
||||||
|
- name: mysql-access
|
||||||
|
# published_ports:
|
||||||
|
# - 80:80
|
||||||
|
volumes:
|
||||||
|
- /usr/share/zoneinfo/Etc/UTC:/etc/timezone:ro
|
||||||
|
- /usr/share/zoneinfo/Etc/UTC:/etc/localtime:ro
|
||||||
|
- "config_{{ docker_container_name_glpi }}:/var/www/html/config"
|
||||||
|
- "data_{{ docker_container_name_glpi }}:/var/www/html/files"
|
||||||
|
- "log_{{ docker_container_name_glpi }}:/var/log"
|
||||||
|
- "marketplace_{{ docker_container_name_glpi }}:/var/www/html/marketplace"
|
||||||
|
- "plugins_{{ docker_container_name_glpi }}:/var/www/html/plugins"
|
||||||
|
|
||||||
|
docker_volumes:
|
||||||
|
- name: "plugins_{{ docker_container_name_glpi }}"
|
||||||
|
- name: "data_{{ docker_container_name_glpi }}"
|
||||||
|
- name: "config_{{ docker_container_name_glpi }}"
|
||||||
|
- name: "marketplace_{{ docker_container_name_glpi }}"
|
||||||
|
- name: "log_{{ docker_container_name_glpi }}"
|
||||||
|
- name: "varlog_{{ docker_container_name_glpi }}"
|
||||||
|
|
||||||
|
|
||||||
|
- name: Create GLPI database
|
||||||
|
community.mysql.mysql_db:
|
||||||
|
name: "{{ mysql_database_glpi }}"
|
||||||
|
state: present
|
||||||
|
login_unix_socket: "{{ mysql_unix_socket }}"
|
||||||
|
login_user: "{{ mysql_login_user }}"
|
||||||
|
login_password: "{{ mysql_login_password }}"
|
||||||
|
login_host: "{{ mysql_login_host | default('') }}"
|
||||||
|
config_file: ''
|
||||||
|
|
||||||
|
|
||||||
|
- name: Create user with password, all database privileges and 'WITH GRANT OPTION' in db1 and db2
|
||||||
|
community.mysql.mysql_user:
|
||||||
|
state: "{{ item.state | default('present') }}"
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
password: "{{ item.password }}"
|
||||||
|
host: "{{ item.host | default('localhost') }}"
|
||||||
|
priv: "{{ item.priv | default(omit) | from_yaml }}"
|
||||||
|
update_password: "{{ item.update_password | default('on_create') }}"
|
||||||
|
login_host: "{{ mysql_login_host | default('') }}"
|
||||||
|
login_unix_socket: "{{ mysql_unix_socket }}"
|
||||||
|
login_user: "{{ mysql_login_user }}"
|
||||||
|
login_password: "{{ mysql_login_password }}"
|
||||||
|
config_file: ''
|
||||||
|
loop: "{{ database_mysql_users }}"
|
||||||
|
vars:
|
||||||
|
database_mysql_users:
|
||||||
|
- name: glpi
|
||||||
|
password: admin
|
||||||
|
host: '%'
|
||||||
|
priv:
|
||||||
|
'glpi.*': 'ALL,GRANT'
|
||||||
|
|
||||||
|
# sudo cp -r /var/www/html/glpi/config/* /var/lib/docker/volumes/glpi_config_glpi/_data/
|
||||||
|
# sudo cp -r /var/www/html/glpi/files/* /var/lib/docker/volumes/glpi_data_glpi/_data/
|
||||||
|
# sudo cp -r /var/www/html/glpi/plugins/* /var/lib/docker/volumes/glpi_glpi_plugins/_data/
|
||||||
|
# sudo cp -r /var/www/html/glpi/marketplace/* /var/lib/docker/volumes/glpi_marketplace_glpi/_data/
|
||||||
|
|
||||||
|
|
||||||
|
# sudo chmod -R 777 /var/lib/docker/volumes/glpi_config_glpi/_data/
|
||||||
|
# sudo chmod -R 777 /var/lib/docker/volumes/glpi_data_glpi/_data/
|
||||||
|
# sudo chmod -R 777 /var/lib/docker/volumes/glpi_glpi_plugins/_data/
|
||||||
|
# sudo chmod -R 777 /var/lib/docker/volumes/glpi_marketplace_glpi/_data/
|
||||||
|
|
||||||
|
- name: Add fail2ban filters
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ item.dest }}"
|
||||||
|
mode: '760'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
loop: "{{ the_files }}"
|
||||||
|
# notify: reload_fail2ban
|
||||||
|
when: >
|
||||||
|
install_fail2ban | default(false) | bool
|
||||||
|
vars:
|
||||||
|
the_files:
|
||||||
|
- src: fail2ban.filter.conf
|
||||||
|
dest: "/etc/fail2ban/filter.d/glpi.local"
|
||||||
|
- src: fail2ban.filter.conf
|
||||||
|
dest: "/etc/fail2ban/filter.d/glpi-api.local"
|
||||||
|
|
||||||
|
|
||||||
|
- name: "Fail2Ban Jail for GLPI"
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: nfc_firewall
|
||||||
|
when: >
|
||||||
|
install_fail2ban | default(false) | bool
|
||||||
|
vars:
|
||||||
|
fail2ban:
|
||||||
|
config:
|
||||||
|
- name: "glpi-{{ docker_container_name_glpi }}"
|
||||||
|
sub_path: jail.d
|
||||||
|
sections:
|
||||||
|
DEFAULT:
|
||||||
|
"glpi_log": "/var/lib/docker/volumes/data_{{ docker_container_name_glpi }}/_data/_log/event.log"
|
||||||
|
glpi:
|
||||||
|
enabled: true
|
||||||
|
mode: polling
|
||||||
|
chain: DOCKER-USER
|
||||||
|
port: http,https
|
||||||
|
logpath: "%(glpi_log)s"
|
||||||
|
filter: glpi
|
||||||
|
findtime: 600
|
||||||
|
maxretry: 5
|
||||||
|
- name: "api_glpi-{{ docker_container_name_glpi }}"
|
||||||
|
sub_path: jail.d
|
||||||
|
sections:
|
||||||
|
DEFAULT:
|
||||||
|
"api_glpi_log": "/var/lib/docker/volumes/log_{{ docker_container_name_glpi }}/_data/apache2/access-glpi.log"
|
||||||
|
api_glpi:
|
||||||
|
enabled: true
|
||||||
|
mode: polling
|
||||||
|
chain: DOCKER-USER
|
||||||
|
port: http,https
|
||||||
|
logpath: "%(api_glpi_log)s"
|
||||||
|
filter: glpi-api
|
||||||
|
findtime: 600
|
||||||
|
maxretry: 5
|
||||||
|
|
||||||
|
|
||||||
|
- name: Task Final playbook variables
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
glpi_installed: true
|
40
tasks/main.yaml
Normal file
40
tasks/main.yaml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
- name: Install GLPI
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: install.yaml
|
||||||
|
apply:
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
when: >
|
||||||
|
install_glpi | bool
|
||||||
|
and
|
||||||
|
not glpi_installed | bool
|
||||||
|
|
||||||
|
|
||||||
|
- name: Configure Log Rotate
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: configure.yaml
|
||||||
|
apply:
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
when: glpi_installed | bool
|
||||||
|
# and
|
||||||
|
# ansible_os_family == "Debian"
|
||||||
|
# and
|
||||||
|
# (
|
||||||
|
# logrotate is defined
|
||||||
|
# and
|
||||||
|
# logrotate | default([]) | length | int > 0
|
||||||
|
# )
|
||||||
|
|
||||||
|
- name: API tasks
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: api/api.yaml
|
||||||
|
apply:
|
||||||
|
tags:
|
||||||
|
- always
|
||||||
|
when: glpi_config_as_code_json | length | int > 0
|
15
templates/fail2ban.filter-api.conf
Normal file
15
templates/fail2ban.filter-api.conf
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#
|
||||||
|
# Fail2ban Filter, GLPI API Denied access
|
||||||
|
#
|
||||||
|
# Managed By: Ansible
|
||||||
|
# Role: nfc_glpi
|
||||||
|
#
|
||||||
|
# Do not edit this file directly as it will be automagically updated by ansible.
|
||||||
|
# to make changes update the ansible play that deploys this file.
|
||||||
|
[Init]
|
||||||
|
maxlines = 2
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
|
||||||
|
failregex = ^(<HOST>[\d|\.?]{1,3}).+apirest.php.+"\s40\d\s\d{1,5}
|
||||||
|
|
17
templates/fail2ban.filter.conf
Normal file
17
templates/fail2ban.filter.conf
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# Fail2ban Filter, GLPI
|
||||||
|
#
|
||||||
|
# Managed By: Ansible
|
||||||
|
# Role: nfc_glpi
|
||||||
|
#
|
||||||
|
# Do not edit this file directly as it will be automagically updated by ansible.
|
||||||
|
# to make changes update the ansible play that deploys this file.
|
||||||
|
[Init]
|
||||||
|
maxlines = 2
|
||||||
|
|
||||||
|
[Definition]
|
||||||
|
# failregex = ^(?P<DATETIME>\d{4}-\d{2}-\d{2}\s?\d{2}:\d{2}:\d{2})\s+?\S+\n?\[login\]\s+?[\d+]?:?[\s+]?Failed\s+?login\s+?for\s(?P<USER>.+)\s+?from\s+?IP\s+?(?P<HOST>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$
|
||||||
|
|
||||||
|
# failregex = ^(.+)ogin] \d+: Failed login for (.+) from IP (<HOST>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$
|
||||||
|
failregex = ^.*?(Failed login for)[\S\s]+(from IP) <HOST>.*$
|
||||||
|
# ^.*\s(\[\S).*?(Failed login for) \S+ (from IP) <HOST>.*$
|
1
website-template
Submodule
1
website-template
Submodule
Submodule website-template added at 992b54805b
Reference in New Issue
Block a user