Migrated to community.vmware_rest

This commit is contained in:
Ansible Core Team 2020-03-09 09:40:30 +00:00 committed by Matt Martz
parent 46b865c7d6
commit f8c4936c10
11 changed files with 0 additions and 1427 deletions

View file

@ -1,720 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import re
import sys
from ansible.module_utils.connection import Connection
from ansible.module_utils.basic import AnsibleModule, env_fallback
from ansible.module_utils._text import to_native
# VMware ReST APIs
#
# Describes each supported VMware ReST APIs and lists its base URL. All
# vSphere ReST APIs begin with '/rest'.
API = dict(
appliance=dict(base='/rest/appliance'),
cis=dict(base='/rest/com/vmware/cis'),
content=dict(base='/rest/com/vmware/content'),
vapi=dict(base='/rest'),
vcenter=dict(base='/rest/vcenter'),
vrops=dict(base='/suiteapi')
)
# Query Filters
#
# This dictionary identifies every valid filter that can be applied to a
# vSphere ReST API query. Each filter has a name, which may be the same
# depending on the type object; an id of the value specified; a type,
# which is typically either a string or a list. If it is a string, the
# format of the expected values is provided as a regex.
FILTER = dict(
clusters=dict(
name='clusters',
id='id',
type='str',
format=r'domain\-[0-9a-fA-F]+',
),
connection_states=dict(
name='connection_states',
id='connection state',
type='list',
choices=[
'CONNECTED',
'DISCONNECTED',
'NOT_RESPONDING',
],
),
datacenters=dict(
name='datacenters',
id='id',
type='str',
format=r'datacenter\-[0-9a-fA-F]+',
),
datastore_types=dict(
name='types',
id='type',
type='list',
choices=[
'',
'CIFS',
'NFS',
'NFS41',
'VFFS',
'VMFS',
'VSAN',
'VVOL',
]
),
datastores=dict(
name='datastores',
id='id',
type='str',
format=r'datastore\-[0-9a-fA-F]+',
),
folder_types=dict(
name='type',
id='type',
type='list',
choices=[
'',
'DATACENTER',
'DATASTORE',
'HOST',
'NETWORK',
'VIRTUAL_MACHINE',
]
),
folders=dict(
name='folders',
id='id',
type='str',
format=r'group\-[hnv][0-9a-fA-F]+',
),
hosts=dict(
name='hosts',
id='id',
type='str',
format=r'host\-[0-9a-fA-F]+',
),
names=dict(
name='names',
id='name',
type='str',
format=r'.+',
),
network_types=dict(
name='types',
id='type',
type='list',
choices=[
'DISTRIBUTED_PORTGROUP',
'OPAQUE_NETWORK',
'STANDARD_PORTGROUP',
],
),
networks=dict(
name='networks',
id='id',
type='str',
format=r'[dvportgroup|network]\-[0-9a-fA-F]+',
),
parent_folders=dict(
name='parent_folders',
id='id',
type='str',
format=r'group\-[hnv][0-9a-fA-F]+',
),
parent_resource_pools=dict(
name='parent_resource_pools',
id='id',
type='str',
format=r'resgroup\-[0-9a-fA-F]+',
),
policies=dict(
name='policies',
id='GUID',
type='str',
format=(r'[0-9a-fA-F]{8}'
r'\-[0-9a-fA-F]{4}'
r'\-[0-9a-fA-F]{4}'
r'\-[0-9a-fA-F]{4}'
r'\-[0-9a-fA-F]{12}'),
),
power_states=dict(
name='power_states',
id='power state',
type='list',
choices=[
'',
'POWERED_OFF',
'POWERED_ON',
'SUSPENDED',
],
),
resource_pools=dict(
name='resource_pools',
id='id',
type='str',
format=r'resgroup\-[0-9a-fA-F]+',
),
status=dict(
name='status',
id='status',
type='list',
choices=[
'COMPLIANT',
'NON_COMPLIANT',
'NOT_APPLICABLE',
'UNKNOWN',
'UNKNOWN_COMPLIANCE',
'OUT_OF_DATE',
],
),
vms=dict(
name='vms',
id='id',
type='str',
format=r'vm\-[0-9a-fA-F]+',
),
)
# vSphere Inventory Objects
#
# This dictionary lists the queryable vSphere inventory objects. Each
# object identifies the API it is managed through, its URL off of the
# API's base, and a list of filters that are valid for this particular
# object.
#
# NOTE: This will be replaced with a class factory pattern as get_id()
# and the get_url() family are tied to this structure.
INVENTORY = dict(
category=dict(
api='cis',
url='/tagging/category',
filters=[],
),
cluster=dict(
api='vcenter',
url='/cluster',
filters=[
'clusters',
'datacenters',
'folders',
'names',
],
),
content_library=dict(
api='content',
url='/library',
filters=[],
),
content_type=dict(
api='content',
url='/type',
filters=[],
),
datacenter=dict(
api='vcenter',
url='/datacenter',
filters=[
'datacenters',
'folders',
'names',
],
),
datastore=dict(
api='vcenter',
url='/datastore',
filters=[
'datacenters',
'datastore_types',
'datastores',
'folders',
'names',
],
),
folder=dict(
api='vcenter',
url='/folder',
filters=[
'datacenters',
'folder_types',
'folders',
'names',
'parent_folders',
],
),
host=dict(
api='vcenter',
url='/host',
filters=[
'clusters',
'connection_states',
'datacenters',
'folders',
'hosts',
'names',
],
),
local_library=dict(
api='content',
url='/local-library',
filters=[],
),
network=dict(
api='vcenter',
url='/network',
filters=[
'datacenters',
'folders',
'names',
'network_types',
'networks',
],
),
resource_pool=dict(
api='vcenter',
url='/resource-pool',
filters=[
'clusters',
'datacenters',
'hosts',
'names',
'parent_resource_pools',
'resource_pools',
]
),
storage_policy=dict(
api='vcenter',
url='/storage/policies',
filters=[
'policies',
'status',
'vms',
],
),
subscribed_library=dict(
api='content',
url='/subscribed-library',
filters=[],
),
tag=dict(
api='cis',
url='/tagging/tag',
filters=[],
),
session=dict(
api='cis',
url='/session',
filters=[],
),
vm=dict(
api='vcenter',
url='/vm',
filters=[
'clusters',
'datacenters',
'folders',
'hosts',
'names',
'power_states',
'resource_pools',
'vms',
],
),
)
class VmwareRestModule(AnsibleModule):
def __init__(self, is_multipart=False, use_object_handler=False, *args, **kwargs):
'''Constructor - This module mediates interactions with the
VMware httpapi connector plugin, implementing VMware's ReST API.
:module: VmwareRestModule extended from AnsibleModule.
:kw is_multipart: Indicates whether module makes multiple API calls.
Default False
:kw use_object_handler: Indicates whether module supports
multiple object types. Default False
'''
# Initialize instance arguments
self.is_multipart = is_multipart
self.use_object_handler = use_object_handler
# Output of module
self.result = {}
# Current key of output
self.key = None
# Current information going to httpapi
self.request = dict(
url=None,
filter=None,
data={},
method=None,
)
# Last response from httpapi
self.response = dict(
status=None,
data={},
)
# Initialize AnsibleModule superclass before params
super(VmwareRestModule, self).__init__(*args, **kwargs)
# Turn on debug if not specified, but ANSIBLE_DEBUG is set
self.module_debug = {}
if self._debug:
self.warn('Enable debug output because ANSIBLE_DEBUG was set.')
self.params['log_level'] = 'debug'
self.log_level = self.params['log_level']
# Params
#
# REQUIRED: Their absence will chuck a rod
self.allow_multiples = self.params['allow_multiples']
self.status_code = self.params['status_code']
# OPTIONAL: Use params.get() to gracefully fail
self.filters = self.params.get('filters')
self.state = self.params.get('state')
# Initialize connection via httpapi connector. See "REST API Calls"
try:
self._connection = Connection(self._socket_path)
except Exception as e:
self.fail(msg=to_native(e))
# Register default status handlers. See "Dynamic Status Handlers"
self._status_handlers = {
'success': self.handle_default_success,
'401': self.handle_default_401,
'404': self.handle_default_404,
'default': self.handle_default_generic,
}
if self.use_object_handler:
self._status_handlers['default'] = self.handle_default_object
# Debugging
#
# Tools to handle debugging output from the APIs.
def _mod_debug(self, key, **kwargs):
self.module_debug[key] = kwargs
if 'module_debug' not in self.module_debug:
self.module_debug = dict(key=kwargs)
else:
self.module_debug.update(key=kwargs)
def _api_debug(self):
'''Route debugging output to the module output.
NOTE: Adding self.path to result['path'] causes an absent in
output. Adding response['data'] causes infinite loop.
'''
return dict(
url=self.request['url'],
filter=self.request['filter'],
data=self.request['data'],
method=self.request['method'],
status=self.response['status'],
state=self.state,
)
# Dynamic Status Handlers
#
# A handler is registered by adding its key, either a module-
# generated value, or the string representation of the status code;
# and the name of the handler function. The provided handlers are
# success defined, by default, as a status code of 200, but
# can be redefined, per module, using the status_code
# parameter in that module's argument_spec.
# 401 Unauthorized access to the API.
# 404 Requested object or API was not found.
# default Any status code not otherwise identified.
# The default handlers are named 'handle_default_[status_code]'.
# User defined handlers should use 'handle_[status_code]' as a
# convention. Note that if the module expects to handle more than
# one type of object, a default object handler replaces the default
# generic handler.
#
# Handlers do not take any arguments, instead using the instance's
# variables to determine the status code and any additional data,
# like object_type. To create or replace a handler, extend this
# class, define the new handler and use the provided 'set_handler'
# method. User handlers can also chain to the default handlers if
# desired.
def set_handler(self, status_key, handler):
'''Registers the handler to the status_key'''
self._status_handlers[status_key] = handler
def _use_handler(self):
'''Invokes the appropriate handler based on status_code'''
if self.response['status'] in self.status_code:
status_key = 'success'
else:
status_key = str(self.response['status'])
if status_key in self._status_handlers.keys():
self._status_handlers[status_key]()
else:
self._status_handlers['default']()
def handle_default_success(self):
'''Default handler for all successful status codes'''
self.result[self.key] = self.response['data']
if self.log_level == 'debug':
self.result[self.key].update(
debug=self._api_debug()
)
if not self.is_multipart:
self.exit()
def handle_default_401(self):
'''Default handler for Unauthorized (401) errors'''
self.fail(msg="Unable to authenticate. Provided credentials are not valid.")
def handle_default_404(self):
'''Default handler for Not-Found (404) errors'''
self.fail(msg="Requested object was not found.")
def handle_default_generic(self):
'''Catch-all handler for all other status codes'''
msg = self.response['data']['value']['messages'][0]['default_message']
self.fail(msg=msg)
def handle_default_object(self):
'''Catch-all handler capable of distinguishing multiple objects'''
try:
msg = self.response['data']['value']['messages'][0]['default_message']
except (KeyError, TypeError):
msg = 'Unable to find the %s object specified due to %s' % (self.key, self.response)
self.fail(msg=msg)
def handle_object_key_error(self):
'''Lazy exception handler'''
msg = ('Please specify correct object type to get information, '
'choices are [%s].' % ", ".join(list(INVENTORY.keys())))
self.fail(msg=msg)
# REST API Calls
#
# VMware's REST API uses GET, POST, PUT, PATCH and DELETE http
# calls to read, create, update and delete objects and their
# attributes. These calls are implemented as functions here.
def get(self, url='/rest', key='result'):
'''Sends a GET request to the httpapi plugin connection to the
specified URL. If successful, the returned data will be placed
in the output under the specified key.
'''
self.request.update(
url=url,
data={},
method='GET',
)
self.key = key
self.response['status'], self.response['data'] = self._connection.send_request(url, {}, method='GET')
self._use_handler()
def post(self, url='/rest', data=None, key='result'):
'''Sends a POST request to the httpapi plugin connection to the
specified URL, with the supplied data. If successful, any
returned data will be placed in the output under the specified
key.
'''
self.request.update(
url=url,
data=data,
method='POST',
)
self.key = key
try:
self.response['status'], self.response['data'] = self._connection.send_request(url, data, method='POST')
except Exception as e:
self.fail(msg=to_native(e))
self._use_handler()
def put(self, url='/rest', data=None, key='result'):
'''Sends a PUT request to the httpapi plugin connection to the
specified URL, with the supplied data. If successful, any
returned data will be placed in the output under the specified
key.
'''
self.request.update(
url=url,
data=data,
method='PUT',
)
self.key = key
self.response['status'], self.response['data'] = self._connection.send_request(url, data, method='PUT')
self._use_handler()
def delete(self, url='/rest', data='result', key='result'):
'''Sends a DELETE request to the httpapi plugin connection to
the specified URL, with the supplied data. If successful, any
returned data will be placed in the output under the specified
key.
'''
self.request.update(
url=url,
data=data,
method='DELETE',
)
self.key = key
self.response['status'], self.response['data'] = self._connection.send_request(url, data, method='DELETE')
self._use_handler()
def get_id(self, object_type, name):
'''Find id(s) of object(s) with given name. allow_multiples
determines whether multiple IDs are returned or not.
:kw object_type: The inventory object type whose id is desired.
:kw name: The name of the object(s) to be retrieved.
:returns: a list of strings representing the IDs of the objects.
'''
try:
url = (API[INVENTORY[object_type]['api']]['base']
+ INVENTORY[object_type]['url'])
if '/' in name:
name.replace('/', '%2F')
url += '&filter.names=' + name
except KeyError:
self.fail(msg='object_type must be one of [%s].'
% ", ".join(list(INVENTORY.keys())))
status, data = self._connection.send_request(url, {}, method='GET')
if status != 200:
self.request.update(url=url, data={}, method='GET')
self.response.update(status=status, data=data)
self.handle_default_generic()
num_items = len(data['value'])
if not self.allow_multiples and num_items > 1:
msg = ('Found %d objects of type %s with name %s. '
'Set allow_multiples to True if this is expected.'
% (num_items, object_type, name))
self.fail(msg=msg)
ids = []
for i in range(num_items):
ids += data[i][object_type]
return ids
def _build_filter(self, object_type):
'''Builds a filter from the optionally supplied params'''
if self.filters:
try:
first = True
for filter in self.filters:
for key in list(filter.keys()):
filter_key = key.lower()
# Check if filter is valid for current object type or not
if filter_key not in INVENTORY[object_type]['filters']:
msg = ('%s is not a valid %s filter, choices are [%s].'
% (key, object_type, ", ".join(INVENTORY[object_type]['filters'])))
self.fail(msg=msg)
# Check if value is valid for the current filter
if ((FILTER[filter_key]['type'] == 'str' and not re.match(FILTER[filter_key]['format'], filter[key])) or
(FILTER[filter_key]['type'] == 'list' and filter[key] not in FILTER[filter_key]['choices'])):
msg = ('%s is not a valid %s %s' % (filter[key], object_type, FILTER[filter_key]['name']))
self.fail(msg=msg)
if first:
self.request['filter'] = '?'
first = False
else:
self.request['filter'] += '&'
# Escape characters
if '/' in filter[key]:
filter[key].replace('/', '%2F')
self.request['filter'] += ('filter.%s=%s'
% (FILTER[filter_key]['name'], filter[key]))
except KeyError:
self.handle_object_key_error()
else:
self.request['filter'] = None
return self.request['filter']
def get_url(self, object_type, with_filter=False):
'''Retrieves the URL of a particular inventory object with or without filter'''
try:
self.url = (API[INVENTORY[object_type]['api']]['base']
+ INVENTORY[object_type]['url'])
if with_filter:
self.url += self._build_filter(object_type)
except KeyError:
self.handle_object_key_error()
return self.url
def get_url_with_filter(self, object_type):
'''Same as get_url, only with_filter is explicitly set'''
return self.get_url(object_type, with_filter=True)
def reset(self):
'''Clears the decks for next request'''
self.request.update(
url=None,
data={},
method=None,
)
self.response.update(
status=None,
data={},
)
def fail(self, msg):
if self.log_level == 'debug':
if self.request['url'] is not None:
self.result['debug'] = self._api_debug()
AnsibleModule.fail_json(self, msg=msg, **self.result)
def exit(self):
'''Called to end client interaction'''
if 'invocation' not in self.result:
self.result['invocation'] = {
'module_args': self.params,
'module_kwargs': {
'is_multipart': self.is_multipart,
'use_object_handler': self.use_object_handler,
}
}
if self.log_level == 'debug':
if not self.is_multipart:
self.result['invocation'].update(debug=self._api_debug())
if self.module_debug:
self.result['invocation'].update(module_debug=self.module_debug)
AnsibleModule.exit_json(self, **self.result)
def _merge_dictionaries(self, a, b):
new = a.copy()
new.update(b)
return new
@staticmethod
def create_argument_spec(use_filters=False, use_state=False):
'''Provide a default argument spec for this module. Filters and
state are optional parameters dependinf on the module's needs.
Additional parameters can be added. The supplied parameters can
have defaults changed or choices pared down, but should not be
removed.
'''
argument_spec = dict(
allow_multiples=dict(type='bool', default=False),
log_level=dict(type='str',
choices=['debug', 'info', 'normal'],
default='normal'),
status_code=dict(type='list', default=[200]),
)
if use_filters:
argument_spec.update(filters=dict(type='list', default=[]))
if use_state:
argument_spec.update(state=dict(type='list',
choices=['absent', 'present', 'query'],
default='query'))
return argument_spec

View file

@ -1,117 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# 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
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = r'''
---
module: vmware_appliance_access_info
short_description: Gathers info about modes of access to the vCenter appliance using REST API.
description:
- This module can be used to gather information about the four modes of accessing the VCSA.
- This module is based on REST API and uses httpapi connection plugin for persistent connection.
- The Appliance API works against the VCSA and uses the "administrator@vsphere.local" user.
version_added: '2.10'
author:
- Paul Knight (@n3pjk)
notes:
- Tested on vSphere 6.7
requirements:
- python >= 2.6
options:
access_mode:
description:
- Method of access to get to appliance
- If not specified, all modes will be returned.
required: false
choices: ['consolecli', 'dcui', 'shell', 'ssh']
type: str
extends_documentation_fragment: VmwareRestModule.documentation
'''
EXAMPLES = r'''
- hosts: all
connection: httpapi
gather_facts: false
vars:
ansible_network_os: vmware
ansible_host: vcenter.my.domain
ansible_user: administrator@vsphere.local
ansible_httpapi_password: "SomePassword"
ansible_httpapi_use_ssl: yes
ansible_httpapi_validate_certs: false
tasks:
- name: Get all access modes information
vmware_appliance_access_info:
- name: Get ssh access mode information
vmware_appliance_access_info:
access_mode: ssh
'''
RETURN = r'''
access_mode:
description: facts about the specified access mode
returned: always
type: dict
sample: {
"value": true
}
'''
from ansible.module_utils.vmware_httpapi.VmwareRestModule import API, VmwareRestModule
SLUG = dict(
consolecli='/access/consolecli',
dcui='/access/dcui',
shell='/access/shell',
ssh='/access/ssh',
)
def get_mode(module, mode):
try:
url = API['appliance']['base'] + SLUG[mode]
except KeyError:
module.fail(msg='[%s] is not a valid access mode. '
'Please specify correct mode, valid choices are '
'[%s].' % (mode, ", ".join(list(SLUG.keys()))))
module.get(url=url, key=mode)
def main():
argument_spec = VmwareRestModule.create_argument_spec()
argument_spec.update(
access_mode=dict(type='str', choices=['consolecli', 'dcui', 'shell', 'ssh'], default=None),
)
module = VmwareRestModule(argument_spec=argument_spec,
supports_check_mode=True,
is_multipart=True,
use_object_handler=True)
access_mode = module.params['access_mode']
if access_mode is None:
access_mode = SLUG.keys()
for mode in access_mode:
get_mode(module, mode)
else:
get_mode(module, access_mode)
module.exit()
if __name__ == '__main__':
main()

