Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions plugins/module_utils/cluster_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""

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

from cm_client import ApiCluster
Expand All @@ -42,5 +42,5 @@
def parse_cluster_result(cluster: ApiCluster) -> dict:
# Retrieve full_version as version
output = dict(version=cluster.full_version)
output.update(_parse_output(cluster.to_dict(), CLUSTER_OUTPUT))
output.update(normalize_output(cluster.to_dict(), CLUSTER_OUTPUT))
return output
70 changes: 22 additions & 48 deletions plugins/module_utils/cm_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,8 @@
from cm_client import (
ApiClient,
ApiCommand,
ApiConfig,
ApiConfigList,
ApiRole,
ApiRoleConfigGroup,
Configuration,
)
from cm_client.rest import ApiException, RESTClientObject
Expand All @@ -47,34 +46,8 @@
__credits__ = ["[email protected]"]
__maintainer__ = ["[email protected]"]

ROLE_OUTPUT = [
"commission_state",
"config_staleness_status",
"ha_status",
"health_checks",
"health_summary",
# "host_ref",
"maintenance_mode",
"maintenance_owners",
"name",
# "role_config_group_ref",
"role_state",
# "service_ref",
"tags",
"type",
"zoo_keeper_server_mode",
]

ROLE_CONFIG_GROUP = [
"name",
"role_type",
"base",
"display_name",
# "service_ref",
]


def _parse_output(entity: dict, filter: list) -> dict:

def normalize_output(entity: dict, filter: list) -> dict:
output = {}
for k in filter:
if k == "tags":
Expand All @@ -85,24 +58,6 @@ def _parse_output(entity: dict, filter: list) -> dict:
return output


def parse_role_result(role: ApiRole) -> dict:
# Retrieve only the host_id, role_config_group, and service identifiers
output = dict(
host_id=role.host_ref.host_id,
role_config_group_name=role.role_config_group_ref.role_config_group_name,
service_name=role.service_ref.service_name,
)
output.update(_parse_output(role.to_dict(), ROLE_OUTPUT))
return output


def parse_role_config_group_result(role_config_group: ApiRoleConfigGroup) -> dict:
# Retrieve only the service identifier
output = dict(service_name=role_config_group.service_ref.service_name)
output.update(_parse_output(role_config_group.to_dict(), ROLE_CONFIG_GROUP))
return output


def normalize_values(add: dict) -> dict:
"""Normalize parameter values. Strings have whitespace trimmed, integers are
converted to strings, and Boolean values are converted their string representation
Expand Down Expand Up @@ -191,6 +146,25 @@ def resolve_tag_updates(
return (delta_add, delta_del)


class ConfigListUpdates(object):
def __init__(self, existing: ApiConfigList, updates: dict, purge: bool) -> None:
current = {r.name: r.value for r in existing.items}
changeset = resolve_parameter_updates(current, updates, purge)

self.diff = dict(
before={k: current[k] if k in current else None for k in changeset.keys()},
after=changeset,
)

self.config = ApiConfigList(
items=[ApiConfig(name=k, value=v) for k, v in changeset.items()]
)

@property
def changed(self) -> bool:
return bool(self.config.items)


class ClusterTemplate(object):
IDEMPOTENT_IDS = frozenset(
["refName", "name", "clusterName", "hostName", "product"]
Expand Down
6 changes: 3 additions & 3 deletions plugins/module_utils/data_context_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""

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

Expand All @@ -38,9 +38,9 @@
]


def _parse_output(data: dict, keys: list) -> dict:
def normalize_output(data: dict, keys: list) -> dict:
return {key: data[key] for key in keys if key in data}


def parse_data_context_result(data_contexts: ApiDataContextList) -> list:
return [_parse_output(item, DATA_CONTEXT_OUTPUT) for item in data_contexts.items]
return [normalize_output(item, DATA_CONTEXT_OUTPUT) for item in data_contexts.items]
4 changes: 2 additions & 2 deletions plugins/module_utils/parcel_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from cm_client import ApiParcel, ParcelResourceApi

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


Expand Down Expand Up @@ -138,5 +138,5 @@ def activate(self):
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))
output.update(normalize_output(parcel.to_dict(), PARCEL))
return output
89 changes: 89 additions & 0 deletions plugins/module_utils/role_config_group_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Copyright 2024 Cloudera, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

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

from cm_client import (
ApiClient,
ApiRoleConfigGroup,
RoleConfigGroupsResourceApi,
MgmtRoleConfigGroupsResourceApi,
)

ROLE_CONFIG_GROUP = [
"name",
"role_type",
"base",
"display_name",
# "service_ref",
]


class BaseRoleConfigGroupDiscoveryException(Exception):
pass


def parse_role_config_group_result(role_config_group: ApiRoleConfigGroup) -> dict:
"""Parse a Role Config Group into a normalized dictionary.

