From 7043c647fbe74d23c51efc278a7b8d2598c85a4c Mon Sep 17 00:00:00 2001 From: ethinot Date: Wed, 11 Sep 2024 09:55:12 +0200 Subject: [PATCH] Init module --- .manala.yaml | 1 + .manala/Makefile | 4 +- .manala/docker/compose.yaml | 2 +- README.md | 2 +- galaxy.yml | 79 ++++++++++++++++++++++++++ meta/runtime.yml | 52 +++++++++++++++++ plugins/.gitignore | 1 + plugins/action/path.py | 109 ++++++++++++++++++++++++++++++++++++ plugins/modules/path.py | 21 +++++++ 9 files changed, 267 insertions(+), 4 deletions(-) create mode 100644 galaxy.yml create mode 100644 meta/runtime.yml create mode 100644 plugins/.gitignore create mode 100644 plugins/action/path.py create mode 100644 plugins/modules/path.py diff --git a/.manala.yaml b/.manala.yaml index b0f3880..afcb525 100644 --- a/.manala.yaml +++ b/.manala.yaml @@ -18,6 +18,7 @@ project: ########## system: + dir: /usr/share/ansible/collections/ansible_collections/manala/path git: config: | # Silence false positive dubious ownership errors diff --git a/.manala/Makefile b/.manala/Makefile index 59d666e..e22b4e5 100644 --- a/.manala/Makefile +++ b/.manala/Makefile @@ -21,8 +21,8 @@ include $(MANALA_DIR)/.manala/docker/docker.mk ########## MANALA_DOCKER_COMPOSE_ENV += \ - MANALA_DIR=$(realpath $(MANALA_DIR)) \ - MANALA_CACHE_DIR=$(realpath $(shell dir=$(MANALA_DIR)/$(MANALA_CACHE_DIR) ; mkdir -p $${dir} ; echo $${dir})) + MANALA_DIR=/usr/share/ansible/collections/ansible_collections/manala/path \ + MANALA_CACHE_DIR=/usr/share/ansible/collections/ansible_collections/manala/path/$(shell dir=$(MANALA_DIR)/$(MANALA_CACHE_DIR) ; mkdir -p $${dir} ; echo $(MANALA_CACHE_DIR)) # Command MANALA_DOCKER_COMMAND = run --rm diff --git a/.manala/docker/compose.yaml b/.manala/docker/compose.yaml index d05d39a..8e93b56 100644 --- a/.manala/docker/compose.yaml +++ b/.manala/docker/compose.yaml @@ -11,7 +11,7 @@ services: build: context: .. dockerfile: docker/Dockerfile - image: manala-ansible-path:20240910083703 + image: manala-ansible-path:20240910140830 volumes: - ../..:${MANALA_DIR} environment: diff --git a/README.md b/README.md index 6dc529a..1e02167 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# Manala Collection - Path +# Ansible Collection - manala.path diff --git a/galaxy.yml b/galaxy.yml new file mode 100644 index 0000000..8233b51 --- /dev/null +++ b/galaxy.yml @@ -0,0 +1,79 @@ +### REQUIRED +# The namespace of the collection. This can be a company/brand/organization or product namespace under which all +# content lives. May only contain alphanumeric lowercase characters and underscores. Namespaces cannot start with +# underscores or numbers and cannot contain consecutive underscores +namespace: manala + +# The name of the collection. Has the same character restrictions as 'namespace' +name: path + +# The version of the collection. Must be compatible with semantic versioning +version: 1.0.0 + +# The path to the Markdown (.md) readme file. This path is relative to the root of the collection +readme: README.md + +# A list of the collection's content authors. Can be just the name or in the format 'Full Name (url) +# @nicks:irc/im.site#channel' +authors: + - Manala + + +### OPTIONAL but strongly recommended +# A short summary description of the collection +description: path handling + +# Either a single license or a list of licenses for content inside of a collection. Ansible Galaxy currently only +# accepts L(SPDX,https://spdx.org/licenses/) licenses. This key is mutually exclusive with 'license_file' +license: + - MIT + +# The path to the license file for the collection. This path is relative to the root of the collection. This key is +# mutually exclusive with 'license' +license_file: LICENSE + +# A list of tags you want to associate with the collection for indexing/searching. A tag name has the same character +# requirements as 'namespace' and 'name' +tags: + - path + - tools + +# Collections that this collection requires to be installed for it to be usable. The key of the dict is the +# collection label 'namespace.name'. The value is a version range +# L(specifiers,https://python-semanticversion.readthedocs.io/en/latest/#requirement-specification). Multiple version +# range specifiers can be set and are separated by ',' +dependencies: {} + +# The URL of the originating SCM repository +repository: https://github.com/manala/ansible-path + +# The URL to any online docs +documentation: https://github.com/manala/ansible-path + +# The URL to the homepage of the collection/project +homepage: https://github.com/manala/ansible-path + +# The URL to the collection issue tracker +issues: https://github.com/manala/ansible-path/issues + +# A list of file glob-like patterns used to filter any files or directories that should not be included in the build +# artifact. A pattern is matched from the relative path of the file or directory of the collection directory. This +# uses 'fnmatch' to match the files or directories. Some directories and files like 'galaxy.yml', '*.pyc', '*.retry', +# and '.git' are always filtered. Mutually exclusive with 'manifest' +build_ignore: + - .github + - .gitignore + - .DS_Store + - .ansible-lint + - .manala.yaml + - .manala + - examples + - Makefile + - tests + +# A dict controlling use of manifest directives used in building the collection artifact. The key 'directives' is a +# list of MANIFEST.in style +# L(directives,https://packaging.python.org/en/latest/guides/using-manifest-in/#manifest-in-commands). The key +# 'omit_default_directives' is a boolean that controls whether the default directives are used. Mutually exclusive +# with 'build_ignore' +# manifest: null diff --git a/meta/runtime.yml b/meta/runtime.yml new file mode 100644 index 0000000..f3589f4 --- /dev/null +++ b/meta/runtime.yml @@ -0,0 +1,52 @@ +--- +# Collections must specify a minimum required ansible version to upload +# to galaxy +requires_ansible: '>=2.15.0' + +# Content that Ansible needs to load from another location or that has +# been deprecated/removed +# plugin_routing: +# action: +# redirected_plugin_name: +# redirect: ns.col.new_location +# deprecated_plugin_name: +# deprecation: +# removal_version: "4.0.0" +# warning_text: | +# See the porting guide on how to update your playbook to +# use ns.col.another_plugin instead. +# removed_plugin_name: +# tombstone: +# removal_version: "2.0.0" +# warning_text: | +# See the porting guide on how to update your playbook to +# use ns.col.another_plugin instead. +# become: +# cache: +# callback: +# cliconf: +# connection: +# doc_fragments: +# filter: +# httpapi: +# inventory: +# lookup: +# module_utils: +# modules: +# netconf: +# shell: +# strategy: +# terminal: +# test: +# vars: + +# Python import statements that Ansible needs to load from another location +# import_redirection: +# ansible_collections.ns.col.plugins.module_utils.old_location: +# redirect: ansible_collections.ns.col.plugins.module_utils.new_location + +# Groups of actions/modules that take a common set of options +# action_groups: +# group_name: +# - module1 +# - module2 diff --git a/plugins/.gitignore b/plugins/.gitignore new file mode 100644 index 0000000..bee8a64 --- /dev/null +++ b/plugins/.gitignore @@ -0,0 +1 @@ +__pycache__ diff --git a/plugins/action/path.py b/plugins/action/path.py new file mode 100644 index 0000000..a35ed7e --- /dev/null +++ b/plugins/action/path.py @@ -0,0 +1,109 @@ +from __future__ import annotations + +from ansible.errors import AnsibleActionFail +from ansible.plugins.action import ActionBase +from ansible.utils.display import Display +from ansible.utils.vars import combine_vars + +display = Display() + + +class ActionModule(ActionBase): + '''Handle path''' + + def run(self, tmp=None, task_vars=None): + + result = super(ActionModule, self).run(tmp, task_vars) + + validation, args = self.validate_argument_spec( + argument_spec={ + 'path': {'type': 'path', 'required': True}, + 'state': {'type': 'str', 'choices': ['present', 'absent', 'file'], 'default': 'present'}, + 'content': {'type': 'str'}, + 'template': {'type': 'path'}, + 'vars': {'type': 'dict', 'default': {}}, + 'user': {'type': 'str'}, + 'group': {'type': 'str'}, + 'mode': {'type': 'raw'}, + 'validate': {'type': 'str'}, + }, + mutually_exclusive=( + ['content', 'template'], + ), + ) + + if args['state'] == 'absent': + display.v('Use "ansible.builtin.file" to ensure "%s" is absent.' % args['path']) + result.update( + self._execute_module( + module_name='ansible.builtin.file', + module_args={ + 'path': args['path'], + 'state': args['state'], + }, + task_vars=task_vars, + ) + ) + elif (args['state'] in ['present', 'file']) and args['content'] is not None: + display.v('Use "ansible.builtin.copy" to ensure "%s" content.' % args['path']) + task = self._task.copy() + task.args = { + 'dest': args['path'], + 'content': args['content'], + 'owner': args['user'], + 'group': args['group'], + 'mode': args['mode'], + 'validate': args['validate'], + } + result.update( + self._shared_loader_obj.action_loader.get( + 'ansible.builtin.copy', + task=task, + connection=self._connection, + play_context=self._play_context, + loader=self._loader, + templar=self._templar, + shared_loader_obj=self._shared_loader_obj, + ).run(task_vars=combine_vars(task_vars, args['vars'])) + ) + elif (args['state'] in ['present', 'file']) and args['template']: + display.v('Use "ansible.builtin.template" to ensure "%s" template.' % args['path']) + task = self._task.copy() + task.args = { + 'src': args['template'], + 'dest': args['path'], + 'owner': args['user'], + 'group': args['group'], + 'mode': args['mode'], + 'validate': args['validate'], + } + result.update( + self._shared_loader_obj.action_loader.get( + 'ansible.builtin.template', + task=task, + connection=self._connection, + play_context=self._play_context, + loader=self._loader, + templar=self._templar, + shared_loader_obj=self._shared_loader_obj, + ).run(task_vars=combine_vars(task_vars, args['vars'])) + ) + elif args['state'] == 'file': + raise AnsibleActionFail('one of the following is required: content, template') + elif args['state'] == 'present': + display.v('Use "ansible.builtin.file" to ensure "%s" is a directory.' % args['path']) + result.update( + self._execute_module( + module_name='ansible.builtin.file', + module_args={ + 'path': args['path'], + 'state': 'directory', + 'owner': args['user'], + 'group': args['group'], + 'mode': args['mode'], + }, + task_vars=task_vars, + ) + ) + + return result diff --git a/plugins/modules/path.py b/plugins/modules/path.py new file mode 100644 index 0000000..49703ce --- /dev/null +++ b/plugins/modules/path.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = ''' +--- +module: path +short_description: Handle path +description: + - Handle path +author: + - Manala (contact@manala.io) +''' + +EXAMPLES = ''' +- name: Path + manala.path.path: +'''