Repository: ansible/ansible

Issue:
sf_volume_manager is using incorrect type entry for QoS setting
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
lib/ansible/modules/storage/netapp/sf_volume-manager.py
qos dict should be of type dict

##### ANSIBLE VERSION
```
ansible 2.3.1.0
```

##### CONFIGURATION

##### OS / ENVIRONMENT
"N/A"

##### SUMMARY
The qos type specified in the Ansible module [1] is listed as a string, however the data is actually a dict of the form {'minIOPS': 1000, 'maxIOPS': 20000, 'burstIOPS': 100000}, you can shove this into a string but it won't parse when sent to the device API.

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Sample
  hosts: localhost
  gather_facts: no
  connection: local
  vars:
    cluster_ip: 10.117.78.235
    cluster_login: admin
    cluster_pass: admin
  tasks:
    - name: Create Volume
      sf_volume_manager:
        hostname: "{{ cluster_ip }}"
        username: "{{ cluster_login }}"
        password: "{{ cluster_pass }}"
        state: present
        name: foo
        account_id: 736
        qos: '{minIOPS: 1000, maxIOPS: 20000, burstIOPS: 50000}'
        size: 1
        size_unit: gb
        enable512e: False
```

##### EXPECTED RESULTS
Volume should be created on the cluster with the specified settings

##### ACTUAL RESULTS
```
TASK [Create Volume] ********************************************************************************************************************************************************************************************************************************************************************************************************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ApiServerError(method_name="CreateVolume", err_json={"id": 2, "error": {"message": "qos: Invalid type: expected object but found \"{'burstIOPS': 50000, 'minIOPS': 1000, 'maxIOPS': 20000}\"\n", "code": 500, "name": "xInvalidParameterType"}})
fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "Error provisioning volume foo of size 1000000000"}
```



Discussion:
cc @hulquest @lmprice @timuster
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/storage/netapp/sf_volume_manager.py b/lib/ansible/modules/storage/netapp/sf_volume_manager.py
--- a/lib/ansible/modules/storage/netapp/sf_volume_manager.py
+++ b/lib/ansible/modules/storage/netapp/sf_volume_manager.py
@@ -49,7 +49,7 @@
         required: false
 
     qos:
-        description: Initial quality of service settings for this volume.
+        description: Initial quality of service settings for this volume. Configure as dict in playbooks.
         required: false
         default: None
 
@@ -102,6 +102,7 @@
        password: "{{ solidfire_password }}"
        state: present
        name: AnsibleVol
+       qos: {minIOPS: 1000, maxIOPS: 20000, burstIOPS: 50000}
        account_id: 3
        enable512e: False
        size: 1
@@ -156,7 +157,7 @@ def __init__(self):
             account_id=dict(required=True, type='int'),
 
             enable512e=dict(type='bool', aliases=['512emulation']),
-            qos=dict(required=False, type='str', default=None),
+            qos=dict(required=False, type='dict', default=None),
             attributes=dict(required=False, type='dict', default=None),
 
             volume_id=dict(type='int', default=None),


Test patch: