summaryrefslogtreecommitdiffstats
path: root/ansible_collections/purestorage/flashblade
diff options
context:
space:
mode:
Diffstat (limited to 'ansible_collections/purestorage/flashblade')
-rw-r--r--ansible_collections/purestorage/flashblade/CHANGELOG.rst16
-rw-r--r--ansible_collections/purestorage/flashblade/FILES.json44
-rw-r--r--ansible_collections/purestorage/flashblade/MANIFEST.json4
-rw-r--r--ansible_collections/purestorage/flashblade/changelogs/.plugin-cache.yaml2
-rw-r--r--ansible_collections/purestorage/flashblade/changelogs/changelog.yaml18
-rw-r--r--ansible_collections/purestorage/flashblade/changelogs/fragments/270_add_go.yaml2
-rw-r--r--ansible_collections/purestorage/flashblade/changelogs/fragments/271_add_worm.yaml2
-rw-r--r--ansible_collections/purestorage/flashblade/changelogs/fragments/273_add_nap.yaml3
-rw-r--r--ansible_collections/purestorage/flashblade/changelogs/fragments/274_fan_in.yaml2
-rw-r--r--ansible_collections/purestorage/flashblade/plugins/modules/purefb_bucket.py108
-rw-r--r--ansible_collections/purestorage/flashblade/plugins/modules/purefb_connect.py10
-rw-r--r--ansible_collections/purestorage/flashblade/plugins/modules/purefb_fs.py48
-rw-r--r--ansible_collections/purestorage/flashblade/plugins/modules/purefb_info.py5
-rw-r--r--ansible_collections/purestorage/flashblade/plugins/modules/purefb_policy.py391
14 files changed, 628 insertions, 27 deletions
diff --git a/ansible_collections/purestorage/flashblade/CHANGELOG.rst b/ansible_collections/purestorage/flashblade/CHANGELOG.rst
index 13b845abd..a673257d2 100644
--- a/ansible_collections/purestorage/flashblade/CHANGELOG.rst
+++ b/ansible_collections/purestorage/flashblade/CHANGELOG.rst
@@ -5,6 +5,18 @@ Purestorage.Flashblade Release Notes
.. contents:: Topics
+v1.17.0
+=======
+
+Minor Changes
+-------------
+
+- purefb_bucket - Add support for strict 17a-4 WORM compliance.
+- purefb_connect - Increase Fan-In and Fan-Out maximums
+- purefb_fs - Add ``group_ownership`` parameter from Purity//FB 4.4.0.
+- purefb_info - Show array network access policy from Purity//FB 4.4.0
+- purefb_policy - Add support for network access policies from Purity//FB 4.4.0
+
v1.16.0
=======
@@ -225,7 +237,6 @@ v1.6.0
Minor Changes
-------------
-- purefb_virtualhost - New module to manage API Clients
- purefb_ad - New module to manage Active Directory Account
- purefb_eula - New module to sign EULA
- purefb_info - Add Active Directory, Kerberos and Object Store Account information
@@ -234,6 +245,7 @@ Minor Changes
- purefb_s3user - Add access policy option to user creation
- purefb_timeout - Add module to set GUI idle timeout
- purefb_userpolicy - New module to manage object store user access policies
+- purefb_virtualhost - New module to manage API Clients
- purefb_virtualhost - New module to manage Object Store Virtual Hosts
New Modules
@@ -292,12 +304,12 @@ Minor Changes
Bugfixes
--------
-- purefb_policy - Resolve multiple issues related to incorrect use of timezones
- purefb_connect - Ensure changing encryption status on array connection is performed correctly
- purefb_connect - Fix breaking change created in purity_fb SDK 1.9.2 for deletion of array connections
- purefb_connect - Hide target array API token
- purefb_ds - Ensure updating directory service configurations completes correctly
- purefb_info - Fix issue getting array info when encrypted connection exists
+- purefb_policy - Resolve multiple issues related to incorrect use of timezones
New Modules
-----------
diff --git a/ansible_collections/purestorage/flashblade/FILES.json b/ansible_collections/purestorage/flashblade/FILES.json
index d7b39dbda..8f3e38a96 100644
--- a/ansible_collections/purestorage/flashblade/FILES.json
+++ b/ansible_collections/purestorage/flashblade/FILES.json
@@ -519,6 +519,13 @@
"format": 1
},
{
+ "name": "changelogs/fragments/274_fan_in.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "1c0e28b50aa1fe8a6325de6ea6dd486019ec307ccb8fa84ef543b8b2f00baef6",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/81_purefb_fs_new_options.yaml",
"ftype": "file",
"chksum_type": "sha256",
@@ -610,6 +617,13 @@
"format": 1
},
{
+ "name": "changelogs/fragments/273_add_nap.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "498d161b9e61c95f2fcf64618d3304c5a46b8e16828306cf2ae585e504b01dc6",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/191_add_quota_info.yaml",
"ftype": "file",
"chksum_type": "sha256",
@@ -666,6 +680,13 @@
"format": 1
},
{
+ "name": "changelogs/fragments/271_add_worm.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "e4a187b7e2f9bc1b81cf60415317dd8f966b214d113f476f2bc18900de54c6a9",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/101_fix_policy_and_timezone_error.yaml",
"ftype": "file",
"chksum_type": "sha256",
@@ -715,6 +736,13 @@
"format": 1
},
{
+ "name": "changelogs/fragments/270_add_go.yaml",
+ "ftype": "file",
+ "chksum_type": "sha256",
+ "chksum_sha256": "81731ce510a6e2cd5947f609ba78ea396e19bbf3e44f36f49ae5c8991f0ca425",
+ "format": 1
+ },
+ {
"name": "changelogs/fragments/113_policy_cleanup.yaml",
"ftype": "file",
"chksum_type": "sha256",
@@ -725,14 +753,14 @@
"name": "changelogs/changelog.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "58ab80ddfd28321e4c9f245810097a8efbcd09898e013b3a83e650d2dd8440ed",
+ "chksum_sha256": "b2c3c0bab9ffe396ec0afe29c985db329e969ec0389ebc5c41e601f93f597e72",
"format": 1
},
{
"name": "changelogs/.plugin-cache.yaml",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "74f8ee5c9b2c27b9b655d822e47443fc68975023c10a6e58c08dc4b925c61bb3",
+ "chksum_sha256": "ef9e016e5b4618c4d5057f035eaf5d7be9c626f2c4265bd3f34430e1561ad6da",
"format": 1
},
{
@@ -928,7 +956,7 @@
"name": "plugins/modules/purefb_policy.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "9c6abe4b8cf5db61cd7a27db057f8d2f28cf0d2ec2bf9b398cf3f9eba68bb0e1",
+ "chksum_sha256": "94b94ab9aa31fac3e8e42024a9605dbab36d7b4b86f6030f0bcf6f00d5283f43",
"format": 1
},
{
@@ -984,7 +1012,7 @@
"name": "plugins/modules/purefb_connect.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "820c57b48e107ef852e6b2665c65ef76d67ffcde916cb21a368dcdae8e1e23e4",
+ "chksum_sha256": "eedb065fa37a7cffe50c2c7cc1ef9717f4ce3aa76ec4334cfb6ee420e44e0260",
"format": 1
},
{
@@ -1117,7 +1145,7 @@
"name": "plugins/modules/purefb_fs.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "2438642ad2a6ce605587eb84e0573010449ce0710d601cbf337dfa4690d7b736",
+ "chksum_sha256": "22af8016c0b29191ade09778e7d6279287ac866130b3fc212f85909f4a8bc099",
"format": 1
},
{
@@ -1166,7 +1194,7 @@
"name": "plugins/modules/purefb_info.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "b6dc24aac2c4733f7f37f0901a70fc3a9679cb06994d1407ba85f92bcc110d53",
+ "chksum_sha256": "70d3b538db7be7ea4b8faa6762d7e978120c112a5c4d81954425ae807ea6f91c",
"format": 1
},
{
@@ -1187,7 +1215,7 @@
"name": "plugins/modules/purefb_bucket.py",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "11e6a2e0aa40ab4f7e50a4c2be3dfd17363e094b8ac126b5ad042c4d65c16055",
+ "chksum_sha256": "507922eadc0bc73ec2a2e0c2e7cdda348203f4bb6b09f1120370c775a64f2bf8",
"format": 1
},
{
@@ -1383,7 +1411,7 @@
"name": "CHANGELOG.rst",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "de7d63a6d1d411e66f64971129b4630faaca228eb0a8348f261034aab83faa04",
+ "chksum_sha256": "cc4723553b99c762a97c9f06c61cae678c1c5cce90ffc7cc43202e23bf4885ed",
"format": 1
}
],
diff --git a/ansible_collections/purestorage/flashblade/MANIFEST.json b/ansible_collections/purestorage/flashblade/MANIFEST.json
index 2af712175..cb9fde10c 100644
--- a/ansible_collections/purestorage/flashblade/MANIFEST.json
+++ b/ansible_collections/purestorage/flashblade/MANIFEST.json
@@ -2,7 +2,7 @@
"collection_info": {
"namespace": "purestorage",
"name": "flashblade",
- "version": "1.16.0",
+ "version": "1.17.0",
"authors": [
"Pure Storage Ansible Team <pure-ansible-team@purestorage.com>"
],
@@ -30,7 +30,7 @@
"name": "FILES.json",
"ftype": "file",
"chksum_type": "sha256",
- "chksum_sha256": "14b510daea00c6bbcbf0a5bcfff2c45937740e569c86fedeb64970968dc4eecc",
+ "chksum_sha256": "985b106cb8f390a1084cc8fd39b7d5ff1d5ec674b068edc67fd1e9108b41e6cc",
"format": 1
},
"format": 1
diff --git a/ansible_collections/purestorage/flashblade/changelogs/.plugin-cache.yaml b/ansible_collections/purestorage/flashblade/changelogs/.plugin-cache.yaml
index c99d4477d..bcb6c205c 100644
--- a/ansible_collections/purestorage/flashblade/changelogs/.plugin-cache.yaml
+++ b/ansible_collections/purestorage/flashblade/changelogs/.plugin-cache.yaml
@@ -256,4 +256,4 @@ plugins:
strategy: {}
test: {}
vars: {}
-version: 1.16.0
+version: 1.17.0
diff --git a/ansible_collections/purestorage/flashblade/changelogs/changelog.yaml b/ansible_collections/purestorage/flashblade/changelogs/changelog.yaml
index eaeb07ed3..71acf6b6a 100644
--- a/ansible_collections/purestorage/flashblade/changelogs/changelog.yaml
+++ b/ansible_collections/purestorage/flashblade/changelogs/changelog.yaml
@@ -168,6 +168,20 @@ releases:
- 266_bucket_fix.yaml
- 268_multi-chassis-lag.yaml
release_date: '2024-02-27'
+ 1.17.0:
+ changes:
+ minor_changes:
+ - purefb_bucket - Add support for strict 17a-4 WORM compliance.
+ - purefb_connect - Increase Fan-In and Fan-Out maximums
+ - purefb_fs - Add ``group_ownership`` parameter from Purity//FB 4.4.0.
+ - purefb_info - Show array network access policy from Purity//FB 4.4.0
+ - purefb_policy - Add support for network access policies from Purity//FB 4.4.0
+ fragments:
+ - 270_add_go.yaml
+ - 271_add_worm.yaml
+ - 273_add_nap.yaml
+ - 274_fan_in.yaml
+ release_date: '2024-04-01'
1.3.0:
changes:
bugfixes:
@@ -210,7 +224,6 @@ releases:
1.4.0:
changes:
bugfixes:
- - purefb_policy - Resolve multiple issues related to incorrect use of timezones
- purefb_connect - Ensure changing encryption status on array connection is
performed correctly
- purefb_connect - Fix breaking change created in purity_fb SDK 1.9.2 for deletion
@@ -218,6 +231,7 @@ releases:
- purefb_connect - Hide target array API token
- purefb_ds - Ensure updating directory service configurations completes correctly
- purefb_info - Fix issue getting array info when encrypted connection exists
+ - purefb_policy - Resolve multiple issues related to incorrect use of timezones
minor_changes:
- purefb_banner - Module to manage the GUI and SSH login message
- purefb_certgrp - Module to manage FlashBlade Certificate Groups
@@ -300,7 +314,6 @@ releases:
1.6.0:
changes:
minor_changes:
- - purefb_virtualhost - New module to manage API Clients
- purefb_ad - New module to manage Active Directory Account
- purefb_eula - New module to sign EULA
- purefb_info - Add Active Directory, Kerberos and Object Store Account information
@@ -309,6 +322,7 @@ releases:
- purefb_s3user - Add access policy option to user creation
- purefb_timeout - Add module to set GUI idle timeout
- purefb_userpolicy - New module to manage object store user access policies
+ - purefb_virtualhost - New module to manage API Clients
- purefb_virtualhost - New module to manage Object Store Virtual Hosts
fragments:
- 127_add_eula.yaml
diff --git a/ansible_collections/purestorage/flashblade/changelogs/fragments/270_add_go.yaml b/ansible_collections/purestorage/flashblade/changelogs/fragments/270_add_go.yaml
new file mode 100644
index 000000000..d875db5ab
--- /dev/null
+++ b/ansible_collections/purestorage/flashblade/changelogs/fragments/270_add_go.yaml
@@ -0,0 +1,2 @@
+minor_changes:
+ - purefb_fs - Add ``group_ownership`` parameter from Purity//FB 4.4.0.
diff --git a/ansible_collections/purestorage/flashblade/changelogs/fragments/271_add_worm.yaml b/ansible_collections/purestorage/flashblade/changelogs/fragments/271_add_worm.yaml
new file mode 100644
index 000000000..379975be3
--- /dev/null
+++ b/ansible_collections/purestorage/flashblade/changelogs/fragments/271_add_worm.yaml
@@ -0,0 +1,2 @@
+minor_changes:
+ - purefb_bucket - Add support for strict 17a-4 WORM compliance.
diff --git a/ansible_collections/purestorage/flashblade/changelogs/fragments/273_add_nap.yaml b/ansible_collections/purestorage/flashblade/changelogs/fragments/273_add_nap.yaml
new file mode 100644
index 000000000..998de322e
--- /dev/null
+++ b/ansible_collections/purestorage/flashblade/changelogs/fragments/273_add_nap.yaml
@@ -0,0 +1,3 @@
+minor_changes:
+ - purefb_info - Show array network access policy from Purity//FB 4.4.0
+ - purefb_policy - Add support for network access policies from Purity//FB 4.4.0
diff --git a/ansible_collections/purestorage/flashblade/changelogs/fragments/274_fan_in.yaml b/ansible_collections/purestorage/flashblade/changelogs/fragments/274_fan_in.yaml
new file mode 100644
index 000000000..719fca54b
--- /dev/null
+++ b/ansible_collections/purestorage/flashblade/changelogs/fragments/274_fan_in.yaml
@@ -0,0 +1,2 @@
+minor_changes:
+ - purefb_connect - Increase Fan-In and Fan-Out maximums
diff --git a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_bucket.py b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_bucket.py
index 27cd7e317..11c8be479 100644
--- a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_bucket.py
+++ b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_bucket.py
@@ -118,13 +118,32 @@ options:
description:
- If set to true, adding bucket policies that grant public access to a bucket is not allowed.
type: bool
- version_added: 1.15.0
+ version_added: '1.15.0'
block_public_access:
description:
- If set to true, access to a bucket with a public policy is restricted to only authenticated
users within the account that bucket belongs to.
type: bool
- version_added: 1.15.0
+ version_added: '1.15.0'
+ eradication_mode:
+ description:
+ - The eradication mode of the bucket.
+ type: str
+ choices: [ "permission-based", "retention-based" ]
+ version_added: '1.17.0'
+ manual_eradication:
+ description:
+ - The manual eradication status of the bucket. If false, the bucket cannot be eradicated after
+ it has been destroyed, unless it is empty. If true, the bucket can be eradicated.
+ type: bool
+ version_added: '1.17.0'
+ eradication_delay:
+ description:
+ - Minimum eradication delay in days. Automatically eradicate destroyed buckets after
+ the delay time passes unless automatic eradication is delayed due to other configuration values.
+ - Valid values are integer days from 1 to 30. Default is 1.
+ type: int
+ version_added: '1.17.0'
extends_documentation_fragment:
- purestorage.flashblade.purestorage.fb
"""
@@ -194,11 +213,13 @@ from ansible_collections.purestorage.flashblade.plugins.module_utils.purefb impo
)
+SEC_PER_DAY = 86400000
MIN_REQUIRED_API_VERSION = "1.5"
VERSIONING_VERSION = "1.9"
VSO_VERSION = "2.5"
QUOTA_VERSION = "2.8"
MODE_VERSION = "2.12"
+WORM_VERSION = "2.13"
def get_s3acc(module, blade):
@@ -354,6 +375,30 @@ def create_bucket(module, blade):
msg="Failed to set Public Access config correctly for bucket {0}. "
"Error: {1}".format(module.params["name"], res.errors[0].message)
)
+ if WORM_VERSION in api_version and module.params["eradication_mode"]:
+ if not module.params["eradication_delay"]:
+ module.params["eradication_delay"] = SEC_PER_DAY
+ else:
+ module.params["eradication_delay"] = (
+ module.params["eradication_delay"] * SEC_PER_DAY
+ )
+ if not module.params["manual_eradication"]:
+ module.params["manual_eradication"] = "disabled"
+ else:
+ module.params["manual_eradication"] = "enabled"
+ worm = BucketPatch(
+ eradication_config=flashblade.BucketEradicationConfig(
+ manual_eradication=module.params["manual_eradication"],
+ eradication_mode=module.params["eradication_mode"],
+ eradication_delay=module.params["eradication_delay"],
+ )
+ )
+ res = bladev2.patch_buckets(bucket=worm, names=[module.params["name"]])
+ if res.status_code != 200:
+ module.warn(
+ msg="Failed to set Bucket Eradication config correctly for bucket {0}. "
+ "Error: {1}".format(module.params["name"], res.errors[0].message)
+ )
module.exit_json(changed=changed)
@@ -416,6 +461,7 @@ def update_bucket(module, blade, bucket):
"""Update Bucket"""
changed = False
change_pac = False
+ change_worm = False
bladev2 = get_system(module)
bucket_detail = list(bladev2.get_buckets(names=[module.params["name"]]).items)[0]
api_version = blade.api_version.list_versions().versions
@@ -520,7 +566,52 @@ def update_bucket(module, blade, bucket):
msg="Failed to update Public Access config correctly for bucket {0}. "
"Error: {1}".format(module.params["name"], res.errors[0].message)
)
- module.exit_json(changed=(changed or change_pac))
+ if WORM_VERSION in api_version:
+ current_worm = {
+ "eradication_delay": bucket_detail.eradication_config.eradication_delay,
+ "manual_eradication": bucket_detail.eradication_config.manual_eradication,
+ "eradication_mode": bucket_detail.eradication_config.eradication_mode,
+ }
+ if module.params["eradication_delay"] is None:
+ new_delay = current_worm["eradication_delay"]
+ else:
+ new_delay = module.params["eradication_delay"] * SEC_PER_DAY
+ if module.params["manual_eradication"] is None:
+ new_manual = current_worm["manual_eradication"]
+ else:
+ if module.params["manual_eradication"]:
+ new_manual = "enabled"
+ else:
+ new_manual = "disabled"
+ if (
+ module.params["eradication_mode"]
+ and module.params["eradication_mode"] != current_worm["eradication_mode"]
+ ):
+ new_mode = module.params["eradication_mode"]
+ else:
+ new_mode = current_worm["eradication_mode"]
+ new_worm = {
+ "eradication_delay": new_delay,
+ "manual_eradication": new_manual,
+ "eradication_mode": new_mode,
+ }
+ if current_worm != new_worm:
+ change_worm = True
+ worm = BucketPatch(
+ public_access_config=flashblade.BucketEradicationConfig(
+ eradication_delay=new_worm.eradication_delay,
+ manual_eradication=new_worm.manual_eradication,
+ eradication_mode=new_worm.eradication_mode,
+ )
+ )
+ if change_worm and not module.check_mode:
+ res = bladev2.patch_buckets(bucket=worm, names=[module.params["name"]])
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to update Eradication config correctly for bucket {0}. "
+ "Error: {1}".format(module.params["name"], res.errors[0].message)
+ )
+ module.exit_json(changed=(changed or change_pac or change_worm))
def eradicate_bucket(module, blade):
@@ -564,6 +655,11 @@ def main():
default="absent", choices=["enabled", "suspended", "absent"]
),
state=dict(default="present", choices=["present", "absent"]),
+ eradication_delay=dict(type="int"),
+ eradication_mode=dict(
+ type="str", choices=["permission-based", "retention-based"]
+ ),
+ manual_eradication=dict(type="bool"),
)
)
@@ -575,6 +671,12 @@ def main():
if not HAS_PYPURECLIENT:
module.fail_json(msg="py-pure-client sdk is required to support VSO mode")
+ if (
+ module.params["eradication_delay"]
+ and not 30 >= module.params["eradication_delay"] >= 1
+ ):
+ module.fail_json(msg="Eradication Delay must be between 1 and 30 days.")
+
state = module.params["state"]
blade = get_blade(module)
api_version = blade.api_version.list_versions().versions
diff --git a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_connect.py b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_connect.py
index 846351453..23e54845c 100644
--- a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_connect.py
+++ b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_connect.py
@@ -138,8 +138,8 @@ from ansible_collections.purestorage.flashblade.plugins.module_utils.purefb impo
)
-FAN_IN_MAXIMUM = 1
-FAN_OUT_MAXIMUM = 3
+FAN_IN_MAXIMUM = 5
+FAN_OUT_MAXIMUM = 5
MIN_REQUIRED_API_VERSION = "1.9"
THROTTLE_API_VERSION = "2.3"
@@ -215,7 +215,7 @@ def create_connection(module, blade):
remote_conn_cnt = (
remote_system.array_connections.list_array_connections().pagination_info.total_item_count
)
- if remote_conn_cnt == FAN_IN_MAXIMUM:
+ if remote_conn_cnt >= FAN_IN_MAXIMUM:
module.fail_json(
msg="Remote array {0} already connected to {1} other array. Fan-In not supported".format(
remote_array, remote_conn_cnt
@@ -244,7 +244,7 @@ def create_connection(module, blade):
def create_v2_connection(module, blade):
"""Create connection between REST 2 capable arrays"""
changed = True
- if blade.get_array_connections().total_item_count == FAN_OUT_MAXIMUM:
+ if blade.get_array_connections().total_item_count >= FAN_OUT_MAXIMUM:
module.fail_json(
msg="FlashBlade fan-out maximum of {0} already reached".format(
FAN_OUT_MAXIMUM
@@ -262,7 +262,7 @@ def create_v2_connection(module, blade):
)
remote_array = list(remote_system.get_arrays().items)[0].name
remote_conn_cnt = remote_system.get_array_connections().total_item_count
- if remote_conn_cnt == FAN_IN_MAXIMUM:
+ if remote_conn_cnt >= FAN_IN_MAXIMUM:
module.fail_json(
msg="Remote array {0} already connected to {1} other array. Fan-In not supported".format(
remote_array, remote_conn_cnt
diff --git a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_fs.py b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_fs.py
index 8d332e8b7..81c12d4b7 100644
--- a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_fs.py
+++ b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_fs.py
@@ -195,11 +195,17 @@ options:
version_added: "1.12.0"
continuous_availability:
description:
- - Deifines if the file system will be continuously available during
+ - Defines if the file system will be continuously available during
disruptive scenarios such as network disruption, blades failover, etc
type: bool
default: true
version_added: "1.15.0"
+ group_ownership:
+ description:
+ - The group ownership for new files and directories in a file system
+ type: str
+ choices: [ 'creator', 'parent-directory' ]
+ version_added: "1.17.0"
extends_documentation_fragment:
- purestorage.flashblade.purestorage.fb
"""
@@ -314,6 +320,7 @@ MULTIPROTOCOL_API_VERSION = "1.11"
EXPORT_POLICY_API_VERSION = "2.3"
SMB_POLICY_API_VERSION = "2.10"
CA_API_VERSION = "2.12"
+GOWNER_API_VERSION = "2.13"
def get_fs(module, blade):
@@ -567,6 +574,21 @@ def create_fs(module, blade):
res.errors[0].message,
)
)
+ if GOWNER_API_VERSION in api_version and module.params["group_ownership"]:
+ go_attr = FileSystemPatch(
+ group_ownership=module.params["group_ownership"]
+ )
+ res = system.patch_file_systems(
+ names=[module.params["name"]], file_system=go_attr
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Filesystem {0} created, but failed to set group ownership"
+ "Error: {1}".format(
+ module.params["name"],
+ res.errors[0].message,
+ )
+ )
module.exit_json(changed=changed)
@@ -911,8 +933,29 @@ def modify_fs(module, blade):
res.errors[0].message,
)
)
+ if GOWNER_API_VERSION in api_version:
+ change_go = False
+ if module.params["group_ownership"] != current_fs.group_ownership:
+ change_go = True
+ if not module.check_mode:
+ go_attr = FileSystemPatch(
+ group_ownership=module.params["group_ownership"]
+ )
+ res = system.patch_file_systems(
+ names=[module.params["name"]], file_system=go_attr
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to modify group ownership for "
+ "filesystem {0}. Error: {1}".format(
+ module.params["name"],
+ res.errors[0].message,
+ )
+ )
- module.exit_json(changed=(changed or change_export or change_share or change_ca))
+ module.exit_json(
+ changed=(changed or change_export or change_share or change_ca or change_go)
+ )
def _delete_fs(module, blade):
@@ -1057,6 +1100,7 @@ def main():
smb_aclmode=dict(
type="str", default="shared", choices=["shared", "native"]
),
+ group_ownership=dict(choices=["creator", "parent-directory"]),
policy_state=dict(default="present", choices=["present", "absent"]),
state=dict(default="present", choices=["present", "absent"]),
delete_link=dict(default=False, type="bool"),
diff --git a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_info.py b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_info.py
index 033312e82..418dacd5d 100644
--- a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_info.py
+++ b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_info.py
@@ -111,6 +111,7 @@ BUCKET_API_VERSION = "2.8"
SMB_CLIENT_API_VERSION = "2.10"
SPACE_API_VERSION = "2.11"
PUBLIC_API_VERSION = "2.12"
+NAP_API_VERSION = "2.13"
def _millisecs_to_time(millisecs):
@@ -218,6 +219,10 @@ def generate_default_dict(module, blade):
default_info["security_update"] = getattr(
blade_info, "security_update", None
)
+ if NAP_API_VERSION in api_version:
+ default_info["network_access_protocol"] = getattr(
+ blade_info.network_access_policy, "name", "None"
+ )
return default_info
diff --git a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_policy.py b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_policy.py
index ebe70aa48..36ffee997 100644
--- a/ansible_collections/purestorage/flashblade/plugins/modules/purefb_policy.py
+++ b/ansible_collections/purestorage/flashblade/plugins/modules/purefb_policy.py
@@ -52,7 +52,7 @@ options:
- Type of policy
default: snapshot
type: str
- choices: [ snapshot, access, nfs, smb_share, smb_client ]
+ choices: [ snapshot, access, nfs, smb_share, smb_client, network ]
version_added: "1.9.0"
account:
description:
@@ -344,6 +344,14 @@ options:
type: str
default: ""
version_added: '1.14.0'
+ interfaces:
+ description:
+ - Specifies which product interfaces the network access policy rule
+ applies to, whether it is permitting or denying access.
+ type: list
+ elements: str
+ choices: [ "management-ssh", "management-rest-api", "management-web-ui", "snmp", "local-network-superuser-password-access" ]
+ version_added: '1.17.0'
extends_documentation_fragment:
- purestorage.flashblade.purestorage.fb
"""
@@ -546,6 +554,8 @@ try:
SmbClientPolicyRule,
SmbClientPolicy,
ObjectStoreAccessPolicyPost,
+ NetworkAccessPolicy,
+ NetworkAccessPolicyRule,
)
except ImportError:
HAS_PYPURECLIENT = False
@@ -577,6 +587,7 @@ NFS_POLICY_API_VERSION = "2.3"
NFS_RENAME_API_VERSION = "2.4"
SMB_POLICY_API_VERSION = "2.10"
SMB_ENCRYPT_API_VERSION = "2.11"
+NET_POLICY_API_VERSION = "2.13"
def _convert_to_millisecs(hour):
@@ -1065,6 +1076,51 @@ def create_smb_client_policy(module, blade):
module.exit_json(changed=changed)
+def create_network_access_policy(module, blade):
+ """Create Network Access Policy"""
+ changed = True
+ versions = blade.api_version.list_versions().versions
+ if not module.check_mode:
+ res = blade.post_network_access_policies(names=[module.params["name"]])
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to create network access policy {0}.Error: {1}".format(
+ module.params["name"], res.errors[0].message
+ )
+ )
+ if not module.params["enabled"]:
+ res = blade.patch_network_access_policies(
+ policy=SmbClientPolicy(enabled=False), names=[module.params["name"]]
+ )
+ if res.status_code != 200:
+ blade.delete_network_access_policies(names=[module.params["name"]])
+ module.fail_json(
+ msg="Failed to create network access policy {0}.Error: {1}".format(
+ module.params["name"], res.errors[0].message
+ )
+ )
+ if not module.params["client"]:
+ module.fail_json(msg="client is required to create a new rule")
+ else:
+ rule = NetworkAccessPolicyRule(
+ client=module.params["client"],
+ effect=module.params["effect"],
+ interfaces=module.params["interfaces"],
+ )
+ res = blade.post_network_access_policies_rules(
+ policy_names=[module.params["name"]],
+ rule=rule,
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to rule for policy {0}. Error: {1}".format(
+ module.params["name"],
+ res.errors[0].message,
+ )
+ )
+ module.exit_json(changed=changed)
+
+
def update_smb_client_policy(module, blade):
"""Update SMB Client Policy Rule"""
@@ -1341,6 +1397,268 @@ def delete_nfs_policy(module, blade):
module.exit_json(changed=changed)
+def update_network_access_policy(module, blade):
+ """Update Networkk Access Policy Rule"""
+
+ changed = False
+ if module.params["client"]:
+ current_policy_rule = blade.get_network_access_policies_rules(
+ policy_names=[module.params["name"]],
+ filter="client='" + module.params["client"] + "'",
+ )
+ if (
+ current_policy_rule.status_code == 200
+ and current_policy_rule.total_item_count == 0
+ ):
+ rule = NetworkAccessPolicyRule(
+ client=module.params["client"],
+ effect=module.params["effect"],
+ interfaces=module.params["interfaces"],
+ )
+ changed = True
+ if not module.check_mode:
+ if module.params["before_rule"]:
+ before_name = (
+ module.params["name"] + "." + str(module.params["before_rule"])
+ )
+ res = blade.post_network_access_policies_rules(
+ policy_names=[module.params["name"]],
+ rule=rule,
+ before_rule_name=before_name,
+ )
+ else:
+ res = blade.post_network_access_policies_rules(
+ policy_names=[module.params["name"]],
+ rule=rule,
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to create rule for client {0} "
+ "in policy {1}. Error: {2}".format(
+ module.params["client"],
+ module.params["name"],
+ res.errors[0].message,
+ )
+ )
+ else:
+ rules = list(current_policy_rule.items)
+ cli_count = None
+ done = False
+ if module.params["client"] == "*":
+ for cli in range(0, len(rules)):
+ if rules[cli].client == "*":
+ cli_count = cli
+ if not cli_count:
+ rule = NetworkAccessPolicyRule(
+ client=module.params["client"],
+ effect=module.params["effect"],
+ interfaces=module.params["interfaces"],
+ )
+ done = True
+ changed = True
+ if not module.check_mode:
+ if module.params["before_rule"]:
+ res = blade.post_network_access_policies_rules(
+ policy_names=[module.params["name"]],
+ rule=rule,
+ before_rule_name=(
+ module.params["name"]
+ + "."
+ + str(module.params["before_rule"]),
+ ),
+ )
+ else:
+ res = blade.post_network_access_policies_rules(
+ policy_names=[module.params["name"]],
+ rule=rule,
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to create rule for "
+ "client {0} in policy {1}. Error: {2}".format(
+ module.params["client"],
+ module.params["name"],
+ res.errors[0].message,
+ )
+ )
+ if not done:
+ old_policy_rule = rules[0]
+ current_rule = {
+ "client": sorted(old_policy_rule.client),
+ "effect": old_policy_rule.effect,
+ "interfaces": old_policy_rule.interfaces,
+ }
+ if module.params["interfaces"]:
+ new_interfaces = module.params["interfaces"]
+ else:
+ new_interfaces = current_rule["interfaces"]
+ if module.params["effect"]:
+ new_effect = module.params["effect"]
+ else:
+ new_effect = current_rule["effect"]
+ if module.params["client"]:
+ new_client = sorted(module.params["client"])
+ else:
+ new_client = sorted(current_rule["client"])
+ new_rule = {
+ "client": new_client,
+ "effect": new_effect,
+ "interfaces": new_interfaces,
+ }
+ if current_rule != new_rule:
+ changed = True
+ if not module.check_mode:
+ rule = NetworkAccessPolicyRule(
+ client=module.params["client"],
+ effect=module.params["effect"],
+ interfaces=module.params["interfaces"],
+ )
+ res = blade.patch_network_access_policies_rules(
+ names=[
+ module.params["name"] + "." + str(old_policy_rule.index)
+ ],
+ rule=rule,
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to update network access client rule {0}. Error: {1}".format(
+ module.params["name"]
+ + "."
+ + str(old_policy_rule.index),
+ res.errors[0].message,
+ )
+ )
+ if (
+ module.params["before_rule"]
+ and module.params["before_rule"] != old_policy_rule.index
+ ):
+ changed = True
+ if not module.check_mode:
+ before_name = (
+ module.params["name"]
+ + "."
+ + str(module.params["before_rule"])
+ )
+ res = blade.patch_network_access_policies_rules(
+ names=[
+ module.params["name"] + "." + str(old_policy_rule.index)
+ ],
+ rule=NetworkAccessPolicyRule(),
+ before_rule_name=before_name,
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to move network access client rule {0}. Error: {1}".format(
+ module.params["name"]
+ + "."
+ + str(old_policy_rule.index),
+ res.errors[0].message,
+ )
+ )
+ current_policy = list(
+ blade.get_network_access_policies(names=[module.params["name"]]).items
+ )[0]
+ if current_policy.enabled != module.params["enabled"]:
+ changed = True
+ if not module.check_mode:
+ res = blade.patch_network_access_policies(
+ policy=NetworkAccessPolicy(enabled=module.params["enabled"]),
+ names=[module.params["name"]],
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to change state of network access policy {0}.Error: {1}".format(
+ module.params["name"], res.errors[0].message
+ )
+ )
+ module.exit_json(changed=changed)
+
+
+def delete_network_access_policy(module, blade):
+ """Delete Network Access Policy, or Rule
+
+ If client is provided then delete the client rule if it exists.
+ """
+
+ changed = False
+ policy_delete = True
+ if module.params["client"]:
+ policy_delete = False
+ res = blade.get_network_access_policies_rules(
+ policy_names=[module.params["name"]],
+ filter="client='" + module.params["client"] + "'",
+ )
+ if res.status_code == 200:
+ if res.total_item_count == 0:
+ pass
+ elif res.total_item_count == 1:
+ rule = list(res.items)[0]
+ if module.params["client"] == rule.client:
+ changed = True
+ if not module.check_mode:
+ res = blade.delete_network_access_policies_rules(
+ names=[rule.name]
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to delete rule for client {0} in policy {1}. "
+ "Error: {2}".format(
+ module.params["client"],
+ module.params["name"],
+ res.errors[0].message,
+ )
+ )
+ else:
+ rules = list(res.items)
+ for cli in range(0, len(rules)):
+ if rules[cli].client == "*":
+ changed = True
+ if not module.check_mode:
+ res = blade.delete_network_access_policies_rules(
+ names=[rules[cli].name]
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to delete rule for client {0} in policy {1}. "
+ "Error: {2}".format(
+ module.params["client"],
+ module.params["name"],
+ res.errors[0].message,
+ )
+ )
+ if policy_delete:
+ changed = True
+ if not module.check_mode:
+ res = blade.delete_network_Access_policies(names=[module.params["name"]])
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to delete network access policy {0}. Error: {1}".format(
+ module.params["name"], res.errors[0].message
+ )
+ )
+ module.exit_json(changed=changed)
+
+
+def rename_network_access_policy(module, blade):
+ """Rename Network Access Policy"""
+
+ changed = True
+ if not module.check_mode:
+ res = blade.patch_network_access_policies(
+ names=[module.params["name"]],
+ policy=NfsExportPolicy(name=module.params["rename"]),
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Failed to rename network access policy {0} to {1}. Error: {2}".format(
+ module.params["name"],
+ module.params["rename"],
+ res.errors[0].message,
+ )
+ )
+ module.exit_json(changed=changed)
+
+
def rename_nfs_policy(module, blade):
"""Rename NFS Export Policy"""
@@ -2544,7 +2862,14 @@ def main():
policy_type=dict(
type="str",
default="snapshot",
- choices=["snapshot", "access", "nfs", "smb_share", "smb_client"],
+ choices=[
+ "snapshot",
+ "access",
+ "nfs",
+ "smb_share",
+ "smb_client",
+ "network",
+ ],
),
enabled=dict(type="bool", default=True),
timezone=dict(type="str"),
@@ -2635,6 +2960,17 @@ def main():
choices=["disabled", "optional", "required"],
),
desc=dict(type="str", default=""),
+ interfaces=dict(
+ type="list",
+ elements="str",
+ choices=[
+ "management-ssh",
+ "management-rest-api",
+ "management-web-ui",
+ "snmp",
+ "local-network-superuser-password-access",
+ ],
+ ),
)
)
@@ -2644,6 +2980,7 @@ def main():
["policy_type", "nfs", ["name"]],
["policy_type", "smb_client", ["name"]],
["policy_type", "smb_share", ["name"]],
+ ["policy_type", "network", ["interfaces"]],
]
module = AnsibleModule(
@@ -2857,6 +3194,56 @@ def main():
create_smb_share_policy(module, blade)
elif state == "absent" and policy:
delete_smb_share_policy(module, blade)
+ elif module.params["policy_type"] == "network":
+ if NET_POLICY_API_VERSION not in versions:
+ module.fail_json(
+ msg=(
+ "Minimum FlashBlade REST version required: {0}".format(
+ NET_POLICY_API_VERSION
+ )
+ )
+ )
+ if not HAS_PYPURECLIENT:
+ module.fail_json(msg="py-pure-client sdk is required for this module")
+ blade = get_system(module)
+ try:
+ policy = list(
+ blade.get_network_access_policies(names=[module.params["name"]]).items
+ )[0]
+ except AttributeError:
+ policy = None
+ if module.params["rename"]:
+ try:
+ new_policy = list(
+ blade.get_network_access_policies(
+ names=[module.params["rename"]]
+ ).items
+ )[0]
+ except AttributeError:
+ new_policy = None
+ if policy and state == "present" and not module.params["rename"]:
+ if module.params["before_rule"]:
+ res = blade.get_network_access_policies_rules(
+ policy_names=[module.params["name"]],
+ names=[
+ module.params["name"] + "." + str(module.params["before_rule"])
+ ],
+ )
+ if res.status_code != 200:
+ module.fail_json(
+ msg="Rule index {0} does not exist.".format(
+ module.params["before_rule"]
+ )
+ )
+ update_network_access_policy(module, blade)
+ elif (
+ state == "present" and module.params["rename"] and policy and not new_policy
+ ):
+ rename_network_access_policy(module, blade)
+ elif state == "present" and not policy and not module.params["rename"]:
+ create_network_access_policy(module, blade)
+ elif state == "absent" and policy:
+ delete_network_access_policy(module, blade)
elif SNAPSHOT_POLICY_API_VERSION in versions:
if not HAS_PYPURECLIENT:
module.fail_json(msg="py-pure-client sdk is required for this module")