Version information
This version is compatible with:
- Puppet Enterprise 2019.8.x, 2019.7.x, 2019.5.x, 2019.4.x, 2019.3.x, 2019.2.x, 2019.1.x, 2019.0.x, 2018.1.x, 2017.3.x, 2017.2.x, 2017.1.x, 2016.5.x, 2016.4.x
- Puppet >= 4.7.0 < 7.0.0
- , , , , , ,
This module has been deprecated by its author since Dec 4th 2020.
The author has suggested dellemc-powerstore as its replacement.
Tasks:
- appliance_collection_query
- file_interface_route_delete
- file_system_create
- file_system_delete
Plans:
- capacity_volumes
- create_assign_protection_policy
- create_multiple_volumes
- create_volume
- create_volume_attach_host_with_fs
- delete_multiple_volumes
- find_empty_volume_groups
- and 2 more. See all plans
Start using this module
Documentation
Puppet module for Dell EMC PowerStore
Table of Contents
- Puppet module for Dell EMC PowerStore
- Installation for use with Puppet Enterprise
Overview
The dellemc-powerstore
module manages resources on Dell EMC PowerStore.
Dell EMC PowerStore is a next-generation midrange data storage solution targeted at customers who are looking for value, flexibility, and simplicity. Dell EMC PowerStore provides our customers with data-centric, intelligent, and adaptable infrastructure that supports both traditional and modern workloads.
The dellemc-powerstore
Puppet module allows you to configure and deploy Dell EMC PowerStore using Puppet Bolt. To that end it offers resource types, tasks and plans.
License
Setup
Requirements
- Puppet Bolt
2.29.0
or later or - Puppet Enterprise
2019.8
or later
Installation for use with Bolt
-
Create a Bolt project with a name of your choosing, for example:
mkdir pws cd pws bolt project init --modules dellemc-powerstore
Your new Bolt project is ready to go. To list available plans, run
bolt plan show
To list all Bolt tasks related to the
volume
resource, runbolt task show --filter volume
See Bolt documentation for more information on Puppet Bolt.
-
Create an
inventory.yaml
in your project directory, like so:version: 2 targets: - name: my_array uri: my.powerstore.host config: transport: remote remote: host: my.powerstore.host user: admin password: My$ecret! remote-transport: powerstore
Installation for use with Puppet Enterprise
Installation of this module needs to be done using PE Code Manager. To that end,
-
Add the following to the
Puppetfile
:mod 'dellemc-powerstore', :latest mod 'puppet-format', :latest
-
Perform a code deploy using Code Manager webhook, CD4PE or by using the command
puppet code deploy
on the Primary PE Server.
Note that it is often recommended to pin the installed modules to specific versions in the Puppetfile
. For the purposes of this document, we use :latest
which will fetch the latest available module version each time Code Manager code deploy is done in PE.
Usage with Bolt
Using Tasks
Introduction to Dell EMC PowerStore tasks
Every Dell EMC PowerStore API endpoint has a corresponding task. For example, for manipulating Dell EMC PowerStore volumes, the following tasks are available:
- volume_collection_query
- volume_instance_query
- volume_attach
- volume_clone
- volume_create
- volume_delete
- volume_detach
- volume_modify
- volume_refresh
- volume_restore
- volume_snapshot
Task usage is displayed by running bolt task show
, for example:
bolt task show powerstore::volume_attach
powerstore::volume_attach - Attach a volume to a host or host group.
USAGE:
bolt task run --targets <node-name> powerstore::volume_attach host_group_id=<value> host_id=<value> id=<value> logical_unit_number=<value>
PARAMETERS:
- host_group_id: Optional[String]
Unique identifier of the host group to be attached to the volume. Only one of host_id or host_group_id can be supplied.
- host_id: Optional[String]
Unique identifier of the host to be attached to the volume. Only one of host_id or host_group_id can be supplied.
- id: String
Unique identifier of volume to attach.
- logical_unit_number: Optional[Integer[0,16383]]
Logical unit number for the host volume access.
The --targets
parameter (abbreviated by -t
) is the name of the device as configured in the inventory file (see above).
Every parameter is displayed along with its data type. Optional parameters have a type starting with the word Optional
. So in the above example, the task accepts 4 parameters:
host_group_id
: optional String parameterhost_id
: optional String parameterid
: required String parameterlogical_unit_number
: optional parameter, should be an Integer between 0 and 16383.
Tasks live in the tasks/
folder of the module repository.
Examples
-
Get a list of volumes:
bolt task run powerstore::volume_collection_query -t my_array
-
Get details of one volume:
bolt task run powerstore::volume_instance_query id=<volume_id> -t my_array
-
Create a volume:
bolt task run powerstore::volume_create name="small_volume" size=1048576 description="Small Volume" -t my_array
Using Plans
Plans are higher-level workflows that can leverage logic, tasks and commands to perform orchestrated operations on managed devices. Plans can be written using YAML or Puppet language (see documentation on writing Plans). Example dellemc-powerstore
plans can be found in the plans directory of this repository and are documented here.
For displaying usage information for a plan, run bolt plan show
, for example:
> bolt plan show powerstore::capacity_volumes
powerstore::capacity_volumes - list volumes with more than given capacity
USAGE:
bolt plan run powerstore::capacity_volumes threshold=<value> targets=<value>
PARAMETERS:
- threshold: Variant[Numeric,String]
Volume capacity needed (in bytes or MB/GB/TB)
- targets: TargetSpec
Example of running the plan:
> bolt plan run powerstore::capacity_volumes -t my_array threshold=220G
Starting: plan powerstore::capacity_volumes
Starting: task powerstore::volume_collection_query on my_array
Finished: task powerstore::volume_collection_query with 0 failures in 1.64 sec
+----------------------+-----------------+------------+
| List of volumes with capacity > 220G |
+----------------------+-----------------+------------+
| volume name | capacity | MB |
+----------------------+-----------------+------------+
| Volume1 | 43980465111040 | 43.98 TB |
| my_large_volume | 595926712320 | 595.93 GB |
| my_terabyte_volume | 1099511627776 | 1.10 TB |
+----------------------+-----------------+------------+
Finished: plan powerstore::capacity_volumes in 1.94 sec
Plan completed successfully with no result
Using Idempotent Puppet Resource Types
Tasks are an imperative way to query or manipulate state. In addition, the dellemc-powerstore
module offers Puppet resource types which offer a declarative and idempotent way of managing the device's desired state.
Example of managing a volume called my_volume
and ensuring it is created if it does not exist:
- Example using YAML-language plan:
resources: - powerstore_volume: my_volume parameters: size: 26843545600 description: My 25G Volume ensure: present
- Example using a Puppet-language plan:
powerstore_volume { 'my_volume': ensure => present, size => 26843545600, description => 'My 25G Volume', }
See the create_volume.pp and create_volume_yaml.yaml example plans showing a parametrized version of the above.
See the reference documentation for a list of all available Resource types.
Usage with Puppet Enterprise
After the module and its dependencies have been deployed inside PE (see Installation for use with Puppet Enterprise), its tasks and plans should become usable in the PE Console and through the PE Orchestrator APIs.
You can onboard the devices using the Nodes | Add | Add Network Device menu option. Please enter the device's credentials (see the inventory.yaml
above for an example of the credential parameters). After the device has been created you can start managing it as a standard PE node using Puppet manifests with resources and run tasks and plans against the device.
Reference
Please see REFERENCE for detailed information on available resource types, tasks and plans.
Direct links to the various parts of the reference documentation:
Limitations
The module has been tested on CentOS 7 and Windows 10 only but should work on any platform Bolt supports.
Development
Installing PDK
To run syntax checks and unit and acceptance tests, you need to first install the Puppet Development Kit, or PDK.
After installing, cd
to the module directory to run various command explained below.
Running syntax checks
> pdk validate
pdk (INFO): Using Ruby 2.5.8
pdk (INFO): Using Puppet 6.17.0
pdk (INFO): Running all available validators...
┌ [✔] Running metadata validators ...
├── [✔] Checking metadata syntax (metadata.json tasks/*.json).
└── [✔] Checking module metadata style (metadata.json).
┌ [✔] Running puppet validators ...
└── [✔] Checking Puppet manifest style (**/*.pp).
┌ [✔] Running ruby validators ...
└── [✔] Checking Ruby code style (**/**.rb).
┌ [✔] Running tasks validators ...
├── [✔] Checking task names (tasks/**/*).
└── [✔] Checking task metadata style (tasks/*.json).
┌ [✔] Running yaml validators ...
└── [✔] Checking YAML syntax (**/*.yaml **/*.yml).
Running unit tests
> pdk test unit
You should expect to see something like this - the most important thing is that you should have 0 failures:
pdk (INFO): Using Ruby 2.5.8
pdk (INFO): Using Puppet 6.17.0
[✔] Preparing to run the unit tests.
......................................................................................................................
Finished in 2.25 seconds (files took 5.17 seconds to load)
118 examples, 0 failures
Setting up the prism mock API server
The current acceptance test suite assumes that the prism
API server is up and running. prism
is a Open Source tool which can read an OpenAPI specification and generate a mock API server on the fly which is then able to validate incoming requests against the OpenAPI schemas and serve compliant responses with example data.
Although - in theory - it is possible to run acceptance tests against a real device, that is much harder to automate because of unknown id
s of existing resources.
-
Install prism by following the documentation
-
Make sure you have a copy of the Dell EMC PowerStore OpenAPI json file, let's call it
powerstore.json
-
Remove all cyclical dependencies from the OpenAPI json file since
prism
does not support cycles inside OpenAPI specifications, producing the filepowerstore-nocycles.json
-
Start the mock API server:
prism mock powerstore-nocycles.json
You will see something like:
[5:43:55 PM] › [CLI] … awaiting Starting Prism… [5:43:56 PM] › [CLI] ℹ info GET http://127.0.0.1:4010/appliance [5:43:56 PM] › [CLI] ℹ info GET http://127.0.0.1:4010/appliance/vel [5:43:56 PM] › [CLI] ℹ info PATCH http://127.0.0.1:4010/appliance/maiores [5:43:56 PM] › [CLI] ℹ info GET http://127.0.0.1:4010/node [5:43:56 PM] › [CLI] ℹ info GET http://127.0.0.1:4010/node/ut [5:43:56 PM] › [CLI] ℹ info GET http://127.0.0.1:4010/network [5:43:56 PM] › [CLI] ℹ info GET http://127.0.0.1:4010/network/dolor [5:43:56 PM] › [CLI] ℹ info PATCH http://127.0.0.1:4010/network/placeat [5:43:56 PM] › [CLI] ℹ info POST http://127.0.0.1:4010/network/adipisci/replace [5:43:56 PM] › [CLI] ℹ info POST http://127.0.0.1:4010/network/nam/scale [5:43:56 PM] › [CLI] ℹ info GET http://127.0.0.1:4010/ip_pool_address [5:43:56 PM] › [CLI] ℹ info GET http://127.0.0.1:4010/ip_pool_address/pariatur ...
The prism mock API server is now up and running on the default port 4010.
Running type/provider acceptance tests
> MOCK_ACCEPTANCE=true pdk bundle rspec spec/acceptance
The test output will be something like this:
pdk (INFO): Using Ruby 2.5.8
pdk (INFO): Using Puppet 6.17.0
Running tests against this machine !
Run options: exclude {:update=>true, :bolt=>true}
powerstore_email_notify_destination
get powerstore_email_notify_destination
create powerstore_email_notify_destination
delete powerstore_email_notify_destination
and the prism log will show something like this:
[5:47:39 PM] › [HTTP SERVER] get /email_notify_destination ℹ info Request received
[5:47:39 PM] › [NEGOTIATOR] ℹ info Request contains an accept header: */*
[5:47:39 PM] › [VALIDATOR] ✔ success The request passed the validation rules. Looking for the best response
[5:47:39 PM] › [NEGOTIATOR] ✔ success Found a compatible content for */*
[5:47:39 PM] › [NEGOTIATOR] ✔ success Responding with the requested status code 200
[5:47:39 PM] › [HTTP SERVER] get /appliance ℹ info Request received
[5:47:39 PM] › [NEGOTIATOR] ℹ info Request contains an accept header: */*
[5:47:39 PM] › [VALIDATOR] ✔ success The request passed the validation rules. Looking for the best response
[5:47:39 PM] › [NEGOTIATOR] ✔ success Found a compatible content for */*
[5:47:39 PM] › [NEGOTIATOR] ✔ success Responding with the requested status code 200
[5:47:39 PM] › [HTTP SERVER] post /email_notify_destination ℹ info Request received
[5:47:39 PM] › [NEGOTIATOR] ℹ info Request contains an accept header: */*
[5:47:39 PM] › [VALIDATOR] ✔ success The request passed the validation rules. Looking for the best response
[5:47:39 PM] › [NEGOTIATOR] ✔ success Found a compatible content for */*
[5:47:39 PM] › [NEGOTIATOR] ✔ success Responding with the requested status code 201
[5:47:50 PM] › [HTTP SERVER] get /appliance ℹ info Request received
[5:47:50 PM] › [NEGOTIATOR] ℹ info Request contains an accept header: */*
[5:47:50 PM] › [VALIDATOR] ✔ success The request passed the validation rules. Looking for the best response
[5:47:50 PM] › [NEGOTIATOR] ✔ success Found a compatible content for */*
[5:47:50 PM] › [NEGOTIATOR] ✔ success Responding with the requested status code 200
[5:47:50 PM] › [HTTP SERVER] get /email_notify_destination ℹ info Request received
[5:47:50 PM] › [NEGOTIATOR] ℹ info Request contains an accept header: */*
[5:47:50 PM] › [VALIDATOR] ✔ success The request passed the validation rules. Looking for the best response
[5:47:50 PM] › [NEGOTIATOR] ✔ success Found a compatible content for */*
[5:47:50 PM] › [NEGOTIATOR] ✔ success Responding with the requested status code 200
[5:47:50 PM] › [HTTP SERVER] get /appliance ℹ info Request received
[5:47:50 PM] › [NEGOTIATOR] ℹ info Request contains an accept header: */*
[5:47:50 PM] › [VALIDATOR] ✔ success The request passed the validation rules. Looking for the best response
[5:47:50 PM] › [NEGOTIATOR] ✔ success Found a compatible content for */*
[5:47:50 PM] › [NEGOTIATOR] ✔ success Responding with the requested status code 200
[5:47:50 PM] › [HTTP SERVER] delete /email_notify_destination/string ℹ info Request received
[5:47:50 PM] › [NEGOTIATOR] ℹ info Request contains an accept header: */*
[5:47:50 PM] › [VALIDATOR] ✔ success The request passed the validation rules. Looking for the best response
[5:47:50 PM] › [NEGOTIATOR] ✔ success Found a compatible content for */*
[5:47:50 PM] › [NEGOTIATOR] ✔ success Responding with the requested status code 204
The get /appliance
request is done for authentication purposes.
Running task acceptance tests
To execute all available acceptance tests for tasks, run the following:
> MOCK_ACCEPTANCE=true pdk bundle exec rspec spec/task
pdk (INFO): Using Ruby 2.5.8
pdk (INFO): Using Puppet 6.17.0
Run options: exclude {:update=>true, :bolt=>true}
powerstore_email_notify_destination
performs email_notify_destination_collection_query
performs email_notify_destination_instance_query
performs email_notify_destination_delete
performs email_notify_destination_create
performs email_notify_destination_test
...
To run a subset of task tests, for example volume-related, do:
> MOCK_ACCEPTANCE=true pdk bundle exec rspec spec/task -e volume
Generating REFERENCE.md
To (re-)generate the REFERENCE.md file which documents the available types, tasks, functions and plans, run:
pdk bundle exec rake strings:generate:reference
Contributors
Contact
... forthcoming ...
Release Notes
See CHANGELOG
What are tasks?
Modules can contain tasks that take action outside of a desired state managed by Puppet. It’s perfect for troubleshooting or deploying one-off changes, distributing scripts to run across your infrastructure, or automating changes that need to happen in a particular order as part of an application deployment.
Tasks in this module release
What are plans?
Modules can contain plans that take action outside of a desired state managed by Puppet. It’s perfect for troubleshooting or deploying one-off changes, distributing scripts to run across your infrastructure, or automating changes that need to happen in a particular order as part of an application deployment.
Dependencies
- puppet/format (>=0.1.1 < 2.0.0)
Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.