mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-04-24 19:31:26 -07:00
Restore removed google modules (#675)
* Revert "Remove entries of modules that no longer exist." partially. This reverts commitc1e1b37da4
. * Revert "The _info module is in google.cloud." This reverts commit26f5c84924
. * Revert "Remove modules that were moved to the google.cloud collection according to ansible/ansible's ansible_builtin_runtime.yml." This reverts commita1442ccc35
. * Fix FQCNs in examples and module references. * Add changelog fragment. * Update ignore.txt. * Remove bad lines.
This commit is contained in:
parent
52cce0b7af
commit
7ac467a359
18 changed files with 1804 additions and 169 deletions
400
plugins/modules/cloud/google/gcp_backend_service.py
Normal file
400
plugins/modules/cloud/google/gcp_backend_service.py
Normal file
|
@ -0,0 +1,400 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright 2017 Google Inc.
|
||||
# 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
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
module: gcp_backend_service
|
||||
short_description: Create or Destroy a Backend Service.
|
||||
description:
|
||||
- Create or Destroy a Backend Service. See
|
||||
U(https://cloud.google.com/compute/docs/load-balancing/http/backend-service) for an overview.
|
||||
Full install/configuration instructions for the Google Cloud modules can
|
||||
be found in the comments of ansible/test/gce_tests.py.
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "apache-libcloud >= 1.3.0"
|
||||
notes:
|
||||
- Update is not currently supported.
|
||||
- Only global backend services are currently supported. Regional backends not currently supported.
|
||||
- Internal load balancing not currently supported.
|
||||
deprecated:
|
||||
removed_in: 2.0.0 # was Ansible 2.12
|
||||
why: Updated modules released with increased functionality
|
||||
alternative: Use M(google.cloud.gcp_compute_backend_service) instead.
|
||||
author:
|
||||
- "Tom Melendez (@supertom) <tom@supertom.com>"
|
||||
options:
|
||||
backend_service_name:
|
||||
description:
|
||||
- Name of the Backend Service.
|
||||
required: true
|
||||
backends:
|
||||
description:
|
||||
- List of backends that make up the backend service. A backend is made up of
|
||||
an instance group and optionally several other parameters. See
|
||||
U(https://cloud.google.com/compute/docs/reference/latest/backendServices)
|
||||
for details.
|
||||
required: true
|
||||
healthchecks:
|
||||
description:
|
||||
- List of healthchecks. Only one healthcheck is supported.
|
||||
required: true
|
||||
enable_cdn:
|
||||
description:
|
||||
- If true, enable Cloud CDN for this Backend Service.
|
||||
type: bool
|
||||
port_name:
|
||||
description:
|
||||
- Name of the port on the managed instance group (MIG) that backend
|
||||
services can forward data to. Required for external load balancing.
|
||||
protocol:
|
||||
description:
|
||||
- The protocol this Backend Service uses to communicate with backends.
|
||||
Possible values are HTTP, HTTPS, TCP, and SSL. The default is HTTP.
|
||||
required: false
|
||||
timeout:
|
||||
description:
|
||||
- How many seconds to wait for the backend before considering it a failed
|
||||
request. Default is 30 seconds. Valid range is 1-86400.
|
||||
required: false
|
||||
service_account_email:
|
||||
description:
|
||||
- Service account email
|
||||
credentials_file:
|
||||
description:
|
||||
- Path to the JSON file associated with the service account email.
|
||||
project_id:
|
||||
description:
|
||||
- GCE project ID.
|
||||
state:
|
||||
description:
|
||||
- Desired state of the resource
|
||||
default: "present"
|
||||
choices: ["absent", "present"]
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Create Minimum Backend Service
|
||||
community.general.gcp_backend_service:
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
credentials_file: "{{ credentials_file }}"
|
||||
project_id: "{{ project_id }}"
|
||||
backend_service_name: "{{ bes }}"
|
||||
backends:
|
||||
- instance_group: managed_instance_group_1
|
||||
healthchecks:
|
||||
- healthcheck_name_for_backend_service
|
||||
port_name: myhttpport
|
||||
state: present
|
||||
|
||||
- name: Create BES with extended backend parameters
|
||||
community.general.gcp_backend_service:
|
||||
service_account_email: "{{ service_account_email }}"
|
||||
credentials_file: "{{ credentials_file }}"
|
||||
project_id: "{{ project_id }}"
|
||||
backend_service_name: "{{ bes }}"
|
||||
backends:
|
||||
- instance_group: managed_instance_group_1
|
||||
max_utilization: 0.6
|
||||
max_rate: 10
|
||||
- instance_group: managed_instance_group_2
|
||||
max_utilization: 0.5
|
||||
max_rate: 4
|
||||
healthchecks:
|
||||
- healthcheck_name_for_backend_service
|
||||
port_name: myhttpport
|
||||
state: present
|
||||
timeout: 60
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
backend_service_created:
|
||||
description: Indicator Backend Service was created.
|
||||
returned: When a Backend Service is created.
|
||||
type: bool
|
||||
sample: "True"
|
||||
backend_service_deleted:
|
||||
description: Indicator Backend Service was deleted.
|
||||
returned: When a Backend Service is deleted.
|
||||
type: bool
|
||||
sample: "True"
|
||||
backend_service_name:
|
||||
description: Name of the Backend Service.
|
||||
returned: Always.
|
||||
type: str
|
||||
sample: "my-backend-service"
|
||||
backends:
|
||||
description: List of backends (comprised of instance_group) that
|
||||
make up a Backend Service.
|
||||
returned: When a Backend Service exists.
|
||||
type: list
|
||||
sample: "[ { 'instance_group': 'mig_one', 'zone': 'us-central1-b'} ]"
|
||||
enable_cdn:
|
||||
description: If Cloud CDN is enabled. null if not set.
|
||||
returned: When a backend service exists.
|
||||
type: bool
|
||||
sample: "True"
|
||||
healthchecks:
|
||||
description: List of healthchecks applied to the Backend Service.
|
||||
returned: When a Backend Service exists.
|
||||
type: list
|
||||
sample: "[ 'my-healthcheck' ]"
|
||||
protocol:
|
||||
description: Protocol used to communicate with the Backends.
|
||||
returned: When a Backend Service exists.
|
||||
type: str
|
||||
sample: "HTTP"
|
||||
port_name:
|
||||
description: Name of Backend Port.
|
||||
returned: When a Backend Service exists.
|
||||
type: str
|
||||
sample: "myhttpport"
|
||||
timeout:
|
||||
description: In seconds, how long before a request sent to a backend is
|
||||
considered failed.
|
||||
returned: If specified.
|
||||
type: int
|
||||
sample: "myhttpport"
|
||||
'''
|
||||
|
||||
try:
|
||||
from ast import literal_eval
|
||||
HAS_PYTHON26 = True
|
||||
except ImportError:
|
||||
HAS_PYTHON26 = False
|
||||
|
||||
try:
|
||||
import libcloud
|
||||
from libcloud.compute.types import Provider
|
||||
from libcloud.compute.providers import get_driver
|
||||
from libcloud.common.google import GoogleBaseError, QuotaExceededError, \
|
||||
ResourceExistsError, ResourceInUseError, ResourceNotFoundError
|
||||
from libcloud.compute.drivers.gce import GCEAddress
|
||||
_ = Provider.GCE
|
||||
HAS_LIBCLOUD = True
|
||||
except ImportError:
|
||||
HAS_LIBCLOUD = False
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.general.plugins.module_utils.gce import gce_connect
|
||||
from ansible_collections.community.general.plugins.module_utils.gcp import check_params
|
||||
|
||||
|
||||
def _validate_params(params):
|
||||
"""
|
||||
Validate backend_service params.
|
||||
|
||||
This function calls _validate_backend_params to verify
|
||||
the backend-specific parameters.
|
||||
|
||||
:param params: Ansible dictionary containing configuration.
|
||||
:type params: ``dict``
|
||||
|
||||
:return: True or raises ValueError
|
||||
:rtype: ``bool`` or `class:ValueError`
|
||||
"""
|
||||
fields = [
|
||||
{'name': 'timeout', 'type': int, 'min': 1, 'max': 86400},
|
||||
]
|
||||
try:
|
||||
check_params(params, fields)
|
||||
_validate_backend_params(params['backends'])
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
return (True, '')
|
||||
|
||||
|
||||
def _validate_backend_params(backends):
|
||||
"""
|
||||
Validate configuration for backends.
|
||||
|
||||
:param backends: Ansible dictionary containing backends configuration (only).
|
||||
:type backends: ``dict``
|
||||
|
||||
:return: True or raises ValueError
|
||||
:rtype: ``bool`` or `class:ValueError`
|
||||
"""
|
||||
fields = [
|
||||
{'name': 'balancing_mode', 'type': str, 'values': ['UTILIZATION', 'RATE', 'CONNECTION']},
|
||||
{'name': 'max_utilization', 'type': float},
|
||||
{'name': 'max_connections', 'type': int},
|
||||
{'name': 'max_rate', 'type': int},
|
||||
{'name': 'max_rate_per_instance', 'type': float},
|
||||
]
|
||||
|
||||
if not backends:
|
||||
raise ValueError('backends should be a list.')
|
||||
|
||||
for backend in backends:
|
||||
try:
|
||||
check_params(backend, fields)
|
||||
except Exception:
|
||||
raise
|
||||
|
||||
if 'max_rate' in backend and 'max_rate_per_instance' in backend:
|
||||
raise ValueError('Both maxRate or maxRatePerInstance cannot be set.')
|
||||
|
||||
return (True, '')
|
||||
|
||||
|
||||
def get_backend_service(gce, name):
|
||||
"""
|
||||
Get a Backend Service from GCE.
|
||||
|
||||
:param gce: An initialized GCE driver object.
|
||||
:type gce: :class: `GCENodeDriver`
|
||||
|
||||
:param name: Name of the Backend Service.
|
||||
:type name: ``str``
|
||||
|
||||
:return: A GCEBackendService object or None.
|
||||
:rtype: :class: `GCEBackendService` or None
|
||||
"""
|
||||
try:
|
||||
# Does the Backend Service already exist?
|
||||
return gce.ex_get_backendservice(name=name)
|
||||
|
||||
except ResourceNotFoundError:
|
||||
return None
|
||||
|
||||
|
||||
def get_healthcheck(gce, name):
|
||||
return gce.ex_get_healthcheck(name)
|
||||
|
||||
|
||||
def get_instancegroup(gce, name, zone=None):
|
||||
return gce.ex_get_instancegroup(name=name, zone=zone)
|
||||
|
||||
|
||||
def create_backend_service(gce, params):
|
||||
"""
|
||||
Create a new Backend Service.
|
||||
|
||||
:param gce: An initialized GCE driver object.
|
||||
:type gce: :class: `GCENodeDriver`
|
||||
|
||||
:param params: Dictionary of parameters needed by the module.
|
||||
:type params: ``dict``
|
||||
|
||||
:return: Tuple with changed stats
|
||||
:rtype: tuple in the format of (bool, bool)
|
||||
"""
|
||||
from copy import deepcopy
|
||||
|
||||
changed = False
|
||||
return_data = False
|
||||
# only one healthcheck is currently supported
|
||||
hc_name = params['healthchecks'][0]
|
||||
hc = get_healthcheck(gce, hc_name)
|
||||
backends = []
|
||||
for backend in params['backends']:
|
||||
ig = get_instancegroup(gce, backend['instance_group'],
|
||||
backend.get('zone', None))
|
||||
kwargs = deepcopy(backend)
|
||||
kwargs['instance_group'] = ig
|
||||
backends.append(gce.ex_create_backend(
|
||||
**kwargs))
|
||||
|
||||
bes = gce.ex_create_backendservice(
|
||||
name=params['backend_service_name'], healthchecks=[hc], backends=backends,
|
||||
enable_cdn=params['enable_cdn'], port_name=params['port_name'],
|
||||
timeout_sec=params['timeout'], protocol=params['protocol'])
|
||||
|
||||
if bes:
|
||||
changed = True
|
||||
return_data = True
|
||||
|
||||
return (changed, return_data)
|
||||
|
||||
|
||||
def delete_backend_service(bes):
|
||||
"""
|
||||
Delete a Backend Service. The Instance Groups are NOT destroyed.
|
||||
"""
|
||||
changed = False
|
||||
return_data = False
|
||||
if bes.destroy():
|
||||
changed = True
|
||||
return_data = True
|
||||
return (changed, return_data)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(argument_spec=dict(
|
||||
backends=dict(type='list', required=True),
|
||||
backend_service_name=dict(required=True),
|
||||
healthchecks=dict(type='list', required=True),
|
||||
service_account_email=dict(),
|
||||
service_account_permissions=dict(type='list'),
|
||||
enable_cdn=dict(type='bool'),
|
||||
port_name=dict(type='str'),
|
||||
protocol=dict(type='str', default='TCP',
|
||||
choices=['HTTP', 'HTTPS', 'SSL', 'TCP']),
|
||||
timeout=dict(type='int'),
|
||||
state=dict(choices=['absent', 'present'], default='present'),
|
||||
pem_file=dict(),
|
||||
credentials_file=dict(),
|
||||
project_id=dict(), ), )
|
||||
|
||||
if not HAS_PYTHON26:
|
||||
module.fail_json(
|
||||
msg="GCE module requires python's 'ast' module, python v2.6+")
|
||||
if not HAS_LIBCLOUD:
|
||||
module.fail_json(
|
||||
msg='libcloud with GCE Backend Service support (1.3+) required for this module.')
|
||||
|
||||
gce = gce_connect(module)
|
||||
if not hasattr(gce, 'ex_create_instancegroupmanager'):
|
||||
module.fail_json(
|
||||
msg='libcloud with GCE Backend Service support (1.3+) required for this module.',
|
||||
changed=False)
|
||||
|
||||
params = {}
|
||||
params['state'] = module.params.get('state')
|
||||
params['backend_service_name'] = module.params.get('backend_service_name')
|
||||
params['backends'] = module.params.get('backends')
|
||||
params['healthchecks'] = module.params.get('healthchecks')
|
||||
params['enable_cdn'] = module.params.get('enable_cdn', None)
|
||||
params['port_name'] = module.params.get('port_name', None)
|
||||
params['protocol'] = module.params.get('protocol', None)
|
||||
params['timeout'] = module.params.get('timeout', None)
|
||||
|
||||
try:
|
||||
_validate_params(params)
|
||||
except Exception as e:
|
||||
module.fail_json(msg=e.message, changed=False)
|
||||
|
||||
changed = False
|
||||
json_output = {'state': params['state']}
|
||||
bes = get_backend_service(gce, params['backend_service_name'])
|
||||
|
||||
if not bes:
|
||||
if params['state'] == 'absent':
|
||||
# Doesn't exist and state==absent.
|
||||
changed = False
|
||||
module.fail_json(
|
||||
msg="Cannot delete unknown backend service: %s" %
|
||||
(params['backend_service_name']))
|
||||
else:
|
||||
# Create
|
||||
(changed, json_output['backend_service_created']) = create_backend_service(gce,
|
||||
params)
|
||||
elif params['state'] == 'absent':
|
||||
# Delete
|
||||
(changed, json_output['backend_service_deleted']) = delete_backend_service(bes)
|
||||
else:
|
||||
# TODO(supertom): Add update support when it is available in libcloud.
|
||||
changed = False
|
||||
|
||||
json_output['changed'] = changed
|
||||
json_output.update(params)
|
||||
module.exit_json(**json_output)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue