Merge pull request #6265 from franckcuny/gce-fixes

Add credential parameters to the GCE modules.
pull/6290/head
jctanner 11 years ago
commit 40ee030790

@ -197,6 +197,7 @@ In addition to Cobbler and EC2, inventory scripts are also available for::
BSD Jails BSD Jails
Digital Ocean Digital Ocean
Google Compute Engine
Linode Linode
OpenShift OpenShift
OpenStack Nova OpenStack Nova

@ -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

@ -51,6 +51,27 @@ options:
required: false required: false
default: null default: null
aliases: [] 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: name:
description: description:
- identifier when working with a single instance - identifier when working with a single instance
@ -90,6 +111,8 @@ options:
aliases: [] aliases: []
requirements: [ "libcloud" ] requirements: [ "libcloud" ]
notes:
- Either I(name) or I(instance_names) is required.
author: Eric Johnson <erjohnso@google.com> author: Eric Johnson <erjohnso@google.com>
''' '''
@ -119,10 +142,14 @@ EXAMPLES = '''
machine_type: n1-standard-1 machine_type: n1-standard-1
image: debian-6 image: debian-6
zone: us-central1-a zone: us-central1-a
service_account_email: unique-email@developer.gserviceaccount.com
pem_file: /path/to/pem_file
project_id: project-id
tasks: tasks:
- name: Launch instances - name: Launch instances
local_action: gce instance_names={{names}} machine_type={{machine_type}} 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 register: gce
- name: Wait for SSH to come up - name: Wait for SSH to come up
local_action: wait_for host={{item.public_ip}} port=22 delay=10 local_action: wait_for host={{item.public_ip}} port=22 delay=10
@ -150,9 +177,6 @@ EXAMPLES = '''
import sys import sys
USER_AGENT_PRODUCT="Ansible-gce"
USER_AGENT_VERSION="v1beta15"
try: try:
from libcloud.compute.types import Provider from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver from libcloud.compute.providers import get_driver
@ -171,25 +195,6 @@ except ImportError:
"msg='GCE module requires python's 'ast' module, python v2.6+'") "msg='GCE module requires python's 'ast' module, python v2.6+'")
sys.exit(1) 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): def get_instance_info(inst):
"""Retrieves instance information from an instance object and returns it """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', zone = dict(choices=['us-central1-a', 'us-central1-b',
'us-central2-a', 'europe-west1-a', 'europe-west1-b'], 'us-central2-a', 'europe-west1-a', 'europe-west1-b'],
default='us-central1-a'), default='us-central1-a'),
service_account_email = dict(),
pem_file = dict(),
project_id = dict(),
) )
) )
gce = gce_connect(module)
image = module.params.get('image') image = module.params.get('image')
instance_names = module.params.get('instance_names') instance_names = module.params.get('instance_names')
machine_type = module.params.get('machine_type') machine_type = module.params.get('machine_type')
@ -368,13 +378,6 @@ def main():
zone = module.params.get('zone') zone = module.params.get('zone')
changed = False 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 = [] inames = []
if isinstance(instance_names, list): if isinstance(instance_names, list):
inames = instance_names inames = instance_names
@ -418,5 +421,6 @@ def main():
# import module snippets # import module snippets
from ansible.module_utils.basic import * from ansible.module_utils.basic import *
from ansible.module_utils.gce import *
main() main()

@ -110,6 +110,27 @@ options:
default: "present" default: "present"
choices: ["active", "present", "absent", "deleted"] choices: ["active", "present", "absent", "deleted"]
aliases: [] 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" ] requirements: [ "libcloud" ]
author: Eric Johnson <erjohnso@google.com> author: Eric Johnson <erjohnso@google.com>
@ -129,41 +150,20 @@ EXAMPLES = '''
import sys import sys
USER_AGENT_PRODUCT="Ansible-gce_lb"
USER_AGENT_VERSION="v1beta15"
try: try:
from libcloud.compute.types import Provider from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver from libcloud.compute.providers import get_driver
from libcloud.loadbalancer.types import Provider as Provider_lb from libcloud.loadbalancer.types import Provider as Provider_lb
from libcloud.loadbalancer.providers import get_driver as get_driver_lb from libcloud.loadbalancer.providers import get_driver as get_driver_lb
from libcloud.common.google import GoogleBaseError, QuotaExceededError, \ from libcloud.common.google import GoogleBaseError, QuotaExceededError, \
ResourceExistsError, ResourceNotFoundError ResourceExistsError, ResourceNotFoundError
_ = Provider.GCE _ = Provider.GCE
except ImportError: except ImportError:
print("failed=True " + \ print("failed=True " + \
"msg='libcloud with GCE support required for this module.'") "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) 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(): def main():
module = AnsibleModule( module = AnsibleModule(
@ -183,9 +183,14 @@ def main():
port_range = dict(), port_range = dict(),
members = dict(type='list'), members = dict(type='list'),
state = dict(default='present'), 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_name = module.params.get('httphealthcheck_name')
httphealthcheck_port = module.params.get('httphealthcheck_port') httphealthcheck_port = module.params.get('httphealthcheck_port')
httphealthcheck_path = module.params.get('httphealthcheck_path') httphealthcheck_path = module.params.get('httphealthcheck_path')
@ -205,9 +210,6 @@ def main():
state = module.params.get('state') state = module.params.get('state')
try: 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 = get_driver_lb(Provider_lb.GCE)(gce_driver=gce)
gcelb.connection.user_agent_append("%s/%s" % ( gcelb.connection.user_agent_append("%s/%s" % (
USER_AGENT_PRODUCT, USER_AGENT_VERSION)) USER_AGENT_PRODUCT, USER_AGENT_VERSION))
@ -329,5 +331,6 @@ def main():
# import module snippets # import module snippets
from ansible.module_utils.basic import * from ansible.module_utils.basic import *
from ansible.module_utils.gce import *
main() main()

@ -73,6 +73,27 @@ options:
default: "present" default: "present"
choices: ["active", "present", "absent", "deleted"] choices: ["active", "present", "absent", "deleted"]
aliases: [] 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" ] requirements: [ "libcloud" ]
author: Eric Johnson <erjohnso@google.com> author: Eric Johnson <erjohnso@google.com>
@ -96,39 +117,17 @@ EXAMPLES = '''
import sys import sys
USER_AGENT_PRODUCT="Ansible-gce_net" try:
USER_AGENT_VERSION="v1beta15" from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
try:
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
from libcloud.common.google import GoogleBaseError, QuotaExceededError, \ from libcloud.common.google import GoogleBaseError, QuotaExceededError, \
ResourceExistsError, ResourceNotFoundError ResourceExistsError, ResourceNotFoundError
_ = Provider.GCE _ = Provider.GCE
except ImportError: except ImportError:
print("failed=True " + \ print("failed=True " + \
"msg='libcloud with GCE support required for this module.'") "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) 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): def format_allowed(allowed):
"""Format the 'allowed' value so that it is GCE compatible.""" """Format the 'allowed' value so that it is GCE compatible."""
@ -159,9 +158,14 @@ def main():
src_range = dict(), src_range = dict(),
src_tags = dict(type='list'), src_tags = dict(type='list'),
state = dict(default='present'), state = dict(default='present'),
service_account_email = dict(),
pem_file = dict(),
project_id = dict(),
) )
) )
gce = gce_connect(module)
allowed = module.params.get('allowed') allowed = module.params.get('allowed')
ipv4_range = module.params.get('ipv4_range') ipv4_range = module.params.get('ipv4_range')
fwname = module.params.get('fwname') fwname = module.params.get('fwname')
@ -170,13 +174,6 @@ def main():
src_tags = module.params.get('src_tags') src_tags = module.params.get('src_tags')
state = module.params.get('state') 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 changed = False
json_output = {'state': state} json_output = {'state': state}
@ -269,5 +266,6 @@ def main():
# import module snippets # import module snippets
from ansible.module_utils.basic import * from ansible.module_utils.basic import *
from ansible.module_utils.gce import *
main() main()

@ -75,6 +75,27 @@ options:
required: false required: false
default: "us-central1-b" default: "us-central1-b"
aliases: [] 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" ] requirements: [ "libcloud" ]
author: Eric Johnson <erjohnso@google.com> author: Eric Johnson <erjohnso@google.com>
@ -82,47 +103,26 @@ author: Eric Johnson <erjohnso@google.com>
EXAMPLES = ''' EXAMPLES = '''
# Simple attachment action to an existing instance # Simple attachment action to an existing instance
- local_action: - local_action:
module: gce_pd module: gce_pd
instance_name: notlocalhost instance_name: notlocalhost
size_gb: 5 size_gb: 5
name: pd name: pd
''' '''
import sys import sys
USER_AGENT_PRODUCT="Ansible-gce_pd" try:
USER_AGENT_VERSION="v1beta15" from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
try:
from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver
from libcloud.common.google import GoogleBaseError, QuotaExceededError, \ from libcloud.common.google import GoogleBaseError, QuotaExceededError, \
ResourceExistsError, ResourceNotFoundError, ResourceInUseError ResourceExistsError, ResourceNotFoundError, ResourceInUseError
_ = Provider.GCE _ = Provider.GCE
except ImportError: except ImportError:
print("failed=True " + \ print("failed=True " + \
"msg='libcloud with GCE support is required for this module.'") "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) 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(): def main():
module = AnsibleModule( module = AnsibleModule(
@ -135,9 +135,14 @@ def main():
size_gb = dict(default=10), size_gb = dict(default=10),
state = dict(default='present'), state = dict(default='present'),
zone = dict(default='us-central1-b'), 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') detach_only = module.params.get('detach_only')
instance_name = module.params.get('instance_name') instance_name = module.params.get('instance_name')
mode = module.params.get('mode') mode = module.params.get('mode')
@ -151,13 +156,6 @@ def main():
msg='Must specify an instance name when detaching a disk', msg='Must specify an instance name when detaching a disk',
changed=False) 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 disk = inst = None
changed = is_attached = False changed = is_attached = False
@ -251,5 +249,6 @@ def main():
# import module snippets # import module snippets
from ansible.module_utils.basic import * from ansible.module_utils.basic import *
from ansible.module_utils.gce import *
main() main()

@ -73,7 +73,7 @@ Version: 0.0.1
''' '''
USER_AGENT_PRODUCT="Ansible-gce_inventory_plugin" USER_AGENT_PRODUCT="Ansible-gce_inventory_plugin"
USER_AGENT_VERSION="v1beta15" USER_AGENT_VERSION="v1"
import sys import sys
import os import os
@ -174,6 +174,10 @@ class GceInventory(object):
def node_to_dict(self, inst): def node_to_dict(self, inst):
md = {} md = {}
if inst is None:
return {}
if inst.extra['metadata'].has_key('items'): if inst.extra['metadata'].has_key('items'):
for entry in inst.extra['metadata']['items']: for entry in inst.extra['metadata']['items']:
md[entry['key']] = entry['value'] md[entry['key']] = entry['value']
@ -192,12 +196,17 @@ class GceInventory(object):
'gce_zone': inst.extra['zone'].name, 'gce_zone': inst.extra['zone'].name,
'gce_tags': inst.extra['tags'], 'gce_tags': inst.extra['tags'],
'gce_metadata': md, '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): def get_instance(self, instance_name):
'''Gets details about a specific instance ''' '''Gets details about a specific instance '''
return self.driver.ex_get_node(instance_name) try:
return self.driver.ex_get_node(instance_name)
except Exception, e:
return None
def group_instances(self): def group_instances(self):
'''Group all instances''' '''Group all instances'''

Loading…
Cancel
Save