Skip to content

Commit

Permalink
Update parcel_info API output and move parsing function to parcel_utils
Browse files Browse the repository at this point in the history
Signed-off-by: Webster Mudge <[email protected]>
  • Loading branch information
wmudge committed May 16, 2024
1 parent 475a2c4 commit f7bc29c
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 107 deletions.
18 changes: 0 additions & 18 deletions plugins/module_utils/cm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@
ApiClient,
ApiCommand,
ApiConfigList,
ApiParcel,
ApiRole,
ApiRoleConfigGroup,
ApiService,
Expand Down Expand Up @@ -92,16 +91,6 @@
# "service_ref",
]

PARCEL = [
"product",
"version",
"stage",
# "cluster_ref",
"state",
"display_name",
"description",
]


def _parse_output(entity: dict, filter: list) -> dict:
output = {}
Expand Down Expand Up @@ -139,13 +128,6 @@ def parse_role_config_group_result(role_config_group: ApiRoleConfigGroup) -> dic
return output


def parse_parcel_result(parcel: ApiParcel) -> dict:
# Retrieve only the cluster identifier
output = dict(cluster_name=parcel.cluster_ref.cluster_name)
output.update(_parse_output(parcel.to_dict(), PARCEL))
return output


def normalize_values(add: dict) -> dict:
"""Normalize whitespace of parameter values.
Expand Down
24 changes: 23 additions & 1 deletion plugins/module_utils/parcel_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@

from enum import IntEnum

from cm_client import ParcelResourceApi
from cm_client import ApiParcel, ParcelResourceApi

from ansible_collections.cloudera.cluster.plugins.module_utils.cm_utils import (
_parse_output,
)


class Parcel(object):
Expand Down Expand Up @@ -118,3 +122,21 @@ def activate(self):
elif self.current < self.STAGE.ACTIVATED:
self.distribute(self.STAGE.ACTIVATED)
self._exec(self.STAGE.ACTIVATED, self.parcel_api.activate_command)


PARCEL = [
"product",
"version",
"stage",
# "cluster_ref",
"state",
"display_name",
"description",
]


def parse_parcel_result(parcel: ApiParcel) -> dict:
# Retrieve only the cluster identifier
output = dict(cluster_name=parcel.cluster_ref.cluster_name)
output.update(_parse_output(parcel.to_dict(), PARCEL))
return output
27 changes: 14 additions & 13 deletions plugins/modules/parcel.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

from ansible_collections.cloudera.cluster.plugins.module_utils.cm_utils import (
ClouderaManagerModule,
parse_parcel_result,
)

from ansible_collections.cloudera.cluster.plugins.module_utils.parcel_utils import (
Parcel,
parse_parcel_result,
)

from cm_client import ClustersResourceApi, ParcelResourceApi
Expand All @@ -31,7 +31,6 @@
}

DOCUMENTATION = r"""
---
module: parcel
short_description: Manage the state of parcels on a cluster
description:
Expand All @@ -41,27 +40,32 @@
author:
- "Ronald Suplina (@rsuplina)"
requirements:
- cm_client
- cm-client
options:
cluster_name:
cluster:
description:
- The name of the cluster
type: str
required: yes
product:
aliases:
- cluster_name
name:
description:
- The name of the product, e.g. CDH, Impala
type: str
required: yes
version:
aliases:
- parcel
- product
parcel_version:
description:
- The semantic version of the product, e.g. 1.1.0, 2.3.0.
type: str
required: yes
state:
description:
- State of the parcel.
- I(present) is the same as I(activated).
- I(present) is mapped to I(activated).
type: str
default: 'present'
choices:
Expand All @@ -74,7 +78,6 @@
"""

EXAMPLES = r"""
---
- name: Download, distribute and activate a parcel on a cluster
cloudera.cluster.parcel:
host: example.cloudera.com
Expand Down Expand Up @@ -114,11 +117,9 @@
product: "ECS"
parcel_version: "1.5.1-b626-ecs-1.5.1-b626.p0.42068229"
state: "downloaded" # Assuming the current state is "distributed" or "activated"
"""

RETURN = r"""
---
parcel:
description: Details about the parcel
type: dict
Expand Down Expand Up @@ -170,7 +171,7 @@ def __init__(self, module):

# Set parameters
self.cluster = self.get_param("cluster")
self.parcel_name = self.get_param("parcel")
self.parcel_name = self.get_param("name")
self.parcel_version = self.get_param("parcel_version")
self.state = self.get_param("state")
self.delay = self.get_param("delay")
Expand All @@ -193,7 +194,7 @@ def process(self):
cluster_api.read_cluster(cluster_name=self.cluster).to_dict()
except ApiException as ex:
if ex.status == 404:
self.module.fail_json(msg=f" Cluster {self.cluster} {ex.reason}")
self.module.fail_json(msg=f" Cluster '{self.cluster}' not found")

