Skip to content

Commit deb6476

Browse files
committed
CDE deployment first commit
Signed-off-by: Alan <[email protected]>
1 parent 9b4bde2 commit deb6476

File tree

2 files changed

+547
-0
lines changed

2 files changed

+547
-0
lines changed

plugins/modules/de.py

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8 -*-
3+
4+
# Copyright 2021 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+
from ansible.module_utils.basic import AnsibleModule
19+
from ansible_collections.cloudera.cloud.plugins.module_utils.cdp_common import CdpModule
20+
21+
ANSIBLE_METADATA = {'metadata_version': '1.1',
22+
'status': ['preview'],
23+
'supported_by': 'community'}
24+
25+
DOCUMENTATION = r'''
26+
---
27+
module: de
28+
short_description: Enable or Disable CDP DataFlow Services
29+
description:
30+
- Enable or Disable CDP DataFlow Services
31+
author:
32+
- "Dan Chaffelson (@chaffelson)"
33+
requirements:
34+
- cdpy
35+
options:
36+
crn:
37+
description: The name or crn of the CDP Environment to host the Dataflow Service
38+
type: str
39+
required: True
40+
aliases:
41+
- name
42+
- env_crn
43+
state:
44+
description:
45+
- The declarative state of the Dataflow Service
46+
type: str
47+
required: False
48+
default: present
49+
choices:
50+
- present
51+
- enabled
52+
- absent
53+
- disabled
54+
nodes_min:
55+
description: The minimum number of kubernetes nodes needed for the environment.
56+
Note that the lowest minimum is 3 nodes.
57+
type: int
58+
default: 3
59+
required: False
60+
aliases:
61+
- min_k8s_node_count
62+
nodes_max:
63+
description: The maximum number of kubernetes nodes that environment may scale up under high-demand situations.
64+
type: int
65+
default: 3
66+
required: False
67+
aliases:
68+
- max_k8s_node_count
69+
public_loadbalancer:
70+
description: Indicates whether or not to use a public load balancer when deploying dependencies stack.
71+
type: bool
72+
required: False
73+
aliases:
74+
- use_public_load_balancer
75+
ip_ranges:
76+
description: The IP ranges authorized to connect to the Kubernetes API server
77+
type: list
78+
required: False
79+
aliases:
80+
- authorized_ip_ranges
81+
persist:
82+
description: Whether or not to retain the database records of related entities during removal.
83+
type: bool
84+
required: False
85+
default: False
86+
wait:
87+
description:
88+
- Flag to enable internal polling to wait for the Dataflow Service to achieve the declared state.
89+
- If set to FALSE, the module will return immediately.
90+
type: bool
91+
required: False
92+
default: True
93+
delay:
94+
description:
95+
- The internal polling interval (in seconds) while the module waits for the Dataflow Service to achieve the
96+
declared state.
97+
type: int
98+
required: False
99+
default: 15
100+
aliases:
101+
- polling_delay
102+
timeout:
103+
description:
104+
- The internal polling timeout (in seconds) while the module waits for the Dataflow Service to achieve the
105+
declared state.
106+
type: int
107+
required: False
108+
default: 3600
109+
aliases:
110+
- polling_timeout
111+
notes:
112+
- This feature this module is for is in Technical Preview
113+
extends_documentation_fragment:
114+
- cloudera.cloud.cdp_sdk_options
115+
- cloudera.cloud.cdp_auth_options
116+
'''
117+
118+
EXAMPLES = r'''
119+
# Note: These examples do not set authentication details.
120+
121+
# Create a Dataflow Service
122+
- cloudera.cloud.de:
123+
name: my-service
124+
nodes_min: 3
125+
nodes_max: 10
126+
public_loadbalancer: True
127+
ip_ranges: ['192.168.0.1/24']
128+
state: present
129+
wait: yes
130+
131+
# Remove a Dataflow Service with Async wait
132+
- cloudera.cloud.de:
133+
name: my-service
134+
persist: False
135+
state: absent
136+
wait: yes
137+
async: 3600
138+
poll: 0
139+
register: __my_teardown_request
140+
141+
'''
142+
143+
RETURN = r'''
144+
---
145+
environments:
146+
description: The information about the named DataFlow Service or DataFlow Services
147+
type: list
148+
returned: always
149+
elements: complex
150+
contains:
151+
crn:
152+
description: The DataFlow Service's parent environment CRN.
153+
returned: always
154+
type: str
155+
name:
156+
description: The DataFlow Service's parent environment name.
157+
returned: always
158+
type: str
159+
cloudPlatform:
160+
description: The cloud platform of the environment.
161+
returned: always
162+
type: str
163+
region:
164+
description: The region of the environment.
165+
returned: always
166+
type: str
167+
deploymentCount:
168+
description: The deployment count.
169+
returned: always
170+
type: str
171+
minK8sNodeCount:
172+
description: The minimum number of Kubernetes nodes that need to be provisioned in the environment.
173+
returned: always
174+
type: int
175+
maxK8sNodeCount:
176+
description: The maximum number of kubernetes nodes that environment may scale up under high-demand situations.
177+
returned: always
178+
type: str
179+
status:
180+
description: The status of a DataFlow enabled environment.
181+
returned: always
182+
type: dict
183+
contains:
184+
state:
185+
description: The state of the environment.
186+
returned: always
187+
type: str
188+
message:
189+
description: A status message for the environment.
190+
returned: always
191+
type: str
192+
k8sNodeCount:
193+
description: The number of kubernetes nodes currently in use by DataFlow for this environment.
194+
returned: always
195+
type: int
196+
instanceType:
197+
description: The instance type of the kubernetes nodes currently in use by DataFlow for this environment.
198+
returned: always
199+
type: str
200+
deLocalUrl:
201+
description: The URL of the environment local DataFlow application.
202+
returned: always
203+
type: str
204+
authorizedIpRanges:
205+
description: The authorized IP Ranges.
206+
returned: always
207+
type: list
208+
activeWarningAlertCount:
209+
description: Current count of active alerts classified as a warning.
210+
returned: always
211+
type: int
212+
activeErrorAlertCount:
213+
description: Current count of active alerts classified as an error.
214+
returned: always
215+
type: int
216+
clusterId:
217+
description: Cluster id of the environment.
218+
returned: if enabled
219+
type: str
220+
sdk_out:
221+
description: Returns the captured CDP SDK log.
222+
returned: when supported
223+
type: str
224+
sdk_out_lines:
225+
description: Returns a list of each line of the captured CDP SDK log.
226+
returned: when supported
227+
type: list
228+
elements: str
229+
'''
230+
231+
232+
class DFService(CdpModule):
233+
def __init__(self, module):
234+
super(DFService, self).__init__(module)
235+
236+
# Set variables
237+
self.name = self._get_param('name')
238+
self.nodes_min = self._get_param('nodes_min')
239+
self.nodes_max = self._get_param('nodes_max')
240+
self.public_loadbalancer = self._get_param('public_loadbalancer')
241+
self.ip_ranges = self._get_param('ip_ranges')
242+
self.persist = self._get_param('persist')
243+
244+
self.state = self._get_param('state')
245+
self.wait = self._get_param('wait')
246+
self.delay = self._get_param('delay')
247+
self.timeout = self._get_param('timeout')
248+
249+
# Initialize return values
250+
self.service = {}
251+
252+
# Initialize internal values
253+
self.target = None
254+
255+
# Execute logic process
256+
self.process()
257+
258+
@CdpModule._Decorators.process_debug
259+
def process(self):
260+
self.name = self.cdpy.environments.resolve_environment_crn(self.name)
261+
self.target = self.cdpy.de.describe_environment(env_crn=self.name)
262+
263+
if self.target is not None:
264+
# DF Database Entry exists
265+
if self.state in ['absent']:
266+
if self.module.check_mode:
267+
self.service = self.target
268+
else:
269+
if self.target['status']['state'] != 'NOT_ENABLED':
270+
self.service = self.cdpy.de.disable_environment(
271+
env_crn=self.name,
272+
persist=self.persist
273+
)
274+
if self.wait:
275+
self.service = self._wait_for_disabled()
276+
else:
277+
self.service = self.target
278+
elif self.state in ['present']:
279+
self.module.warn(
280+
"Dataflow Service already enabled and configuration validation and reconciliation is not supported;" +
281+
"to change a Dataflow Service, explicitly disable and recreate the Service or use the UI")
282+
if self.wait:
283+
self.service = self._wait_for_enabled()
284+
else:
285+
self.module.fail_json(
286+
msg="State %s is not valid for this module" % self.state)
287+
else:
288+
# Environment does not have DF database entry, and probably doesn't exist
289+
if self.state in ['absent']:
290+
self.module.log(
291+
"Dataflow Service %s already disabled in CDP Environment %s" % (self.name, self.env))
292+
elif self.state in ['present']:
293+
# create DF Service
294+
if not self.module.check_mode:
295+
self.service = self.cdpy.de.enable_environment(
296+
env_crn=self.name,
297+
authorized_ips=self.ip_ranges,
298+
min_nodes=self.nodes_min,
299+
max_nodes=self.nodes_max,
300+
enable_public_ip=self.public_loadbalancer
301+
)
302+
if self.wait:
303+
self.service = self._wait_for_enabled()
304+
else:
305+
self.module.fail_json(
306+
msg="State %s is not valid for this module" % self.state)
307+
308+
def _wait_for_enabled(self):
309+
return self.cdpy.sdk.wait_for_state(
310+
describe_func=self.cdpy.de.describe_environment, params=dict(env_crn=self.name),
311+
field=['status', 'state'], state=self.cdpy.sdk.STARTED_STATES,
312+
delay=self.delay, timeout=self.timeout
313+
)
314+
315+
def _wait_for_disabled(self):
316+
return self.cdpy.sdk.wait_for_state(
317+
describe_func=self.cdpy.de.describe_environment, params=dict(env_crn=self.name), state=None,
318+
delay=self.delay, timeout=self.timeout
319+
)
320+
321+
322+
def main():
323+
module = AnsibleModule(
324+
argument_spec=CdpModule.argument_spec(
325+
name=dict(required=True, type='str', aliases=['crn', 'env_crn']),
326+
nodes_min=dict(required=False, type='int', default=3, aliases=['min_k8s_node_count']),
327+
nodes_max=dict(required=False, type='int', default=3, aliases=['max_k8s_node_count']),
328+
public_loadbalancer=dict(required=False, type='bool', default=False, aliases=['use_public_load_balancer']),
329+
ip_ranges=dict(required=False, type='list', elements='str', default=list(),
330+
aliases=['authorized_ip_ranges']),
331+
persist=dict(required=False, type='bool', default=False),
332+
state=dict(required=False, type='str', choices=['present', 'absent'],
333+
default='present'),
334+
wait=dict(required=False, type='bool', default=True),
335+
delay=dict(required=False, type='int', aliases=['polling_delay'], default=15),
336+
timeout=dict(required=False, type='int', aliases=['polling_timeout'], default=3600)
337+
),
338+
supports_check_mode=True,
339+
)
340+
341+
result = DFService(module)
342+
output = dict(changed=False, service=result.service)
343+
344+
if result.debug:
345+
output.update(sdk_out=result.log_out, sdk_out_lines=result.log_lines)
346+
347+
module.exit_json(**output)
348+
349+
350+
if __name__ == '__main__':
351+
main()

0 commit comments

Comments
 (0)