From 3d66ed3ae314d0c14ce5b6f427f90217c85c4f8b Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 23 Nov 2020 14:10:18 +0100 Subject: [PATCH] Remove deprecated modules and plugins. (#1347) * Remove deprecated modules and plugins. * Clean up BOTMETA. * Re-add _netapp doc fragment and module utils. This is needed by the remaining na_ontap_gather_facts module scheduled for removal in 3.0.0. --- .github/BOTMETA.yml | 7 - .../fragments/remove-deprecated-modules.yml | 20 + meta/runtime.yml | 76 +-- plugins/callback/actionable.py | 61 -- plugins/callback/full_skip.py | 76 --- plugins/callback/stderr.py | 71 -- plugins/modules/foreman.py | 1 - plugins/modules/github_hooks.py | 1 - plugins/modules/katello.py | 1 - plugins/modules/na_cdot_aggregate.py | 1 - plugins/modules/na_cdot_license.py | 1 - plugins/modules/na_cdot_lun.py | 1 - plugins/modules/na_cdot_qtree.py | 1 - plugins/modules/na_cdot_svm.py | 1 - plugins/modules/na_cdot_user.py | 1 - plugins/modules/na_cdot_user_role.py | 1 - plugins/modules/na_cdot_volume.py | 1 - .../remote_management/foreman/foreman.py | 157 ----- .../remote_management/foreman/katello.py | 615 ------------------ plugins/modules/sf_account_manager.py | 1 - plugins/modules/sf_check_connections.py | 1 - .../modules/sf_snapshot_schedule_manager.py | 1 - .../modules/sf_volume_access_group_manager.py | 1 - plugins/modules/sf_volume_manager.py | 1 - .../source_control/github/github_hooks.py | 193 ------ .../storage/netapp/na_cdot_aggregate.py | 228 ------- .../modules/storage/netapp/na_cdot_license.py | 296 --------- plugins/modules/storage/netapp/na_cdot_lun.py | 373 ----------- .../modules/storage/netapp/na_cdot_qtree.py | 234 ------- plugins/modules/storage/netapp/na_cdot_svm.py | 246 ------- .../modules/storage/netapp/na_cdot_user.py | 301 --------- .../storage/netapp/na_cdot_user_role.py | 227 ------- .../modules/storage/netapp/na_cdot_volume.py | 437 ------------- .../storage/netapp/sf_account_manager.py | 263 -------- .../storage/netapp/sf_check_connections.py | 179 ----- .../netapp/sf_snapshot_schedule_manager.py | 384 ----------- .../netapp/sf_volume_access_group_manager.py | 244 ------- .../storage/netapp/sf_volume_manager.py | 315 --------- tests/sanity/ignore-2.10.txt | 35 - tests/sanity/ignore-2.11.txt | 35 - tests/sanity/ignore-2.9.txt | 48 -- 41 files changed, 58 insertions(+), 5079 deletions(-) create mode 100644 changelogs/fragments/remove-deprecated-modules.yml delete mode 100644 plugins/callback/actionable.py delete mode 100644 plugins/callback/full_skip.py delete mode 100644 plugins/callback/stderr.py delete mode 120000 plugins/modules/foreman.py delete mode 120000 plugins/modules/github_hooks.py delete mode 120000 plugins/modules/katello.py delete mode 120000 plugins/modules/na_cdot_aggregate.py delete mode 120000 plugins/modules/na_cdot_license.py delete mode 120000 plugins/modules/na_cdot_lun.py delete mode 120000 plugins/modules/na_cdot_qtree.py delete mode 120000 plugins/modules/na_cdot_svm.py delete mode 120000 plugins/modules/na_cdot_user.py delete mode 120000 plugins/modules/na_cdot_user_role.py delete mode 120000 plugins/modules/na_cdot_volume.py delete mode 100644 plugins/modules/remote_management/foreman/foreman.py delete mode 100644 plugins/modules/remote_management/foreman/katello.py delete mode 120000 plugins/modules/sf_account_manager.py delete mode 120000 plugins/modules/sf_check_connections.py delete mode 120000 plugins/modules/sf_snapshot_schedule_manager.py delete mode 120000 plugins/modules/sf_volume_access_group_manager.py delete mode 120000 plugins/modules/sf_volume_manager.py delete mode 100644 plugins/modules/source_control/github/github_hooks.py delete mode 100644 plugins/modules/storage/netapp/na_cdot_aggregate.py delete mode 100644 plugins/modules/storage/netapp/na_cdot_license.py delete mode 100644 plugins/modules/storage/netapp/na_cdot_lun.py delete mode 100644 plugins/modules/storage/netapp/na_cdot_qtree.py delete mode 100644 plugins/modules/storage/netapp/na_cdot_svm.py delete mode 100644 plugins/modules/storage/netapp/na_cdot_user.py delete mode 100644 plugins/modules/storage/netapp/na_cdot_user_role.py delete mode 100644 plugins/modules/storage/netapp/na_cdot_volume.py delete mode 100644 plugins/modules/storage/netapp/sf_account_manager.py delete mode 100644 plugins/modules/storage/netapp/sf_check_connections.py delete mode 100644 plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py delete mode 100644 plugins/modules/storage/netapp/sf_volume_access_group_manager.py delete mode 100644 plugins/modules/storage/netapp/sf_volume_manager.py diff --git a/.github/BOTMETA.yml b/.github/BOTMETA.yml index 5792257dd0..ed72fdcd2a 100644 --- a/.github/BOTMETA.yml +++ b/.github/BOTMETA.yml @@ -20,9 +20,6 @@ files: maintainers: $team_macos labels: macos say keywords: brew cask darwin homebrew macosx macports osx - $callbacks/stderr.py: - maintainers: ysn2233 - labels: stderr $callbacks/sumologic.py: maintainers: ryancurrah labels: sumologic @@ -733,8 +730,6 @@ files: maintainers: jagadeeshnv $modules/remote_management/dellemc/ome_device_info.py: maintainers: Sajna-Shetty - $modules/remote_management/foreman/: - maintainers: ehelms ares ekohl xprazak2 $modules/remote_management/hpilo/: maintainers: haad ignore: dagwieers @@ -776,8 +771,6 @@ files: maintainers: andreparames $modules/source_control/git_config.py: maintainers: djmattyg007 mgedmin - $modules/source_control/github/github_hooks.py: - maintainers: pcgentry $modules/source_control/github/github_deploy_key.py: maintainers: bincyber $modules/source_control/github/github_issue.py: diff --git a/changelogs/fragments/remove-deprecated-modules.yml b/changelogs/fragments/remove-deprecated-modules.yml new file mode 100644 index 0000000000..ff62051735 --- /dev/null +++ b/changelogs/fragments/remove-deprecated-modules.yml @@ -0,0 +1,20 @@ +removed_features: +- The deprecated ``foreman`` module has been removed. Use the modules from the theforeman.foreman collection instead (https://github.com/ansible-collections/community.general/pull/1347) (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``katello`` module has been removed. Use the modules from the theforeman.foreman collection instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``github_hooks`` module has been removed. Use ``community.general.github_webhook`` and ``community.general.github_webhook_info`` instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``na_cdot_aggregate`` module has been removed. Use netapp.ontap.na_ontap_aggregate instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``na_cdot_license`` module has been removed. Use netapp.ontap.na_ontap_license instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``na_cdot_lun`` module has been removed. Use netapp.ontap.na_ontap_lun instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``na_cdot_qtree`` module has been removed. Use netapp.ontap.na_ontap_qtree instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``na_cdot_svm`` module has been removed. Use netapp.ontap.na_ontap_svm instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``na_cdot_user`` module has been removed. Use netapp.ontap.na_ontap_user instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``na_cdot_user_role`` module has been removed. Use netapp.ontap.na_ontap_user_role instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``na_cdot_volume`` module has been removed. Use netapp.ontap.na_ontap_volume instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``sf_account_manager`` module has been removed. Use netapp.elementsw.na_elementsw_account instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``sf_check_connections`` module has been removed. Use netapp.elementsw.na_elementsw_check_connections instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``sf_snapshot_schedule_manager`` module has been removed. Use netapp.elementsw.na_elementsw_snapshot_schedule instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``sf_volume_access_group_manager`` module has been removed. Use netapp.elementsw.na_elementsw_access_group instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``sf_volume_manager`` module has been removed. Use netapp.elementsw.na_elementsw_volume instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``actionable`` callback plugin has been removed. Use the ``ansible.builtin.default`` callback plugin with ``display_skipped_hosts = no`` and ``display_ok_hosts = no`` options instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``full_skip`` callback plugin has been removed. Use the ``ansible.builtin.default`` callback plugin with ``display_skipped_hosts = no`` option instead (https://github.com/ansible-collections/community.general/pull/1347). +- The deprecated ``stderr`` callback plugin has been removed. Use the ``ansible.builtin.default`` callback plugin with ``display_failed_stderr = yes`` option instead (https://github.com/ansible-collections/community.general/pull/1347). diff --git a/meta/runtime.yml b/meta/runtime.yml index a9ac14bd68..03e7eec693 100644 --- a/meta/runtime.yml +++ b/meta/runtime.yml @@ -96,9 +96,9 @@ plugin_routing: docker_volume_info: redirect: community.docker.docker_volume_info foreman: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use the modules from the theforeman.foreman collection instead. gcdns_record: deprecation: removal_version: 2.0.0 @@ -140,9 +140,9 @@ plugin_routing: removal_version: 2.0.0 warning_text: see plugin documentation for details github_hooks: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use community.general.github_webhook and community.general.github_webhook_info instead. helm: deprecation: removal_version: 3.0.0 @@ -160,9 +160,9 @@ plugin_routing: removal_version: 3.0.0 warning_text: see plugin documentation for details katello: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use the modules from the theforeman.foreman collection instead. ldap_attr: deprecation: removal_version: 3.0.0 @@ -184,37 +184,37 @@ plugin_routing: removal_version: 3.0.0 warning_text: see plugin documentation for details na_cdot_aggregate: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.ontap.na_ontap_aggregate instead. na_cdot_license: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.ontap.na_ontap_license instead. na_cdot_lun: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.ontap.na_ontap_lun instead. na_cdot_qtree: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.ontap.na_ontap_qtree instead. na_cdot_svm: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.ontap.na_ontap_svm instead. na_cdot_user: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.ontap.na_ontap_user instead. na_cdot_user_role: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.ontap.na_ontap_user_role instead. na_cdot_volume: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.ontap.na_ontap_volume instead. na_ontap_gather_facts: deprecation: removal_version: 3.0.0 @@ -416,25 +416,25 @@ plugin_routing: removal_version: 3.0.0 warning_text: see plugin documentation for details sf_account_manager: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.elementsw.na_elementsw_account instead. sf_check_connections: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.elementsw.na_elementsw_check_connections instead. sf_snapshot_schedule_manager: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.elementsw.na_elementsw_snapshot_schedule instead. sf_volume_access_group_manager: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.elementsw.na_elementsw_access_group instead. sf_volume_manager: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use netapp.elementsw.na_elementsw_volume instead. smartos_image_facts: deprecation: removal_version: 3.0.0 @@ -457,17 +457,17 @@ plugin_routing: redirect: community.docker.swarm callback: actionable: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use the 'default' callback plugin with 'display_skipped_hosts = no' and 'display_ok_hosts = no' options. full_skip: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use the 'default' callback plugin with 'display_skipped_hosts = no' option. stderr: - deprecation: + tombstone: removal_version: 2.0.0 - warning_text: see plugin documentation for details + warning_text: Use the 'default' callback plugin with 'display_failed_stderr = yes' option. inventory: docker_machine: redirect: community.docker.docker_machine diff --git a/plugins/callback/actionable.py b/plugins/callback/actionable.py deleted file mode 100644 index 8309a846b3..0000000000 --- a/plugins/callback/actionable.py +++ /dev/null @@ -1,61 +0,0 @@ -# (c) 2015, Andrew Gaffney -# (c) 2017 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = ''' - author: Unknown (!UNKNOWN) - callback: actionable - type: stdout - short_description: shows only items that need attention - description: - - Use this callback when you dont care about OK nor Skipped. - - This callback suppresses any non Failed or Changed status. - deprecated: - why: The 'default' callback plugin now supports this functionality - removed_in: '2.0.0' # was Ansible 2.11 - alternative: "'default' callback plugin with 'display_skipped_hosts = no' and 'display_ok_hosts = no' options" - extends_documentation_fragment: - - default_callback - requirements: - - set as stdout callback in configuration - # Override defaults from 'default' callback plugin - options: - display_skipped_hosts: - name: Show skipped hosts - description: "Toggle to control displaying skipped task/host results in a task" - type: bool - default: no - env: - - name: DISPLAY_SKIPPED_HOSTS - deprecated: - why: environment variables without "ANSIBLE_" prefix are deprecated - version: "2.0.0" # was Ansible 2.12 - alternatives: the "ANSIBLE_DISPLAY_SKIPPED_HOSTS" environment variable - - name: ANSIBLE_DISPLAY_SKIPPED_HOSTS - ini: - - key: display_skipped_hosts - section: defaults - display_ok_hosts: - name: Show 'ok' hosts - description: "Toggle to control displaying 'ok' task/host results in a task" - type: bool - default: no - env: - - name: ANSIBLE_DISPLAY_OK_HOSTS - ini: - - key: display_ok_hosts - section: defaults -''' - -from ansible.plugins.callback.default import CallbackModule as CallbackModule_default - - -class CallbackModule(CallbackModule_default): - - CALLBACK_VERSION = 2.0 - CALLBACK_TYPE = 'stdout' - CALLBACK_NAME = 'community.general.actionable' diff --git a/plugins/callback/full_skip.py b/plugins/callback/full_skip.py deleted file mode 100644 index 9fce697013..0000000000 --- a/plugins/callback/full_skip.py +++ /dev/null @@ -1,76 +0,0 @@ -# (c) 2012-2014, Michael DeHaan -# (c) 2017 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = ''' - author: Unknown (!UNKNOWN) - callback: full_skip - type: stdout - short_description: suppresses tasks if all hosts skipped - description: - - Use this plugin when you do not care about any output for tasks that were completely skipped - deprecated: - why: The 'default' callback plugin now supports this functionality - removed_in: '2.0.0' # was Ansible 2.11 - alternative: "'default' callback plugin with 'display_skipped_hosts = no' option" - extends_documentation_fragment: - - default_callback - requirements: - - set as stdout in configuration -''' - -from ansible.plugins.callback.default import CallbackModule as CallbackModule_default - - -class CallbackModule(CallbackModule_default): - - ''' - This is the default callback interface, which simply prints messages - to stdout when new callback events are received. - ''' - - CALLBACK_VERSION = 2.0 - CALLBACK_TYPE = 'stdout' - CALLBACK_NAME = 'community.general.full_skip' - - def v2_runner_on_skipped(self, result): - self.outlines = [] - - def v2_playbook_item_on_skipped(self, result): - self.outlines = [] - - def v2_runner_item_on_skipped(self, result): - self.outlines = [] - - def v2_runner_on_failed(self, result, ignore_errors=False): - self.display() - super(CallbackModule, self).v2_runner_on_failed(result, ignore_errors) - - def v2_playbook_on_task_start(self, task, is_conditional): - self.outlines = [] - self.outlines.append("TASK [%s]" % task.get_name().strip()) - if self._display.verbosity >= 2: - path = task.get_path() - if path: - self.outlines.append("task path: %s" % path) - - def v2_playbook_item_on_ok(self, result): - self.display() - super(CallbackModule, self).v2_playbook_item_on_ok(result) - - def v2_runner_on_ok(self, result): - self.display() - super(CallbackModule, self).v2_runner_on_ok(result) - - def display(self): - if len(self.outlines) == 0: - return - (first, rest) = self.outlines[0], self.outlines[1:] - self._display.banner(first) - for line in rest: - self._display.display(line) - self.outlines = [] diff --git a/plugins/callback/stderr.py b/plugins/callback/stderr.py deleted file mode 100644 index 9aa0e3fdef..0000000000 --- a/plugins/callback/stderr.py +++ /dev/null @@ -1,71 +0,0 @@ -# (c) 2017, Frederic Van Espen -# (c) 2017 Ansible Project -# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) - -# Make coding more python3-ish -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -DOCUMENTATION = ''' - author: Unknown (!UNKNOWN) - callback: stderr - type: stdout - requirements: - - set as main display callback - short_description: Splits output, sending failed tasks to stderr - deprecated: - why: The 'default' callback plugin now supports this functionality - removed_in: '2.0.0' # was Ansible 2.11 - alternative: "'default' callback plugin with 'display_failed_stderr = yes' option" - extends_documentation_fragment: - - default_callback - description: - - This is the stderr callback plugin, it behaves like the default callback plugin but sends error output to stderr. - - Also it does not output skipped host/task/item status -''' - -from ansible import constants as C -from ansible.plugins.callback.default import CallbackModule as CallbackModule_default - - -class CallbackModule(CallbackModule_default): - - ''' - This is the stderr callback plugin, which reuses the default - callback plugin but sends error output to stderr. - ''' - - CALLBACK_VERSION = 2.0 - CALLBACK_TYPE = 'stdout' - CALLBACK_NAME = 'community.general.stderr' - - def __init__(self): - - self.super_ref = super(CallbackModule, self) - self.super_ref.__init__() - - def v2_runner_on_failed(self, result, ignore_errors=False): - - delegated_vars = result._result.get('_ansible_delegated_vars', None) - self._clean_results(result._result, result._task.action) - - if self._play.strategy == 'free' and self._last_task_banner != result._task._uuid: - self._print_task_banner(result._task) - - self._handle_exception(result._result, use_stderr=True) - self._handle_warnings(result._result) - - if result._task.loop and 'results' in result._result: - self._process_items(result) - - else: - if delegated_vars: - self._display.display("fatal: [%s -> %s]: FAILED! => %s" % (result._host.get_name(), delegated_vars['ansible_host'], - self._dump_results(result._result)), color=C.COLOR_ERROR, - stderr=True) - else: - self._display.display("fatal: [%s]: FAILED! => %s" % (result._host.get_name(), self._dump_results(result._result)), - color=C.COLOR_ERROR, stderr=True) - - if ignore_errors: - self._display.display("...ignoring", color=C.COLOR_SKIP) diff --git a/plugins/modules/foreman.py b/plugins/modules/foreman.py deleted file mode 120000 index ef892b3c7a..0000000000 --- a/plugins/modules/foreman.py +++ /dev/null @@ -1 +0,0 @@ -./remote_management/foreman/foreman.py \ No newline at end of file diff --git a/plugins/modules/github_hooks.py b/plugins/modules/github_hooks.py deleted file mode 120000 index 7498c9e267..0000000000 --- a/plugins/modules/github_hooks.py +++ /dev/null @@ -1 +0,0 @@ -./source_control/github/github_hooks.py \ No newline at end of file diff --git a/plugins/modules/katello.py b/plugins/modules/katello.py deleted file mode 120000 index 3022888122..0000000000 --- a/plugins/modules/katello.py +++ /dev/null @@ -1 +0,0 @@ -./remote_management/foreman/katello.py \ No newline at end of file diff --git a/plugins/modules/na_cdot_aggregate.py b/plugins/modules/na_cdot_aggregate.py deleted file mode 120000 index 92cf66834c..0000000000 --- a/plugins/modules/na_cdot_aggregate.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/na_cdot_aggregate.py \ No newline at end of file diff --git a/plugins/modules/na_cdot_license.py b/plugins/modules/na_cdot_license.py deleted file mode 120000 index ea38ed2440..0000000000 --- a/plugins/modules/na_cdot_license.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/na_cdot_license.py \ No newline at end of file diff --git a/plugins/modules/na_cdot_lun.py b/plugins/modules/na_cdot_lun.py deleted file mode 120000 index 292ebc19fe..0000000000 --- a/plugins/modules/na_cdot_lun.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/na_cdot_lun.py \ No newline at end of file diff --git a/plugins/modules/na_cdot_qtree.py b/plugins/modules/na_cdot_qtree.py deleted file mode 120000 index 9f6ad745d3..0000000000 --- a/plugins/modules/na_cdot_qtree.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/na_cdot_qtree.py \ No newline at end of file diff --git a/plugins/modules/na_cdot_svm.py b/plugins/modules/na_cdot_svm.py deleted file mode 120000 index 72c985ed2c..0000000000 --- a/plugins/modules/na_cdot_svm.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/na_cdot_svm.py \ No newline at end of file diff --git a/plugins/modules/na_cdot_user.py b/plugins/modules/na_cdot_user.py deleted file mode 120000 index 95229d944d..0000000000 --- a/plugins/modules/na_cdot_user.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/na_cdot_user.py \ No newline at end of file diff --git a/plugins/modules/na_cdot_user_role.py b/plugins/modules/na_cdot_user_role.py deleted file mode 120000 index 4d824d8d13..0000000000 --- a/plugins/modules/na_cdot_user_role.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/na_cdot_user_role.py \ No newline at end of file diff --git a/plugins/modules/na_cdot_volume.py b/plugins/modules/na_cdot_volume.py deleted file mode 120000 index a4579473a1..0000000000 --- a/plugins/modules/na_cdot_volume.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/na_cdot_volume.py \ No newline at end of file diff --git a/plugins/modules/remote_management/foreman/foreman.py b/plugins/modules/remote_management/foreman/foreman.py deleted file mode 100644 index b209b05ae2..0000000000 --- a/plugins/modules/remote_management/foreman/foreman.py +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Eric D Helms -# 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: foreman -short_description: Manage Foreman Resources -deprecated: - removed_in: 2.0.0 # was Ansible 2.12 - why: "Replaced by re-designed individual modules living at https://github.com/theforeman/foreman-ansible-modules" - alternative: https://github.com/theforeman/foreman-ansible-modules -description: - - Allows the management of Foreman resources inside your Foreman server. -author: -- Eric D Helms (@ehelms) -requirements: - - nailgun >= 0.28.0 - - python >= 2.6 - - datetime -options: - server_url: - description: - - URL of Foreman server. - required: true - username: - description: - - Username on Foreman server. - required: true - verify_ssl: - description: - - Whether to verify an SSL connection to Foreman server. - type: bool - default: False - password: - description: - - Password for user accessing Foreman server. - required: true - entity: - description: - - The Foreman resource that the action will be performed on (e.g. organization, host). - required: true - params: - description: - - Parameters associated to the entity resource to set or edit in dictionary format (e.g. name, description). - required: true -''' - -EXAMPLES = ''' -- name: Create CI Organization - community.general.foreman: - username: admin - password: admin - server_url: https://fakeserver.com - entity: organization - params: - name: My Cool New Organization - delegate_to: localhost -''' - -RETURN = '''# ''' - -import traceback - -try: - from nailgun import entities - from nailgun.config import ServerConfig - HAS_NAILGUN_PACKAGE = True -except Exception: - HAS_NAILGUN_PACKAGE = False - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native - - -class NailGun(object): - def __init__(self, server, entities, module): - self._server = server - self._entities = entities - self._module = module - - def find_organization(self, name, **params): - org = self._entities.Organization(self._server, name=name, **params) - response = org.search(set(), {'search': 'name={0}'.format(name)}) - - if len(response) == 1: - return response[0] - - return None - - def organization(self, params): - name = params['name'] - del params['name'] - org = self.find_organization(name, **params) - - if org: - org = self._entities.Organization(self._server, name=name, id=org.id, **params) - org.update() - else: - org = self._entities.Organization(self._server, name=name, **params) - org.create() - - return True - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True), - username=dict(type='str', required=True, no_log=True), - password=dict(type='str', required=True, no_log=True), - entity=dict(type='str', required=True), - verify_ssl=dict(type='bool', default=False), - params=dict(type='dict', required=True, no_log=True), - ), - supports_check_mode=True, - ) - - if not HAS_NAILGUN_PACKAGE: - module.fail_json(msg="Missing required nailgun module (check docs or install with: pip install nailgun") - - server_url = module.params['server_url'] - username = module.params['username'] - password = module.params['password'] - entity = module.params['entity'] - params = module.params['params'] - verify_ssl = module.params['verify_ssl'] - - server = ServerConfig( - url=server_url, - auth=(username, password), - verify=verify_ssl - ) - ng = NailGun(server, entities, module) - - # Lets make an connection to the server with username and password - try: - org = entities.Organization(server) - org.search() - except Exception as e: - module.fail_json(msg="Failed to connect to Foreman server: %s " % to_native(e), - exception=traceback.format_exc()) - - if entity == 'organization': - ng.organization(params) - module.exit_json(changed=True, result="%s updated" % entity) - else: - module.fail_json(changed=False, result="Unsupported entity supplied") - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/remote_management/foreman/katello.py b/plugins/modules/remote_management/foreman/katello.py deleted file mode 100644 index 732c4723df..0000000000 --- a/plugins/modules/remote_management/foreman/katello.py +++ /dev/null @@ -1,615 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# Copyright: (c) 2016, Eric D Helms -# 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: katello -short_description: Manage Katello Resources -deprecated: - removed_in: '2.0.0' # was Ansible 2.12 - why: "Replaced by re-designed individual modules living at https://github.com/theforeman/foreman-ansible-modules" - alternative: https://github.com/theforeman/foreman-ansible-modules -description: - - Allows the management of Katello resources inside your Foreman server. -author: -- Eric D Helms (@ehelms) -requirements: - - nailgun >= 0.28.0 - - python >= 2.6 - - datetime -options: - server_url: - description: - - URL of Foreman server. - required: true - username: - description: - - Username on Foreman server. - required: true - password: - description: - - Password for user accessing Foreman server. - required: true - entity: - description: - - The Foreman resource that the action will be performed on (e.g. organization, host). - choices: - - - repository - - manifest - - repository_set - - sync_plan - - content_view - - lifecycle_environment - - activation_key - - product - - required: true - action: - description: - - action associated to the entity resource to set or edit in dictionary format. - - Possible Action in relation to Entitys. - - "sync (available when entity=product or entity=repository)" - - "publish (available when entity=content_view)" - - "promote (available when entity=content_view)" - choices: - - sync - - publish - - promote - required: false - params: - description: - - Parameters associated to the entity resource and action, to set or edit in dictionary format. - - Each choice may be only available with specific entitys and actions. - - "Possible Choices are in the format of param_name ([entry,action,action,...],[entity,..],...)." - - The action "None" means no action specified. - - Possible Params in relation to entity and action. - - "name ([product,sync,None], [repository,sync], [repository_set,None], [sync_plan,None]," - - "[content_view,promote,publish,None], [lifecycle_environment,None], [activation_key,None])" - - "organization ([product,sync,None] ,[repository,sync,None], [repository_set,None], [sync_plan,None], " - - "[content_view,promote,publish,None], [lifecycle_environment,None], [activation_key,None])" - - "content ([manifest,None])" - - "product ([repository,sync,None], [repository_set,None], [sync_plan,None])" - - "basearch ([repository_set,None])" - - "releaserver ([repository_set,None])" - - "sync_date ([sync_plan,None])" - - "interval ([sync_plan,None])" - - "repositories ([content_view,None])" - - "from_environment ([content_view,promote])" - - "to_environment([content_view,promote])" - - "prior ([lifecycle_environment,None])" - - "content_view ([activation_key,None])" - - "lifecycle_environment ([activation_key,None])" - required: true - task_timeout: - description: - - The timeout in seconds to wait for the started Foreman action to finish. - - If the timeout is reached and the Foreman action did not complete, the ansible task fails. However the foreman action does not get canceled. - default: 1000 - required: false - verify_ssl: - description: - - verify the ssl/https connection (e.g for a valid certificate) - default: false - type: bool - required: false -''' - -EXAMPLES = ''' ---- -# Simple Example: - -- name: Create Product - community.general.katello: - username: admin - password: admin - server_url: https://fakeserver.com - entity: product - params: - name: Centos 7 - delegate_to: localhost - -# Abstraction Example: -# katello.yml ---- -- name: "{{ name }}" - community.general.katello: - username: admin - password: admin - server_url: https://fakeserver.com - entity: "{{ entity }}" - params: "{{ params }}" - delegate_to: localhost - -# tasks.yml ---- -- include: katello.yml - vars: - name: Create Dev Environment - entity: lifecycle_environment - params: - name: Dev - prior: Library - organization: Default Organization - -- include: katello.yml - vars: - name: Create Centos Product - entity: product - params: - name: Centos 7 - organization: Default Organization - -- include: katello.yml - vars: - name: Create 7.2 Repository - entity: repository - params: - name: Centos 7.2 - product: Centos 7 - organization: Default Organization - content_type: yum - url: http://mirror.centos.org/centos/7/os/x86_64/ - -- include: katello.yml - vars: - name: Create Centos 7 View - entity: content_view - params: - name: Centos 7 View - organization: Default Organization - repositories: - - name: Centos 7.2 - product: Centos 7 - -- include: katello.yml - vars: - name: Enable RHEL Product - entity: repository_set - params: - name: Red Hat Enterprise Linux 7 Server (RPMs) - product: Red Hat Enterprise Linux Server - organization: Default Organization - basearch: x86_64 - releasever: 7 - -- include: katello.yml - vars: - name: Promote Contentview Environment with longer timeout - task_timeout: 10800 - entity: content_view - action: promote - params: - name: MyContentView - organization: MyOrganisation - from_environment: Testing - to_environment: Production - -# Best Practices - -# In Foreman, things can be done in parallel. -# When a conflicting action is already running, -# the task will fail instantly instead of waiting for the already running action to complete. -# So you should use a "until success" loop to catch this. - -- name: Promote Contentview Environment with increased Timeout - community.general.katello: - username: ansibleuser - password: supersecret - task_timeout: 10800 - entity: content_view - action: promote - params: - name: MyContentView - organization: MyOrganisation - from_environment: Testing - to_environment: Production - register: task_result - until: task_result is success - retries: 9 - delay: 120 - -''' - -RETURN = '''# ''' - -import datetime -import os -import traceback - -try: - from nailgun import entities, entity_fields, entity_mixins - from nailgun.config import ServerConfig - HAS_NAILGUN_PACKAGE = True -except Exception: - HAS_NAILGUN_PACKAGE = False - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native - - -class NailGun(object): - def __init__(self, server, entities, module, task_timeout): - self._server = server - self._entities = entities - self._module = module - entity_mixins.TASK_TIMEOUT = task_timeout - - def find_organization(self, name, **params): - org = self._entities.Organization(self._server, name=name, **params) - response = org.search(set(), {'search': 'name={0}'.format(name)}) - - if len(response) == 1: - return response[0] - else: - self._module.fail_json(msg="No organization found for %s" % name) - - def find_lifecycle_environment(self, name, organization): - org = self.find_organization(organization) - - lifecycle_env = self._entities.LifecycleEnvironment(self._server, name=name, organization=org) - response = lifecycle_env.search() - - if len(response) == 1: - return response[0] - else: - self._module.fail_json(msg="No Lifecycle Found found for %s" % name) - - def find_product(self, name, organization): - org = self.find_organization(organization) - - product = self._entities.Product(self._server, name=name, organization=org) - response = product.search() - - if len(response) == 1: - return response[0] - else: - self._module.fail_json(msg="No Product found for %s" % name) - - def find_repository(self, name, product, organization): - product = self.find_product(product, organization) - - repository = self._entities.Repository(self._server, name=name, product=product) - repository._fields['organization'] = entity_fields.OneToOneField(entities.Organization) - repository.organization = product.organization - response = repository.search() - - if len(response) == 1: - return response[0] - else: - self._module.fail_json(msg="No Repository found for %s" % name) - - def find_content_view(self, name, organization): - org = self.find_organization(organization) - - content_view = self._entities.ContentView(self._server, name=name, organization=org) - response = content_view.search() - - if len(response) == 1: - return response[0] - else: - self._module.fail_json(msg="No Content View found for %s" % name) - - def organization(self, params): - name = params['name'] - del params['name'] - org = self.find_organization(name, **params) - - if org: - org = self._entities.Organization(self._server, name=name, id=org.id, **params) - org.update() - else: - org = self._entities.Organization(self._server, name=name, **params) - org.create() - - return True - - def manifest(self, params): - org = self.find_organization(params['organization']) - params['organization'] = org.id - - try: - file = open(os.getcwd() + params['content'], 'r') - content = file.read() - finally: - file.close() - - manifest = self._entities.Subscription(self._server) - - try: - manifest.upload( - data={'organization_id': org.id}, - files={'content': content} - ) - return True - except Exception as e: - - if "Import is the same as existing data" in e.message: - return False - else: - self._module.fail_json(msg="Manifest import failed with %s" % to_native(e), - exception=traceback.format_exc()) - - def product(self, params): - org = self.find_organization(params['organization']) - params['organization'] = org.id - - product = self._entities.Product(self._server, **params) - response = product.search() - - if len(response) == 1: - product.id = response[0].id - product.update() - else: - product.create() - - return True - - def sync_product(self, params): - org = self.find_organization(params['organization']) - product = self.find_product(params['name'], org.name) - - return product.sync() - - def repository(self, params): - product = self.find_product(params['product'], params['organization']) - params['product'] = product.id - del params['organization'] - - repository = self._entities.Repository(self._server, **params) - repository._fields['organization'] = entity_fields.OneToOneField(entities.Organization) - repository.organization = product.organization - response = repository.search() - - if len(response) == 1: - repository.id = response[0].id - repository.update() - else: - repository.create() - - return True - - def sync_repository(self, params): - org = self.find_organization(params['organization']) - repository = self.find_repository(params['name'], params['product'], org.name) - - return repository.sync() - - def repository_set(self, params): - product = self.find_product(params['product'], params['organization']) - del params['product'] - del params['organization'] - - if not product: - return False - else: - reposet = self._entities.RepositorySet(self._server, product=product, name=params['name']) - reposet = reposet.search()[0] - - formatted_name = [params['name'].replace('(', '').replace(')', '')] - formatted_name.append(params['basearch']) - - if 'releasever' in params: - formatted_name.append(params['releasever']) - - formatted_name = ' '.join(formatted_name) - - repository = self._entities.Repository(self._server, product=product, name=formatted_name) - repository._fields['organization'] = entity_fields.OneToOneField(entities.Organization) - repository.organization = product.organization - repository = repository.search() - - if len(repository) == 0: - if 'releasever' in params: - reposet.enable(data={'basearch': params['basearch'], 'releasever': params['releasever']}) - else: - reposet.enable(data={'basearch': params['basearch']}) - - return True - - def sync_plan(self, params): - org = self.find_organization(params['organization']) - params['organization'] = org.id - params['sync_date'] = datetime.datetime.strptime(params['sync_date'], "%H:%M") - - products = params['products'] - del params['products'] - - sync_plan = self._entities.SyncPlan( - self._server, - name=params['name'], - organization=org - ) - response = sync_plan.search() - - sync_plan.sync_date = params['sync_date'] - sync_plan.interval = params['interval'] - - if len(response) == 1: - sync_plan.id = response[0].id - sync_plan.update() - else: - response = sync_plan.create() - sync_plan.id = response[0].id - - if products: - ids = [] - - for name in products: - product = self.find_product(name, org.name) - ids.append(product.id) - - sync_plan.add_products(data={'product_ids': ids}) - - return True - - def content_view(self, params): - org = self.find_organization(params['organization']) - - content_view = self._entities.ContentView(self._server, name=params['name'], organization=org) - response = content_view.search() - - if len(response) == 1: - content_view.id = response[0].id - content_view.update() - else: - content_view = content_view.create() - - if params['repositories']: - repos = [] - - for repository in params['repositories']: - repository = self.find_repository(repository['name'], repository['product'], org.name) - repos.append(repository) - - content_view.repository = repos - content_view.update(['repository']) - - def find_content_view_version(self, name, organization, environment): - env = self.find_lifecycle_environment(environment, organization) - content_view = self.find_content_view(name, organization) - - content_view_version = self._entities.ContentViewVersion(self._server, content_view=content_view) - response = content_view_version.search(['content_view'], {'environment_id': env.id}) - - if len(response) == 1: - return response[0] - else: - self._module.fail_json(msg="No Content View version found for %s" % response) - - def publish(self, params): - content_view = self.find_content_view(params['name'], params['organization']) - - return content_view.publish() - - def promote(self, params): - to_environment = self.find_lifecycle_environment(params['to_environment'], params['organization']) - version = self.find_content_view_version(params['name'], params['organization'], params['from_environment']) - - data = {'environment_id': to_environment.id} - return version.promote(data=data) - - def lifecycle_environment(self, params): - org = self.find_organization(params['organization']) - prior_env = self.find_lifecycle_environment(params['prior'], params['organization']) - - lifecycle_env = self._entities.LifecycleEnvironment(self._server, name=params['name'], organization=org, prior=prior_env) - response = lifecycle_env.search() - - if len(response) == 1: - lifecycle_env.id = response[0].id - lifecycle_env.update() - else: - lifecycle_env.create() - - return True - - def activation_key(self, params): - org = self.find_organization(params['organization']) - - activation_key = self._entities.ActivationKey(self._server, name=params['name'], organization=org) - response = activation_key.search() - - if len(response) == 1: - activation_key.id = response[0].id - activation_key.update() - else: - activation_key.create() - - if params['content_view']: - content_view = self.find_content_view(params['content_view'], params['organization']) - lifecycle_environment = self.find_lifecycle_environment(params['lifecycle_environment'], params['organization']) - - activation_key.content_view = content_view - activation_key.environment = lifecycle_environment - activation_key.update() - - return True - - -def main(): - module = AnsibleModule( - argument_spec=dict( - server_url=dict(type='str', required=True), - username=dict(type='str', required=True, no_log=True), - password=dict(type='str', required=True, no_log=True), - entity=dict(type='str', required=True, - choices=['repository', 'manifest', 'repository_set', 'sync_plan', - 'content_view', 'lifecycle_environment', 'activation_key', 'product']), - action=dict(type='str', choices=['sync', 'publish', 'promote']), - verify_ssl=dict(type='bool', default=False), - task_timeout=dict(type='int', default=1000), - params=dict(type='dict', required=True, no_log=True), - ), - supports_check_mode=True, - ) - - if not HAS_NAILGUN_PACKAGE: - module.fail_json(msg="Missing required nailgun module (check docs or install with: pip install nailgun") - - server_url = module.params['server_url'] - username = module.params['username'] - password = module.params['password'] - entity = module.params['entity'] - action = module.params['action'] - params = module.params['params'] - verify_ssl = module.params['verify_ssl'] - task_timeout = module.params['task_timeout'] - - server = ServerConfig( - url=server_url, - auth=(username, password), - verify=verify_ssl - ) - ng = NailGun(server, entities, module, task_timeout) - - # Lets make an connection to the server with username and password - try: - org = entities.Organization(server) - org.search() - except Exception as e: - module.fail_json(msg="Failed to connect to Foreman server: %s " % e) - - result = False - - if entity == 'product': - if action == 'sync': - result = ng.sync_product(params) - else: - result = ng.product(params) - elif entity == 'repository': - if action == 'sync': - result = ng.sync_repository(params) - else: - result = ng.repository(params) - elif entity == 'manifest': - result = ng.manifest(params) - elif entity == 'repository_set': - result = ng.repository_set(params) - elif entity == 'sync_plan': - result = ng.sync_plan(params) - elif entity == 'content_view': - if action == 'publish': - result = ng.publish(params) - elif action == 'promote': - result = ng.promote(params) - else: - result = ng.content_view(params) - elif entity == 'lifecycle_environment': - result = ng.lifecycle_environment(params) - elif entity == 'activation_key': - result = ng.activation_key(params) - else: - module.fail_json(changed=False, result="Unsupported entity supplied") - - module.exit_json(changed=result, result="%s updated" % entity) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/sf_account_manager.py b/plugins/modules/sf_account_manager.py deleted file mode 120000 index ea90a145ca..0000000000 --- a/plugins/modules/sf_account_manager.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/sf_account_manager.py \ No newline at end of file diff --git a/plugins/modules/sf_check_connections.py b/plugins/modules/sf_check_connections.py deleted file mode 120000 index 00133989d7..0000000000 --- a/plugins/modules/sf_check_connections.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/sf_check_connections.py \ No newline at end of file diff --git a/plugins/modules/sf_snapshot_schedule_manager.py b/plugins/modules/sf_snapshot_schedule_manager.py deleted file mode 120000 index d92f19db09..0000000000 --- a/plugins/modules/sf_snapshot_schedule_manager.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/sf_snapshot_schedule_manager.py \ No newline at end of file diff --git a/plugins/modules/sf_volume_access_group_manager.py b/plugins/modules/sf_volume_access_group_manager.py deleted file mode 120000 index 6f279e0be7..0000000000 --- a/plugins/modules/sf_volume_access_group_manager.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/sf_volume_access_group_manager.py \ No newline at end of file diff --git a/plugins/modules/sf_volume_manager.py b/plugins/modules/sf_volume_manager.py deleted file mode 120000 index fa17346ae1..0000000000 --- a/plugins/modules/sf_volume_manager.py +++ /dev/null @@ -1 +0,0 @@ -./storage/netapp/sf_volume_manager.py \ No newline at end of file diff --git a/plugins/modules/source_control/github/github_hooks.py b/plugins/modules/source_control/github/github_hooks.py deleted file mode 100644 index e326711d73..0000000000 --- a/plugins/modules/source_control/github/github_hooks.py +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -# (c) 2013, Phillip Gentry -# 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: github_hooks -short_description: Manages GitHub service hooks. -deprecated: - removed_in: 2.0.0 # was Ansible 2.12 - why: Replaced by more granular modules - alternative: Use M(community.general.github_webhook) and M(community.general.github_webhook_info) instead. -description: - - Adds service hooks and removes service hooks that have an error status. -options: - user: - description: - - GitHub username. - required: true - oauthkey: - description: - - The oauth key provided by GitHub. It can be found/generated on GitHub under "Edit Your Profile" >> "Developer settings" >> "Personal Access Tokens" - required: true - repo: - description: - - > - This is the API url for the repository you want to manage hooks for. It should be in the form of: https://api.github.com/repos/user:/repo:. - Note this is different than the normal repo url. - required: true - hookurl: - description: - - When creating a new hook, this is the url that you want GitHub to post to. It is only required when creating a new hook. - required: false - action: - description: - - This tells the githooks module what you want it to do. - required: true - choices: [ "create", "cleanall", "list", "clean504" ] - validate_certs: - description: - - If C(no), SSL certificates for the target repo will not be validated. This should only be used - on personally controlled sites using self-signed certificates. - required: false - default: 'yes' - type: bool - content_type: - description: - - Content type to use for requests made to the webhook - required: false - default: 'json' - choices: ['json', 'form'] - -author: "Phillip Gentry, CX Inc (@pcgentry)" -''' - -EXAMPLES = ''' -- name: Create a new service hook ignoring duplicates - community.general.github_hooks: - action: create - hookurl: http://11.111.111.111:2222 - user: '{{ gituser }}' - oauthkey: '{{ oauthkey }}' - repo: https://api.github.com/repos/pcgentry/Github-Auto-Deploy - -# Cleaning all hooks for this repo that had an error on the last update. -# Since this works for all hooks in a repo it is probably best that this would be called from a handler. -- name: Clean all hooks - community.general.github_hooks: - action: cleanall - user: '{{ gituser }}' - oauthkey: '{{ oauthkey }}' - repo: '{{ repo }}' - delegate_to: localhost -''' - -import json -import base64 - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.urls import fetch_url -from ansible.module_utils._text import to_bytes - - -def request(module, url, user, oauthkey, data='', method='GET'): - auth = base64.b64encode(to_bytes('%s:%s' % (user, oauthkey)).replace('\n', '')) - headers = { - 'Authorization': 'Basic %s' % auth, - } - response, info = fetch_url(module, url, headers=headers, data=data, method=method) - return response, info - - -def _list(module, oauthkey, repo, user): - url = "%s/hooks" % repo - response, info = request(module, url, user, oauthkey) - if info['status'] != 200: - return False, '' - else: - return False, response.read() - - -def _clean504(module, oauthkey, repo, user): - current_hooks = _list(module, oauthkey, repo, user)[1] - decoded = json.loads(current_hooks) - - for hook in decoded: - if hook['last_response']['code'] == 504: - _delete(module, oauthkey, repo, user, hook['id']) - - return 0, current_hooks - - -def _cleanall(module, oauthkey, repo, user): - current_hooks = _list(module, oauthkey, repo, user)[1] - decoded = json.loads(current_hooks) - - for hook in decoded: - if hook['last_response']['code'] != 200: - _delete(module, oauthkey, repo, user, hook['id']) - - return 0, current_hooks - - -def _create(module, hookurl, oauthkey, repo, user, content_type): - url = "%s/hooks" % repo - values = { - "active": True, - "name": "web", - "config": { - "url": "%s" % hookurl, - "content_type": "%s" % content_type - } - } - data = json.dumps(values) - response, info = request(module, url, user, oauthkey, data=data, method='POST') - if info['status'] != 200: - return 0, '[]' - else: - return 0, response.read() - - -def _delete(module, oauthkey, repo, user, hookid): - url = "%s/hooks/%s" % (repo, hookid) - response, info = request(module, url, user, oauthkey, method='DELETE') - return response.read() - - -def main(): - module = AnsibleModule( - argument_spec=dict( - action=dict(required=True, choices=['list', 'clean504', 'cleanall', 'create']), - hookurl=dict(required=False), - oauthkey=dict(required=True, no_log=True), - repo=dict(required=True), - user=dict(required=True), - validate_certs=dict(default=True, type='bool'), - content_type=dict(default='json', choices=['json', 'form']), - ) - ) - - action = module.params['action'] - hookurl = module.params['hookurl'] - oauthkey = module.params['oauthkey'] - repo = module.params['repo'] - user = module.params['user'] - content_type = module.params['content_type'] - - if action == "list": - (rc, out) = _list(module, oauthkey, repo, user) - - if action == "clean504": - (rc, out) = _clean504(module, oauthkey, repo, user) - - if action == "cleanall": - (rc, out) = _cleanall(module, oauthkey, repo, user) - - if action == "create": - (rc, out) = _create(module, hookurl, oauthkey, repo, user, content_type) - - if rc != 0: - module.fail_json(msg="failed", result=out) - - module.exit_json(msg="success", result=out) - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/na_cdot_aggregate.py b/plugins/modules/storage/netapp/na_cdot_aggregate.py deleted file mode 100644 index f82bd7eae6..0000000000 --- a/plugins/modules/storage/netapp/na_cdot_aggregate.py +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: na_cdot_aggregate - -short_description: Manage NetApp cDOT aggregates. -extends_documentation_fragment: -- community.general._netapp.ontap - -author: Sumit Kumar (@timuster) - -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: Updated modules released with increased functionality - alternative: Use M(netapp.ontap.na_ontap_aggregate) instead. - -description: -- Create or destroy aggregates on NetApp cDOT. - -options: - - state: - required: true - description: - - Whether the specified aggregate should exist or not. - choices: ['present', 'absent'] - - name: - required: true - description: - - The name of the aggregate to manage. - - disk_count: - description: - - Number of disks to place into the aggregate, including parity disks. - - The disks in this newly-created aggregate come from the spare disk pool. - - The smallest disks in this pool join the aggregate first, unless the C(disk-size) argument is provided. - - Either C(disk-count) or C(disks) must be supplied. Range [0..2^31-1]. - - Required when C(state=present). - -''' - -EXAMPLES = """ -- name: Manage Aggregates - community.general.na_cdot_aggregate: - state: present - name: ansibleAggr - disk_count: 1 - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - -- name: Manage Aggregates - community.general.na_cdot_aggregate: - state: present - name: ansibleAggr - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppCDOTAggregate(object): - - def __init__(self): - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - disk_count=dict(required=False, type='int'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('state', 'present', ['disk_count']) - ], - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - self.disk_count = p['disk_count'] - - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_ontap_zapi(module=self.module) - - def get_aggr(self): - """ - Checks if aggregate exists. - - :return: - True if aggregate found - False if aggregate is not found - :rtype: bool - """ - - aggr_get_iter = netapp_utils.zapi.NaElement('aggr-get-iter') - query_details = netapp_utils.zapi.NaElement.create_node_with_children( - 'aggr-attributes', **{'aggregate-name': self.name}) - - query = netapp_utils.zapi.NaElement('query') - query.add_child_elem(query_details) - aggr_get_iter.add_child_elem(query) - - try: - result = self.server.invoke_successfully(aggr_get_iter, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - # Error 13040 denotes an aggregate not being found. - if to_native(e.code) == "13040": - return False - else: - self.module.fail_json(msg=to_native(e), exception=traceback.format_exc()) - - if (result.get_child_by_name('num-records') and - int(result.get_child_content('num-records')) >= 1): - return True - else: - return False - - def create_aggr(self): - aggr_create = netapp_utils.zapi.NaElement.create_node_with_children( - 'aggr-create', **{'aggregate': self.name, - 'disk-count': str(self.disk_count)}) - - try: - self.server.invoke_successfully(aggr_create, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error provisioning aggregate %s: %s" % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def delete_aggr(self): - aggr_destroy = netapp_utils.zapi.NaElement.create_node_with_children( - 'aggr-destroy', **{'aggregate': self.name}) - - try: - self.server.invoke_successfully(aggr_destroy, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error removing aggregate %s: %s" % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def rename_aggregate(self): - aggr_rename = netapp_utils.zapi.NaElement.create_node_with_children( - 'aggr-rename', **{'aggregate': self.name, - 'new-aggregate-name': - self.name}) - - try: - self.server.invoke_successfully(aggr_rename, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error renaming aggregate %s: %s" % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def apply(self): - changed = False - aggregate_exists = self.get_aggr() - rename_aggregate = False - - # check if anything needs to be changed (add/delete/update) - - if aggregate_exists: - if self.state == 'absent': - changed = True - - elif self.state == 'present': - if self.name is not None and not self.name == self.name: - rename_aggregate = True - changed = True - - else: - if self.state == 'present': - # Aggregate does not exist, but requested state is present. - changed = True - - if changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not aggregate_exists: - self.create_aggr() - - else: - if rename_aggregate: - self.rename_aggregate() - - elif self.state == 'absent': - self.delete_aggr() - - self.module.exit_json(changed=changed) - - -def main(): - v = NetAppCDOTAggregate() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/na_cdot_license.py b/plugins/modules/storage/netapp/na_cdot_license.py deleted file mode 100644 index 36c5416a3b..0000000000 --- a/plugins/modules/storage/netapp/na_cdot_license.py +++ /dev/null @@ -1,296 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: na_cdot_license - -short_description: Manage NetApp cDOT protocol and feature licenses -extends_documentation_fragment: -- community.general._netapp.ontap - -author: Sumit Kumar (@timuster) - -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: Updated modules released with increased functionality - alternative: Use M(netapp.ontap.na_ontap_license) instead. - -description: -- Add or remove licenses on NetApp ONTAP. - -options: - - remove_unused: - description: - - Remove licenses that have no controller affiliation in the cluster. - type: bool - default: false - - remove_expired: - description: - - Remove licenses that have expired in the cluster. - type: bool - default: false - - serial_number: - description: - - Serial number of the node associated with the license. - - This parameter is used primarily when removing license for a specific service. - - If this parameter is not provided, the cluster serial number is used by default. - - licenses: - description: - - List of licenses to add or remove. - - Please note that trying to remove a non-existent license will throw an error. - suboptions: - base: - description: - - Cluster Base License - nfs: - description: - - NFS License - cifs: - description: - - CIFS License - iscsi: - description: - - iSCSI License - fcp: - description: - - FCP License - cdmi: - description: - - CDMI License - snaprestore: - description: - - SnapRestore License - snapmirror: - description: - - SnapMirror License - flexclone: - description: - - FlexClone License - snapvault: - description: - - SnapVault License - snaplock: - description: - - SnapLock License - snapmanagersuite: - description: - - SnapManagerSuite License - snapprotectapps: - description: - - SnapProtectApp License - v_storageattach: - description: - - Virtual Attached Storage License - -''' - - -EXAMPLES = """ -- name: Add licenses - community.general.na_cdot_license: - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - serial_number: ################# - licenses: - nfs: ################# - cifs: ################# - iscsi: ################# - fcp: ################# - snaprestore: ################# - flexclone: ################# - -- name: Remove licenses - community.general.na_cdot_license: - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - remove_unused: false - remove_expired: true - serial_number: ################# - licenses: - nfs: remove -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppCDOTLicense(object): - - def __init__(self): - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - serial_number=dict(required=False, type='str', default=None), - remove_unused=dict(default=False, type='bool'), - remove_expired=dict(default=False, type='bool'), - licenses=dict(default=False, type='dict'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - supports_check_mode=False - ) - - p = self.module.params - - # set up state variables - self.serial_number = p['serial_number'] - self.remove_unused = p['remove_unused'] - self.remove_expired = p['remove_expired'] - self.licenses = p['licenses'] - - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_ontap_zapi(module=self.module) - - def get_licensing_status(self): - """ - Check licensing status - - :return: package (key) and licensing status (value) - :rtype: dict - """ - license_status = netapp_utils.zapi.NaElement('license-v2-status-list-info') - result = None - try: - result = self.server.invoke_successfully(license_status, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error checking license status: %s" % - to_native(e), exception=traceback.format_exc()) - - return_dictionary = {} - license_v2_status = result.get_child_by_name('license-v2-status') - if license_v2_status: - for license_v2_status_info in license_v2_status.get_children(): - package = license_v2_status_info.get_child_content('package') - status = license_v2_status_info.get_child_content('method') - return_dictionary[package] = status - - return return_dictionary - - def remove_licenses(self, remove_list): - """ - Remove requested licenses - :param: - remove_list : List of packages to remove - - """ - license_delete = netapp_utils.zapi.NaElement('license-v2-delete') - for package in remove_list: - license_delete.add_new_child('package', package) - - if self.serial_number is not None: - license_delete.add_new_child('serial-number', self.serial_number) - - try: - self.server.invoke_successfully(license_delete, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error removing license %s" % - to_native(e), exception=traceback.format_exc()) - - def remove_unused_licenses(self): - """ - Remove unused licenses - """ - remove_unused = netapp_utils.zapi.NaElement('license-v2-delete-unused') - try: - self.server.invoke_successfully(remove_unused, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error removing unused licenses: %s" % - to_native(e), exception=traceback.format_exc()) - - def remove_expired_licenses(self): - """ - Remove expired licenses - """ - remove_expired = netapp_utils.zapi.NaElement('license-v2-delete-expired') - try: - self.server.invoke_successfully(remove_expired, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error removing expired licenses: %s" % - to_native(e), exception=traceback.format_exc()) - - def update_licenses(self): - """ - Update licenses - """ - # Remove unused and expired licenses, if requested. - if self.remove_unused: - self.remove_unused_licenses() - - if self.remove_expired: - self.remove_expired_licenses() - - # Next, add/remove specific requested licenses. - license_add = netapp_utils.zapi.NaElement('license-v2-add') - codes = netapp_utils.zapi.NaElement('codes') - remove_list = [] - for key, value in self.licenses.items(): - str_value = str(value) - # Make sure license is not an empty string. - if str_value and str_value.strip(): - if str_value.lower() == 'remove': - remove_list.append(str(key).lower()) - else: - codes.add_new_child('license-code-v2', str_value) - - # Remove requested licenses. - if len(remove_list) != 0: - self.remove_licenses(remove_list) - - # Add requested licenses - if len(codes.get_children()) != 0: - license_add.add_child_elem(codes) - try: - self.server.invoke_successfully(license_add, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error adding licenses: %s" % - to_native(e), exception=traceback.format_exc()) - - def apply(self): - changed = False - # Add / Update licenses. - license_status = self.get_licensing_status() - self.update_licenses() - new_license_status = self.get_licensing_status() - - if license_status != new_license_status: - changed = True - - self.module.exit_json(changed=changed) - - -def main(): - v = NetAppCDOTLicense() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/na_cdot_lun.py b/plugins/modules/storage/netapp/na_cdot_lun.py deleted file mode 100644 index 3236dbeeb5..0000000000 --- a/plugins/modules/storage/netapp/na_cdot_lun.py +++ /dev/null @@ -1,373 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: na_cdot_lun - -short_description: Manage NetApp cDOT luns -extends_documentation_fragment: -- community.general._netapp.ontap - -author: Sumit Kumar (@timuster) - -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: Updated modules released with increased functionality - alternative: Use M(netapp.ontap.na_ontap_lun) instead. - -description: -- Create, destroy, resize luns on NetApp cDOT. - -options: - - state: - description: - - Whether the specified lun should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - The name of the lun to manage. - required: true - - flexvol_name: - description: - - The name of the FlexVol the lun should exist on. - - Required when C(state=present). - - size: - description: - - The size of the lun in C(size_unit). - - Required when C(state=present). - - size_unit: - description: - - The unit used to interpret the size parameter. - choices: ['bytes', 'b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'] - default: 'gb' - - force_resize: - description: - - Forcibly reduce the size. This is required for reducing the size of the LUN to avoid accidentally reducing the LUN size. - default: false - - force_remove: - description: - - If "true", override checks that prevent a LUN from being destroyed if it is online and mapped. - - If "false", destroying an online and mapped LUN will fail. - default: false - - force_remove_fenced: - description: - - If "true", override checks that prevent a LUN from being destroyed while it is fenced. - - If "false", attempting to destroy a fenced LUN will fail. - - The default if not specified is "false". This field is available in Data ONTAP 8.2 and later. - default: false - - vserver: - required: true - description: - - The name of the vserver to use. - -''' - -EXAMPLES = """ -- name: Create LUN - community.general.na_cdot_lun: - state: present - name: ansibleLUN - flexvol_name: ansibleVolume - vserver: ansibleVServer - size: 5 - size_unit: mb - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - -- name: Resize Lun - community.general.na_cdot_lun: - state: present - name: ansibleLUN - force_resize: True - flexvol_name: ansibleVolume - vserver: ansibleVServer - size: 5 - size_unit: gb - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppCDOTLUN(object): - - def __init__(self): - - self._size_unit_map = dict( - bytes=1, - b=1, - kb=1024, - mb=1024 ** 2, - gb=1024 ** 3, - tb=1024 ** 4, - pb=1024 ** 5, - eb=1024 ** 6, - zb=1024 ** 7, - yb=1024 ** 8 - ) - - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - size=dict(type='int'), - size_unit=dict(default='gb', - choices=['bytes', 'b', 'kb', 'mb', 'gb', 'tb', - 'pb', 'eb', 'zb', 'yb'], type='str'), - force_resize=dict(default=False, type='bool'), - force_remove=dict(default=False, type='bool'), - force_remove_fenced=dict(default=False, type='bool'), - flexvol_name=dict(type='str'), - vserver=dict(required=True, type='str'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('state', 'present', ['flexvol_name', 'size']) - ], - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - self.size_unit = p['size_unit'] - if p['size'] is not None: - self.size = p['size'] * self._size_unit_map[self.size_unit] - else: - self.size = None - self.force_resize = p['force_resize'] - self.force_remove = p['force_remove'] - self.force_remove_fenced = p['force_remove_fenced'] - self.flexvol_name = p['flexvol_name'] - self.vserver = p['vserver'] - - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_ontap_zapi(module=self.module, vserver=self.vserver) - - def get_lun(self): - """ - Return details about the LUN - - :return: Details about the lun - :rtype: dict - """ - - luns = [] - tag = None - while True: - lun_info = netapp_utils.zapi.NaElement('lun-get-iter') - if tag: - lun_info.add_new_child('tag', tag, True) - - query_details = netapp_utils.zapi.NaElement('lun-info') - query_details.add_new_child('vserver', self.vserver) - query_details.add_new_child('volume', self.flexvol_name) - - query = netapp_utils.zapi.NaElement('query') - query.add_child_elem(query_details) - - lun_info.add_child_elem(query) - - result = self.server.invoke_successfully(lun_info, True) - if result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) >= 1: - attr_list = result.get_child_by_name('attributes-list') - luns.extend(attr_list.get_children()) - - tag = result.get_child_content('next-tag') - - if tag is None: - break - - # The LUNs have been extracted. - # Find the specified lun and extract details. - return_value = None - for lun in luns: - path = lun.get_child_content('path') - _rest, _splitter, found_name = path.rpartition('/') - - if found_name == self.name: - size = lun.get_child_content('size') - - # Find out if the lun is attached - attached_to = None - lun_id = None - if lun.get_child_content('mapped') == 'true': - lun_map_list = netapp_utils.zapi.NaElement.create_node_with_children( - 'lun-map-list-info', **{'path': path}) - - result = self.server.invoke_successfully( - lun_map_list, enable_tunneling=True) - - igroups = result.get_child_by_name('initiator-groups') - if igroups: - for igroup_info in igroups.get_children(): - igroup = igroup_info.get_child_content( - 'initiator-group-name') - attached_to = igroup - lun_id = igroup_info.get_child_content('lun-id') - - return_value = { - 'name': found_name, - 'size': size, - 'attached_to': attached_to, - 'lun_id': lun_id - } - else: - continue - - return return_value - - def create_lun(self): - """ - Create LUN with requested name and size - """ - path = '/vol/%s/%s' % (self.flexvol_name, self.name) - lun_create = netapp_utils.zapi.NaElement.create_node_with_children( - 'lun-create-by-size', **{'path': path, - 'size': str(self.size), - 'ostype': 'linux'}) - - try: - self.server.invoke_successfully(lun_create, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error provisioning lun %s of size %s: %s" % (self.name, self.size, to_native(e)), - exception=traceback.format_exc()) - - def delete_lun(self): - """ - Delete requested LUN - """ - path = '/vol/%s/%s' % (self.flexvol_name, self.name) - - lun_delete = netapp_utils.zapi.NaElement.create_node_with_children( - 'lun-destroy', **{'path': path, - 'force': str(self.force_remove), - 'destroy-fenced-lun': - str(self.force_remove_fenced)}) - - try: - self.server.invoke_successfully(lun_delete, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error deleting lun %s: %s" % (path, to_native(e)), - exception=traceback.format_exc()) - - def resize_lun(self): - """ - Resize requested LUN. - - :return: True if LUN was actually re-sized, false otherwise. - :rtype: bool - """ - path = '/vol/%s/%s' % (self.flexvol_name, self.name) - - lun_resize = netapp_utils.zapi.NaElement.create_node_with_children( - 'lun-resize', **{'path': path, - 'size': str(self.size), - 'force': str(self.force_resize)}) - try: - self.server.invoke_successfully(lun_resize, enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - if to_native(e.code) == "9042": - # Error 9042 denotes the new LUN size being the same as the - # old LUN size. This happens when there's barely any difference - # in the two sizes. For example, from 8388608 bytes to - # 8194304 bytes. This should go away if/when the default size - # requested/reported to/from the controller is changed to a - # larger unit (MB/GB/TB). - return False - else: - self.module.fail_json(msg="Error resizing lun %s: %s" % (path, to_native(e)), - exception=traceback.format_exc()) - - return True - - def apply(self): - property_changed = False - multiple_properties_changed = False - size_changed = False - lun_exists = False - lun_detail = self.get_lun() - - if lun_detail: - lun_exists = True - current_size = lun_detail['size'] - - if self.state == 'absent': - property_changed = True - - elif self.state == 'present': - if not int(current_size) == self.size: - size_changed = True - property_changed = True - - else: - if self.state == 'present': - property_changed = True - - if property_changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not lun_exists: - self.create_lun() - - else: - if size_changed: - # Ensure that size was actually changed. Please - # read notes in 'resize_lun' function for details. - size_changed = self.resize_lun() - if not size_changed and not \ - multiple_properties_changed: - property_changed = False - - elif self.state == 'absent': - self.delete_lun() - - changed = property_changed or size_changed - # TODO: include other details about the lun (size, etc.) - self.module.exit_json(changed=changed) - - -def main(): - v = NetAppCDOTLUN() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/na_cdot_qtree.py b/plugins/modules/storage/netapp/na_cdot_qtree.py deleted file mode 100644 index 9f7ce60d0a..0000000000 --- a/plugins/modules/storage/netapp/na_cdot_qtree.py +++ /dev/null @@ -1,234 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: na_cdot_qtree - -short_description: Manage qtrees -extends_documentation_fragment: -- community.general._netapp.ontap - -author: Sumit Kumar (@timuster) - -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: Updated modules released with increased functionality - alternative: Use M(netapp.ontap.na_ontap_qtree) instead. - -description: -- Create or destroy Qtrees. - -options: - - state: - description: - - Whether the specified Qtree should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - The name of the Qtree to manage. - required: true - - flexvol_name: - description: - - The name of the FlexVol the Qtree should exist on. Required when C(state=present). - - vserver: - description: - - The name of the vserver to use. - required: true - -''' - -EXAMPLES = """ -- name: Create QTree - community.general.na_cdot_qtree: - state: present - name: ansibleQTree - flexvol_name: ansibleVolume - vserver: ansibleVServer - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - -- name: Rename QTree - community.general.na_cdot_qtree: - state: present - name: ansibleQTree - flexvol_name: ansibleVolume - vserver: ansibleVServer - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppCDOTQTree(object): - - def __init__(self): - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - flexvol_name=dict(type='str'), - vserver=dict(required=True, type='str'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('state', 'present', ['flexvol_name']) - ], - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - self.flexvol_name = p['flexvol_name'] - self.vserver = p['vserver'] - - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_ontap_zapi(module=self.module, vserver=self.vserver) - - def get_qtree(self): - """ - Checks if the qtree exists. - - :return: - True if qtree found - False if qtree is not found - :rtype: bool - """ - - qtree_list_iter = netapp_utils.zapi.NaElement('qtree-list-iter') - query_details = netapp_utils.zapi.NaElement.create_node_with_children( - 'qtree-info', **{'vserver': self.vserver, - 'volume': self.flexvol_name, - 'qtree': self.name}) - - query = netapp_utils.zapi.NaElement('query') - query.add_child_elem(query_details) - qtree_list_iter.add_child_elem(query) - - result = self.server.invoke_successfully(qtree_list_iter, - enable_tunneling=True) - - if (result.get_child_by_name('num-records') and - int(result.get_child_content('num-records')) >= 1): - return True - else: - return False - - def create_qtree(self): - qtree_create = netapp_utils.zapi.NaElement.create_node_with_children( - 'qtree-create', **{'volume': self.flexvol_name, - 'qtree': self.name}) - - try: - self.server.invoke_successfully(qtree_create, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error provisioning qtree %s: %s" % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def delete_qtree(self): - path = '/vol/%s/%s' % (self.flexvol_name, self.name) - qtree_delete = netapp_utils.zapi.NaElement.create_node_with_children( - 'qtree-delete', **{'qtree': path}) - - try: - self.server.invoke_successfully(qtree_delete, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error deleting qtree %s: %s" % (path, to_native(e)), - exception=traceback.format_exc()) - - def rename_qtree(self): - path = '/vol/%s/%s' % (self.flexvol_name, self.name) - new_path = '/vol/%s/%s' % (self.flexvol_name, self.name) - qtree_rename = netapp_utils.zapi.NaElement.create_node_with_children( - 'qtree-rename', **{'qtree': path, - 'new-qtree-name': new_path}) - - try: - self.server.invoke_successfully(qtree_rename, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg="Error renaming qtree %s: %s" % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def apply(self): - changed = False - qtree_exists = False - rename_qtree = False - qtree_detail = self.get_qtree() - - if qtree_detail: - qtree_exists = True - - if self.state == 'absent': - # Qtree exists, but requested state is 'absent'. - changed = True - - elif self.state == 'present': - if self.name is not None and not self.name == \ - self.name: - changed = True - rename_qtree = True - - else: - if self.state == 'present': - # Qtree does not exist, but requested state is 'present'. - changed = True - - if changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not qtree_exists: - self.create_qtree() - - else: - if rename_qtree: - self.rename_qtree() - - elif self.state == 'absent': - self.delete_qtree() - - self.module.exit_json(changed=changed) - - -def main(): - v = NetAppCDOTQTree() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/na_cdot_svm.py b/plugins/modules/storage/netapp/na_cdot_svm.py deleted file mode 100644 index 0227a014fa..0000000000 --- a/plugins/modules/storage/netapp/na_cdot_svm.py +++ /dev/null @@ -1,246 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: na_cdot_svm - -short_description: Manage NetApp cDOT svm -extends_documentation_fragment: -- community.general._netapp.ontap - -author: Sumit Kumar (@timuster) - -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: Updated modules released with increased functionality - alternative: Use M(netapp.ontap.na_ontap_svm) instead. - -description: -- Create or destroy svm on NetApp cDOT - -options: - - state: - description: - - Whether the specified SVM should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - The name of the SVM to manage. - required: true - - root_volume: - description: - - Root volume of the SVM. Required when C(state=present). - - root_volume_aggregate: - description: - - The aggregate on which the root volume will be created. - - Required when C(state=present). - - root_volume_security_style: - description: - - Security Style of the root volume. - - When specified as part of the vserver-create, this field represents the security style for the Vserver root volume. - - When specified as part of vserver-get-iter call, this will return the list of matching Vservers. - - Possible values are 'unix', 'ntfs', 'mixed'. - - The 'unified' security style, which applies only to Infinite Volumes, cannot be applied to a Vserver's root volume. - - Valid options are "unix" for NFS, "ntfs" for CIFS, "mixed" for Mixed, "unified" for Unified. - - Required when C(state=present) - choices: ['unix', 'ntfs', 'mixed', 'unified'] - -''' - -EXAMPLES = """ - - - name: Create SVM - community.general.na_cdot_svm: - state: present - name: ansibleVServer - root_volume: vol1 - root_volume_aggregate: aggr1 - root_volume_security_style: mixed - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppCDOTSVM(object): - - def __init__(self): - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - root_volume=dict(type='str'), - root_volume_aggregate=dict(type='str'), - root_volume_security_style=dict(type='str', choices=['unix', - 'ntfs', - 'mixed', - 'unified' - ]), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('state', 'present', ['root_volume', - 'root_volume_aggregate', - 'root_volume_security_style']) - ], - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - self.root_volume = p['root_volume'] - self.root_volume_aggregate = p['root_volume_aggregate'] - self.root_volume_security_style = p['root_volume_security_style'] - - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_ontap_zapi(module=self.module) - - def get_vserver(self): - """ - Checks if vserver exists. - - :return: - True if vserver found - False if vserver is not found - :rtype: bool - """ - - vserver_info = netapp_utils.zapi.NaElement('vserver-get-iter') - query_details = netapp_utils.zapi.NaElement.create_node_with_children( - 'vserver-info', **{'vserver-name': self.name}) - - query = netapp_utils.zapi.NaElement('query') - query.add_child_elem(query_details) - vserver_info.add_child_elem(query) - - result = self.server.invoke_successfully(vserver_info, - enable_tunneling=False) - - if (result.get_child_by_name('num-records') and - int(result.get_child_content('num-records')) >= 1): - - """ - TODO: - Return more relevant parameters about vserver that can - be updated by the playbook. - """ - return True - else: - return False - - def create_vserver(self): - vserver_create = netapp_utils.zapi.NaElement.create_node_with_children( - 'vserver-create', **{'vserver-name': self.name, - 'root-volume': self.root_volume, - 'root-volume-aggregate': - self.root_volume_aggregate, - 'root-volume-security-style': - self.root_volume_security_style - }) - - try: - self.server.invoke_successfully(vserver_create, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error provisioning SVM %s with root volume %s on aggregate %s: %s' - % (self.name, self.root_volume, self.root_volume_aggregate, to_native(e)), - exception=traceback.format_exc()) - - def delete_vserver(self): - vserver_delete = netapp_utils.zapi.NaElement.create_node_with_children( - 'vserver-destroy', **{'vserver-name': self.name}) - - try: - self.server.invoke_successfully(vserver_delete, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error deleting SVM %s with root volume %s on aggregate %s: %s' - % (self.name, self.root_volume, self.root_volume_aggregate, to_native(e)), - exception=traceback.format_exc()) - - def rename_vserver(self): - vserver_rename = netapp_utils.zapi.NaElement.create_node_with_children( - 'vserver-rename', **{'vserver-name': self.name, - 'new-name': self.name}) - - try: - self.server.invoke_successfully(vserver_rename, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error renaming SVM %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def apply(self): - changed = False - vserver_exists = self.get_vserver() - rename_vserver = False - if vserver_exists: - if self.state == 'absent': - changed = True - - elif self.state == 'present': - # Update properties - pass - - else: - if self.state == 'present': - changed = True - - if changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not vserver_exists: - self.create_vserver() - - else: - if rename_vserver: - self.rename_vserver() - - elif self.state == 'absent': - self.delete_vserver() - - self.module.exit_json(changed=changed) - - -def main(): - v = NetAppCDOTSVM() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/na_cdot_user.py b/plugins/modules/storage/netapp/na_cdot_user.py deleted file mode 100644 index 626e0aa04c..0000000000 --- a/plugins/modules/storage/netapp/na_cdot_user.py +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: na_cdot_user - -short_description: useradmin configuration and management -extends_documentation_fragment: -- community.general._netapp.ontap - -author: Sumit Kumar (@timuster) - -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: Updated modules released with increased functionality - alternative: Use M(netapp.ontap.na_ontap_user) instead. - -description: -- Create or destroy users. - -options: - - state: - description: - - Whether the specified user should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - The name of the user to manage. - required: true - - application: - description: - - Applications to grant access to. - required: true - choices: ['console', 'http','ontapi','rsh','snmp','sp','ssh','telnet'] - - authentication_method: - description: - - Authentication method for the application. - - Not all authentication methods are valid for an application. - - Valid authentication methods for each application are as denoted in I(authentication_choices_description). - - password for console application - - password, domain, nsswitch, cert for http application. - - password, domain, nsswitch, cert for ontapi application. - - community for snmp application (when creating SNMPv1 and SNMPv2 users). - - usm and community for snmp application (when creating SNMPv3 users). - - password for sp application. - - password for rsh application. - - password for telnet application. - - password, publickey, domain, nsswitch for ssh application. - required: true - choices: ['community', 'password', 'publickey', 'domain', 'nsswitch', 'usm'] - - set_password: - description: - - Password for the user account. - - It is ignored for creating snmp users, but is required for creating non-snmp users. - - For an existing user, this value will be used as the new password. - - role_name: - description: - - The name of the role. Required when C(state=present) - - - vserver: - description: - - The name of the vserver to use. - required: true - -''' - -EXAMPLES = """ - - - name: Create User - community.general.na_cdot_user: - state: present - name: SampleUser - application: ssh - authentication_method: password - set_password: apn1242183u1298u41 - role_name: vsadmin - vserver: ansibleVServer - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppCDOTUser(object): - """ - Common operations to manage users and roles. - """ - - def __init__(self): - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - - application=dict(required=True, type='str', choices=[ - 'console', 'http', 'ontapi', 'rsh', - 'snmp', 'sp', 'ssh', 'telnet']), - authentication_method=dict(required=True, type='str', - choices=['community', 'password', - 'publickey', 'domain', - 'nsswitch', 'usm']), - set_password=dict(required=False, type='str', default=None), - role_name=dict(required=False, type='str'), - - vserver=dict(required=True, type='str'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('state', 'present', ['role_name']) - ], - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - - self.application = p['application'] - self.authentication_method = p['authentication_method'] - self.set_password = p['set_password'] - self.role_name = p['role_name'] - - self.vserver = p['vserver'] - - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_ontap_zapi(module=self.module) - - def get_user(self): - """ - Checks if the user exists. - - :return: - True if user found - False if user is not found - :rtype: bool - """ - - security_login_get_iter = netapp_utils.zapi.NaElement('security-login-get-iter') - query_details = netapp_utils.zapi.NaElement.create_node_with_children( - 'security-login-account-info', **{'vserver': self.vserver, - 'user-name': self.name, - 'application': self.application, - 'authentication-method': - self.authentication_method}) - - query = netapp_utils.zapi.NaElement('query') - query.add_child_elem(query_details) - security_login_get_iter.add_child_elem(query) - - try: - result = self.server.invoke_successfully(security_login_get_iter, - enable_tunneling=False) - - if result.get_child_by_name('num-records') and int(result.get_child_content('num-records')) >= 1: - return True - else: - return False - - except netapp_utils.zapi.NaApiError as e: - # Error 16034 denotes a user not being found. - if to_native(e.code) == "16034": - return False - else: - self.module.fail_json(msg='Error getting user %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def create_user(self): - user_create = netapp_utils.zapi.NaElement.create_node_with_children( - 'security-login-create', **{'vserver': self.vserver, - 'user-name': self.name, - 'application': self.application, - 'authentication-method': - self.authentication_method, - 'role-name': self.role_name}) - if self.set_password is not None: - user_create.add_new_child('password', self.set_password) - - try: - self.server.invoke_successfully(user_create, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error creating user %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def delete_user(self): - user_delete = netapp_utils.zapi.NaElement.create_node_with_children( - 'security-login-delete', **{'vserver': self.vserver, - 'user-name': self.name, - 'application': self.application, - 'authentication-method': - self.authentication_method}) - - try: - self.server.invoke_successfully(user_delete, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error removing user %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def change_password(self): - """ - Changes the password - - :return: - True if password updated - False if password is not updated - :rtype: bool - """ - self.server.set_vserver(self.vserver) - modify_password = netapp_utils.zapi.NaElement.create_node_with_children( - 'security-login-modify-password', **{ - 'new-password': str(self.set_password), - 'user-name': self.name}) - try: - self.server.invoke_successfully(modify_password, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - if to_native(e.code) == '13114': - return False - else: - self.module.fail_json(msg='Error setting password for user %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - self.server.set_vserver(None) - return True - - def apply(self): - property_changed = False - password_changed = False - user_exists = self.get_user() - - if user_exists: - if self.state == 'absent': - property_changed = True - - elif self.state == 'present': - if self.set_password is not None: - password_changed = self.change_password() - else: - if self.state == 'present': - # Check if anything needs to be updated - property_changed = True - - if property_changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not user_exists: - self.create_user() - - # Add ability to update parameters. - - elif self.state == 'absent': - self.delete_user() - - changed = property_changed or password_changed - self.module.exit_json(changed=changed) - - -def main(): - v = NetAppCDOTUser() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/na_cdot_user_role.py b/plugins/modules/storage/netapp/na_cdot_user_role.py deleted file mode 100644 index 8813320036..0000000000 --- a/plugins/modules/storage/netapp/na_cdot_user_role.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: na_cdot_user_role - -short_description: useradmin configuration and management -extends_documentation_fragment: -- community.general._netapp.ontap - -author: Sumit Kumar (@timuster) - -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: Updated modules released with increased functionality - alternative: Use M(netapp.ontap.na_ontap_user_role) instead. - -description: -- Create or destroy user roles - -options: - - state: - description: - - Whether the specified user should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - The name of the role to manage. - required: true - - command_directory_name: - description: - - The command or command directory to which the role has an access. - required: true - - access_level: - description: - - The name of the role to manage. - choices: ['none', 'readonly', 'all'] - default: 'all' - - vserver: - description: - - The name of the vserver to use. - required: true - -''' - -EXAMPLES = """ - - - name: Create User Role - community.general.na_cdot_user_role: - state: present - name: ansibleRole - command_directory_name: DEFAULT - access_level: none - vserver: ansibleVServer - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppCDOTUserRole(object): - - def __init__(self): - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - - command_directory_name=dict(required=True, type='str'), - access_level=dict(required=False, type='str', default='all', - choices=['none', 'readonly', 'all']), - - vserver=dict(required=True, type='str'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - - self.command_directory_name = p['command_directory_name'] - self.access_level = p['access_level'] - - self.vserver = p['vserver'] - - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_ontap_zapi(module=self.module) - - def get_role(self): - """ - Checks if the role exists for specific command-directory-name. - - :return: - True if role found - False if role is not found - :rtype: bool - """ - - security_login_role_get_iter = netapp_utils.zapi.NaElement( - 'security-login-role-get-iter') - query_details = netapp_utils.zapi.NaElement.create_node_with_children( - 'security-login-role-info', **{'vserver': self.vserver, - 'role-name': self.name, - 'command-directory-name': - self.command_directory_name}) - - query = netapp_utils.zapi.NaElement('query') - query.add_child_elem(query_details) - security_login_role_get_iter.add_child_elem(query) - - try: - result = self.server.invoke_successfully( - security_login_role_get_iter, enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - # Error 16031 denotes a role not being found. - if to_native(e.code) == "16031": - return False - else: - self.module.fail_json(msg='Error getting role %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - if (result.get_child_by_name('num-records') and - int(result.get_child_content('num-records')) >= 1): - return True - else: - return False - - def create_role(self): - role_create = netapp_utils.zapi.NaElement.create_node_with_children( - 'security-login-role-create', **{'vserver': self.vserver, - 'role-name': self.name, - 'command-directory-name': - self.command_directory_name, - 'access-level': - self.access_level}) - - try: - self.server.invoke_successfully(role_create, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error creating role %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def delete_role(self): - role_delete = netapp_utils.zapi.NaElement.create_node_with_children( - 'security-login-role-delete', **{'vserver': self.vserver, - 'role-name': self.name, - 'command-directory-name': - self.command_directory_name}) - - try: - self.server.invoke_successfully(role_delete, - enable_tunneling=False) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error removing role %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def apply(self): - changed = False - role_exists = self.get_role() - - if role_exists: - if self.state == 'absent': - changed = True - - # Check if properties need to be updated - else: - if self.state == 'present': - changed = True - - if changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not role_exists: - self.create_role() - - # Update properties - - elif self.state == 'absent': - self.delete_role() - - self.module.exit_json(changed=changed) - - -def main(): - v = NetAppCDOTUserRole() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/na_cdot_volume.py b/plugins/modules/storage/netapp/na_cdot_volume.py deleted file mode 100644 index c10911d406..0000000000 --- a/plugins/modules/storage/netapp/na_cdot_volume.py +++ /dev/null @@ -1,437 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: na_cdot_volume - -short_description: Manage NetApp cDOT volumes -extends_documentation_fragment: -- community.general._netapp.ontap - -author: Sumit Kumar (@timuster) - -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: Updated modules released with increased functionality - alternative: Use M(netapp.ontap.na_ontap_volume) instead. - -description: -- Create or destroy volumes on NetApp cDOT - -options: - - state: - description: - - Whether the specified volume should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - The name of the volume to manage. - required: true - - infinite: - description: - - Set True if the volume is an Infinite Volume. - type: bool - default: 'no' - - online: - description: - - Whether the specified volume is online, or not. - type: bool - default: 'yes' - - aggregate_name: - description: - - The name of the aggregate the flexvol should exist on. Required when C(state=present). - - size: - description: - - The size of the volume in (size_unit). Required when C(state=present). - - size_unit: - description: - - The unit used to interpret the size parameter. - choices: ['bytes', 'b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'] - default: 'gb' - - vserver: - description: - - Name of the vserver to use. - required: true - - junction_path: - description: - - Junction path where to mount the volume - required: false - - export_policy: - description: - - Export policy to set for the specified junction path. - required: false - default: default - - snapshot_policy: - description: - - Snapshot policy to set for the specified volume. - required: false - default: default - -''' - -EXAMPLES = """ - - - name: Create FlexVol - community.general.na_cdot_volume: - state: present - name: ansibleVolume - infinite: False - aggregate_name: aggr1 - size: 20 - size_unit: mb - vserver: ansibleVServer - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - junction_path: /ansibleVolume - export_policy: all_nfs_networks - snapshot_policy: daily - - - name: Make FlexVol offline - community.general.na_cdot_volume: - state: present - name: ansibleVolume - infinite: False - online: False - vserver: ansibleVServer - hostname: "{{ netapp_hostname }}" - username: "{{ netapp_username }}" - password: "{{ netapp_password }}" - -""" - -RETURN = """ - - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_NETAPP_LIB = netapp_utils.has_netapp_lib() - - -class NetAppCDOTVolume(object): - - def __init__(self): - - self._size_unit_map = dict( - bytes=1, - b=1, - kb=1024, - mb=1024 ** 2, - gb=1024 ** 3, - tb=1024 ** 4, - pb=1024 ** 5, - eb=1024 ** 6, - zb=1024 ** 7, - yb=1024 ** 8 - ) - - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - is_infinite=dict(required=False, type='bool', default=False, aliases=['infinite']), - is_online=dict(required=False, type='bool', default=True, aliases=['online']), - size=dict(type='int'), - size_unit=dict(default='gb', - choices=['bytes', 'b', 'kb', 'mb', 'gb', 'tb', - 'pb', 'eb', 'zb', 'yb'], type='str'), - aggregate_name=dict(type='str'), - vserver=dict(required=True, type='str', default=None), - junction_path=dict(required=False, type='str', default=None), - export_policy=dict(required=False, type='str', default='default'), - snapshot_policy=dict(required=False, type='str', default='default'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('state', 'present', ['aggregate_name', 'size']) - ], - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - self.is_infinite = p['is_infinite'] - self.is_online = p['is_online'] - self.size_unit = p['size_unit'] - self.vserver = p['vserver'] - self.junction_path = p['junction_path'] - self.export_policy = p['export_policy'] - self.snapshot_policy = p['snapshot_policy'] - - if p['size'] is not None: - self.size = p['size'] * self._size_unit_map[self.size_unit] - else: - self.size = None - self.aggregate_name = p['aggregate_name'] - - if HAS_NETAPP_LIB is False: - self.module.fail_json(msg="the python NetApp-Lib module is required") - else: - self.server = netapp_utils.setup_ontap_zapi(module=self.module, vserver=self.vserver) - - def get_volume(self): - """ - Return details about the volume - :param: - name : Name of the volume - - :return: Details about the volume. None if not found. - :rtype: dict - """ - volume_info = netapp_utils.zapi.NaElement('volume-get-iter') - volume_attributes = netapp_utils.zapi.NaElement('volume-attributes') - volume_id_attributes = netapp_utils.zapi.NaElement('volume-id-attributes') - volume_id_attributes.add_new_child('name', self.name) - volume_attributes.add_child_elem(volume_id_attributes) - - query = netapp_utils.zapi.NaElement('query') - query.add_child_elem(volume_attributes) - - volume_info.add_child_elem(query) - - result = self.server.invoke_successfully(volume_info, True) - - return_value = None - - if result.get_child_by_name('num-records') and \ - int(result.get_child_content('num-records')) >= 1: - - volume_attributes = result.get_child_by_name( - 'attributes-list').get_child_by_name( - 'volume-attributes') - # Get volume's current size - volume_space_attributes = volume_attributes.get_child_by_name( - 'volume-space-attributes') - current_size = volume_space_attributes.get_child_content('size') - - # Get volume's state (online/offline) - volume_state_attributes = volume_attributes.get_child_by_name( - 'volume-state-attributes') - current_state = volume_state_attributes.get_child_content('state') - is_online = None - if current_state == "online": - is_online = True - elif current_state == "offline": - is_online = False - return_value = { - 'name': self.name, - 'size': current_size, - 'is_online': is_online, - } - - return return_value - - def create_volume(self): - create_parameters = {'volume': self.name, - 'containing-aggr-name': self.aggregate_name, - 'size': str(self.size), - } - if self.junction_path: - create_parameters['junction-path'] = str(self.junction_path) - if self.export_policy != 'default': - create_parameters['export-policy'] = str(self.export_policy) - if self.snapshot_policy != 'default': - create_parameters['snapshot-policy'] = str(self.snapshot_policy) - - volume_create = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-create', **create_parameters) - - try: - self.server.invoke_successfully(volume_create, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error provisioning volume %s of size %s: %s' % (self.name, self.size, to_native(e)), - exception=traceback.format_exc()) - - def delete_volume(self): - if self.is_infinite: - volume_delete = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-destroy-async', **{'volume-name': self.name}) - else: - volume_delete = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-destroy', **{'name': self.name, 'unmount-and-offline': - 'true'}) - - try: - self.server.invoke_successfully(volume_delete, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error deleting volume %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def rename_volume(self): - """ - Rename the volume. - - Note: 'is_infinite' needs to be set to True in order to rename an - Infinite Volume. - """ - if self.is_infinite: - volume_rename = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-rename-async', - **{'volume-name': self.name, 'new-volume-name': str( - self.name)}) - else: - volume_rename = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-rename', **{'volume': self.name, 'new-volume-name': str( - self.name)}) - try: - self.server.invoke_successfully(volume_rename, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error renaming volume %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def resize_volume(self): - """ - Re-size the volume. - - Note: 'is_infinite' needs to be set to True in order to rename an - Infinite Volume. - """ - if self.is_infinite: - volume_resize = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-size-async', - **{'volume-name': self.name, 'new-size': str( - self.size)}) - else: - volume_resize = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-size', **{'volume': self.name, 'new-size': str( - self.size)}) - try: - self.server.invoke_successfully(volume_resize, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error re-sizing volume %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def change_volume_state(self): - """ - Change volume's state (offline/online). - - Note: 'is_infinite' needs to be set to True in order to change the - state of an Infinite Volume. - """ - state_requested = None - if self.is_online: - # Requested state is 'online'. - state_requested = "online" - if self.is_infinite: - volume_change_state = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-online-async', - **{'volume-name': self.name}) - else: - volume_change_state = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-online', - **{'name': self.name}) - else: - # Requested state is 'offline'. - state_requested = "offline" - if self.is_infinite: - volume_change_state = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-offline-async', - **{'volume-name': self.name}) - else: - volume_change_state = netapp_utils.zapi.NaElement.create_node_with_children( - 'volume-offline', - **{'name': self.name}) - try: - self.server.invoke_successfully(volume_change_state, - enable_tunneling=True) - except netapp_utils.zapi.NaApiError as e: - self.module.fail_json(msg='Error changing the state of volume %s to %s: %s' % - (self.name, state_requested, to_native(e)), - exception=traceback.format_exc()) - - def apply(self): - changed = False - volume_exists = False - rename_volume = False - resize_volume = False - volume_detail = self.get_volume() - - if volume_detail: - volume_exists = True - - if self.state == 'absent': - changed = True - - elif self.state == 'present': - if str(volume_detail['size']) != str(self.size): - resize_volume = True - changed = True - if (volume_detail['is_online'] is not None) and (volume_detail['is_online'] != self.is_online): - changed = True - if self.is_online is False: - # Volume is online, but requested state is offline - pass - else: - # Volume is offline but requested state is online - pass - - else: - if self.state == 'present': - changed = True - - if changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not volume_exists: - self.create_volume() - - else: - if resize_volume: - self.resize_volume() - if volume_detail['is_online'] is not \ - None and volume_detail['is_online'] != \ - self.is_online: - self.change_volume_state() - # Ensure re-naming is the last change made. - if rename_volume: - self.rename_volume() - - elif self.state == 'absent': - self.delete_volume() - - self.module.exit_json(changed=changed) - - -def main(): - v = NetAppCDOTVolume() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/sf_account_manager.py b/plugins/modules/storage/netapp/sf_account_manager.py deleted file mode 100644 index 58c6962b25..0000000000 --- a/plugins/modules/storage/netapp/sf_account_manager.py +++ /dev/null @@ -1,263 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: sf_account_manager -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: This Module has been replaced - alternative: please use M(netapp.elementsw.na_elementsw_account) -short_description: Manage SolidFire accounts -extends_documentation_fragment: -- community.general._netapp.solidfire - -author: Sumit Kumar (@timuster) -description: -- Create, destroy, or update accounts on SolidFire - -options: - - state: - description: - - Whether the specified account should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - Unique username for this account. (May be 1 to 64 characters in length). - required: true - - new_name: - description: - - New name for the user account. - - initiator_secret: - description: - - CHAP secret to use for the initiator. Should be 12-16 characters long and impenetrable. - - The CHAP initiator secrets must be unique and cannot be the same as the target CHAP secret. - - If not specified, a random secret is created. - - target_secret: - description: - - CHAP secret to use for the target (mutual CHAP authentication). - - Should be 12-16 characters long and impenetrable. - - The CHAP target secrets must be unique and cannot be the same as the initiator CHAP secret. - - If not specified, a random secret is created. - - attributes: - description: List of Name/Value pairs in JSON object format. - - account_id: - description: - - The ID of the account to manage or update. - - status: - description: - - Status of the account. - -''' - -EXAMPLES = """ -- name: Create Account - community.general.sf_account_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: present - name: TenantA - -- name: Modify Account - community.general.sf_account_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: present - name: TenantA - new_name: TenantA-Renamed - -- name: Delete Account - community.general.sf_account_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: absent - name: TenantA-Renamed -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_SF_SDK = netapp_utils.has_sf_sdk() - - -class SolidFireAccount(object): - - def __init__(self): - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - account_id=dict(required=False, type='int', default=None), - - new_name=dict(required=False, type='str', default=None), - initiator_secret=dict(required=False, type='str'), - target_secret=dict(required=False, type='str'), - attributes=dict(required=False, type='dict'), - status=dict(required=False, type='str'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - self.account_id = p['account_id'] - - self.new_name = p['new_name'] - self.initiator_secret = p['initiator_secret'] - self.target_secret = p['target_secret'] - self.attributes = p['attributes'] - self.status = p['status'] - - if HAS_SF_SDK is False: - self.module.fail_json(msg="Unable to import the SolidFire Python SDK") - else: - self.sfe = netapp_utils.create_sf_connection(module=self.module) - - def get_account(self): - """ - Return account object if found - - :return: Details about the account. None if not found. - :rtype: dict - """ - account_list = self.sfe.list_accounts() - - for account in account_list.accounts: - if account.username == self.name: - # Update self.account_id: - if self.account_id is not None: - if account.account_id == self.account_id: - return account - else: - self.account_id = account.account_id - return account - return None - - def create_account(self): - try: - self.sfe.add_account(username=self.name, - initiator_secret=self.initiator_secret, - target_secret=self.target_secret, - attributes=self.attributes) - except Exception as e: - self.module.fail_json(msg='Error creating account %s: %s)' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def delete_account(self): - try: - self.sfe.remove_account(account_id=self.account_id) - - except Exception as e: - self.module.fail_json(msg='Error deleting account %s: %s' % (self.account_id, to_native(e)), - exception=traceback.format_exc()) - - def update_account(self): - try: - self.sfe.modify_account(account_id=self.account_id, - username=self.new_name, - status=self.status, - initiator_secret=self.initiator_secret, - target_secret=self.target_secret, - attributes=self.attributes) - - except Exception as e: - self.module.fail_json(msg='Error updating account %s: %s' % (self.account_id, to_native(e)), - exception=traceback.format_exc()) - - def apply(self): - changed = False - account_exists = False - update_account = False - account_detail = self.get_account() - - if account_detail: - account_exists = True - - if self.state == 'absent': - changed = True - - elif self.state == 'present': - # Check if we need to update the account - - if account_detail.username is not None and self.new_name is not None and \ - account_detail.username != self.new_name: - update_account = True - changed = True - - elif account_detail.status is not None and self.status is not None \ - and account_detail.status != self.status: - update_account = True - changed = True - - elif account_detail.initiator_secret is not None and self.initiator_secret is not None \ - and account_detail.initiator_secret != self.initiator_secret: - update_account = True - changed = True - - elif account_detail.target_secret is not None and self.target_secret is not None \ - and account_detail.target_secret != self.target_secret: - update_account = True - changed = True - - elif account_detail.attributes is not None and self.attributes is not None \ - and account_detail.attributes != self.attributes: - update_account = True - changed = True - else: - if self.state == 'present': - changed = True - - if changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not account_exists: - self.create_account() - elif update_account: - self.update_account() - - elif self.state == 'absent': - self.delete_account() - - self.module.exit_json(changed=changed) - - -def main(): - v = SolidFireAccount() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/sf_check_connections.py b/plugins/modules/storage/netapp/sf_check_connections.py deleted file mode 100644 index cfe2483230..0000000000 --- a/plugins/modules/storage/netapp/sf_check_connections.py +++ /dev/null @@ -1,179 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: sf_check_connections -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: This Module has been replaced - alternative: please use M(netapp.elementsw.na_elementsw_check_connections) -short_description: Check connectivity to MVIP and SVIP. -extends_documentation_fragment: -- community.general._netapp.solidfire - -author: Sumit Kumar (@timuster) -description: -- Used to test the management connection to the cluster. -- The test pings the MVIP and SVIP, and executes a simple API method to verify connectivity. - -options: - - skip: - description: - - Skip checking connection to SVIP or MVIP. - choices: ['svip', 'mvip'] - - mvip: - description: - - Optionally, use to test connection of a different MVIP. - - This is not needed to test the connection to the target cluster. - - svip: - description: - - Optionally, use to test connection of a different SVIP. - - This is not needed to test the connection to the target cluster. - -''' - - -EXAMPLES = """ - - name: Check connections to MVIP and SVIP - community.general.sf_check_connections: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" -""" - -RETURN = """ - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_SF_SDK = netapp_utils.has_sf_sdk() - - -class SolidFireConnection(object): - - def __init__(self): - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - skip=dict(required=False, type='str', default=None, choices=['mvip', 'svip']), - mvip=dict(required=False, type='str', default=None), - svip=dict(required=False, type='str', default=None) - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.skip = p['skip'] - self.mvip = p['mvip'] - self.svip = p['svip'] - - if HAS_SF_SDK is False: - self.module.fail_json(msg="Unable to import the SolidFire Python SDK") - else: - self.sfe = netapp_utils.ElementFactory.create(p['hostname'], p['username'], p['password'], port=442) - - def check_mvip_connection(self): - """ - Check connection to MVIP - - :return: true if connection was successful, false otherwise. - :rtype: bool - """ - try: - test = self.sfe.test_connect_mvip(mvip=self.mvip) - result = test.details.connected - # Todo - Log details about the test - return result - - except Exception as e: - self.module.fail_json(msg='Error checking connection to MVIP: %s' % to_native(e), exception=traceback.format_exc()) - return False - - def check_svip_connection(self): - """ - Check connection to SVIP - - :return: true if connection was successful, false otherwise. - :rtype: bool - """ - try: - test = self.sfe.test_connect_svip(svip=self.svip) - result = test.details.connected - # Todo - Log details about the test - return result - - except Exception as e: - self.module.fail_json(msg='Error checking connection to SVIP: %s' % to_native(e), exception=traceback.format_exc()) - return False - - def check(self): - - failed = True - msg = '' - - if self.skip is None: - mvip_connection_established = self.check_mvip_connection() - svip_connection_established = self.check_svip_connection() - - # Set failed and msg - if not mvip_connection_established: - failed = True - msg = 'Connection to MVIP failed.' - elif not svip_connection_established: - failed = True - msg = 'Connection to SVIP failed.' - else: - failed = False - - elif self.skip == 'mvip': - svip_connection_established = self.check_svip_connection() - - # Set failed and msg - if not svip_connection_established: - failed = True - msg = 'Connection to SVIP failed.' - else: - failed = False - - elif self.skip == 'svip': - mvip_connection_established = self.check_mvip_connection() - - # Set failed and msg - if not mvip_connection_established: - failed = True - msg = 'Connection to MVIP failed.' - else: - failed = False - - if failed: - self.module.fail_json(msg=msg) - else: - self.module.exit_json() - - -def main(): - v = SolidFireConnection() - v.check() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py b/plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py deleted file mode 100644 index 296e50bd29..0000000000 --- a/plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py +++ /dev/null @@ -1,384 +0,0 @@ -#!/usr/bin/python -# (c) 2017, NetApp, Inc -# 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: sf_snapshot_schedule_manager -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: This Module has been replaced - alternative: please use M(netapp.elementsw.na_elementsw_snapshot_schedule) -short_description: Manage SolidFire snapshot schedules -extends_documentation_fragment: -- community.general._netapp.solidfire - -author: Sumit Kumar (@timuster) -description: -- Create, destroy, or update accounts on SolidFire - -options: - - state: - description: - - Whether the specified schedule should exist or not. - required: true - choices: ['present', 'absent'] - - paused: - description: - - Pause / Resume a schedule. - required: false - - recurring: - description: - - Should the schedule recur? - required: false - - time_interval_days: - description: Time interval in days. - required: false - default: 1 - - time_interval_hours: - description: Time interval in hours. - required: false - default: 0 - - time_interval_minutes: - description: Time interval in minutes. - required: false - default: 0 - - name: - description: - - Name for the snapshot schedule. - required: true - - snapshot_name: - description: - - Name for the created snapshots. - required: false - - volumes: - description: - - Volume IDs that you want to set the snapshot schedule for. - - At least 1 volume ID is required for creating a new schedule. - - required when C(state=present) - required: false - - retention: - description: - - Retention period for the snapshot. - - Format is 'HH:mm:ss'. - required: false - - schedule_id: - description: - - The schedule ID for the schedule that you want to update or delete. - required: false - - starting_date: - description: - - Starting date for the schedule. - - Required when C(state=present). - - Please use two '-' in the above format, or you may see an error- TypeError, is not JSON serializable description. - - "Format: C(2016--12--01T00:00:00Z)" - required: false -''' - -EXAMPLES = """ - - name: Create Snapshot schedule - community.general.sf_snapshot_schedule_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: present - name: Schedule_A - time_interval_days: 1 - starting_date: 2016--12--01T00:00:00Z - volumes: 7 - - - name: Update Snapshot schedule - community.general.sf_snapshot_schedule_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: present - schedule_id: 6 - recurring: True - snapshot_name: AnsibleSnapshots - - - name: Delete Snapshot schedule - community.general.sf_snapshot_schedule_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: absent - schedule_id: 6 -""" - -RETURN = """ - -schedule_id: - description: Schedule ID of the newly created schedule - returned: success - type: str -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - - -HAS_SF_SDK = netapp_utils.has_sf_sdk() - - -class SolidFireSnapShotSchedule(object): - - def __init__(self): - - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - - time_interval_days=dict(required=False, type='int', default=1), - time_interval_hours=dict(required=False, type='int', default=0), - time_interval_minutes=dict(required=False, type='int', default=0), - - paused=dict(required=False, type='bool'), - recurring=dict(required=False, type='bool'), - - starting_date=dict(type='str'), - - snapshot_name=dict(required=False, type='str'), - volumes=dict(required=False, type='list'), - retention=dict(required=False, type='str'), - - schedule_id=dict(type='int'), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('state', 'present', ['starting_date', 'volumes']) - ], - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - - # self.interval = p['interval'] - - self.time_interval_days = p['time_interval_days'] - self.time_interval_hours = p['time_interval_hours'] - self.time_interval_minutes = p['time_interval_minutes'] - - self.paused = p['paused'] - self.recurring = p['recurring'] - - self.starting_date = p['starting_date'] - if self.starting_date is not None: - self.starting_date = self.starting_date.replace("--", "-") - - self.snapshot_name = p['snapshot_name'] - self.volumes = p['volumes'] - self.retention = p['retention'] - - self.schedule_id = p['schedule_id'] - - self.create_schedule_result = None - - if HAS_SF_SDK is False: - self.module.fail_json(msg="Unable to import the SolidFire Python SDK") - else: - self.sfe = netapp_utils.create_sf_connection(module=self.module) - - def get_schedule(self): - schedule_list = self.sfe.list_schedules() - for schedule in schedule_list.schedules: - if schedule.name == self.name: - # Update self.schedule_id: - if self.schedule_id is not None: - if schedule.schedule_id == self.schedule_id: - return schedule - else: - self.schedule_id = schedule.schedule_id - return schedule - - return None - - def create_schedule(self): - - try: - sched = netapp_utils.Schedule() - # if self.interval == 'time_interval': - sched.frequency = netapp_utils.TimeIntervalFrequency(days=self.time_interval_days, - hours=self.time_interval_hours, - minutes=self.time_interval_minutes) - - # Create schedule - sched.name = self.name - sched.schedule_info = netapp_utils.ScheduleInfo( - volume_ids=self.volumes, - snapshot_name=self.snapshot_name, - retention=self.retention - ) - sched.paused = self.paused - sched.recurring = self.recurring - sched.starting_date = self.starting_date - - self.create_schedule_result = self.sfe.create_schedule(schedule=sched) - - except Exception as e: - self.module.fail_json(msg='Error creating schedule %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def delete_schedule(self): - - try: - get_schedule_result = self.sfe.get_schedule(schedule_id=self.schedule_id) - sched = get_schedule_result.schedule - sched.to_be_deleted = True - self.sfe.modify_schedule(schedule=sched) - - except Exception as e: - self.module.fail_json(msg='Error deleting schedule %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def update_schedule(self): - - try: - get_schedule_result = self.sfe.get_schedule(schedule_id=self.schedule_id) - sched = get_schedule_result.schedule - - # Update schedule properties - - # if self.interval == 'time_interval': - temp_frequency = netapp_utils.TimeIntervalFrequency(days=self.time_interval_days, - hours=self.time_interval_hours, - minutes=self.time_interval_minutes) - - if sched.frequency.days != temp_frequency.days or \ - sched.frequency.hours != temp_frequency.hours \ - or sched.frequency.minutes != temp_frequency.minutes: - sched.frequency = temp_frequency - - sched.name = self.name - if self.volumes is not None: - sched.schedule_info.volume_ids = self.volumes - if self.retention is not None: - sched.schedule_info.retention = self.retention - if self.snapshot_name is not None: - sched.schedule_info.snapshot_name = self.snapshot_name - if self.paused is not None: - sched.paused = self.paused - if self.recurring is not None: - sched.recurring = self.recurring - if self.starting_date is not None: - sched.starting_date = self.starting_date - - # Make API call - self.sfe.modify_schedule(schedule=sched) - - except Exception as e: - self.module.fail_json(msg='Error updating schedule %s: %s' % (self.name, to_native(e)), - exception=traceback.format_exc()) - - def apply(self): - changed = False - schedule_exists = False - update_schedule = False - schedule_detail = self.get_schedule() - - if schedule_detail: - schedule_exists = True - - if self.state == 'absent': - changed = True - - elif self.state == 'present': - # Check if we need to update the account - - if self.retention is not None and schedule_detail.schedule_info.retention != self.retention: - update_schedule = True - changed = True - - elif schedule_detail.name != self.name: - update_schedule = True - changed = True - - elif self.snapshot_name is not None and schedule_detail.schedule_info.snapshot_name != self.snapshot_name: - update_schedule = True - changed = True - - elif self.volumes is not None and schedule_detail.schedule_info.volume_ids != self.volumes: - update_schedule = True - changed = True - - elif self.paused is not None and schedule_detail.paused != self.paused: - update_schedule = True - changed = True - - elif self.recurring is not None and schedule_detail.recurring != self.recurring: - update_schedule = True - changed = True - - elif self.starting_date is not None and schedule_detail.starting_date != self.starting_date: - update_schedule = True - changed = True - - elif self.time_interval_minutes is not None or self.time_interval_hours is not None \ - or self.time_interval_days is not None: - - temp_frequency = netapp_utils.TimeIntervalFrequency(days=self.time_interval_days, - hours=self.time_interval_hours, - minutes=self.time_interval_minutes) - - if schedule_detail.frequency.days != temp_frequency.days or \ - schedule_detail.frequency.hours != temp_frequency.hours \ - or schedule_detail.frequency.minutes != temp_frequency.minutes: - update_schedule = True - changed = True - - else: - if self.state == 'present': - changed = True - - if changed: - if self.module.check_mode: - # Skip changes - pass - else: - if self.state == 'present': - if not schedule_exists: - self.create_schedule() - elif update_schedule: - self.update_schedule() - - elif self.state == 'absent': - self.delete_schedule() - - if self.create_schedule_result is not None: - self.module.exit_json(changed=changed, schedule_id=self.create_schedule_result.schedule_id) - else: - self.module.exit_json(changed=changed) - - -def main(): - v = SolidFireSnapShotSchedule() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/sf_volume_access_group_manager.py b/plugins/modules/storage/netapp/sf_volume_access_group_manager.py deleted file mode 100644 index 78e3097d48..0000000000 --- a/plugins/modules/storage/netapp/sf_volume_access_group_manager.py +++ /dev/null @@ -1,244 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: sf_volume_access_group_manager -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: This Module has been replaced - alternative: please use M(netapp.elementsw.na_elementsw_access_group) -short_description: Manage SolidFire Volume Access Groups -extends_documentation_fragment: -- community.general._netapp.solidfire - -author: Sumit Kumar (@timuster) -description: -- Create, destroy, or update volume access groups on SolidFire - -options: - - state: - description: - - Whether the specified volume access group should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - Name of the volume access group. It is not required to be unique, but recommended. - required: true - - initiators: - description: - - List of initiators to include in the volume access group. If unspecified, the access group will start out without configured initiators. - - volumes: - description: - - List of volumes to initially include in the volume access group. If unspecified, the access group will start without any volumes. - - virtual_network_id: - description: - - The ID of the SolidFire Virtual Network ID to associate the volume access group with. - - virtual_network_tags: - description: - - The ID of the VLAN Virtual Network Tag to associate the volume access group with. - - attributes: - description: List of Name/Value pairs in JSON object format. - - volume_access_group_id: - description: - - The ID of the volume access group to modify or delete. - -''' - -EXAMPLES = """ - - name: Create Volume Access Group - community.general.sf_volume_access_group_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: present - name: AnsibleVolumeAccessGroup - volumes: [7,8] - - - name: Modify Volume Access Group - community.general.sf_volume_access_group_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: present - volume_access_group_id: 1 - name: AnsibleVolumeAccessGroup-Renamed - attributes: {"volumes": [1,2,3], "virtual_network_id": 12345} - - - name: Delete Volume Access Group - community.general.sf_volume_access_group_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: absent - volume_access_group_id: 1 -""" - -RETURN = """ - - -""" -import traceback - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - -HAS_SF_SDK = netapp_utils.has_sf_sdk() - - -class SolidFireVolumeAccessGroup(object): - - def __init__(self): - - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - volume_access_group_id=dict(required=False, type='int', default=None), - - initiators=dict(required=False, type='list', default=None), - volumes=dict(required=False, type='list', default=None), - virtual_network_id=dict(required=False, type='list', default=None), - virtual_network_tags=dict(required=False, type='list', default=None), - attributes=dict(required=False, type='dict', default=None), - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - self.volume_access_group_id = p['volume_access_group_id'] - - self.initiators = p['initiators'] - self.volumes = p['volumes'] - self.virtual_network_id = p['virtual_network_id'] - self.virtual_network_tags = p['virtual_network_tags'] - self.attributes = p['attributes'] - - if HAS_SF_SDK is False: - self.module.fail_json(msg="Unable to import the SolidFire Python SDK") - else: - self.sfe = netapp_utils.create_sf_connection(module=self.module) - - def get_volume_access_group(self): - access_groups_list = self.sfe.list_volume_access_groups() - - for group in access_groups_list.volume_access_groups: - if group.name == self.name: - # Update self.volume_access_group_id: - if self.volume_access_group_id is not None: - if group.volume_access_group_id == self.volume_access_group_id: - return group - else: - self.volume_access_group_id = group.volume_access_group_id - return group - return None - - def create_volume_access_group(self): - try: - self.sfe.create_volume_access_group(name=self.name, - initiators=self.initiators, - volumes=self.volumes, - virtual_network_id=self.virtual_network_id, - virtual_network_tags=self.virtual_network_tags, - attributes=self.attributes) - except Exception as e: - self.module.fail_json(msg="Error creating volume access group %s: %s" % - (self.name, to_native(e)), exception=traceback.format_exc()) - - def delete_volume_access_group(self): - try: - self.sfe.delete_volume_access_group(volume_access_group_id=self.volume_access_group_id) - - except Exception as e: - self.module.fail_json(msg="Error deleting volume access group %s: %s" % - (self.volume_access_group_id, to_native(e)), - exception=traceback.format_exc()) - - def update_volume_access_group(self): - try: - self.sfe.modify_volume_access_group(volume_access_group_id=self.volume_access_group_id, - virtual_network_id=self.virtual_network_id, - virtual_network_tags=self.virtual_network_tags, - name=self.name, - initiators=self.initiators, - volumes=self.volumes, - attributes=self.attributes) - except Exception as e: - self.module.fail_json(msg="Error updating volume access group %s: %s" % - (self.volume_access_group_id, to_native(e)), exception=traceback.format_exc()) - - def apply(self): - changed = False - group_exists = False - update_group = False - group_detail = self.get_volume_access_group() - - if group_detail: - group_exists = True - - if self.state == 'absent': - changed = True - - elif self.state == 'present': - # Check if we need to update the group - if self.volumes is not None and group_detail.volumes != self.volumes: - update_group = True - changed = True - elif self.initiators is not None and group_detail.initiators != self.initiators: - update_group = True - changed = True - elif self.virtual_network_id is not None or self.virtual_network_tags is not None or \ - self.attributes is not None: - update_group = True - changed = True - - else: - if self.state == 'present': - changed = True - - if changed: - if self.module.check_mode: - pass - else: - if self.state == 'present': - if not group_exists: - self.create_volume_access_group() - elif update_group: - self.update_volume_access_group() - - elif self.state == 'absent': - self.delete_volume_access_group() - - self.module.exit_json(changed=changed) - - -def main(): - v = SolidFireVolumeAccessGroup() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/plugins/modules/storage/netapp/sf_volume_manager.py b/plugins/modules/storage/netapp/sf_volume_manager.py deleted file mode 100644 index 9d5378a251..0000000000 --- a/plugins/modules/storage/netapp/sf_volume_manager.py +++ /dev/null @@ -1,315 +0,0 @@ -#!/usr/bin/python - -# (c) 2017, NetApp, Inc -# 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: sf_volume_manager -deprecated: - removed_in: 2.0.0 # was Ansible 2.11 - why: This Module has been replaced - alternative: please use M(netapp.elementsw.na_elementsw_volume) -short_description: Manage SolidFire volumes -extends_documentation_fragment: -- community.general._netapp.solidfire - -author: Sumit Kumar (@timuster) -description: -- Create, destroy, or update volumes on SolidFire - -options: - - state: - description: - - Whether the specified volume should exist or not. - required: true - choices: ['present', 'absent'] - - name: - description: - - The name of the volume to manage. - required: true - - account_id: - description: - - Account ID for the owner of this volume. - required: true - - 512emulation: - description: - - Should the volume provide 512-byte sector emulation? - - Required when C(state=present) - - qos: - description: Initial quality of service settings for this volume. Configure as dict in playbooks. - - attributes: - description: A YAML dictionary of attributes that you would like to apply on this volume. - - volume_id: - description: - - The ID of the volume to manage or update. - - In order to create multiple volumes with the same name, but different volume_ids, please declare the I(volume_id) - parameter with an arbitrary value. However, the specified volume_id will not be assigned to the newly created - volume (since it's an auto-generated property). - - size: - description: - - The size of the volume in (size_unit). - - Required when C(state = present). - - size_unit: - description: - - The unit used to interpret the size parameter. - choices: ['bytes', 'b', 'kb', 'mb', 'gb', 'tb', 'pb', 'eb', 'zb', 'yb'] - default: 'gb' - - access: - description: - - "Access allowed for the volume." - - "readOnly: Only read operations are allowed." - - "readWrite: Reads and writes are allowed." - - "locked: No reads or writes are allowed." - - "replicationTarget: Identify a volume as the target volume for a paired set of volumes. If the volume is not paired, the access status is locked." - - "If unspecified, the access settings of the clone will be the same as the source." - choices: ['readOnly', 'readWrite', 'locked', 'replicationTarget'] - -''' - -EXAMPLES = """ - - name: Create Volume - community.general.sf_volume_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: present - name: AnsibleVol - qos: {minIOPS: 1000, maxIOPS: 20000, burstIOPS: 50000} - account_id: 3 - enable512e: False - size: 1 - size_unit: gb - - - name: Update Volume - community.general.sf_volume_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: present - name: AnsibleVol - account_id: 3 - access: readWrite - - - name: Delete Volume - community.general.sf_volume_manager: - hostname: "{{ solidfire_hostname }}" - username: "{{ solidfire_username }}" - password: "{{ solidfire_password }}" - state: absent - name: AnsibleVol - account_id: 2 -""" - -RETURN = """ - -msg: - description: Success message - returned: success - type: str - -""" - -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils._text import to_native -import ansible_collections.community.general.plugins.module_utils._netapp as netapp_utils - -HAS_SF_SDK = netapp_utils.has_sf_sdk() - - -class SolidFireVolume(object): - - def __init__(self): - - self._size_unit_map = netapp_utils.SF_BYTE_MAP - - self.argument_spec = netapp_utils.ontap_sf_host_argument_spec() - self.argument_spec.update(dict( - state=dict(required=True, choices=['present', 'absent']), - name=dict(required=True, type='str'), - account_id=dict(required=True, type='int'), - - enable512e=dict(type='bool', aliases=['512emulation']), - qos=dict(required=False, type='dict', default=None), - attributes=dict(required=False, type='dict', default=None), - - volume_id=dict(type='int', default=None), - size=dict(type='int'), - size_unit=dict(default='gb', - choices=['bytes', 'b', 'kb', 'mb', 'gb', 'tb', - 'pb', 'eb', 'zb', 'yb'], type='str'), - - access=dict(required=False, type='str', default=None, choices=['readOnly', 'readWrite', - 'locked', 'replicationTarget']), - - )) - - self.module = AnsibleModule( - argument_spec=self.argument_spec, - required_if=[ - ('state', 'present', ['size', 'enable512e']) - ], - supports_check_mode=True - ) - - p = self.module.params - - # set up state variables - self.state = p['state'] - self.name = p['name'] - self.account_id = p['account_id'] - self.enable512e = p['enable512e'] - self.qos = p['qos'] - self.attributes = p['attributes'] - - self.volume_id = p['volume_id'] - self.size_unit = p['size_unit'] - if p['size'] is not None: - self.size = p['size'] * self._size_unit_map[self.size_unit] - else: - self.size = None - self.access = p['access'] - if HAS_SF_SDK is False: - self.module.fail_json(msg="Unable to import the SolidFire Python SDK") - else: - self.sfe = netapp_utils.create_sf_connection(module=self.module) - - def get_volume(self): - """ - Return volume object if found - - :return: Details about the volume. None if not found. - :rtype: dict - """ - volume_list = self.sfe.list_volumes_for_account(account_id=self.account_id) - for volume in volume_list.volumes: - if volume.name == self.name: - # Update self.volume_id - if self.volume_id is not None: - if volume.volume_id == self.volume_id and str(volume.delete_time) == "": - return volume - else: - if str(volume.delete_time) == "": - self.volume_id = volume.volume_id - return volume - return None - - def create_volume(self): - try: - self.sfe.create_volume(name=self.name, - account_id=self.account_id, - total_size=self.size, - enable512e=self.enable512e, - qos=self.qos, - attributes=self.attributes) - - except Exception as err: - self.module.fail_json(msg="Error provisioning volume %s of size %s" % (self.name, self.size), - exception=to_native(err)) - - def delete_volume(self): - try: - self.sfe.delete_volume(volume_id=self.volume_id) - - except Exception as err: - self.module.fail_json(msg="Error deleting volume %s" % self.volume_id, - exception=to_native(err)) - - def update_volume(self): - try: - self.sfe.modify_volume(self.volume_id, - account_id=self.account_id, - access=self.access, - qos=self.qos, - total_size=self.size, - attributes=self.attributes) - - except Exception as err: - self.module.fail_json(msg="Error updating volume %s" % self.name, - exception=to_native(err)) - - def apply(self): - changed = False - volume_exists = False - update_volume = False - volume_detail = self.get_volume() - - if volume_detail: - volume_exists = True - - if self.state == 'absent': - # Checking for state change(s) here, and applying it later in the code allows us to support - # check_mode - changed = True - - elif self.state == 'present': - if volume_detail.access is not None and self.access is not None and volume_detail.access != self.access: - update_volume = True - changed = True - - elif volume_detail.account_id is not None and self.account_id is not None \ - and volume_detail.account_id != self.account_id: - update_volume = True - changed = True - - elif volume_detail.qos is not None and self.qos is not None and volume_detail.qos != self.qos: - update_volume = True - changed = True - - elif volume_detail.total_size is not None and volume_detail.total_size != self.size: - size_difference = abs(float(volume_detail.total_size - self.size)) - # Change size only if difference is bigger than 0.001 - if size_difference / self.size > 0.001: - update_volume = True - changed = True - - elif volume_detail.attributes is not None and self.attributes is not None and \ - volume_detail.attributes != self.attributes: - update_volume = True - changed = True - else: - if self.state == 'present': - changed = True - - result_message = "" - - if changed: - if self.module.check_mode: - result_message = "Check mode, skipping changes" - else: - if self.state == 'present': - if not volume_exists: - self.create_volume() - result_message = "Volume created" - elif update_volume: - self.update_volume() - result_message = "Volume updated" - - elif self.state == 'absent': - self.delete_volume() - result_message = "Volume deleted" - - self.module.exit_json(changed=changed, msg=result_message) - - -def main(): - v = SolidFireVolume() - v.apply() - - -if __name__ == '__main__': - main() diff --git a/tests/sanity/ignore-2.10.txt b/tests/sanity/ignore-2.10.txt index 5433665bc6..c38b1109ce 100644 --- a/tests/sanity/ignore-2.10.txt +++ b/tests/sanity/ignore-2.10.txt @@ -622,9 +622,6 @@ plugins/modules/remote_management/cobbler/cobbler_system.py validate-modules:par plugins/modules/remote_management/dellemc/idrac_server_config_profile.py validate-modules:doc-missing-type plugins/modules/remote_management/dellemc/idrac_server_config_profile.py validate-modules:parameter-type-not-in-doc plugins/modules/remote_management/dellemc/ome_device_info.py validate-modules:parameter-list-no-elements -plugins/modules/remote_management/foreman/foreman.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/foreman/katello.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/foreman/katello.py yamllint:unparsable-with-libyaml plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:doc-choices-do-not-match-spec plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc @@ -706,7 +703,6 @@ plugins/modules/source_control/git_config.py validate-modules:parameter-type-not plugins/modules/source_control/github/github_deploy_key.py validate-modules:doc-missing-type plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-type-not-in-doc -plugins/modules/source_control/github/github_hooks.py validate-modules:doc-missing-type plugins/modules/source_control/github/github_issue.py validate-modules:doc-missing-type plugins/modules/source_control/github/github_issue.py validate-modules:parameter-type-not-in-doc plugins/modules/source_control/github/github_key.py validate-modules:doc-missing-type @@ -741,41 +737,10 @@ plugins/modules/storage/ibm/ibm_sa_vol.py validate-modules:doc-missing-type plugins/modules/storage/ibm/ibm_sa_vol.py validate-modules:doc-required-mismatch plugins/modules/storage/ibm/ibm_sa_vol_map.py validate-modules:doc-missing-type plugins/modules/storage/ibm/ibm_sa_vol_map.py validate-modules:doc-required-mismatch -plugins/modules/storage/netapp/na_cdot_aggregate.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_aggregate.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_license.py validate-modules:incompatible-default-type -plugins/modules/storage/netapp/na_cdot_license.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_lun.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_lun.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_qtree.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_qtree.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_svm.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_svm.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_user.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_user.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_user_role.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_user_role.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:no-default-for-required-parameter -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:undocumented-parameter plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:doc-missing-type plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:parameter-list-no-elements plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:parameter-state-invalid-choice plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_account_manager.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/sf_account_manager.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_check_connections.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:parameter-list-no-elements -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:parameter-list-no-elements -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:parameter-invalid -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:undocumented-parameter plugins/modules/storage/purestorage/purefa_facts.py validate-modules:doc-required-mismatch plugins/modules/storage/purestorage/purefa_facts.py validate-modules:parameter-list-no-elements plugins/modules/storage/purestorage/purefa_facts.py validate-modules:return-syntax-error diff --git a/tests/sanity/ignore-2.11.txt b/tests/sanity/ignore-2.11.txt index 5433665bc6..c38b1109ce 100644 --- a/tests/sanity/ignore-2.11.txt +++ b/tests/sanity/ignore-2.11.txt @@ -622,9 +622,6 @@ plugins/modules/remote_management/cobbler/cobbler_system.py validate-modules:par plugins/modules/remote_management/dellemc/idrac_server_config_profile.py validate-modules:doc-missing-type plugins/modules/remote_management/dellemc/idrac_server_config_profile.py validate-modules:parameter-type-not-in-doc plugins/modules/remote_management/dellemc/ome_device_info.py validate-modules:parameter-list-no-elements -plugins/modules/remote_management/foreman/foreman.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/foreman/katello.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/foreman/katello.py yamllint:unparsable-with-libyaml plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:doc-choices-do-not-match-spec plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc @@ -706,7 +703,6 @@ plugins/modules/source_control/git_config.py validate-modules:parameter-type-not plugins/modules/source_control/github/github_deploy_key.py validate-modules:doc-missing-type plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-type-not-in-doc -plugins/modules/source_control/github/github_hooks.py validate-modules:doc-missing-type plugins/modules/source_control/github/github_issue.py validate-modules:doc-missing-type plugins/modules/source_control/github/github_issue.py validate-modules:parameter-type-not-in-doc plugins/modules/source_control/github/github_key.py validate-modules:doc-missing-type @@ -741,41 +737,10 @@ plugins/modules/storage/ibm/ibm_sa_vol.py validate-modules:doc-missing-type plugins/modules/storage/ibm/ibm_sa_vol.py validate-modules:doc-required-mismatch plugins/modules/storage/ibm/ibm_sa_vol_map.py validate-modules:doc-missing-type plugins/modules/storage/ibm/ibm_sa_vol_map.py validate-modules:doc-required-mismatch -plugins/modules/storage/netapp/na_cdot_aggregate.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_aggregate.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_license.py validate-modules:incompatible-default-type -plugins/modules/storage/netapp/na_cdot_license.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_lun.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_lun.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_qtree.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_qtree.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_svm.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_svm.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_user.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_user.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_user_role.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_user_role.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:no-default-for-required-parameter -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:undocumented-parameter plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:doc-missing-type plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:parameter-list-no-elements plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:parameter-state-invalid-choice plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_account_manager.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/sf_account_manager.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_check_connections.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:parameter-list-no-elements -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:parameter-list-no-elements -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:parameter-invalid -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:undocumented-parameter plugins/modules/storage/purestorage/purefa_facts.py validate-modules:doc-required-mismatch plugins/modules/storage/purestorage/purefa_facts.py validate-modules:parameter-list-no-elements plugins/modules/storage/purestorage/purefa_facts.py validate-modules:return-syntax-error diff --git a/tests/sanity/ignore-2.9.txt b/tests/sanity/ignore-2.9.txt index 33b046946c..7e51df747e 100644 --- a/tests/sanity/ignore-2.9.txt +++ b/tests/sanity/ignore-2.9.txt @@ -491,12 +491,6 @@ plugins/modules/remote_management/cobbler/cobbler_sync.py validate-modules:param plugins/modules/remote_management/cobbler/cobbler_system.py validate-modules:parameter-type-not-in-doc plugins/modules/remote_management/dellemc/idrac_server_config_profile.py validate-modules:doc-missing-type plugins/modules/remote_management/dellemc/idrac_server_config_profile.py validate-modules:parameter-type-not-in-doc -plugins/modules/remote_management/foreman/foreman.py validate-modules:deprecation-mismatch -plugins/modules/remote_management/foreman/foreman.py validate-modules:invalid-documentation -plugins/modules/remote_management/foreman/foreman.py validate-modules:missing-main-call -plugins/modules/remote_management/foreman/katello.py validate-modules:deprecation-mismatch -plugins/modules/remote_management/foreman/katello.py validate-modules:invalid-documentation -plugins/modules/remote_management/foreman/katello.py validate-modules:missing-main-call plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:doc-choices-do-not-match-spec plugins/modules/remote_management/hpilo/hpilo_boot.py validate-modules:parameter-type-not-in-doc plugins/modules/remote_management/hpilo/hpilo_info.py validate-modules:parameter-type-not-in-doc @@ -559,9 +553,6 @@ plugins/modules/source_control/git_config.py validate-modules:parameter-type-not plugins/modules/source_control/github/github_deploy_key.py validate-modules:doc-missing-type plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-invalid plugins/modules/source_control/github/github_deploy_key.py validate-modules:parameter-type-not-in-doc -plugins/modules/source_control/github/github_hooks.py validate-modules:deprecation-mismatch -plugins/modules/source_control/github/github_hooks.py validate-modules:invalid-documentation -plugins/modules/source_control/github/github_hooks.py validate-modules:missing-main-call plugins/modules/source_control/github/github_issue.py validate-modules:doc-missing-type plugins/modules/source_control/github/github_issue.py validate-modules:parameter-type-not-in-doc plugins/modules/source_control/github/github_key.py validate-modules:doc-missing-type @@ -581,49 +572,10 @@ plugins/modules/storage/ibm/ibm_sa_host_ports.py validate-modules:doc-missing-ty plugins/modules/storage/ibm/ibm_sa_pool.py validate-modules:doc-missing-type plugins/modules/storage/ibm/ibm_sa_vol.py validate-modules:doc-missing-type plugins/modules/storage/ibm/ibm_sa_vol_map.py validate-modules:doc-missing-type -plugins/modules/storage/netapp/na_cdot_aggregate.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/na_cdot_aggregate.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/na_cdot_aggregate.py validate-modules:missing-main-call -plugins/modules/storage/netapp/na_cdot_license.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/na_cdot_license.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/na_cdot_license.py validate-modules:missing-main-call -plugins/modules/storage/netapp/na_cdot_lun.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/na_cdot_lun.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/na_cdot_lun.py validate-modules:missing-main-call -plugins/modules/storage/netapp/na_cdot_qtree.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/na_cdot_qtree.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/na_cdot_qtree.py validate-modules:missing-main-call -plugins/modules/storage/netapp/na_cdot_svm.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/na_cdot_svm.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/na_cdot_svm.py validate-modules:missing-main-call -plugins/modules/storage/netapp/na_cdot_user.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/na_cdot_user.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/na_cdot_user.py validate-modules:missing-main-call -plugins/modules/storage/netapp/na_cdot_user_role.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/na_cdot_user_role.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/na_cdot_user_role.py validate-modules:missing-main-call -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/na_cdot_volume.py validate-modules:missing-main-call plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:deprecation-mismatch plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:doc-missing-type plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:invalid-documentation plugins/modules/storage/netapp/na_ontap_gather_facts.py validate-modules:parameter-type-not-in-doc -plugins/modules/storage/netapp/sf_account_manager.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/sf_account_manager.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/sf_account_manager.py validate-modules:missing-main-call -plugins/modules/storage/netapp/sf_check_connections.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/sf_check_connections.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/sf_check_connections.py validate-modules:missing-main-call -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/sf_snapshot_schedule_manager.py validate-modules:missing-main-call -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/sf_volume_access_group_manager.py validate-modules:missing-main-call -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:deprecation-mismatch -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:invalid-documentation -plugins/modules/storage/netapp/sf_volume_manager.py validate-modules:missing-main-call plugins/modules/storage/purestorage/purefa_facts.py validate-modules:deprecation-mismatch plugins/modules/storage/purestorage/purefa_facts.py validate-modules:invalid-documentation plugins/modules/storage/purestorage/purefa_facts.py validate-modules:return-syntax-error