From 4d5da24646aa661b3f8ac2a43408b85f9f5c0a76 Mon Sep 17 00:00:00 2001 From: Andrew Block Date: Sun, 22 May 2022 21:39:46 -0500 Subject: [PATCH] ostree support Signed-off-by: Andrew Block --- plugins/module_utils/pulp.py | 86 +++++++++++ plugins/modules/ostree_distribution.py | 142 ++++++++++++++++++ plugins/modules/ostree_remote.py | 121 +++++++++++++++ plugins/modules/ostree_repository.py | 108 +++++++++++++ .../ostree_repository_import_commits.py | 133 ++++++++++++++++ plugins/modules/ostree_sync.py | 83 ++++++++++ 6 files changed, 673 insertions(+) create mode 100644 plugins/modules/ostree_distribution.py create mode 100644 plugins/modules/ostree_remote.py create mode 100644 plugins/modules/ostree_repository.py create mode 100644 plugins/modules/ostree_repository_import_commits.py create mode 100644 plugins/modules/ostree_sync.py diff --git a/plugins/module_utils/pulp.py b/plugins/module_utils/pulp.py index 9a6ad448..630a22f9 100644 --- a/plugins/module_utils/pulp.py +++ b/plugins/module_utils/pulp.py @@ -1203,3 +1203,89 @@ def _href(self): if self.module.pulp_api.openapi_version == 2 else "container_container_repository_href" ) + + +# Ostree entities + + +class PulpOstreeRepository(PulpRepository): + _list_id = "repositories_ostree_ostree_list" + _read_id = "repositories_ostree_ostree_read" + _create_id = "repositories_ostree_ostree_create" + _update_id = "repositories_ostree_ostree_update" + _partial_update_id = "repositories_ostree_ostree_partial_update" + _delete_id = "repositories_ostree_ostree_delete" + _sync_id = "repositories_ostree_ostree_sync" + _import_commits_id = "repositories_ostree_ostree_import_commits" + + _name_singular = "repository" + _name_plural = "repositories" + + @property + def _href(self): + return ( + "ostree_repository_href" + if self.module.pulp_api.openapi_version == 2 + else "ostree_ostree_repository_href" + ) + + def import_commits(self, parameters=None): + + repository_version = self.entity["latest_version_href"] + + # In check_mode, assume nothing changed + if not self.module.check_mode: + + response = self.module.pulp_api.call( + self._import_commits_id, parameters=self.primary_key, body=parameters + ) + + PulpTask(self.module, {"pulp_href": response["task"]}).wait_for() + + self.find() + + if repository_version != self.entity["latest_version_href"]: + repository_version = self.entity["latest_version_href"] + self.module.set_changed() + + self.module.set_result("repository_version", repository_version) + + +class PulpOstreeDistribution(PulpEntity): + _list_id = "distributions_ostree_ostree_list" + _read_id = "distributions_ostree_ostree_read" + _create_id = "distributions_ostree_ostree_create" + _update_id = "distributions_ostree_ostree_update" + _partial_update_id = "distributions_ostree_ostree_partial_update" + _delete_id = "distributions_ostree_ostree_delete" + + _name_singular = "distribution" + _name_plural = "distributions" + + @property + def _href(self): + return ( + "ostree_distribution_href" + if self.module.pulp_api.openapi_version == 2 + else "ostree_ostree_distribution_href" + ) + + +class PulpOstreeRemote(PulpRemote): + _list_id = "remotes_ostree_ostree_list" + _read_id = "remotes_ostree_ostree_read" + _create_id = "remotes_ostree_ostree_create" + _update_id = "remotes_ostree_ostree_update" + _partial_update_id = "remotes_ostree_ostree_partial_update" + _delete_id = "remotes_ostree_ostree_delete" + + _name_singular = "remote" + _name_plural = "remotes" + + @property + def _href(self): + return ( + "ostree_remote_href" + if self.module.pulp_api.openapi_version == 2 + else "ostree_ostree_remote_href" + ) diff --git a/plugins/modules/ostree_distribution.py b/plugins/modules/ostree_distribution.py new file mode 100644 index 00000000..7fcb6502 --- /dev/null +++ b/plugins/modules/ostree_distribution.py @@ -0,0 +1,142 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# copyright (c) 2019, Matthias Dellweg +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = r""" +--- +module: ostree_distribution +short_description: Manage ostree distributions of a pulp api server instance +description: + - "This performs CRUD operations on ostree distributions in a pulp api server instance." +options: + name: + description: + - Name of the distribution to query or manipulate + type: str + required: true + base_path: + description: + - Base path to the distribution + type: str + required: true + repository: + description: + - Name of the repository + type: str + required: false + version: + description: + - Repository version number + type: str + required: false + content_guard: + description: + - Name of the content guard for the served content + - "Warning: This feature is not yet supported." + type: str + required: false +extends_documentation_fragment: + - pulp.squeezer.pulp + - pulp.squeezer.pulp.entity_state +author: + - Andrew Block (@sabre1041) +""" + +EXAMPLES = r""" +- name: Read list of ostree distributions from pulp api server + pulp.squeezer.ostree_distribution: + pulp_url: https://pulp.example.org + username: admin + password: password + register: distribution_status +- name: Report pulp ostree distributions + debug: + var: distribution_status + +- name: Create a ostree distribution + pulp.squeezer.ostree_distribution: + pulp_url: https://pulp.example.org + username: admin + password: password + name: new_ostree_distribution + base_path: new/ostree/dist + repository: ostree_repository + state: present + +- name: Delete a ostree distribution + pulp.squeezer.ostree_distribution: + pulp_url: https://pulp.example.org + username: admin + password: password + name: new_ostree_distribution + state: absent +""" + +RETURN = r""" + distributions: + description: List of ostree distributions + type: list + returned: when no name is given + distribution: + description: Ostree distribution details + type: dict + returned: when name is given +""" + + +from ansible_collections.pulp.squeezer.plugins.module_utils.pulp import ( + PulpEntityAnsibleModule, + PulpOstreeDistribution, + PulpContentGuard, +) + + +def main(): + with PulpEntityAnsibleModule( + argument_spec=dict( + name=dict(required=True), + base_path=dict(required=True), + repository=dict(), + version=dict(), + content_guard=dict(), + ), + required_if=[ + ("state", "present", ["name", "base_path"]), + ("state", "absent", ["name"]), + ], + ) as module: + + content_guard_name = module.params["content_guard"] + + natural_key = { + "name": module.params["name"], + } + desired_attributes = { + key: module.params[key] + for key in ["base_path", "repository"] + if module.params[key] is not None + } + + if content_guard_name is not None: + if content_guard_name: + content_guard = PulpContentGuard(module, {"name": content_guard_name}) + content_guard.find(failsafe=False) + desired_attributes["content_guard"] = content_guard.href + else: + desired_attributes["content_guard"] = None + + if module.params["version"] is not None: + desired_attributes["version"] = module.params["version"] or None + + PulpOstreeDistribution(module, natural_key, desired_attributes).process() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/ostree_remote.py b/plugins/modules/ostree_remote.py new file mode 100644 index 00000000..6f315476 --- /dev/null +++ b/plugins/modules/ostree_remote.py @@ -0,0 +1,121 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# copyright (c) 2022, Andrew Block +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = r""" +--- +module: ostree_remote +short_description: Manage ostree remotes of a pulp api server instance +description: + - "This performs CRUD operations on ostree remotes in a pulp api server instance." +options: + policy: + description: + - Whether downloads should be performed immediately, or lazy. + type: str + choices: + - immediate + - on_demand + - streamed +extends_documentation_fragment: + - pulp.squeezer.pulp + - pulp.squeezer.pulp.entity_state + - pulp.squeezer.pulp.remote +author: + - Andrew Block (@sabre1041) +""" + +EXAMPLES = r""" +- name: Read list of ostree remotes from pulp api server + pulp.squeezer.ostree_remote: + pulp_url: https://pulp.example.org + username: admin + password: password + register: remote_status +- name: Report pulp ostree remotes + debug: + var: remote_status + +- name: Create a ostree remote + pulp.squeezer.ostree_remote: + pulp_url: https://pulp.example.org + username: admin + password: password + name: new_ostree_remote + url: http://localhost/pub//pulp_manifest + state: present + +- name: Delete a ostree remote + pulp.squeezer.ostree_remote: + pulp_url: https://pulp.example.org + username: admin + password: password + name: new_ostree_remote + state: absent +""" + +RETURN = r""" + remotes: + description: List of ostree remotes + type: list + returned: when no name is given + remote: + description: Ostree remote details + type: dict + returned: when name is given +""" + + +from ansible_collections.pulp.squeezer.plugins.module_utils.pulp import ( + PulpRemoteAnsibleModule, + PulpOstreeRemote, +) + + +def main(): + with PulpRemoteAnsibleModule( + argument_spec=dict( + policy=dict(choices=["immediate", "on_demand", "streamed"]), + ), + required_if=[("state", "present", ["name"]), ("state", "absent", ["name"])], + ) as module: + + natural_key = {"name": module.params["name"]} + desired_attributes = { + key: module.params[key] + for key in ["url", "download_concurrency", "policy", "tls_validation"] + if module.params[key] is not None + } + + # Nullifiable values + if module.params["remote_username"] is not None: + desired_attributes["username"] = module.params["remote_username"] or None + if module.params["remote_password"] is not None: + desired_attributes["password"] = module.params["remote_password"] or None + desired_attributes.update( + { + key: module.params[key] or None + for key in [ + "proxy_url", + "proxy_username", + "proxy_password", + "ca_cert", + "client_cert", + "client_key", + ] + if module.params[key] is not None + } + ) + + PulpOstreeRemote(module, natural_key, desired_attributes).process() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/ostree_repository.py b/plugins/modules/ostree_repository.py new file mode 100644 index 00000000..1c82e28d --- /dev/null +++ b/plugins/modules/ostree_repository.py @@ -0,0 +1,108 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# copyright (c) 2022, Andrew Block +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = r""" +--- +module: ostree_repository +short_description: Manage ostree repositories of a pulp api server instance +description: + - "This performs CRUD operations on ostree repositories in a pulp api server instance." +options: + name: + description: + - Name of the repository to query or manipulate + type: str + description: + description: + - Description of the repository + type: str + remote: + description: + - Name of the remote + type: str + +extends_documentation_fragment: + - pulp.squeezer.pulp + - pulp.squeezer.pulp.entity_state +author: + - Andrew Block (@sabre1041) +""" + +EXAMPLES = r""" +- name: Read list of ostree repositories from pulp api server + pulp.squeezer.ostree_repository: + pulp_url: https://pulp.example.org + username: admin + password: password + register: repo_status +- name: Report pulp ostree repositories + debug: + var: repo_status + +- name: Create a ostree repository + pulp.squeezer.ostree_repository: + pulp_url: https://pulp.example.org + username: admin + password: password + name: new_repo + description: A brand new repository with a description + state: present + +- name: Delete a ostree repository + pulp.squeezer.ostree_repository: + pulp_url: https://pulp.example.org + username: admin + password: password + name: new_repo + state: absent +""" + +RETURN = r""" + repositories: + description: List of ostree repositories + type: list + returned: when no name is given + repository: + description: Ostree repository details + type: dict + returned: when name is given +""" + + +from ansible_collections.pulp.squeezer.plugins.module_utils.pulp import ( + PulpEntityAnsibleModule, + PulpOstreeRepository, +) + + +def main(): + with PulpEntityAnsibleModule( + argument_spec=dict( + name=dict(), + description=dict(), + remote=dict(), + ), + required_if=[("state", "present", ["name"]), ("state", "absent", ["name"])], + ) as module: + + natural_key = {"name": module.params["name"]} + desired_attributes = {} + if module.params["description"] is not None: + desired_attributes["description"] = module.params["description"] or None + + if module.params["remote"] is not None: + desired_attributes["remote"] = module.params["remote"] or None + + PulpOstreeRepository(module, natural_key, desired_attributes).process() + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/ostree_repository_import_commits.py b/plugins/modules/ostree_repository_import_commits.py new file mode 100644 index 00000000..59050ce4 --- /dev/null +++ b/plugins/modules/ostree_repository_import_commits.py @@ -0,0 +1,133 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# copyright (c) 2022, Andrew Block +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = r""" +--- +module: ostree_repository_import_commits +short_description: Imports commits to a repository on a pulp server +description: + - "This module imports commits into a repository." + - "In check_mode this module assumes, nothing changed upstream." +options: + repository: + description: + - Name of the repository to manipulate + type: str + required: true + repository_name: + description: + - Name of the repository containing the imported commits + type: str + required: true + file: + description: + - A local file that commits should be imported from + type: str + required: true + ref: + description: + - Name of the reference + type: str + required: false + parent_commit: + description: + - Name of the parent commit + type: str + required: false + +extends_documentation_fragment: + - pulp.squeezer.pulp +author: + - Andrew Block (@sabre1041) +""" + +EXAMPLES = r""" +- name: Import commits repository + pulp.squeezer.ostree_repository_import_commits: + pulp_url: https://pulp.example.org + username: admin + password: password + repository: ostree_repo_1 + repository_name: repo + file: local_repo.tar + register: import_commits_result +- name: Report synched repository version + debug: + var: import_commits_result.repository_version +""" + +RETURN = r""" + repository_version: + description: Repository version after importing the commits + type: dict + returned: always +""" + +import os +from ansible_collections.pulp.squeezer.plugins.module_utils.pulp import ( + PulpAnsibleModule, + PulpOstreeRepository, + PulpArtifact, + SqueezerException, +) + + +def main(): + with PulpAnsibleModule( + argument_spec=dict( + file=dict(required=True), + repository=dict(required=True), + repository_name=dict(required=True), + ref=dict(required=False), + parent_commit=dict(required=False), + ), + ) as module: + + if not os.path.exists(module.params["file"]): + raise SqueezerException("File not found.") + sha256 = module.sha256(module.params["file"]) + + repository = PulpOstreeRepository(module, {"name": module.params["repository"]}) + repository.find(failsafe=False) + + natural_key = { + "sha256": sha256, + } + uploads = { + "file": module.params["file"], + } + + module.params["state"] = "present" + + artifact = PulpArtifact(module, natural_key, uploads=uploads) + artifact.process() + artifact.find() + + parameters = { + "repository_name": module.params["repository_name"], + "artifact": artifact.entity["pulp_href"], + } + + ref = module.params["ref"] + + if ref is not None: + parameters.update({"ref": ref}) + + parent_commit = module.params["parent_commit"] + + if parent_commit is not None: + parameters.update({"parent_commit": parent_commit}) + + repository.import_commits(parameters) + + +if __name__ == "__main__": + main() diff --git a/plugins/modules/ostree_sync.py b/plugins/modules/ostree_sync.py new file mode 100644 index 00000000..243dcd6e --- /dev/null +++ b/plugins/modules/ostree_sync.py @@ -0,0 +1,83 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# copyright (c) 2022, Andrew Block +# GNU General Public License v3.0+ (see LICENSE or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function + +__metaclass__ = type + + +DOCUMENTATION = r""" +--- +module: ostree_sync +short_description: Synchronize a ostree remote on a pulp server +description: + - "This module synchronizes a ostree remote into a repository." + - "In check_mode this module assumes, nothing changed upstream." +options: + remote: + description: + - Name of the remote to synchronize + type: str + required: true + repository: + description: + - Name of the repository + type: str + required: true +extends_documentation_fragment: + - pulp.squeezer.pulp +author: + - Andrew Block (@sabre1041) +""" + +EXAMPLES = r""" +- name: Sync ostree remote into repository + pulp.squeezer.ostree_sync: + pulp_url: https://pulp.example.org + username: admin + password: password + repository: ostree_repo_1 + remote: ostree_remote_1 + register: sync_result +- name: Report synched repository version + debug: + var: sync_result.repository_version +""" + +RETURN = r""" + repository_version: + description: Repository version after synching + type: dict + returned: always +""" + + +from ansible_collections.pulp.squeezer.plugins.module_utils.pulp import ( + PulpAnsibleModule, + PulpOstreeRemote, + PulpOstreeRepository, +) + + +def main(): + with PulpAnsibleModule( + argument_spec=dict( + remote=dict(required=True), + repository=dict(required=True), + ), + ) as module: + + remote = PulpOstreeRemote(module, {"name": module.params["remote"]}) + remote.find(failsafe=False) + + repository = PulpOstreeRepository(module, {"name": module.params["repository"]}) + repository.find(failsafe=False) + + repository.process_sync(remote) + + +if __name__ == "__main__": + main()