summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/plugins/modules/ocapi_info.py
blob: 9906d804c10e2bb1d030bb3f1bab4591964871ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#!/usr/bin/python
# -*- coding: utf-8 -*-

# Copyright (c) 2022 Western Digital Corporation
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import absolute_import, division, print_function

__metaclass__ = type


DOCUMENTATION = '''
---
module: ocapi_info
version_added: 6.3.0
short_description: Manages Out-Of-Band controllers using Open Composable API (OCAPI)
description:
  - Builds OCAPI URIs locally and sends them to remote OOB controllers to
    get information back.
extends_documentation_fragment:
  - community.general.attributes
  - community.general.attributes.info_module
options:
  category:
    required: true
    description:
      - Category to execute on OOB controller.
    type: str
  command:
    required: true
    description:
      - Command to execute on OOB controller.
    type: str
  baseuri:
    required: true
    description:
      - Base URI of OOB controller.
    type: str
  proxy_slot_number:
    description: For proxied inband requests, the slot number of the IOM.  Only applies if O(baseuri) is a proxy server.
    type: int
  username:
    required: true
    description:
      - Username for authenticating to OOB controller.
    type: str
  password:
    required: true
    description:
      - Password for authenticating to OOB controller.
    type: str
  timeout:
    description:
      - Timeout in seconds for URL requests to OOB controller.
    default: 10
    type: int
  job_name:
    description:
      - Name of job for fetching status.
    type: str


author: "Mike Moerk (@mikemoerk)"
'''

EXAMPLES = '''
  - name: Get job status
    community.general.ocapi_info:
      category: Status
      command: JobStatus
      baseuri: "http://iom1.wdc.com"
      jobName: FirmwareUpdate
      username: "{{ username }}"
      password: "{{ password }}"
'''

RETURN = '''
msg:
    description: Message with action result or error description.
    returned: always
    type: str
    sample: "Action was successful"

percentComplete:
    description: Percent complete of the relevant operation.  Applies to O(command=JobStatus).
    returned: when supported
    type: int
    sample: 99

operationStatus:
    description: Status of the relevant operation.  Applies to O(command=JobStatus).  See OCAPI documentation for details.
    returned: when supported
    type: str
    sample: "Activate needed"

operationStatusId:
    description: Integer value of status (corresponds to operationStatus).  Applies to O(command=JobStatus).  See OCAPI documentation for details.
    returned: when supported
    type: int
    sample: 65540

operationHealth:
    description: Health of the operation.  Applies to O(command=JobStatus).  See OCAPI documentation for details.
    returned: when supported
    type: str
    sample: "OK"

operationHealthId:
    description: >
     Integer value for health of the operation (corresponds to RV(operationHealth)). Applies to O(command=JobStatus).
     See OCAPI documentation for details.
    returned: when supported
    type: str
    sample: "OK"

details:
    description: Details of the relevant operation.  Applies to O(command=JobStatus).
    returned: when supported
    type: list
    elements: str

status:
    description: Dictionary containing status information.  See OCAPI documentation for details.
    returned: when supported
    type: dict
    sample: {
        "Details": [
            "None"
        ],
        "Health": [
            {
                "ID": 5,
                "Name": "OK"
            }
        ],
        "State": {
            "ID": 16,
            "Name": "In service"
            }
       }
'''

from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.general.plugins.module_utils.ocapi_utils import OcapiUtils
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.six.moves.urllib.parse import urljoin

# More will be added as module features are expanded
CATEGORY_COMMANDS_ALL = {
    "Jobs": ["JobStatus"]
}


def main():
    result = {}
    module = AnsibleModule(
        argument_spec=dict(
            category=dict(required=True),
            command=dict(required=True, type='str'),
            job_name=dict(type='str'),
            baseuri=dict(required=True, type='str'),
            proxy_slot_number=dict(type='int'),
            username=dict(required=True),
            password=dict(required=True, no_log=True),
            timeout=dict(type='int', default=10)
        ),
        supports_check_mode=True
    )

    category = module.params['category']
    command = module.params['command']

    # admin credentials used for authentication
    creds = {
        'user': module.params['username'],
        'pswd': module.params['password']
    }

    # timeout
    timeout = module.params['timeout']

    base_uri = "https://" + module.params["baseuri"]
    proxy_slot_number = module.params.get("proxy_slot_number")
    ocapi_utils = OcapiUtils(creds, base_uri, proxy_slot_number, timeout, module)

    # Check that Category is valid
    if category not in CATEGORY_COMMANDS_ALL:
        module.fail_json(msg=to_native("Invalid Category '%s'. Valid Categories = %s" % (category, list(CATEGORY_COMMANDS_ALL.keys()))))

    # Check that the command is valid
    if command not in CATEGORY_COMMANDS_ALL[category]:
        module.fail_json(msg=to_native("Invalid Command '%s'. Valid Commands = %s" % (command, CATEGORY_COMMANDS_ALL[category])))

    # Organize by Categories / Commands
    if category == "Jobs":
        if command == "JobStatus":
            if module.params.get("job_name") is None:
                module.fail_json(msg=to_native(
                    "job_name required for JobStatus command."))
            job_uri = urljoin(base_uri, 'Jobs/' + module.params["job_name"])
            result = ocapi_utils.get_job_status(job_uri)

    if result['ret'] is False:
        module.fail_json(msg=to_native(result['msg']))
    else:
        del result['ret']
        changed = False
        session = result.get('session', dict())
        kwargs = {
            "changed": changed,
            "session": session,
            "msg": "Action was successful." if not module.check_mode else result.get(
                "msg", "No action performed in check mode."
            )
        }
        result_keys = [result_key for result_key in result if result_key not in kwargs]
        for result_key in result_keys:
            kwargs[result_key] = result[result_key]
        module.exit_json(**kwargs)


if __name__ == '__main__':
    main()