View file

@ -1,148 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# 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
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = r'''
---
module: vmware_appliance_health_info
short_description: Gathers info about health of the VCSA.
description:
- This module can be used to gather information about VCSA health.
- This module is based on REST API and uses httpapi connection plugin for persistent connection.
- The Appliance API works against the VCSA and uses the "administrator@vsphere.local" user.
version_added: '2.10'
author:
- Paul Knight (@n3pjk)
notes:
- Tested on vSphere 6.7
requirements:
- python >= 2.6
options:
subsystem:
description:
- A subsystem of the VCSA.
required: false
choices: ['applmgmt', 'databasestorage', 'lastcheck', 'load', 'mem', 'softwarepackages', 'storage', 'swap', 'system']
type: str
asset:
description:
- A VCSA asset that has associated health metrics.
- Valid choices have yet to be determined at this time.
required: false
type: str
extends_documentation_fragment: VmwareRestModule.documentation
'''
EXAMPLES = r'''
- hosts: all
connection: httpapi
gather_facts: false
vars:
ansible_network_os: vmware
ansible_host: vcenter.my.domain
ansible_user: administrator@vsphere.local
ansible_httpapi_password: "SomePassword"
ansible_httpapi_use_ssl: yes
ansible_httpapi_validate_certs: false
tasks:
- name: Get all health attribute information
vmware_appliance_health_info:
- name: Get system health information
vmware_appliance_health_info:
subsystem: system
'''
RETURN = r'''
attribute:
description: facts about the specified health attribute
returned: always
type: dict
sample: {
"value": true
}
'''
from ansible.module_utils.vmware_httpapi.VmwareRestModule import API, VmwareRestModule
SLUG = dict(
applmgmt='/health/applmgmt',
databasestorage='/health/database-storage',
load='/health/load',
mem='/health/mem',
softwarepackages='/health/software-packages',
storage='/health/storage',
swap='/health/swap',
system='/health/system',
lastcheck='/health/system/lastcheck',
)
def get_subsystem(module, subsystem):
try:
url = API['appliance']['base'] + SLUG[subsystem]
except KeyError:
module.fail(msg='[%s] is not a valid subsystem. '
'Please specify correct subsystem, valid choices are '
'[%s].' % (subsystem, ", ".join(list(SLUG.keys()))))
module.get(url=url, key=subsystem)
def main():
argument_spec = VmwareRestModule.create_argument_spec()
argument_spec.update(
subsystem=dict(
type='str',
required=False,
choices=[
'applmgmt',
'databasestorage',
'lastcheck',
'load',
'mem',
'softwarepackages',
'storage',
'swap',
'system',
],
),
asset=dict(type='str', required=False),
)
module = VmwareRestModule(argument_spec=argument_spec,
supports_check_mode=True,
is_multipart=True,
use_object_handler=True)
subsystem = module.params['subsystem']
asset = module.params['asset']
if asset is not None:
url = (API['appliance']['base']
+ ('/health/%s/messages' % asset))
module.get(url=url, key=asset)
elif subsystem is None:
subsystem = SLUG.keys()
for sys in subsystem:
get_subsystem(module, sys)
else:
get_subsystem(module, subsystem)
module.exit()
if __name__ == '__main__':
main()

