diff --git a/build/ansible b/build/ansible index 2125463a079a..bd937c6e3f21 160000 --- a/build/ansible +++ b/build/ansible @@ -1 +1 @@ -Subproject commit 2125463a079a8a4f72095c69b91cc7a5b702c678 +Subproject commit bd937c6e3f21e9e8b2e618f29f70d23192a693f4 diff --git a/build/terraform b/build/terraform index 27ade47e5a15..e6af1c2a7d73 160000 --- a/build/terraform +++ b/build/terraform @@ -1 +1 @@ -Subproject commit 27ade47e5a153f76a7a274a40f057fcd3097b7a8 +Subproject commit e6af1c2a7d739403073bcd0c5ef078269244f036 diff --git a/products/compute/ansible.yaml b/products/compute/ansible.yaml index 322c3e0a1f4e..879109cdb9a5 100644 --- a/products/compute/ansible.yaml +++ b/products/compute/ansible.yaml @@ -230,6 +230,21 @@ overrides: !ruby/object:Provider::ResourceOverrides timeoutSec: !ruby/object:Provider::Ansible::PropertyOverride aliases: - timeout_seconds + InstanceGroup: !ruby/object:Provider::Ansible::ResourceOverride + properties: + instances: !ruby/object:Provider::Ansible::PropertyOverride + version_added: '2.7' + exclude: false + update: | + instance = InstanceLogic(module) + instance.run() + post_action: | + if fetch: + instance = InstanceLogic(module) + instance.run() + fetch.update({'instances': instance.list_instances()}) + provider_helpers: + - 'products/compute/helpers/python/instancegroup_instances.py' Instance: !ruby/object:Provider::Ansible::ResourceOverride provider_helpers: - 'products/compute/helpers/python/provider_instance.py' diff --git a/products/compute/api.yaml b/products/compute/api.yaml index a79f82ed5b2c..383110a6fa7d 100644 --- a/products/compute/api.yaml +++ b/products/compute/api.yaml @@ -1866,6 +1866,20 @@ objects: imports: 'name' description: 'A reference to the zone where the instance group resides.' required: true + - !ruby/object:Api::Type::Array + name: 'instances' + description: | + The list of instances associated with this InstanceGroup. + All instances must be created before being added to an InstanceGroup. + All instances not in this list will be removed from the InstanceGroup + and will not be deleted. + Only the full identifier of the instance will be returned. + exclude: true + item_type: !ruby/object:Api::Type::ResourceRef + name: 'instance' + description: 'An instance being added to the InstanceGroup' + resource: 'Instance' + imports: 'selfLink' properties: - !ruby/object:Api::Type::Time name: 'creationTimestamp' diff --git a/products/compute/helpers/python/instancegroup_instances.py b/products/compute/helpers/python/instancegroup_instances.py new file mode 100644 index 000000000000..e6fc176ba21a --- /dev/null +++ b/products/compute/helpers/python/instancegroup_instances.py @@ -0,0 +1,64 @@ +<% +# Instance Logic handling for Instance Groups +# This code handles the adding + removing of instances from an instance group. +# It should be run after all normal create/update/delete logic. + +-%> +class InstanceLogic(object): + def __init__(self, module): + self.module = module + self.current_instances = self.list_instances() + self.module_instances = [] + + # Transform module list of instances (dicts of instance responses) into a list of selfLinks. + instances = self.module.params.get('instances') + if instances: + for instance in instances: + self.module_instances.append(replace_resource_dict(instance, 'selfLink')) + + def run(self): + # Find all instances to add and add them + instances_to_add = list(set(self.module_instances) - set(self.current_instances)) + if instances_to_add: + self.add_instances(instances_to_add) + + # Find all instances to remove and remove them + instances_to_remove = list(set(self.current_instances) - set(self.module_instances)) + if instances_to_remove: + self.remove_instances(instances_to_remove) + + def list_instances(self): + auth = GcpSession(self.module, 'compute') + response = return_if_object(self.module, auth.post(self._list_instances_url(), {'instanceState': 'ALL'}), + 'compute#instanceGroupsListInstances') + + # Transform instance list into a list of selfLinks for diffing with module parameters + instances = [] + for instance in response.get('items', []): + instances.append(instance['instance']) + return instances + + def add_instances(self, instances): + auth = GcpSession(self.module, 'compute') + wait_for_operation(self.module, auth.post(self._add_instances_url(), self._build_request(instances))) + + def remove_instances(self, instances): + auth = GcpSession(self.module, 'compute') + wait_for_operation(self.module, auth.post(self._remove_instances_url(), self._build_request(instances))) + + def _list_instances_url(self): + return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instanceGroups/{name}/listInstances".format(**self.module.params) + + def _remove_instances_url(self): + return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instanceGroups/{name}/removeInstances".format(**self.module.params) + + def _add_instances_url(self): + return "https://www.googleapis.com/compute/v1/projects/{project}/zones/{zone}/instanceGroups/{name}/addInstances".format(**self.module.params) + + def _build_request(self, instances): + request = { + 'instances': [] + } + for instance in instances: + request['instances'].append({'instance': instance}) + return request diff --git a/provider/ansible/resource_override.rb b/provider/ansible/resource_override.rb index 965887126195..bca140d07c40 100644 --- a/provider/ansible/resource_override.rb +++ b/provider/ansible/resource_override.rb @@ -27,6 +27,7 @@ module OverrideProperties attr_reader :hidden attr_reader :imports attr_reader :post_create + attr_reader :post_action attr_reader :provider_helpers attr_reader :return_if_object attr_reader :unwrap_resource @@ -60,6 +61,7 @@ def validate check_optional_property :hidden, ::Array check_property :imports, ::Array check_optional_property :post_create, ::String + check_optional_property :post_action, ::String check_property :provider_helpers, ::Array check_optional_property :return_if_object, ::String check_optional_property :update, ::String diff --git a/templates/ansible/resource.erb b/templates/ansible/resource.erb index 7b2761ef3703..904e296838be 100644 --- a/templates/ansible/resource.erb +++ b/templates/ansible/resource.erb @@ -196,6 +196,9 @@ def main(): else: fetch = {} +<% if object.post_action -%> +<%= lines(indent(object.post_action, 4)) -%> +<% end # ifobject.post_create -%> fetch.update({'changed': changed}) <% end # object.readonly -%>