1#!/usr/local/bin/python3.8
2# -*- coding: utf-8 -*-
3#
4# Copyright (c) 2020 T-Systems Multimedia Solutions GmbH
5# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6#
7# This module is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This software is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this software.  If not, see <http://www.gnu.org/licenses/>.
19
20from __future__ import absolute_import, division, print_function
21
22__metaclass__ = type
23
24DOCUMENTATION = """
25---
26module: icinga_host_template
27short_description: Manage host templates in Icinga2
28description:
29   - Add or remove a host template to Icinga2 through the director API.
30author: Michaela Mattes (@michaelamattes)
31extends_documentation_fragment:
32  - ansible.builtin.url
33  - t_systems_mms.icinga_director.common_options
34version_added: '1.2.0'
35notes:
36  - This module supports check mode.
37options:
38  state:
39    description:
40      - Apply feature state.
41    choices: [ "present", "absent" ]
42    default: present
43    type: str
44  object_name:
45    description:
46      - Icinga object name for this host template.
47      - This is usually a fully qualified host name but it could basically be any kind of string.
48      - To make things easier for your users we strongly suggest to use meaningful names for templates.
49      - For example "generic-host" is ugly, "Standard Linux Server" is easier to understand.
50    aliases: ['name']
51    required: true
52    type: str
53  display_name:
54    description:
55      - Alternative name for this host.
56      - Might be a host alias or and kind of string helping your users to identify this host.
57    type: str
58  address:
59    description:
60      - Host address. Usually an IPv4 address, but may be any kind of address your check plugin is able to deal with.
61    type: str
62  address6:
63    description:
64      - Host IPv6 address. Usually an IPv64 address, but may be any kind of address your check plugin is able to deal with.
65    type: str
66  groups:
67    description:
68      - Hostgroups that should be directly assigned to this node. Hostgroups can be useful for various reasons.
69      - You might assign service checks based on assigned hostgroup. They are also often used as an instrument to enforce restricted views in Icinga Web 2.
70      - Hostgroups can be directly assigned to single hosts or to host templates.
71      - You might also want to consider assigning hostgroups using apply rules.
72    type: list
73    elements: str
74    default: []
75  check_command:
76    description:
77      - The name of the check command.
78      - Though this is not required to be defined in the director, you still have to supply a check_command in a host or host-template.
79    type: str
80  event_command:
81    description:
82      - Event command for host which gets called on every check execution if one of these conditions matches
83      - The host is in a soft state
84      - The host state changes into a hard state
85      - The host state recovers from a soft or hard state to OK/Up
86    type: str
87  check_interval:
88    description:
89      - Your regular check interval.
90    type: str
91  retry_interval:
92    description:
93      - Retry interval, will be applied after a state change unless the next hard state is reached.
94    type: str
95  disabled:
96    description:
97      - Disabled objects will not be deployed.
98    default: False
99    type: bool
100    choices: [True, False]
101  imports:
102    description:
103      - Choose a host-template.
104    type: list
105    elements: str
106  max_check_attempts:
107    description:
108      - Defines after how many check attempts a new hard state is reached.
109    type: str
110  zone:
111    description:
112      - Set the zone.
113    type: str
114  vars:
115    description:
116      - Custom properties of the host.
117    type: "dict"
118  notes:
119    description:
120      - Additional notes for this object.
121    type: str
122    version_added: '1.8.0'
123  notes_url:
124    description:
125      - An URL pointing to additional notes for this object.
126      - Separate multiple urls like this "'http://url1' 'http://url2'".
127      - Maximum length is 255 characters.
128    type: str
129    version_added: '1.8.0'
130  has_agent:
131    description:
132      - Whether this host has the Icinga 2 Agent installed.
133    type: bool
134    choices: [True, False]
135    version_added: '1.9.0'
136  master_should_connect:
137    description:
138      - Whether the parent (master) node should actively try to connect to this agent.
139    type: bool
140    choices: [True, False]
141    version_added: '1.9.0'
142  accept_config:
143    description:
144      - Whether the agent is configured to accept config.
145    type: bool
146    choices: [True, False]
147    version_added: '1.9.0'
148  command_endpoint:
149    description:
150      - The endpoint where commands are executed on.
151    type: str
152"""
153
154EXAMPLES = """
155- name: Create host template
156  t_systems_mms.icinga_director.icinga_host_template:
157    state: present
158    url: "{{ icinga_url }}"
159    url_username: "{{ icinga_user }}"
160    url_password: "{{ icinga_pass }}"
161    object_name: foohosttemplate
162    display_name: foohosttemplate
163    disabled: false
164    check_command: dummy
165    check_interval: 90s
166    retry_interval: 30s
167    groups:
168      - "foohostgroup"
169    imports:
170      - ''
171    notes: "example note"
172    notes_url: "'http://url1' 'http://url2'"
173    has_agent: true
174    master_should_connect: true
175    max_check_attempts: 3
176    accept_config: true
177    command_endpoint: fooendpoint
178"""
179
180RETURN = r""" # """
181
182from ansible.module_utils.basic import AnsibleModule
183from ansible.module_utils.urls import url_argument_spec
184from ansible_collections.t_systems_mms.icinga_director.plugins.module_utils.icinga import (
185    Icinga2APIObject,
186)
187
188
189# ===========================================
190# Module execution.
191#
192def main():
193    # use the predefined argument spec for url
194    argument_spec = url_argument_spec()
195    # add our own arguments
196    argument_spec.update(
197        state=dict(default="present", choices=["absent", "present"]),
198        url=dict(required=True),
199        object_name=dict(required=True, aliases=["name"]),
200        display_name=dict(required=False),
201        groups=dict(type="list", elements="str", default=[], required=False),
202        check_command=dict(required=False),
203        check_interval=dict(required=False),
204        retry_interval=dict(required=False),
205        imports=dict(type="list", elements="str", required=False),
206        disabled=dict(type="bool", default=False, choices=[True, False]),
207        address=dict(required=False),
208        address6=dict(required=False),
209        zone=dict(required=False, default=None),
210        vars=dict(type="dict", default=None),
211        notes=dict(type="str", required=False),
212        notes_url=dict(type="str", required=False),
213        has_agent=dict(type="bool", choices=[True, False]),
214        master_should_connect=dict(type="bool", choices=[True, False]),
215        max_check_attempts=dict(required=False),
216        accept_config=dict(type="bool", choices=[True, False]),
217        event_command=dict(type="str", required=False),
218        command_endpoint=dict(type="str", required=False),
219    )
220
221    # Define the main module
222    module = AnsibleModule(
223        argument_spec=argument_spec, supports_check_mode=True
224    )
225
226    data = {
227        "object_name": module.params["object_name"],
228        "object_type": "template",
229        "display_name": module.params["display_name"],
230        "groups": module.params["groups"],
231        "check_command": module.params["check_command"],
232        "check_interval": module.params["check_interval"],
233        "retry_interval": module.params["retry_interval"],
234        "imports": module.params["imports"],
235        "disabled": module.params["disabled"],
236        "address": module.params["address"],
237        "address6": module.params["address6"],
238        "zone": module.params["zone"],
239        "vars": module.params["vars"],
240        "notes": module.params["notes"],
241        "notes_url": module.params["notes_url"],
242        "has_agent": module.params["has_agent"],
243        "master_should_connect": module.params["master_should_connect"],
244        "max_check_attempts": module.params["max_check_attempts"],
245        "accept_config": module.params["accept_config"],
246        "event_command": module.params["event_command"],
247        "command_endpoint": module.params["command_endpoint"],
248    }
249
250    icinga_object = Icinga2APIObject(module=module, path="/host", data=data)
251
252    changed, diff = icinga_object.update(module.params["state"])
253    module.exit_json(
254        changed=changed,
255        diff=diff,
256    )
257
258
259# import module snippets
260if __name__ == "__main__":
261    main()
262