View file

@ -1,149 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# 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
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = r'''
---
module: vmware_cis_category_info
short_description: Gathers info about all, or a specified category.
description:
- This module can be used to gather information about a specific category.
- This module can also gather facts about all categories.
- This module is based on REST API and uses httpapi connection plugin for persistent connection.
version_added: '2.10'
author:
- Paul Knight (@n3pjk)
notes:
- Tested on vSphere 6.7
requirements:
- python >= 2.6
options:
category_id:
description:
- The object id of the category.
- Exclusive of category_name and used_by_*.
required: false
type: str
category_name:
description:
- The name of the category.
- Exclusive of category_id and used_by_*.
required: false
type: str
used_by_id:
description:
- The id of the entity to list applied categories.
- Exclusive of other used_by_* and category_*.
type: str
used_by_name:
description:
- The name of the entity to list applied categories, whose type is specified in used_by_type.
- Exclusive of other used_by_id and category_*.
type: str
used_by_type:
description:
- The type of the entity to list applied categories, whose name is specified in used_by_name.
- Exclusive of other used_by_id and category_*.
choices: ['cluster', 'content_library', 'content_type', 'datacenter',
'datastore', 'folder', 'host', 'local_library', 'network',
'resource_pool', 'subscribed_library', 'tag', 'vm']
type: str
extends_documentation_fragment: VmwareRestModule.documentation
'''
EXAMPLES = r'''
- name: Get all categories
vmware_cis_category_info:
'''
RETURN = r'''
category:
description: facts about the specified category
returned: always
type: dict
sample: {
"value": true
}
'''
from ansible.module_utils.vmware_httpapi.VmwareRestModule import VmwareRestModule
def main():
argument_spec = VmwareRestModule.create_argument_spec()
argument_spec.update(
category_name=dict(type='str', required=False),
category_id=dict(type='str', required=False),
used_by_name=dict(type='str', required=False),
used_by_type=dict(
type='str',
required=False,
choices=[
'cluster',
'content_library',
'content_type',
'datacenter',
'datastore',
'folder',
'host',
'local_library',
'network',
'resource_pool',
'subscribed_library',
'tag',
'vm',
],
),
used_by_id=dict(type='str', required=False),
)
required_together = [
['used_by_name', 'used_by_type']
]
mutually_exclusive = [
['category_name', 'category_id', 'used_by_id', 'used_by_name'],
['category_name', 'category_id', 'used_by_id', 'used_by_type'],
]
module = VmwareRestModule(argument_spec=argument_spec,
required_together=required_together,
mutually_exclusive=mutually_exclusive,
supports_check_mode=True)
category_name = module.params['category_name']
category_id = module.params['category_id']
used_by_name = module.params['used_by_name']
used_by_type = module.params['used_by_type']
used_by_id = module.params['used_by_id']
url = module.get_url('category')
data = {}
if category_name is not None:
category_id = module.get_id('category', category_name)
if category_id is not None:
url += '/id:' + category_id
module.get(url=url)
else:
if used_by_name is not None:
used_by_id = module.get_id(used_by_type, used_by_name)
url += '?~action=list-used-categories'
data = {
'used_by_entity': used_by_id
}
module.post(url=url, data=data)
module.exit()
if __name__ == '__main__':
main()

View file

@ -1,117 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Abhijeet Kasurde <akasurde@redhat.com>
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# 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
ANSIBLE_METADATA = {
'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'
}
DOCUMENTATION = r'''
---
module: vmware_core_info
short_description: Gathers info about various VMware inventory objects using REST API
description:
- This module can be used to gather information about various VMware inventory objects.
- This module is based on REST API and uses httpapi connection plugin for persistent connection.
version_added: '2.10'
author:
- Abhijeet Kasurde (@Akasurde)
- Paul Knight (@n3pjk)
notes:
- Tested on vSphere 6.7
requirements:
- python >= 2.6
options:
object_type:
description:
- Type of VMware object.
- Valid choices are datacenter, cluster, datastore, folder, host,
network, resource_pool, virtual_machine, content_library,
local_library, subscribed_library, content_type, tag, category.
type: str
default: datacenter
filters:
description:
- A list of filters to find the given object.
- Valid filters for datacenter object type - folders, datacenters, names.
- Valid filters for cluster object type - folders, datacenters, names, clusters.
- Valid filters for datastore object type - folders, datacenters, names, datastores, types.
- Valid filters for folder object type - folders, parent_folders, names, datacenters, type.
- Valid filters for host object type - folders, hosts, names, datacenters, clusters, connection_states.
- Valid filters for network object type - folders, types, names, datacenters, networks.
- Valid filters for resource_pool object type - resource_pools, parent_resource_pools, names, datacenters, hosts, clusters.
- Valid filters for virtual_machine object type - folders, resource_pools, power_states, vms, names, datacenters, hosts, clusters.
- content_library, local_library, subscribed_library, content_type, tag, category does not take any filters.
default: []
type: list
extends_documentation_fragment: VmwareRestModule_filters.documentation
'''
EXAMPLES = r'''
- name: Get All VM without any filters
block:
- name: Get VMs
vmware_core_info:
object_type: "{{ object_type }}"
register: vm_result
- assert:
that:
- vm_result[object_type].value | length > 0
vars:
object_type: vm
- name: Get all clusters from Asia-Datacenter1
vmware_core_info:
object_type: cluster
filters:
- datacenters: "{{ datacenter_obj }}"
register: clusters_result
'''
RETURN = r'''
object_info:
description: information about the given VMware object
returned: always
type: dict
sample: {
"value": [
{
"cluster": "domain-c42",
"drs_enabled": false,
"ha_enabled": false,
"name": "Asia-Cluster1"
}
]
}
'''
from ansible.module_utils.vmware_httpapi.VmwareRestModule import VmwareRestModule
def main():
argument_spec = VmwareRestModule.create_argument_spec(use_filters=True)
argument_spec.update(
object_type=dict(type='str', default='datacenter'),
)
module = VmwareRestModule(argument_spec=argument_spec,
supports_check_mode=True,
use_object_handler=True)
object_type = module.params['object_type']
url = module.get_url_with_filter(object_type)
module.get(url=url, key=object_type)
module.exit()
if __name__ == '__main__':
main()

