Skip to content

Commit dea792b

Browse files
authored
Move DFX Beta implementation to GA process (#31)
* Renamed df.py to df_service.py to reflect that other DataFlow modules for Deployments will be needed in future * Include changes to submission parameters and method names for 'cdp df' calls in cdpy * Modify enable and disable service logic to match new methods and parameters * df_info now supports name, df_crn, or env_crn for filtering results * env_info once again checks for DataFlow during detailed Environment information collection * Added input validation for DataFlow service creation Signed-off-by: Daniel Chaffelson <[email protected]>
1 parent 9b4bde2 commit dea792b

File tree

6 files changed

+101
-54
lines changed

6 files changed

+101
-54
lines changed

docs/_sources/df.rst.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ Examples
181181
# Note: These examples do not set authentication details.
182182

183183
# Create a Dataflow Service
184-
- cloudera.cloud.df:
184+
- cloudera.cloud.df_service:
185185
name: my-service
186186
nodes_min: 3
187187
nodes_max: 10
@@ -191,7 +191,7 @@ Examples
191191
wait: yes
192192

193193
# Remove a Dataflow Service with Async wait
194-
- cloudera.cloud.df:
194+
- cloudera.cloud.df_service:
195195
name: my-service
196196
persist: False
197197
state: absent

docsrc/df.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ Examples
181181
# Note: These examples do not set authentication details.
182182

183183
# Create a Dataflow Service
184-
- cloudera.cloud.df:
184+
- cloudera.cloud.df_service:
185185
name: my-service
186186
nodes_min: 3
187187
nodes_max: 10
@@ -191,7 +191,7 @@ Examples
191191
wait: yes
192192

193193
# Remove a Dataflow Service with Async wait
194-
- cloudera.cloud.df:
194+
- cloudera.cloud.df_service:
195195
name: my-service
196196
persist: False
197197
state: absent

plugins/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ modules employ the underlying SDK contained within the `cdpy` Python package.
1616
| [datalake](./modules/datalake.py) | Create, manage, and destroy CDP Datalakes |
1717
| [datalake_info](./modules/datalake_info.py) | Gather information about CDP Datalakes |
1818
| [datalake_runtime_info](./modules/datalake_runtime_info.py) | Gather information about CDP Datalake Runtimes |
19-
| [df](./modules/df.py) | Enable or disable CDP DataFlow services |
19+
| [df](./modules/df_service.py) | Enable or disable CDP DataFlow services |
2020
| [df_info](./modules/df_info.py) | Gather information about CDP DataFlow services |
2121
| [dw_cluster](./modules/dw_cluster.py) | Create, manage, and destroy CDP Data Warehouse experiences |
2222
| [dw_cluster_info](./modules/dw_cluster_info.py) | Gather information about CDP Data Warehouse experiences |

plugins/modules/df_info.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,24 @@
3636
options:
3737
name:
3838
description:
39-
- If a name is provided, that DataFlow Service will be described.
40-
- Must be CDP Environment CRN or string name of DataFlow Service
39+
- If a name is provided, that DataFlow Service will be described
40+
- Must be the string name of the CDP Environment
41+
- Mutually exclusive with df_crn and env_crn
4142
type: str
4243
required: False
43-
aliases:
44-
- crn
44+
df_crn:
45+
description:
46+
- If a df_crn is provided, that DataFlow Service will be described
47+
- Mutually exclusive with name and env_crn
48+
type: str
49+
required: False
50+
env_crn:
51+
description:
52+
- If an env_crn is provided, the DataFlow Service for that Environment will be described
53+
- Mutually exclusive with name and df_crn
54+
type: str
55+
required: False
56+
4557
notes:
4658
- This feature this module is for is in Technical Preview
4759
extends_documentation_fragment:
@@ -59,9 +71,13 @@
5971
- cloudera.cloud.df_info:
6072
name: example-service
6173
62-
# Gather detailed information about a named DataFlow Service using a CRN
74+
# Gather detailed information about a named DataFlow Service using a Dataflow CRN
6375
- cloudera.cloud.df_info:
64-
crn: example-service-crn
76+
df_crn: crn:cdp:df:region:tenant-uuid4:service:service-uuid4
77+
78+
# Gather detailed information about a named DataFlow Service using an Environment CRN
79+
- cloudera.cloud.df_info:
80+
df_crn: crn:cdp:environments:region:tenant-uuid4:environment:environment-uuid4
6581
'''
6682

6783
RETURN = r'''
@@ -159,32 +175,38 @@ def __init__(self, module):
159175

160176
# Set variables
161177
self.name = self._get_param('name')
178+
self.df_crn = self._get_param('df_crn')
179+
self.env_crn = self._get_param('env_crn')
162180

163181
# Initialize return values
164182
self.services = []
165183

184+
# Initialize internal values
185+
self.all_services = []
186+
166187
# Execute logic process
167188
self.process()
168189

169190
@CdpModule._Decorators.process_debug
170191
def process(self):
171-
if self.name: # Note that both None and '' will trigger this
172-
if self.name.startswith('crn:'):
173-
service_single = self.cdpy.df.describe_environment(env_crn=self.name)
174-
if service_single is not None:
175-
self.services.append(service_single)
176-
else:
177-
self.services = self.cdpy.df.list_environments(name=self.name)
192+
# Note that parameters are defaulted to None, and are skipped if None at submission
193+
self.all_services = self.cdpy.df.list_services(df_crn=self.df_crn, name=self.name, env_crn=self.env_crn)
194+
if any(x is not None for x in [self.name, self.df_crn, self.env_crn]):
195+
# Any set parameter indicates a describe is preferred to the lower information list command
196+
self.services = [self.cdpy.df.describe_service(df_crn=x['crn']) for x in self.all_services]
178197
else:
179-
self.services = self.cdpy.df.list_environments()
198+
self.services = self.all_services
180199

181200

182201
def main():
183202
module = AnsibleModule(
184203
argument_spec=CdpModule.argument_spec(
185-
name=dict(required=False, type='str', aliases=['crn']),
204+
name=dict(required=False, type='str'),
205+
df_crn=dict(required=False, type='str'),
206+
env_crn=dict(required=False, type='str'),
186207
),
187208
supports_check_mode=True,
209+
mutually_exclusive=['name', 'df_crn', 'env_crn']
188210
)
189211

190212
result = DFInfo(module)

plugins/modules/df.py renamed to plugins/modules/df_service.py

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@
8383
type: bool
8484
required: False
8585
default: False
86+
terminate:
87+
description: Whether or not to terminate all deployments associated with this DataFlow service
88+
type: bool
89+
required: False
90+
default: False
8691
wait:
8792
description:
8893
- Flag to enable internal polling to wait for the Dataflow Service to achieve the declared state.
@@ -119,7 +124,7 @@
119124
# Note: These examples do not set authentication details.
120125
121126
# Create a Dataflow Service
122-
- cloudera.cloud.df:
127+
- cloudera.cloud.df_service:
123128
name: my-service
124129
nodes_min: 3
125130
nodes_max: 10
@@ -129,7 +134,7 @@
129134
wait: yes
130135
131136
# Remove a Dataflow Service with Async wait
132-
- cloudera.cloud.df:
137+
- cloudera.cloud.df_service:
133138
name: my-service
134139
persist: False
135140
state: absent
@@ -234,12 +239,17 @@ def __init__(self, module):
234239
super(DFService, self).__init__(module)
235240

236241
# Set variables
237-
self.name = self._get_param('name')
242+
self.env_crn = self._get_param('env_crn')
243+
self.df_crn = self._get_param('df_crn')
238244
self.nodes_min = self._get_param('nodes_min')
239245
self.nodes_max = self._get_param('nodes_max')
240246
self.public_loadbalancer = self._get_param('public_loadbalancer')
241-
self.ip_ranges = self._get_param('ip_ranges')
247+
self.lb_ip_ranges = self._get_param('loadbalancer_ip_ranges')
248+
self.kube_ip_ranges = self._get_param('kube_ip_ranges')
249+
self.cluster_subnets = self._get_param('cluster_subnets')
250+
self.lb_subnets = self._get_param('lb_subnets')
242251
self.persist = self._get_param('persist')
252+
self.terminate = self._get_param('terminate')
243253
self.force = self._get_param('force')
244254

245255
self.state = self._get_param('state')
@@ -252,16 +262,16 @@ def __init__(self, module):
252262

253263
# Initialize internal values
254264
self.target = None
255-
self.env_crn = None
256265

257266
# Execute logic process
258267
self.process()
259268

260269
@CdpModule._Decorators.process_debug
261270
def process(self):
262-
self.env_crn = self.cdpy.environments.resolve_environment_crn(self.name)
263271
if self.env_crn is not None:
264-
self.target = self.cdpy.df.describe_environment(env_crn=self.name)
272+
self.env_crn = self.cdpy.environments.resolve_environment_crn(self.env_crn)
273+
if self.env_crn is not None or self.df_crn is not None:
274+
self.target = self.cdpy.df.describe_service(env_crn=self.env_crn, df_crn=self.df_crn)
265275

266276
if self.target is not None:
267277
# DF Database Entry exists
@@ -283,19 +293,22 @@ def process(self):
283293
# Environment does not have DF database entry, and probably doesn't exist
284294
if self.state in ['absent']:
285295
self.module.log(
286-
"Dataflow Service %s already disabled in CDP Environment %s" % (self.name, self.env_crn))
296+
"Dataflow Service already disabled in CDP Environment %s" % self.env_crn)
287297
elif self.state in ['present']:
288298
if self.env_crn is None:
289299
self.module.fail_json(msg="Could not retrieve CRN for CDP Environment %s" % self.env)
290300
else:
291301
# create DF Service
292302
if not self.module.check_mode:
293-
self.service = self.cdpy.df.enable_environment(
303+
self.service = self.cdpy.df.enable_service(
294304
env_crn=self.env_crn,
295-
authorized_ips=self.ip_ranges,
296305
min_nodes=self.nodes_min,
297306
max_nodes=self.nodes_max,
298-
enable_public_ip=self.public_loadbalancer
307+
enable_public_ip=self.public_loadbalancer,
308+
lb_ips=self.lb_ip_ranges,
309+
kube_ips=self.kube_ip_ranges,
310+
cluster_subnets=self.cluster_subnets,
311+
lb_subnets=self.lb_subnets
299312
)
300313
if self.wait:
301314
self.service = self._wait_for_enabled()
@@ -305,65 +318,77 @@ def process(self):
305318

306319
def _wait_for_enabled(self):
307320
return self.cdpy.sdk.wait_for_state(
308-
describe_func=self.cdpy.df.describe_environment, params=dict(env_crn=self.env_crn),
321+
describe_func=self.cdpy.df.describe_service, params=dict(env_crn=self.env_crn),
309322
field=['status', 'state'], state=self.cdpy.sdk.STARTED_STATES,
310323
delay=self.delay, timeout=self.timeout
311324
)
312325

313326
def _disable_df(self):
314327
# Attempt clean Disable, which also ensures we have tried at least once before we do a forced removal
315328
if self.target['status']['state'] in self.cdpy.sdk.REMOVABLE_STATES:
316-
self.service = self.cdpy.df.disable_environment(
317-
env_crn=self.env_crn,
318-
persist=self.persist
329+
self.service = self.cdpy.df.disable_service(
330+
df_crn=self.df_crn,
331+
persist=self.persist,
332+
terminate=self.terminate
319333
)
334+
else:
335+
self.module.warn("Attempting to disable DataFlow Service but state %s not in Removable States %s"
336+
% (self.target['status']['state'], self.cdpy.sdk.REMOVABLE_STATES))
320337
if self.wait:
321338
# Wait for Clean Disable, if possible
322339
self.service = self.cdpy.sdk.wait_for_state(
323-
describe_func=self.cdpy.df.describe_environment, params=dict(env_crn=self.env_crn),
340+
describe_func=self.cdpy.df.describe_service, params=dict(df_crn=self.df_crn),
324341
field=['status', 'state'],
325342
state=self.cdpy.sdk.STOPPED_STATES + self.cdpy.sdk.REMOVABLE_STATES + [None],
326343
delay=self.delay, timeout=self.timeout, ignore_failures=True
327344
)
328345
else:
329-
self.service = self.cdpy.df.describe_environment(env_crn=self.name)
346+
self.service = self.cdpy.df.describe_service(df_crn=self.df_crn)
330347
# Check disable result against need for further forced delete action, in case it didn't work first time around
331348
if self.service is not None:
332349
if self.service['status']['state'] in self.cdpy.sdk.REMOVABLE_STATES:
333350
if self.force:
334-
self.service = self.cdpy.df.delete_environment(
335-
env_crn=self.env_crn
351+
self.service = self.cdpy.df.reset_service(
352+
df_crn=self.df_crn
336353
)
337354
else:
338355
self.module.fail_json(msg="DF Service Disable failed and Force delete not requested")
339356
if self.wait:
340357
self.service = self.cdpy.sdk.wait_for_state(
341-
describe_func=self.cdpy.df.describe_environment, params=dict(env_crn=self.env_crn),
358+
describe_func=self.cdpy.df.describe_service, params=dict(df_crn=self.df_crn),
342359
field=None, # This time we require removal or declare failure
343360
delay=self.delay, timeout=self.timeout
344361
)
345362
else:
346-
self.service = self.cdpy.df.describe_environment(env_crn=self.name)
363+
self.service = self.cdpy.df.describe_service(df_crn=self.df_crn)
347364

348365

349366
def main():
350367
module = AnsibleModule(
351368
argument_spec=CdpModule.argument_spec(
352-
name=dict(required=True, type='str', aliases=['crn', 'env_crn']),
353-
nodes_min=dict(required=False, type='int', default=3, aliases=['min_k8s_node_count']),
354-
nodes_max=dict(required=False, type='int', default=3, aliases=['max_k8s_node_count']),
355-
public_loadbalancer=dict(required=False, type='bool', default=False, aliases=['use_public_load_balancer']),
356-
ip_ranges=dict(required=False, type='list', elements='str', default=list(),
357-
aliases=['authorized_ip_ranges']),
358-
persist=dict(required=False, type='bool', default=False),
359-
state=dict(required=False, type='str', choices=['present', 'absent'],
369+
env_crn=dict(type='str'),
370+
df_crn=dict(type='str'),
371+
nodes_min=dict(type='int', default=3, aliases=['min_k8s_node_count']),
372+
nodes_max=dict(type='int', default=3, aliases=['max_k8s_node_count']),
373+
public_loadbalancer=dict(type='bool', default=False, aliases=['use_public_load_balancer']),
374+
loadbalancer_ip_ranges=dict(type='list', elements='str', default=None),
375+
kube_ip_ranges=dict(type='list', elements='str', default=None),
376+
cluster_subnets=dict(type='list', elements='str', default=None),
377+
loadbalancer_subnets=dict(type='list', elements='str', default=None),
378+
persist=dict(type='bool', default=False),
379+
terminate=dict(type='bool', default=False),
380+
state=dict(type='str', choices=['present', 'absent'],
360381
default='present'),
361-
force=dict(required=False, type='bool', default=False, aliases=['force_delete']),
362-
wait=dict(required=False, type='bool', default=True),
363-
delay=dict(required=False, type='int', aliases=['polling_delay'], default=15),
364-
timeout=dict(required=False, type='int', aliases=['polling_timeout'], default=3600)
382+
force=dict(type='bool', default=False, aliases=['force_delete']),
383+
wait=dict(type='bool', default=True),
384+
delay=dict(type='int', aliases=['polling_delay'], default=15),
385+
timeout=dict(type='int', aliases=['polling_timeout'], default=3600)
365386
),
366387
supports_check_mode=True,
388+
required_if=[
389+
('state', 'present', ('env_crn', ), False),
390+
('state', 'absent', ('df_crn', ), False)
391+
]
367392
)
368393

369394
result = DFService(module)

plugins/modules/env_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ def process(self):
436436
for this_env in self.environments:
437437
df = None
438438
# Removing until DF is GA so we are not dependent on Beta functionality
439-
# df = self.cdpy.df.describe_environment(this_env['crn'])
439+
df = self.cdpy.df.list_services(env_crn=this_env['crn'])
440440
this_env['descendants'] = {
441441
'datahub': self.cdpy.datahub.describe_all_clusters(this_env['environmentName']),
442442
'dw': self.cdpy.dw.gather_clusters(this_env['crn']),

0 commit comments

Comments
 (0)