Skip to content

Commit 09dea14

Browse files
committed
Add cm_service_config module for service-wide configuration management
Signed-off-by: Webster Mudge <[email protected]>
1 parent 563f6f6 commit 09dea14

File tree

2 files changed

+457
-0
lines changed

2 files changed

+457
-0
lines changed
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
#!/usr/bin/python
2+
# -*- coding: utf-8 -*-
3+
4+
# Copyright 2024 Cloudera, Inc. All Rights Reserved.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
DOCUMENTATION = r"""
19+
module: cm_service_config
20+
short_description: Manage the Cloudera Manager service configuration
21+
description:
22+
- Manage a configuration (service-wide) for the Cloudera Manager service.
23+
author:
24+
- "Webster Mudge (@wmudge)"
25+
requirements:
26+
- cm-client
27+
options:
28+
parameters:
29+
description:
30+
- The service-wide configuration to set.
31+
- To unset a parameter, use C(None) as the value.
32+
type: dict
33+
required: yes
34+
aliases:
35+
- params
36+
view:
37+
description:
38+
- The view to materialize.
39+
type: str
40+
default: summary
41+
choices:
42+
- summary
43+
- full
44+
extends_documentation_fragment:
45+
- ansible.builtin.action_common_attributes
46+
- cloudera.cluster.cm_options
47+
- cloudera.cluster.cm_endpoint
48+
- cloudera.cluster.purge
49+
- cloudera.cluster.message
50+
attributes:
51+
check_mode:
52+
support: full
53+
diff_mode:
54+
support: full
55+
platform:
56+
platforms: all
57+
"""
58+
59+
EXAMPLES = r"""
60+
- name: Update (append) several service-wide parameters
61+
cloudera.cluster.cm_service_config:
62+
host: example.cloudera.com
63+
username: "jane_smith"
64+
password: "S&peR4Ec*re"
65+
parameters:
66+
a_configuration: "schema://host:port"
67+
another_configuration: 234
68+
69+
- name: Reset a service-wide parameter
70+
cloudera.cluster.cm_service_config:
71+
host: example.cloudera.com
72+
username: "jane_smith"
73+
password: "S&peR4Ec*re"
74+
parameters:
75+
some_conf: None
76+
77+
- name: Update (purge) service-wide parameters
78+
cloudera.cluster.cm_service_config:
79+
host: example.cloudera.com
80+
username: "jane_smith"
81+
password: "S&peR4Ec*re"
82+
cluster: example-cluster
83+
service: example-service
84+
parameters:
85+
config_one: ValueOne
86+
config_two: 4567
87+
purge: yes
88+
89+
- name: Reset all service-wide parameters
90+
cloudera.cluster.cm_service_config:
91+
host: example.cloudera.com
92+
username: "jane_smith"
93+
password: "S&peR4Ec*re"
94+
cluster: example-cluster
95+
service: example-service
96+
parameters: {}
97+
purge: yes
98+
"""
99+
100+
RETURN = r"""
101+
config:
102+
description: Service-wide configuration details for the Cloudera Manager service.
103+
type: list
104+
elements: dict
105+
contains:
106+
name:
107+
description: The canonical name that identifies this configuration parameter.
108+
type: str
109+
returned: always
110+
value:
111+
description:
112+
- The user-defined value.
113+
- When absent, the default value (if any) will be used.
114+
- Can also be absent, when enumerating allowed configs.
115+
type: str
116+
returned: always
117+
required:
118+
description:
119+
- Whether this configuration is required for the service.
120+
- If any required configuration is not set, operations on the service may not work.
121+
- Available using I(view=full).
122+
type: bool
123+
returned: when supported
124+
default:
125+
description:
126+
- The default value.
127+
- Available using I(view=full).
128+
type: str
129+
returned: when supported
130+
display_name:
131+
description:
132+
- A user-friendly name of the parameters, as would have been shown in the web UI.
133+
- Available using I(view=full).
134+
type: str
135+
returned: when supported
136+
description:
137+
description:
138+
- A textual description of the parameter.
139+
- Available using I(view=full).
140+
type: str
141+
returned: when supported
142+
related_name:
143+
description:
144+
- If applicable, contains the related configuration variable used by the source project.
145+
- Available using I(view=full).
146+
type: str
147+
returned: when supported
148+
sensitive:
149+
description:
150+
- Whether this configuration is sensitive, i.e. contains information such as passwords, which might affect how the value of this configuration might be shared by the caller.
151+
type: bool
152+
returned: when supported
153+
validation_state:
154+
description:
155+
- State of the configuration parameter after validation.
156+
- Available using I(view=full).
157+
type: str
158+
returned: when supported
159+
sample:
160+
- OK
161+
- WARNING
162+
- ERROR
163+
validation_message:
164+
description:
165+
- A message explaining the parameter's validation state.
166+
- Available using I(view=full).
167+
type: str
168+
returned: when supported
169+
validation_warnings_suppressed:
170+
description:
171+
- Whether validation warnings associated with this parameter are suppressed.
172+
- In general, suppressed validation warnings are hidden in the Cloudera Manager UI.
173+
- Configurations that do not produce warnings will not contain this field.
174+
- Available using I(view=full).
175+
type: bool
176+
returned: when supported
177+
"""
178+
179+
import json
180+
181+
from ansible_collections.cloudera.cluster.plugins.module_utils.cm_utils import (
182+
ClouderaManagerMutableModule,
183+
)
184+
from ansible_collections.cloudera.cluster.plugins.module_utils.service_utils import (
185+
ServiceConfigUpdates,
186+
)
187+
188+
189+
from cm_client import (
190+
MgmtServiceResourceApi,
191+
)
192+
from cm_client.rest import ApiException
193+
194+
195+
class ClouderaManagerServiceConfig(ClouderaManagerMutableModule):
196+
def __init__(self, module):
197+
super(ClouderaManagerServiceConfig, self).__init__(module)
198+
199+
# Set the parameters
200+
self.params = self.get_param("parameters")
201+
self.purge = self.get_param("purge")
202+
self.view = self.get_param("view")
203+
204+
# Initialize the return value
205+
self.changed = False
206+
self.diff = {}
207+
self.config = []
208+
209+
# Execute the logic
210+
self.process()
211+
212+
@ClouderaManagerMutableModule.handle_process
213+
def process(self):
214+
refresh = True
215+
api_instance = MgmtServiceResourceApi(self.api_client)
216+
217+
try:
218+
existing = api_instance.read_service_config()
219+
except ApiException as ex:
220+
if ex.status == 404:
221+
self.module.fail_json(msg=json.loads(ex.body)["message"])
222+
else:
223+
raise ex
224+
225+
updates = ServiceConfigUpdates(existing, self.params, self.purge)
226+
227+
if updates.changed:
228+
self.changed = True
229+
230+
if self.module._diff:
231+
self.diff = updates.diff
232+
233+
if not self.module.check_mode:
234+
self.config = [
235+
p.to_dict()
236+
for p in api_instance.update_service_config(
237+
message=self.message, body=updates.config
238+
).items
239+
]
240+
241+
if self.view == "full":
242+
refresh = False
243+
244+
if refresh:
245+
self.config = [
246+
p.to_dict()
247+
for p in api_instance.read_service_config(view=self.view).items
248+
]
249+
250+
251+
def main():
252+
module = ClouderaManagerMutableModule.ansible_module(
253+
argument_spec=dict(
254+
parameters=dict(type="dict", required=True, aliases=["params"]),
255+
purge=dict(type="bool", default=False),
256+
view=dict(
257+
default="summary",
258+
choices=["summary", "full"],
259+
),
260+
),
261+
supports_check_mode=True,
262+
)
263+
264+
result = ClouderaManagerServiceConfig(module)
265+
266+
output = dict(
267+
changed=result.changed,
268+
config=result.config,
269+
)
270+
271+
if module._diff:
272+
output.update(diff=result.diff)
273+
274+
if result.debug:
275+
log = result.log_capture.getvalue()
276+
output.update(debug=log, debug_lines=log.split("\n"))
277+
278+
module.exit_json(**output)
279+
280+
281+
if __name__ == "__main__":
282+
main()

0 commit comments

Comments
 (0)