Skip to content

Commit

Permalink
WIP use pulp_glue converge
Browse files Browse the repository at this point in the history
  • Loading branch information
mdellweg committed Jul 21, 2024
1 parent 3c1f0e4 commit 8339aad
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 46 deletions.
2 changes: 1 addition & 1 deletion lower_bounds_constraints.lock
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pulp-glue==0.20.0
pulp-glue==0.27.0
98 changes: 53 additions & 45 deletions plugins/module_utils/pulp_glue.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
from pulp_glue.common import __version__ as pulp_glue_version
from pulp_glue.common.context import PulpContext, PulpException, PulpNoWait

GLUE_VERSION_SPEC = ">=0.20.0,<0.27"
if not SpecifierSet(GLUE_VERSION_SPEC).contains(pulp_glue_version):
GLUE_VERSION_SPEC = ">=0.27.0dev0,<0.28"
if not SpecifierSet(GLUE_VERSION_SPEC, prereleases=True).contains(pulp_glue_version):
raise ImportError(
f"Installed 'pulp-glue' version '{pulp_glue_version}' is not in '{GLUE_VERSION_SPEC}'."
)
Expand Down Expand Up @@ -112,16 +112,23 @@ def __init__(self, **kwargs):
),
background_tasks=False,
timeout=self.params["timeout"],
fake_mode=self.check_mode, # This should be the same as api_kwargs["safe_calls_only"]
)

def __enter__(self):
self._changed = False
self._results = {}
self._diff_states = []

return self

def __exit__(self, exc_class, exc_value, tb):
if exc_class is None:
if self._diff_states:
self._results["diff"] = {
"before": self._diff_states[0],
"after": self._diff_states[-1],
}
self.exit_json(changed=self._changed, **self._results)
else:
if issubclass(exc_class, (PulpException, PulpNoWait, SqueezerException)):
Expand All @@ -141,6 +148,9 @@ def set_changed(self):
def set_result(self, key, value):
self._results[key] = value

def record_diff_state(self, value):
self._diff_states.append(value)


class PulpEntityAnsibleModule(PulpAnsibleModule):
def __init__(self, context_class, entity_singular, entity_plural, **kwargs):
Expand All @@ -152,6 +162,7 @@ def __init__(self, context_class, entity_singular, entity_plural, **kwargs):
argument_spec.update(kwargs.pop("argument_spec", {}))
super().__init__(argument_spec=argument_spec, **kwargs)
self.state = self.params["state"]

self.context = context_class(self.pulp_ctx)
self.entity_singular = entity_singular
self.entity_plural = entity_plural
Expand All @@ -163,56 +174,53 @@ def represent(self, entity):
}

def process(self, natural_key, desired_attributes):
if None not in natural_key.values():
if "pulp_href" in natural_key:
self.context.pulp_href = natural_key["pulp_href"]
else:
self.context.entity = natural_key
try:
entity = self.represent(self.context.entity)
except PulpException:
entity = None
if self.state is None:
pass
elif self.state == "absent":
if entity is not None:
if not self.check_mode:
self.context.delete()
entity = None
self.set_changed()
elif self.state == "present":
entity = self.process_present(entity, natural_key, desired_attributes)
else:
entity = self.process_special(entity, natural_key, desired_attributes)
self.set_result(self.entity_singular, entity)
if self.state is None:
return self.process_info(natural_key, desired_attributes)

if "pulp_href" in natural_key:
self.context.pulp_href = natural_key["pulp_href"]
else:
if self.state is not None:
raise SqueezerException(f"Invalid state '{self.state}' for entity listing.")
if None in natural_key.values():
raise SqueezerException("Insufficient information to identify the entity.")
self.context.entity = natural_key

if self.state == "present":
desired_entity = desired_attributes
elif self.state == "absent":
desired_entity = None
else:
self.set_result(
self.entity_singular,
self.process_special(self.context.entity, natural_key, desired_attributes),
)
return
changed, before, after = self.context.converge(desired_entity)
if before is not None:
before = self.represent(before)
if after is not None:
after = self.represent(after)
if changed:
self.set_changed()
self.record_diff_state(before)
self.record_diff_state(after)
self.set_result(self.entity_singular, after)

def process_info(self, natural_key, desired_attributes):
if any((value is not None for value in desired_attributes.values())):
raise SqueezerException("Cannot use attributes when querying entities.")
# TODO turn this into a filtering query instead
if None in natural_key.values():
entities = [
self.represent(entity)
for entity in self.context.list(limit=-1, offset=0, parameters={})
]
self.set_result(self.entity_plural, entities)

def process_present(self, entity, natural_key, desired_attributes):
if entity is None:
entity = {**desired_attributes, **natural_key}
if not self.check_mode:
self.context.create(body=entity)
entity = self.context.entity
entity = self.represent(entity)
self.set_changed()
else:
updated_attributes = {k: v for k, v in desired_attributes.items() if entity.get(k) != v}
if updated_attributes:
if not self.check_mode:
self.context.update(body=updated_attributes)
entity = self.context.entity
else:
entity.update(updated_attributes)
entity = self.represent(entity)
self.set_changed()
return entity
if "pulp_href" in natural_key:
self.context.pulp_href = natural_key["pulp_href"]
else:
self.context.entity = natural_key
self.set_result(self.entity_singular, self.represent(self.context.entity))

def process_special(self, entity, natural_key, desired_attributes):
raise SqueezerException(f"Invalid state '{self.state}'.")
Expand Down

0 comments on commit 8339aad

Please sign in to comment.