try:
parcel = Parcel(
Expand Down Expand Up @@ -241,7 +242,7 @@ def main():
module = ClouderaManagerModule.ansible_module(
argument_spec=dict(
cluster=dict(required=True, aliases=["cluster_name"]),
parcel=dict(required=True, aliases=["parcel_name", "product", "name"]),
name=dict(required=True, aliases=["parcel", "product"]),
parcel_version=dict(required=True),
delay=dict(
required=False, type="int", default=10, aliases=["polling_interval"]
Expand Down
106 changes: 61 additions & 45 deletions plugins/modules/parcel_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@
ClouderaManagerModule,
)

from ansible_collections.cloudera.cluster.plugins.module_utils.parcel_utils import (
parse_parcel_result,
)

from cm_client import ClustersResourceApi, ParcelResourceApi, ParcelsResourceApi
from cm_client.rest import ApiException

Expand All @@ -26,35 +30,40 @@
}

DOCUMENTATION = r"""
---
module: parcel_info
short_description: Gather details about the parcels on the cluster
description:
- Gathers details about a single parcel or about all parcels on the cluster
author:
- "Ronald Suplina (@rsuplina)"
requirements:
- cm_client
- cm-client
options:
cluster_name:
cluster:
description:
- The name of the cluster
type: str
required: yes
product:
aliases:
- cluster_name
name:
description:
- The name of the product, e.g. CDH, Impala
- The name of the product, e.g. CDH, Impala.
- Required if I(parcel_version) is declared.
type: str
required: no
aliases:
- product
- parcel
parcel_version:
description:
- The version of the product, e.g. 1.1.0, 2.3.0.
- Required if I(name) is declared.
type: str
required: no
"""

EXAMPLES = r"""
---
- name: Gather details about specific parcel
cloudera.cluster.parcel_info:
host: example.cloudera.com
Expand All @@ -73,9 +82,8 @@
"""

RETURN = r"""
---
cloudera_manager:
description: Returns details about specific parcel or all parcels on the cluster
parcels:
description: Returns details about a specific parcel or all parcels on the cluster
type: list
elements: dict
contains:
Expand All @@ -84,88 +92,96 @@
type: str
returned: always
version:
description: The version of the product
description: The version of the product.
type: str
returned: always
stage:
description: Current stage of the parcel.
type: str
returned: always
state:
description: The state of the parcel. This shows the progress of state transitions and if there were any errors.
description:
- The state of the parcel.
- This shows the progress of state transitions and if there were any errors.
type: dict
returned: always
clusterRef:
description: A reference to the enclosing cluster.
returned: optional
cluster_name:
description: The name of the enclosing cluster.
type: dict
returned: always
displayName:
display_name:
description: Display name of the parcel.
type: str
returned: always
returned: optional
description:
description: Description of the parcel.
type: str
returned: always
returned: optional
"""


class ClouderaParcelInfo(ClouderaManagerModule):
def __init__(self, module):
super(ClouderaParcelInfo, self).__init__(module)
self.cluster_name = self.get_param("cluster_name")
self.product = self.get_param("product")

self.cluster = self.get_param("cluster")
self.parcel = self.get_param("name")
self.parcel_version = self.get_param("parcel_version")

self.output = {}
self.changed = False

self.process()

@ClouderaManagerModule.handle_process
def process(self):
parcel_api_instance = ParcelResourceApi(self.api_client)
parcels_api_instance = ParcelsResourceApi(self.api_client)
cluster_api_instance = ClustersResourceApi(self.api_client)

self.parcel_output = {}
self.changed = False
parcel_api = ParcelResourceApi(self.api_client)
parcels_api = ParcelsResourceApi(self.api_client)
cluster_api = ClustersResourceApi(self.api_client)

try:
cluster_api_instance.read_cluster(cluster_name=self.cluster_name).to_dict()
cluster_api.read_cluster(cluster_name=self.cluster)
except ApiException as ex:
if ex.status == 404:
self.module.fail_json(msg=f" Cluster {self.cluster_name} {ex.reason}")

if self.product and self.parcel_version:
self.parcel_info = parcel_api_instance.read_parcel(
cluster_name=self.cluster_name,
product=self.product,
version=self.parcel_version,
).to_dict()
self.parcel_output = {"items": [self.parcel_info]}
self.module.fail_json(msg=f"Cluster '{self.cluster}' not found")

if self.parcel and self.parcel_version:
try:
parcel_info = parcel_api.read_parcel(
cluster_name=self.cluster,
product=self.parcel,
version=self.parcel_version,
)
self.output = [parse_parcel_result(parcel_info)]
except ApiException as ex:
if ex.status == 404:
pass
else:
self.parcel_output = parcels_api_instance.read_parcels(
cluster_name=self.cluster_name
).to_dict()
self.output = [
parse_parcel_result(p)
for p in parcels_api.read_parcels(cluster_name=self.cluster).items
]


def main():
module = ClouderaManagerModule.ansible_module(
argument_spec=dict(
cluster_name=dict(required=True, type="str"),
product=dict(required=False, type="str"),
parcel_version=dict(required=False, type="str"),
cluster=dict(required=True, aliases=["cluster_name"]),
name=dict(aliases=["product", "parcel"]),
parcel_version=dict(),
),
supports_check_mode=True,
required_together=[
("product", "parcel_version"),
("name", "parcel_version"),
],
)

result = ClouderaParcelInfo(module)

changed = result.changed

output = dict(
changed=changed,
cloudera_manager=result.parcel_output,
changed=result.changed,
parcels=result.output,
)

if result.debug:
Expand Down
Loading

0 comments on commit f7bc29c

Please sign in to comment.