diff --git a/lib/ansible/modules/cloud/google/gce.py b/lib/ansible/modules/cloud/google/gce.py index 1eb9baae6ff..9aab4cf6ca0 100644 --- a/lib/ansible/modules/cloud/google/gce.py +++ b/lib/ansible/modules/cloud/google/gce.py @@ -28,6 +28,20 @@ options: stable debian image) required: false default: "debian-8" + image_family: + description: + - image family from which to select the image. The most recent + non-deprecated image in the family will be used. + required: false + default: null + version_added: "2.4" + external_projects: + description: + - A list of other projects (accessible with the provisioning credentials) + to be searched for the image. + required: false + default: null + version_added: "2.4" instance_names: description: - a comma-separated list of instance names to create or destroy @@ -197,6 +211,22 @@ EXAMPLES = ''' project_id: "your-project-name" disk_size: 32 +# Create a single instance of an image from the "my-base-image" image family +# in the us-central1-a Zone of the n1-standard-1 machine type. +# This image family is in the "my-other-project" GCP project. + gce: + instance_names: my-test-instance1 + zone: us-central1-a + machine_type: n1-standard-1 + image_family: my-base-image + external_projects: + - my-other-project + state: present + service_account_email: "your-sa@your-project-name.iam.gserviceaccount.com" + credentials_file: "/path/to/your-key.json" + project_id: "your-project-name" + disk_size: 32 + # Create a single Debian 8 instance in the us-central1-a Zone # Use existing disks, custom network/subnetwork, set service account permissions # add tags and metadata. @@ -291,6 +321,7 @@ EXAMPLES = ''' ''' import socket +import logging try: from ast import literal_eval @@ -379,6 +410,8 @@ def create_instances(module, gce, instance_names, number, lc_zone): """ image = module.params.get('image') + image_family = module.params.get('image_family') + external_projects = module.params.get('external_projects') machine_type = module.params.get('machine_type') metadata = module.params.get('metadata') network = module.params.get('network') @@ -452,7 +485,7 @@ def create_instances(module, gce, instance_names, number, lc_zone): else: metadata = md - lc_image = LazyDiskImage(module, gce, image, lc_disks) + lc_image = LazyDiskImage(module, gce, image, lc_disks, family=image_family, projects=external_projects) ex_sa_perms = [] bad_perms = [] if service_account_permissions: @@ -615,6 +648,8 @@ def main(): module = AnsibleModule( argument_spec = dict( image = dict(default='debian-8'), + image_family = dict(), + external_projects = dict(type='list'), instance_names = dict(), machine_type = dict(default='n1-standard-1'), metadata = dict(), @@ -650,6 +685,9 @@ def main(): gce = gce_connect(module) + image = module.params.get('image') + image_family = module.params.get('image_family') + external_projects = module.params.get('external_projects') instance_names = module.params.get('instance_names') name = module.params.get('name') number = module.params.get('num_instances') @@ -713,19 +751,24 @@ class LazyDiskImage: Object for lazy instantiation of disk image gce.ex_get_image is a very expensive call, so we want to avoid calling it as much as possible. """ - def __init__(self, module, gce, name, has_pd): + def __init__(self, module, gce, name, has_pd, family=None, projects=None): self.image = None self.was_called = False self.gce = gce self.name = name self.has_pd = has_pd self.module = module + self.family = family + self.projects = projects def __call__(self): if not self.was_called: self.was_called = True if not self.has_pd: - self.image = self.gce.ex_get_image(self.name) + if self.family: + self.image = self.gce.ex_get_image_from_family(self.family, ex_project_list=self.projects) + else: + self.image = self.gce.ex_get_image(self.name, ex_project_list=self.projects) if not self.image: self.module.fail_json(msg='image or disks missing for create instance', changed=False) return self.image diff --git a/lib/ansible/modules/cloud/google/gce_pd.py b/lib/ansible/modules/cloud/google/gce_pd.py index 6eadebac601..f69d447c1cb 100644 --- a/lib/ansible/modules/cloud/google/gce_pd.py +++ b/lib/ansible/modules/cloud/google/gce_pd.py @@ -166,6 +166,8 @@ def main(): size_gb = dict(default=10), disk_type = dict(default='pd-standard'), image = dict(), + image_family = dict(), + external_projects = dict(type='list'), snapshot = dict(), state = dict(default='present'), zone = dict(default='us-central1-b'), @@ -188,6 +190,8 @@ def main(): size_gb = module.params.get('size_gb') disk_type = module.params.get('disk_type') image = module.params.get('image') + image_family = module.params.get('image_family') + external_projects = module.params.get('external_projects') snapshot = module.params.get('snapshot') state = module.params.get('state') zone = module.params.get('zone') @@ -257,8 +261,10 @@ def main(): image, snapshot), changed=False) lc_image = None lc_snapshot = None - if image is not None: - lc_image = gce.ex_get_image(image) + if image_family is not None: + lc_image = gce.ex_get_image_from_family(image_family, ex_project_list=external_projects) + elif image is not None: + lc_image = gce.ex_get_image(image, ex_project_list=external_projects) elif snapshot is not None: lc_snapshot = gce.ex_get_snapshot(snapshot) try: