Merge pull request #6265 from franckcuny/gce-fixes
Add credential parameters to the GCE modules.
This commit is contained in:
commit
40ee030790
7 changed files with 185 additions and 130 deletions
|
@ -197,6 +197,7 @@ In addition to Cobbler and EC2, inventory scripts are also available for::
|
|||
|
||||
BSD Jails
|
||||
Digital Ocean
|
||||
Google Compute Engine
|
||||
Linode
|
||||
OpenShift
|
||||
OpenStack Nova
|
||||
|
|
41
lib/ansible/module_utils/gce.py
Normal file
41
lib/ansible/module_utils/gce.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
USER_AGENT_PRODUCT="Ansible-gce"
|
||||
USER_AGENT_VERSION="v1"
|
||||
|
||||
def gce_connect(module):
|
||||
"""Return a Google Cloud Engine connection."""
|
||||
service_account_email = module.params.get('service_account_email', None)
|
||||
pem_file = module.params.get('pem_file', None)
|
||||
project_id = module.params.get('project_id', None)
|
||||
|
||||
if service_account_email is None or pem_file is None:
|
||||
# Load in the libcloud secrets file
|
||||
try:
|
||||
import secrets
|
||||
except ImportError:
|
||||
secrets = None
|
||||
|
||||
service_account_email, pem_file = getattr(secrets, 'GCE_PARAMS', (None, None))
|
||||
keyword_params = getattr(secrets, 'GCE_KEYWORD_PARAMS', {})
|
||||
project_id = keyword_params.get('project', None)
|
||||
|
||||
if service_account_email is None or pem_file is None or project_id is None:
|
||||
module.fail_json(msg='Missing GCE connection parameters in libcloud secrets file.')
|
||||
return None
|
||||
|
||||
try:
|
||||
gce = get_driver(Provider.GCE)(service_account_email, pem_file, datacenter=module.params.get('zone'), project=project_id)
|
||||
gce.connection.user_agent_append("%s/%s" % (
|
||||
USER_AGENT_PRODUCT, USER_AGENT_VERSION))
|
||||
except (RuntimeError, ValueError), e:
|
||||
module.fail_json(msg=str(e), changed=False)
|
||||
except Exception, e:
|
||||
module.fail_json(msg=unexpected_error_msg(e), changed=False)
|
||||
|
||||
return gce
|
||||
|
||||
def unexpected_error_msg(error):
|
||||
"""Create an 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
|
64
library/cloud/gce
Normal file → Executable file
64
library/cloud/gce
Normal file → Executable file
|
@ -51,6 +51,27 @@ options:
|
|||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
service_account_email:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
pem_file:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- path to the pem file associated with the service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
project_id:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- your GCE project ID
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
name:
|
||||
description:
|
||||
- identifier when working with a single instance
|
||||
|
@ -90,6 +111,8 @@ options:
|
|||
aliases: []
|
||||
|
||||
requirements: [ "libcloud" ]
|
||||
notes:
|
||||
- Either I(name) or I(instance_names) is required.
|
||||
author: Eric Johnson <erjohnso@google.com>
|
||||
'''
|
||||
|
||||
|
@ -119,10 +142,14 @@ EXAMPLES = '''
|
|||
machine_type: n1-standard-1
|
||||
image: debian-6
|
||||
zone: us-central1-a
|
||||
service_account_email: unique-email@developer.gserviceaccount.com
|
||||
pem_file: /path/to/pem_file
|
||||
project_id: project-id
|
||||
tasks:
|
||||
- name: Launch instances
|
||||
local_action: gce instance_names={{names}} machine_type={{machine_type}}
|
||||
image={{image}} zone={{zone}}
|
||||
image={{image}} zone={{zone}} service_account_email={{ service_account_email }}
|
||||
pem_file={{ pem_file }} project_id={{ project_id }}
|
||||
register: gce
|
||||
- name: Wait for SSH to come up
|
||||
local_action: wait_for host={{item.public_ip}} port=22 delay=10
|
||||
|
@ -150,9 +177,6 @@ EXAMPLES = '''
|
|||
|
||||
import sys
|
||||
|
||||
USER_AGENT_PRODUCT="Ansible-gce"
|
||||
USER_AGENT_VERSION="v1beta15"
|
||||
|
||||
try:
|
||||
from libcloud.compute.types import Provider
|
||||
from libcloud.compute.providers import get_driver
|
||||
|
@ -171,25 +195,6 @@ except ImportError:
|
|||
"msg='GCE module requires python's 'ast' module, python v2.6+'")
|
||||
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 parametres in libcloud secrets file.'")
|
||||
sys.exit(1)
|
||||
|
||||
def unexpected_error_msg(error):
|
||||
"""Create an 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 get_instance_info(inst):
|
||||
"""Retrieves instance information from an instance object and returns it
|
||||
|
@ -353,9 +358,14 @@ def main():
|
|||
zone = dict(choices=['us-central1-a', 'us-central1-b',
|
||||
'us-central2-a', 'europe-west1-a', 'europe-west1-b'],
|
||||
default='us-central1-a'),
|
||||
service_account_email = dict(),
|
||||
pem_file = dict(),
|
||||
project_id = dict(),
|
||||
)
|
||||
)
|
||||
|
||||
gce = gce_connect(module)
|
||||
|
||||
image = module.params.get('image')
|
||||
instance_names = module.params.get('instance_names')
|
||||
machine_type = module.params.get('machine_type')
|
||||
|
@ -368,13 +378,6 @@ def main():
|
|||
zone = module.params.get('zone')
|
||||
changed = False
|
||||
|
||||
try:
|
||||
gce = get_driver(Provider.GCE)(*ARGS, datacenter=zone, **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)
|
||||
|
||||
inames = []
|
||||
if isinstance(instance_names, list):
|
||||
inames = instance_names
|
||||
|
@ -418,5 +421,6 @@ def main():
|
|||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.gce import *
|
||||
|
||||
main()
|
||||
|
|
|
@ -110,6 +110,27 @@ options:
|
|||
default: "present"
|
||||
choices: ["active", "present", "absent", "deleted"]
|
||||
aliases: []
|
||||
service_account_email:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
pem_file:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- path to the pem file associated with the service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
project_id:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- your GCE project ID
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
|
||||
requirements: [ "libcloud" ]
|
||||
author: Eric Johnson <erjohnso@google.com>
|
||||
|
@ -129,8 +150,6 @@ EXAMPLES = '''
|
|||
|
||||
import sys
|
||||
|
||||
USER_AGENT_PRODUCT="Ansible-gce_lb"
|
||||
USER_AGENT_VERSION="v1beta15"
|
||||
|
||||
try:
|
||||
from libcloud.compute.types import Provider
|
||||
|
@ -145,25 +164,6 @@ except ImportError:
|
|||
"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 main():
|
||||
module = AnsibleModule(
|
||||
|
@ -183,9 +183,14 @@ def main():
|
|||
port_range = dict(),
|
||||
members = dict(type='list'),
|
||||
state = dict(default='present'),
|
||||
service_account_email = dict(),
|
||||
pem_file = dict(),
|
||||
project_id = dict(),
|
||||
)
|
||||
)
|
||||
|
||||
gce = gce_connect(module)
|
||||
|
||||
httphealthcheck_name = module.params.get('httphealthcheck_name')
|
||||
httphealthcheck_port = module.params.get('httphealthcheck_port')
|
||||
httphealthcheck_path = module.params.get('httphealthcheck_path')
|
||||
|
@ -205,9 +210,6 @@ def main():
|
|||
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))
|
||||
gcelb = get_driver_lb(Provider_lb.GCE)(gce_driver=gce)
|
||||
gcelb.connection.user_agent_append("%s/%s" % (
|
||||
USER_AGENT_PRODUCT, USER_AGENT_VERSION))
|
||||
|
@ -329,5 +331,6 @@ def main():
|
|||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.gce import *
|
||||
|
||||
main()
|
||||
|
|
|
@ -73,6 +73,27 @@ options:
|
|||
default: "present"
|
||||
choices: ["active", "present", "absent", "deleted"]
|
||||
aliases: []
|
||||
service_account_email:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
pem_file:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- path to the pem file associated with the service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
project_id:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- your GCE project ID
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
|
||||
requirements: [ "libcloud" ]
|
||||
author: Eric Johnson <erjohnso@google.com>
|
||||
|
@ -96,9 +117,6 @@ EXAMPLES = '''
|
|||
|
||||
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
|
||||
|
@ -110,25 +128,6 @@ except ImportError:
|
|||
"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."""
|
||||
|
@ -159,9 +158,14 @@ def main():
|
|||
src_range = dict(),
|
||||
src_tags = dict(type='list'),
|
||||
state = dict(default='present'),
|
||||
service_account_email = dict(),
|
||||
pem_file = dict(),
|
||||
project_id = dict(),
|
||||
)
|
||||
)
|
||||
|
||||
gce = gce_connect(module)
|
||||
|
||||
allowed = module.params.get('allowed')
|
||||
ipv4_range = module.params.get('ipv4_range')
|
||||
fwname = module.params.get('fwname')
|
||||
|
@ -170,13 +174,6 @@ def main():
|
|||
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}
|
||||
|
||||
|
@ -269,5 +266,6 @@ def main():
|
|||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.gce import *
|
||||
|
||||
main()
|
||||
|
|
|
@ -75,6 +75,27 @@ options:
|
|||
required: false
|
||||
default: "us-central1-b"
|
||||
aliases: []
|
||||
service_account_email:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
pem_file:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- path to the pem file associated with the service account email
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
project_id:
|
||||
version_added: 1.5.1
|
||||
description:
|
||||
- your GCE project ID
|
||||
required: false
|
||||
default: null
|
||||
aliases: []
|
||||
|
||||
requirements: [ "libcloud" ]
|
||||
author: Eric Johnson <erjohnso@google.com>
|
||||
|
@ -91,9 +112,6 @@ EXAMPLES = '''
|
|||
|
||||
import sys
|
||||
|
||||
USER_AGENT_PRODUCT="Ansible-gce_pd"
|
||||
USER_AGENT_VERSION="v1beta15"
|
||||
|
||||
try:
|
||||
from libcloud.compute.types import Provider
|
||||
from libcloud.compute.providers import get_driver
|
||||
|
@ -105,24 +123,6 @@ except ImportError:
|
|||
"msg='libcloud with GCE support is 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):
|
||||
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 main():
|
||||
module = AnsibleModule(
|
||||
|
@ -135,9 +135,14 @@ def main():
|
|||
size_gb = dict(default=10),
|
||||
state = dict(default='present'),
|
||||
zone = dict(default='us-central1-b'),
|
||||
service_account_email = dict(),
|
||||
pem_file = dict(),
|
||||
project_id = dict(),
|
||||
)
|
||||
)
|
||||
|
||||
gce = gce_connect(module)
|
||||
|
||||
detach_only = module.params.get('detach_only')
|
||||
instance_name = module.params.get('instance_name')
|
||||
mode = module.params.get('mode')
|
||||
|
@ -151,13 +156,6 @@ def main():
|
|||
msg='Must specify an instance name when detaching a disk',
|
||||
changed=False)
|
||||
|
||||
try:
|
||||
gce = get_driver(Provider.GCE)(*ARGS, datacenter=zone, **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)
|
||||
|
||||
disk = inst = None
|
||||
changed = is_attached = False
|
||||
|
||||
|
@ -251,5 +249,6 @@ def main():
|
|||
|
||||
# import module snippets
|
||||
from ansible.module_utils.basic import *
|
||||
from ansible.module_utils.gce import *
|
||||
|
||||
main()
|
||||
|
|
|
@ -73,7 +73,7 @@ Version: 0.0.1
|
|||
'''
|
||||
|
||||
USER_AGENT_PRODUCT="Ansible-gce_inventory_plugin"
|
||||
USER_AGENT_VERSION="v1beta15"
|
||||
USER_AGENT_VERSION="v1"
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
@ -174,6 +174,10 @@ class GceInventory(object):
|
|||
|
||||
def node_to_dict(self, inst):
|
||||
md = {}
|
||||
|
||||
if inst is None:
|
||||
return {}
|
||||
|
||||
if inst.extra['metadata'].has_key('items'):
|
||||
for entry in inst.extra['metadata']['items']:
|
||||
md[entry['key']] = entry['value']
|
||||
|
@ -192,12 +196,17 @@ class GceInventory(object):
|
|||
'gce_zone': inst.extra['zone'].name,
|
||||
'gce_tags': inst.extra['tags'],
|
||||
'gce_metadata': md,
|
||||
'gce_network': net
|
||||
'gce_network': net,
|
||||
# Hosts don't have a public name, so we add an IP
|
||||
'ansible_ssh_host': inst.public_ips[0]
|
||||
}
|
||||
|
||||
def get_instance(self, instance_name):
|
||||
'''Gets details about a specific instance '''
|
||||
try:
|
||||
return self.driver.ex_get_node(instance_name)
|
||||
except Exception, e:
|
||||
return None
|
||||
|
||||
def group_instances(self):
|
||||
'''Group all instances'''
|
||||
|
|
Loading…
Reference in a new issue