Returns the following:
- name (str)
- role_type (str)
- base (bool)
- display_name (str)
- config (dict)

Args:
role_config_group (ApiRoleConfigGroup): Role Config Group

Returns:
dict: Normalized dictionary of returned values
"""
# Retrieve only the service identifier
output = dict(service_name=role_config_group.service_ref.service_name)
output.update(normalize_output(role_config_group.to_dict(), ROLE_CONFIG_GROUP))
output.update(config={c.name: c.value for c in role_config_group.config.items})
return output


def get_base_role_config_group(
api_client: ApiClient, cluster_name: str, service_name: str, role_type: str
) -> ApiRoleConfigGroup:
rcg_api = RoleConfigGroupsResourceApi(api_client)
rcgs = [
r
for r in rcg_api.read_role_config_groups(cluster_name, service_name).items
if r.role_type == role_type and r.base
]
if len(rcgs) != 1:
raise BaseRoleConfigGroupDiscoveryException(role_count=len(rcgs))
else:
return rcgs[0]


def get_mgmt_base_role_config_group(
api_client: ApiClient, role_type: str
) -> ApiRoleConfigGroup:
rcg_api = MgmtRoleConfigGroupsResourceApi(api_client)
rcgs = [
r
for r in rcg_api.read_role_config_groups().items
if r.role_type == role_type and r.base
]
if len(rcgs) != 1:
raise BaseRoleConfigGroupDiscoveryException(role_count=len(rcgs))
else:
return rcgs[0]
74 changes: 74 additions & 0 deletions plugins/module_utils/role_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright 2024 Cloudera, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

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

from cm_client import (
ApiClient,
ApiRoleList,
RolesResourceApi,
MgmtRolesResourceApi,
)
from cm_client import ApiRole

ROLE_OUTPUT = [
"commission_state",
"config_staleness_status",
"ha_status",
"health_checks",
"health_summary",
# "host_ref",
"maintenance_mode",
"maintenance_owners",
"name",
# "role_config_group_ref",
"role_state",
# "service_ref",
"tags",
"type",
"zoo_keeper_server_mode",
]


def parse_role_result(role: ApiRole) -> dict:
# Retrieve only the host_id, role_config_group, and service identifiers
output = dict(
host_id=role.host_ref.host_id,
role_config_group_name=role.role_config_group_ref.role_config_group_name,
service_name=role.service_ref.service_name,
)
output.update(normalize_output(role.to_dict(), ROLE_OUTPUT))
return output


def get_mgmt_roles(api_client: ApiClient, role_type: str) -> ApiRoleList:
role_api = MgmtRolesResourceApi(api_client)
return ApiRoleList(
items=[r for r in role_api.read_roles().items if r.type == role_type]
)


def get_roles(
api_client: ApiClient, cluster_name: str, service_name: str, role_type: str
) -> ApiRoleList:
role_api = RolesResourceApi(api_client)
return ApiRoleList(
items=[
r
for r in role_api.read_roles(cluster_name, service_name).items
if r.type == role_type
]
)
9 changes: 7 additions & 2 deletions plugins/module_utils/service_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"""

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

Expand Down Expand Up @@ -47,10 +47,15 @@
def parse_service_result(service: ApiService) -> dict:
# Retrieve only the cluster_name
output = dict(cluster_name=service.cluster_ref.cluster_name)
output.update(_parse_output(service.to_dict(), SERVICE_OUTPUT))
output.update(normalize_output(service.to_dict(), SERVICE_OUTPUT))
return output


def parse_cm_service_result(service: ApiService) -> dict:
# Ignore cluster_name
return normalize_output(service.to_dict(), SERVICE_OUTPUT)


class ServiceConfigUpdates(object):
def __init__(self, existing: ApiServiceConfig, updates: dict, purge: bool) -> None:
current = {r.name: r.value for r in existing.items}
Expand Down
Loading
Loading