Skip to content

Commit baf5807

Browse files
committed
feat: add service module
1 parent 06a2fc4 commit baf5807

File tree

1 file changed

+184
-0
lines changed

1 file changed

+184
-0
lines changed

plugins/modules/pfsense_service.py

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
4+
# Copyright: (c) 2022, Peter B. Dick <peter.dick@fovea.de>
5+
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6+
7+
from __future__ import absolute_import, division, print_function
8+
9+
__metaclass__ = type
10+
11+
ANSIBLE_METADATA = {'metadata_version': '1.1',
12+
'status': ['preview'],
13+
'supported_by': 'community'}
14+
15+
DOCUMENTATION = """
16+
---
17+
module: pfsense_service
18+
version_added: "0.4.3"
19+
author: Peter B. Dick
20+
short_description: Adds a service to PFSense config settings
21+
description:
22+
- Adds a service to PFSense config settings
23+
notes:
24+
options:
25+
name:
26+
description: The name of the service
27+
required: true
28+
type: str
29+
rcfile:
30+
description: The name of the rc file
31+
required: true
32+
type: str
33+
executable:
34+
description: The name of the executable
35+
required: true
36+
type: str
37+
description:
38+
description: This parameter is not yet supported!
39+
required: false
40+
type: str
41+
"""
42+
43+
EXAMPLES = """
44+
- name: add a service
45+
pfsense_service:
46+
name: filebeat
47+
rcfile: filebeat
48+
executable: filebeat
49+
"""
50+
51+
RETURN = """
52+
commands:
53+
description: the set of commands that would be pushed to the remote device (if pfSense had a CLI)
54+
returned: always
55+
type: list
56+
sample: ["services add filebeat"]
57+
"""
58+
59+
from copy import deepcopy
60+
from ansible.module_utils.basic import AnsibleModule
61+
from ansible_collections.pfsensible.core.plugins.module_utils.module_base import PFSenseModuleBase
62+
63+
SERVICE_ARGUMENT_SPEC = dict(
64+
name=dict(required=True, type='str'),
65+
rcfile=dict(required=True, type='str'),
66+
executable=dict(required=True, type='str'),
67+
description=dict(default='', required=False, type='str'),
68+
)
69+
70+
71+
class PFSenseServiceModule(PFSenseModuleBase):
72+
""" module managing pfsense Service settings """
73+
74+
@staticmethod
75+
def get_argument_spec():
76+
""" return argument spec """
77+
return SERVICE_ARGUMENT_SPEC
78+
79+
##############################
80+
# init
81+
#
82+
def __init__(self, module, pfsense=None):
83+
super(PFSenseServiceModule, self).__init__(module, pfsense)
84+
self.serviceElement = None
85+
self.name = "pfsense_service"
86+
self.installedPackagesElement = self.pfsense.get_element('installedpackages', create_node=True)
87+
88+
def _params_to_obj(self):
89+
""" return a dict from module params """
90+
params = self.params
91+
obj = self.pfsense.element_to_dict(self.serviceElement)
92+
self.before = deepcopy(obj)
93+
self.before_elt = deepcopy(self.serviceElement)
94+
95+
def _set_param(target, param):
96+
if params.get(param) is not None:
97+
if isinstance(params[param], str):
98+
target[param] = params[param]
99+
else:
100+
target[param] = str(params[param])
101+
102+
for param in SERVICE_ARGUMENT_SPEC:
103+
_set_param(obj, param)
104+
105+
return obj
106+
107+
def _validate_params(self):
108+
""" do some extra checks on input parameters """
109+
pass
110+
111+
def run(self, params):
112+
""" process input params to add/update/delete """
113+
self.params = params
114+
115+
# find given name for service in parameter name
116+
serviceName = params.get('name')
117+
118+
# find service for service name
119+
for service in self.installedPackagesElement.findall('service'):
120+
if service is not None:
121+
name = service.find('name').text
122+
if serviceName == name:
123+
self.serviceElement = service
124+
125+
# add a new new service if none exist with the given parameter name
126+
if self.serviceElement is None:
127+
self.serviceElement = self.pfsense.new_element('service')
128+
self.installedPackagesElement.append(self.serviceElement)
129+
130+
self.target_elt = self.serviceElement
131+
self._validate_params()
132+
self.obj = self._params_to_obj()
133+
self._add()
134+
135+
def _update(self):
136+
""" make the target pfsense reload """
137+
cmd = '''
138+
require_once("filter.inc");
139+
require_once("Service.inc");
140+
$retval = 0;
141+
$retval |= Service_resync_config();
142+
'''
143+
return self.pfsense.phpshell(cmd)
144+
145+
@staticmethod
146+
def _get_obj_name():
147+
""" return obj's name """
148+
return "Service"
149+
150+
@staticmethod
151+
def fvalue_bool(value):
152+
""" boolean value formatting function """
153+
if value is None or value is False or value == 'none' or value != 'on':
154+
return 'False'
155+
156+
return 'True'
157+
158+
def _log_fields(self, before=None):
159+
""" generate pseudo-CLI command fields parameters to create an obj """
160+
values = ''
161+
162+
for param in SERVICE_ARGUMENT_SPEC:
163+
if SERVICE_ARGUMENT_SPEC[param]['type'] == 'bool':
164+
values += self.format_updated_cli_field(self.obj, self.before, param, fvalue=self.fvalue_bool,
165+
add_comma=(values), log_none=False)
166+
else:
167+
values += self.format_updated_cli_field(self.obj, self.before, param, add_comma=(values),
168+
log_none=False)
169+
170+
return values
171+
172+
173+
def main():
174+
module = AnsibleModule(
175+
argument_spec=SERVICE_ARGUMENT_SPEC,
176+
supports_check_mode=True)
177+
178+
pfmodule = PFSenseServiceModule(module)
179+
pfmodule.run(module.params)
180+
pfmodule.commit_changes()
181+
182+
183+
if __name__ == '__main__':
184+
main()

0 commit comments

Comments
 (0)