Skip to content

Commit 6eb4d30

Browse files
committed
Added cluster_subnets_filter and loadbalancer_subnets_filter options to module.
Signed-off-by: Andre Araujo <araujo@cloudera.com>
1 parent 2880443 commit 6eb4d30

File tree

1 file changed

+69
-2
lines changed

1 file changed

+69
-2
lines changed

plugins/modules/df_service.py

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1515
# See the License for the specific language governing permissions and
1616
# limitations under the License.
17-
17+
import json
18+
import jmespath
1819
from ansible.module_utils.basic import AnsibleModule
1920
from ansible_collections.cloudera.cloud.plugins.module_utils.cdp_common import CdpModule
2021

@@ -89,13 +90,33 @@
8990
cluster_subnets:
9091
description:
9192
- Subnet ids that will be assigned to the Kubernetes cluster
93+
- Mutually exclusive with the cluster_subnets_filter option
9294
type: list
9395
required: False
96+
cluster_subnets_filter:
97+
description:
98+
- JMESPath expression to filter the subnets to be used for the Kubernetes cluster
99+
- The expression will be applied to the full list of subnets for the specified environment
100+
- Each subnet in the list is an object with the following attributes: subnetId, subnetName, availabilityZone, cidr
101+
- The filter expression must only filter the list, but not apply any attribute projection
102+
- Mutually exclusive with the cluster_subnets option
103+
type: str
104+
required: False
94105
loadbalancer_subnets:
95106
description:
96107
- Subnet ids that will be assigned to the load balancer
108+
- Mutually exclusive with the loadbalancer_subnets_filter option
97109
type: list
98110
required: False
111+
loadbalancer_subnets_filter:
112+
description:
113+
- JMESPath expression to filter the subnets to be used for the load balancer
114+
- The expression will be applied to the full list of subnets for the specified environment
115+
- Each subnet in the list is an object with the following attributes: subnetId, subnetName, availabilityZone, cidr
116+
- The filter expression must only filter the list, but not apply any attribute projection
117+
- Mutually exclusive with the cluster_subnets option
118+
type: str
119+
required: False
99120
persist:
100121
description: Whether or not to retain the database records of related entities during removal.
101122
type: bool
@@ -157,6 +178,8 @@
157178
nodes_min: 3
158179
nodes_max: 10
159180
public_loadbalancer: True
181+
cluster_subnets_filter: "[?contains(subnetName, 'pvt')]"
182+
loadbalancer_subnets_filter: "[?contains(subnetName, 'pub')]"
160183
kube_ip_ranges: ['192.168.0.1/24']
161184
state: present
162185
wait: yes
@@ -275,7 +298,9 @@ def __init__(self, module):
275298
self.lb_ip_ranges = self._get_param('loadbalancer_ip_ranges')
276299
self.kube_ip_ranges = self._get_param('kube_ip_ranges')
277300
self.cluster_subnets = self._get_param('cluster_subnets')
301+
self.cluster_subnets_filter = self._get_param('cluster_subnets_filter')
278302
self.lb_subnets = self._get_param('loadbalancer_subnets')
303+
self.lb_subnets_filter = self._get_param('loadbalancer_subnets_filter')
279304
self.persist = self._get_param('persist')
280305
self.terminate = self._get_param('terminate')
281306
self.force = self._get_param('force')
@@ -330,6 +355,21 @@ def process(self):
330355
self.module.fail_json(msg="Could not retrieve CRN for CDP Environment %s" % original_env_crn)
331356
else:
332357
# create DF Service
358+
if self.cluster_subnets_filter or self.lb_subnets_filter:
359+
try:
360+
env_info = self.cdpy.environments.describe_environment(self.env_crn)
361+
subnet_metadata = list(env_info['network']['subnetMetadata'].values())
362+
except Exception:
363+
subnet_metadata = []
364+
if not subnet_metadata:
365+
self.module.fail_json(
366+
msg="Could not retrieve subnet metadata for CDP Environment %s" % self.env_crn)
367+
368+
if self.cluster_subnets_filter:
369+
self.cluster_subnets = self._filter_subnets(self.cluster_subnets_filter, subnet_metadata)
370+
if self.lb_subnets_filter:
371+
self.lb_subnets = self._filter_subnets(self.lb_subnets_filter, subnet_metadata)
372+
333373
if not self.module.check_mode:
334374
self.service = self.cdpy.df.enable_service(
335375
env_crn=self.env_crn,
@@ -356,6 +396,27 @@ def _wait_for_enabled(self):
356396
delay=self.delay, timeout=self.timeout
357397
)
358398

399+
def _filter_subnets(self, query, subnets):
400+
"""Apply a JMESPath to an array of subnets and return the id of the selected subnets.
401+
The query must only filter the array, without applying any projection. The query result must also be an
402+
array of subnet objects.
403+
404+
:param query: JMESpath query to filter the subnet array.
405+
:param subnets: An array of subnet objects. Each subnet in the array is an object with the following attributes:
406+
subnetId, subnetName, availabilityZone, cidr.
407+
:return: An array of subnet ids.
408+
"""
409+
filtered_subnets = []
410+
try:
411+
filtered_subnets = jmespath.search(query, subnets)
412+
except Exception:
413+
self.module.fail_json(msg="The specified subnet filter is an invalid JMESPath expression: " % query)
414+
try:
415+
return [s['subnetId'] for s in filtered_subnets]
416+
except Exception:
417+
self.module.fail_json(msg='The subnet filter "%s" should return an array of subnet objects '
418+
'but instead returned this: %s' % (query, json.dumps(filtered_subnets)))
419+
359420
def _disable_df(self):
360421
# Attempt clean Disable, which also ensures we have tried at least once before we do a forced removal
361422
if self.target['status']['state'] in self.cdpy.sdk.REMOVABLE_STATES:
@@ -412,7 +473,9 @@ def main():
412473
loadbalancer_ip_ranges=dict(type='list', elements='str', default=None),
413474
kube_ip_ranges=dict(type='list', elements='str', default=None),
414475
cluster_subnets=dict(type='list', elements='str', default=None),
476+
cluster_subnets_filter=dict(type='str', default=None),
415477
loadbalancer_subnets=dict(type='list', elements='str', default=None),
478+
loadbalancer_subnets_filter=dict(type='str', default=None),
416479
persist=dict(type='bool', default=False),
417480
terminate=dict(type='bool', default=False),
418481
tags=dict(required=False, type='dict', default=None),
@@ -426,7 +489,11 @@ def main():
426489
required_if=[
427490
('state', 'present', ('env_crn', ), False),
428491
('state', 'absent', ('df_crn', ), False)
429-
]
492+
],
493+
mutually_exclusive=[
494+
('cluster_subnets', 'cluster_subnets_filter'),
495+
('loadbalancer_subnets', 'loadbalancer_subnets_filter'),
496+
],
430497
)
431498

432499
result = DFService(module)

0 commit comments

Comments
 (0)