mirror of
				https://github.com/ansible-collections/community.general.git
				synced 2024-09-14 20:13:21 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			273 lines
		
	
	
	
		
			9.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			273 lines
		
	
	
	
		
			9.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/python
 | 
						|
# Copyright 2013 Google Inc.
 | 
						|
#
 | 
						|
# This file is part of Ansible
 | 
						|
#
 | 
						|
# Ansible is free software: you can redistribute it and/or modify
 | 
						|
# it under the terms of the GNU General Public License as published by
 | 
						|
# the Free Software Foundation, either version 3 of the License, or
 | 
						|
# (at your option) any later version.
 | 
						|
#
 | 
						|
# Ansible is distributed in the hope that it will be useful,
 | 
						|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
# GNU General Public License for more details.
 | 
						|
#
 | 
						|
# You should have received a copy of the GNU General Public License
 | 
						|
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.
 | 
						|
 | 
						|
DOCUMENTATION = '''
 | 
						|
---
 | 
						|
module: gce_net
 | 
						|
version_added: "1.5"
 | 
						|
short_description: create/destroy GCE networks and firewall rules
 | 
						|
description:
 | 
						|
    - This module can create and destroy Google Compue Engine networks and
 | 
						|
      firewall rules U(https://developers.google.com/compute/docs/networking).
 | 
						|
      The I(name) parameter is reserved for referencing a network while the
 | 
						|
      I(fwname) parameter is used to reference firewall rules.
 | 
						|
      IPv4 Address ranges must be specified using the CIDR
 | 
						|
      U(http://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing) format.
 | 
						|
      Full install/configuration instructions for the gce* modules can
 | 
						|
      be found in the comments of ansible/test/gce_tests.py.
 | 
						|
options:
 | 
						|
  allowed:
 | 
						|
    description:
 | 
						|
      - the protocol:ports to allow ('tcp:80' or 'tcp:80,443' or 'tcp:80-800')
 | 
						|
    required: false
 | 
						|
    default: null 
 | 
						|
    aliases: []
 | 
						|
  ipv4_range:
 | 
						|
    description:
 | 
						|
      - the IPv4 address range in CIDR notation for the network
 | 
						|
    required: false
 | 
						|
    aliases: ['cidr']
 | 
						|
  fwname:
 | 
						|
    description:
 | 
						|
      - name of the firewall rule
 | 
						|
    required: false
 | 
						|
    default: null
 | 
						|
    aliases: ['fwrule']
 | 
						|
  name:
 | 
						|
    description:
 | 
						|
      - name of the network
 | 
						|
    required: false
 | 
						|
    default: null
 | 
						|
    aliases: []
 | 
						|
  src_range:
 | 
						|
    description:
 | 
						|
      - the source IPv4 address range in CIDR notation
 | 
						|
    required: false
 | 
						|
    default: null
 | 
						|
    aliases: ['src_cidr']
 | 
						|
  src_tags:
 | 
						|
    description:
 | 
						|
      - the source instance tags for creating a firewall rule
 | 
						|
    required: false
 | 
						|
    default: null
 | 
						|
    aliases: []
 | 
						|
  state:
 | 
						|
    description:
 | 
						|
      - desired state of the persistent disk
 | 
						|
    required: false
 | 
						|
    default: "present"
 | 
						|
    choices: ["active", "present", "absent", "deleted"]
 | 
						|
    aliases: []
 | 
						|
 | 
						|
requirements: [ "libcloud" ]
 | 
						|
author: Eric Johnson <erjohnso@google.com>
 | 
						|
'''
 | 
						|
 | 
						|
EXAMPLES = '''
 | 
						|
# Simple example of creating a new network
 | 
						|
- local_action: 
 | 
						|
    module: gce_net
 | 
						|
    name: privatenet
 | 
						|
    ipv4_range: '10.240.16.0/24'
 | 
						|
   
 | 
						|
# Simple example of creating a new firewall rule
 | 
						|
- local_action: 
 | 
						|
    module: gce_net
 | 
						|
    name: privatenet
 | 
						|
    allowed: tcp:80,8080
 | 
						|
    src_tags: ["web", "proxy"]
 | 
						|
 | 
						|
'''
 | 
						|
 | 
						|
import sys
 | 
						|
 | 
						|
USER_AGENT_PRODUCT="Ansible-gce_net"
 | 
						|
USER_AGENT_VERSION="v1beta15"
 | 
						|
 | 
						|
try:                                                                            
 | 
						|
    from libcloud.compute.types import Provider                                 
 | 
						|
    from libcloud.compute.providers import get_driver                           
 | 
						|
    from libcloud.common.google import GoogleBaseError, QuotaExceededError, \
 | 
						|
            ResourceExistsError, ResourceNotFoundError
 | 
						|
    _ = Provider.GCE                                                            
 | 
						|
except ImportError:                                                             
 | 
						|
    print("failed=True " + \
 | 
						|
            "msg='libcloud with GCE support required for this module.'")
 | 
						|
    sys.exit(1)                                                                 
 | 
						|
                                                                                
 | 
						|
# Load in the libcloud secrets file                                             
 | 
						|
try:                                                                            
 | 
						|
    import secrets                                                              
 | 
						|
except ImportError:                                                             
 | 
						|
    secrets = None                                                              
 | 
						|
ARGS = getattr(secrets, 'GCE_PARAMS', ())                                       
 | 
						|
KWARGS = getattr(secrets, 'GCE_KEYWORD_PARAMS', {})                             
 | 
						|
 | 
						|
if not ARGS or not 'project' in KWARGS:
 | 
						|
    print("failed=True msg='Missing GCE connection " + \
 | 
						|
            "parameters in libcloud secrets file.'")
 | 
						|
    sys.exit(1)
 | 
						|
 | 
						|
def unexpected_error_msg(error):
 | 
						|
    """Format error string based on passed in error."""
 | 
						|
    msg='Unexpected response: HTTP return_code['
 | 
						|
    msg+='%s], API error code[%s] and message: %s' % (
 | 
						|
            error.http_code, error.code, str(error.value))
 | 
						|
    return msg
 | 
						|
 | 
						|
def format_allowed(allowed):
 | 
						|
    """Format the 'allowed' value so that it is GCE compatible."""
 | 
						|
    if allowed.count(":") == 0:
 | 
						|
        protocol = allowed
 | 
						|
        ports = []
 | 
						|
    elif allowed.count(":") == 1:
 | 
						|
        protocol, ports = allowed.split(":")
 | 
						|
    else:
 | 
						|
        return []
 | 
						|
    if ports.count(","):
 | 
						|
        ports = ports.split(",")
 | 
						|
    else:
 | 
						|
        ports = [ports]
 | 
						|
    return_val = {"IPProtocol": protocol}
 | 
						|
    if ports:
 | 
						|
        return_val["ports"] = ports
 | 
						|
    return [return_val]
 | 
						|
 | 
						|
 | 
						|