View file

@ -1,35 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# 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
class ModuleDocFragment(object):
# Parameters for VMware ReST HTTPAPI modules omits filters and state
DOCUMENTATION = r'''
options:
allow_multiples:
description:
- Indicates whether get_id() can return multiple IDs for a given name.
- Typically, this should be false when updating or deleting; otherwise, all named objects could be affected.
required: true
version_added: "2.10"
type: bool
log_level:
description:
- If ANSIBLE_DEBUG is set, this will be forced to 'debug', but can be user-defined otherwise.
required: True
choices: ['debug', 'info', 'normal']
version_added: "2.10"
type: str
default: 'normal'
status_code:
description:
- A list of integer status codes considered to be successful for the this module.
required: true
version_added: "2.10"
type: list
default: [200]
'''

View file

@ -1,41 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# 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
class ModuleDocFragment(object):
# Parameters for VMware ReST HTTPAPI modules includes filters
DOCUMENTATION = r'''
options:
allow_multiples:
description:
- Indicates whether get_id() can return multiple IDs for a given name.
- Typically, this should be false when updating or deleting; otherwise, all named objects could be affected.
required: true
version_added: "2.10"
type: bool
filters:
description:
- The key/value pairs describing filters to be applied to the request(s) made by this instance.
required: false
version_added: "2.10"
type: dict
log_level:
description:
- If ANSIBLE_DEBUG is set, this will be forced to 'debug', but can be user-defined otherwise.
required: True
choices: ['debug', 'info', 'normal']
version_added: "2.10"
type: str
default: 'normal'
status_code:
description:
- A list of integer status codes considered to be successful for the this module.
required: true
version_added: "2.10"
type: list
default: [200]
'''

View file

@ -1,49 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# 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
class ModuleDocFragment(object):
# Parameters for VMware ReST HTTPAPI modules includes filters and state
DOCUMENTATION = r'''
options:
allow_multiples:
description:
- Indicates whether get_id() can return multiple IDs for a given name.
- Typically, this should be false when updating or deleting; otherwise, all named objects could be affected.
required: true
version_added: "2.10"
type: bool
filters:
description:
- The key/value pairs describing filters to be applied to the request(s) made by this instance.
required: false
version_added: "2.10"
type: dict
log_level:
description:
- If ANSIBLE_DEBUG is set, this will be forced to 'debug', but can be user-defined otherwise.
required: True
choices: ['debug', 'info', 'normal']
version_added: "2.10"
type: str
default: 'normal'
state:
description:
- Either 'absent' or 'present', depending on whether object should be removed or created.
required: false
choices: ['absent', 'present', 'query']
version_added: "2.10"
type: str
default: 'present'
status_code:
description:
- A list of integer status codes considered to be successful for the this module.
required: true
version_added: "2.10"
type: list
default: [200]
'''

View file

@ -1,43 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright: (c) 2019, Paul Knight <paul.knight@delaware.gov>
# 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
class ModuleDocFragment(object):
# Parameters for VMware ReST HTTPAPI modules includes filters and state
DOCUMENTATION = r'''
options:
allow_multiples:
description:
- Indicates whether get_id() can return multiple IDs for a given name.
- Typically, this should be false when updating or deleting; otherwise, all named objects could be affected.
required: true
version_added: "2.10"
type: bool
log_level:
description:
- If ANSIBLE_DEBUG is set, this will be forced to 'debug', but can be user-defined otherwise.
required: True
choices: ['debug', 'info', 'normal']
version_added: "2.10"
type: str
default: 'normal'
state:
description:
- Either 'absent' or 'present', depending on whether object should be removed or created.
required: false
choices: ['absent', 'present', 'query']
version_added: "2.10"
type: str
default: 'present'
status_code:
description:
- A list of integer status codes considered to be successful for the this module.
required: true
version_added: "2.10"
type: list
default: [200]
'''

View file

@ -1666,14 +1666,6 @@ lib/ansible/modules/cloud/vmware/vmware_vspan_session.py validate-modules:parame
lib/ansible/modules/cloud/vmware/vmware_vspan_session.py validate-modules:undocumented-parameter
lib/ansible/modules/cloud/vmware/vmware_vswitch.py validate-modules:parameter-list-no-elements
lib/ansible/modules/cloud/vmware/vsphere_copy.py validate-modules:undocumented-parameter
lib/ansible/modules/cloud/vmware_httpapi/vmware_appliance_access_info.py validate-modules:doc-required-mismatch
lib/ansible/modules/cloud/vmware_httpapi/vmware_appliance_access_info.py validate-modules:parameter-list-no-elements
lib/ansible/modules/cloud/vmware_httpapi/vmware_appliance_health_info.py validate-modules:doc-required-mismatch
lib/ansible/modules/cloud/vmware_httpapi/vmware_appliance_health_info.py validate-modules:parameter-list-no-elements
lib/ansible/modules/cloud/vmware_httpapi/vmware_cis_category_info.py validate-modules:doc-required-mismatch
lib/ansible/modules/cloud/vmware_httpapi/vmware_cis_category_info.py validate-modules:parameter-list-no-elements
lib/ansible/modules/cloud/vmware_httpapi/vmware_core_info.py validate-modules:doc-required-mismatch
lib/ansible/modules/cloud/vmware_httpapi/vmware_core_info.py validate-modules:parameter-list-no-elements
lib/ansible/modules/commands/command.py validate-modules:doc-missing-type
lib/ansible/modules/commands/command.py validate-modules:nonexistent-parameter-documented
lib/ansible/modules/commands/command.py validate-modules:parameter-list-no-elements