def main():
 | 
						|
    module = AnsibleModule(
 | 
						|
        argument_spec = dict(
 | 
						|
            allowed = dict(),
 | 
						|
            ipv4_range = dict(),
 | 
						|
            fwname = dict(),
 | 
						|
            name = dict(),
 | 
						|
            src_range = dict(),
 | 
						|
            src_tags = dict(type='list'),
 | 
						|
            state = dict(default='present'),
 | 
						|
        )
 | 
						|
    )
 | 
						|
 | 
						|
    allowed = module.params.get('allowed')
 | 
						|
    ipv4_range = module.params.get('ipv4_range')
 | 
						|
    fwname = module.params.get('fwname')
 | 
						|
    name = module.params.get('name')
 | 
						|
    src_range = module.params.get('src_range')
 | 
						|
    src_tags = module.params.get('src_tags')
 | 
						|
    state = module.params.get('state')
 | 
						|
 | 
						|
    try:
 | 
						|
        gce = get_driver(Provider.GCE)(*ARGS, **KWARGS)
 | 
						|
        gce.connection.user_agent_append("%s/%s" % (
 | 
						|
                USER_AGENT_PRODUCT, USER_AGENT_VERSION))
 | 
						|
    except Exception, e:
 | 
						|
        module.fail_json(msg=unexpected_error_msg(e), changed=False)
 | 
						|
 | 
						|
    changed = False
 | 
						|
    json_output = {'state': state}
 | 
						|
 | 
						|
    if state in ['active', 'present']:
 | 
						|
        network = None
 | 
						|
        try:
 | 
						|
            network = gce.ex_get_network(name)
 | 
						|
            json_output['name'] = name
 | 
						|
            json_output['ipv4_range'] = network.cidr
 | 
						|
        except ResourceNotFoundError:
 | 
						|
            pass
 | 
						|
        except Exception, e:
 | 
						|
            module.fail_json(msg=unexpected_error_msg(e), changed=False)
 | 
						|
 | 
						|
        # user wants to create a new network that doesn't yet exist
 | 
						|
        if name and not network:
 | 
						|
            if not ipv4_range:
 | 
						|
                module.fail_json(msg="Missing required 'ipv4_range' parameter",
 | 
						|
                    changed=False)
 | 
						|
 | 
						|
            try:
 | 
						|
                network = gce.ex_create_network(name, ipv4_range)
 | 
						|
                json_output['name'] = name
 | 
						|
                json_output['ipv4_range'] = ipv4_range
 | 
						|
                changed = True
 | 
						|
            except Exception, e:
 | 
						|
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
 | 
						|
 | 
						|
        if fwname:
 | 
						|
            # user creating a firewall rule
 | 
						|
            if not allowed and not src_range and not src_tags:
 | 
						|
                if changed and network:
 | 
						|
                    module.fail_json(
 | 
						|
                        msg="Network created, but missing required " + \
 | 
						|
                        "firewall rule parameter(s)", changed=True)
 | 
						|
                module.fail_json(
 | 
						|
                    msg="Missing required firewall rule parameter(s)",
 | 
						|
                    changed=False)
 | 
						|
 | 
						|
            allowed_list = format_allowed(allowed)
 | 
						|
 | 
						|
            try:
 | 
						|
                gce.ex_create_firewall(fwname, allowed_list, network=name,
 | 
						|
                        source_ranges=src_range, source_tags=src_tags)
 | 
						|
                changed = True
 | 
						|
            except ResourceExistsError:
 | 
						|
                pass
 | 
						|
            except Exception, e:
 | 
						|
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
 | 
						|
 | 
						|
            json_output['fwname'] = fwname
 | 
						|
            json_output['allowed'] = allowed
 | 
						|
            json_output['src_range'] = src_range
 | 
						|
            json_output['src_tags'] = src_tags
 | 
						|
 | 
						|
    if state in ['absent', 'deleted']:
 | 
						|
        if fwname:
 | 
						|
            json_output['fwname'] = fwname
 | 
						|
            fw = None
 | 
						|
            try:
 | 
						|
                fw = gce.ex_get_firewall(fwname)
 | 
						|
            except ResourceNotFoundError:
 | 
						|
                pass
 | 
						|
            except Exception, e:
 | 
						|
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
 | 
						|
            if fw:
 | 
						|
                gce.ex_destroy_firewall(fw)
 | 
						|
                changed = True
 | 
						|
        if name:
 | 
						|
            json_output['name'] = name
 | 
						|
            network = None
 | 
						|
            try:
 | 
						|
                network = gce.ex_get_network(name)
 | 
						|
#                json_output['d1'] = 'found network name %s' % name
 | 
						|
            except ResourceNotFoundError:
 | 
						|
#                json_output['d2'] = 'not found network name %s' % name
 | 
						|
                pass
 | 
						|
            except Exception, e:
 | 
						|
#                json_output['d3'] = 'error with %s' % name
 | 
						|
                module.fail_json(msg=unexpected_error_msg(e), changed=False)
 | 
						|
            if network:
 | 
						|
#                json_output['d4'] = 'deleting %s' % name
 | 
						|
                gce.ex_destroy_network(network)
 | 
						|
#                json_output['d5'] = 'deleted %s' % name
 | 
						|
                changed = True
 | 
						|
 | 
						|
    json_output['changed'] = changed
 | 
						|
    print json.dumps(json_output)
 | 
						|
    sys.exit(0)
 | 
						|
 | 
						|
# import module snippets
 | 
						|
from ansible.module_utils.basic import *
 | 
						|
 | 
						|
main()
 |