# Copyright 2024 Google Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

---
name: 'PerInstanceConfig'
api_resource_type_kind: InstanceGroupManager
api_variant_patterns:
  - 'projects/{project}/zones/{zone}/instanceGroupManagers/{instanceGroupManager}'
description: |
  A config defined for a single managed instance that belongs to an instance group manager. It preserves the instance name
  across instance group manager operations and can define stateful disks or metadata that are unique to the instance.
references:
  guides:
    'Official Documentation': 'https://cloud.google.com/compute/docs/instance-groups/stateful-migs#per-instance_configs'
  api: 'https://cloud.google.com/compute/docs/reference/rest/v1/instanceGroupManagers'
docs:
id_format: '{{project}}/{{zone}}/{{instance_group_manager}}/{{name}}'
base_url: 'projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}'
self_link: 'projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/listPerInstanceConfigs'
create_url: 'projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/createInstances'
update_url: 'projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/updatePerInstanceConfigs'
update_verb: 'POST'
read_verb: 'POST'
delete_url: 'projects/{{project}}/zones/{{zone}}/instanceGroupManagers/{{instance_group_manager}}/deletePerInstanceConfigs'
delete_verb: 'POST'
mutex: 'instanceGroupManager/{{project}}/{{zone}}/{{instance_group_manager}}/{{name}}'
timeouts:
  insert_minutes: 20
  update_minutes: 20
  delete_minutes: 20
async:
  actions: ['create', 'delete', 'update']
  type: 'OpAsync'
  operation:
    base_url: '{{op_id}}'
  result:
    resource_inside_response: false
identity:
  - name
nested_query:
  keys:
    - items
  is_list_of_ids: false
  modify_by_patch: false
custom_code:
  encoder: 'templates/terraform/encoders/compute_per_instance_config.go.tmpl'
  update_encoder: 'templates/terraform/update_encoder/compute_per_instance_config.go.tmpl'
  post_update: 'templates/terraform/post_update/compute_per_instance_config.go.tmpl'
  custom_delete: 'templates/terraform/custom_delete/per_instance_config.go.tmpl'
exclude_tgc: true
examples:
  - name: 'stateful_igm'
    primary_resource_id: 'stateful-instance'
    vars:
      template_name: 'my-template'
      igm_name: 'my-igm'
      disk_name: 'my-disk-name'
      # Fine-grained resource need different autogenerated tests, as
      # we need to check destroy during a test step where the parent resource
      # still exists, rather than during CheckDestroy (when read returns
      # nothing because the parent resource has then also been destroyed)
    exclude_test: true
virtual_fields:
  - name: 'minimal_action'
    description: |
      The minimal action to perform on the instance during an update.
      Default is `NONE`. Possible values are:
      * REPLACE
      * RESTART
      * REFRESH
      * NONE
    type: String
    default_value: "NONE"
  - name: 'most_disruptive_allowed_action'
    description: |
      The most disruptive action to perform on the instance during an update.
      Default is `REPLACE`. Possible values are:
      * REPLACE
      * RESTART
      * REFRESH
      * NONE
    type: String
    default_value: "REPLACE"
  - name: 'remove_instance_on_destroy'
    description: |
      When true, deleting this config will immediately remove the underlying instance.
      When false, deleting this config will use the behavior as determined by remove_instance_on_destroy.
    type: Boolean
    default_value: false
  - name: 'remove_instance_state_on_destroy'
    description: |
      When true, deleting this config will immediately remove any specified state from the underlying instance.
      When false, deleting this config will *not* immediately remove any state from the underlying instance.
      State will be removed on the next instance recreation or update.
    type: Boolean
    default_value: false
parameters:
  - name: 'zone'
    type: ResourceRef
    description: |
      Zone where the containing instance group manager is located
    url_param_only: true
    required: false
    immutable: true
    ignore_read: true
    default_from_api: true
    resource: 'Zone'
    imports: 'name'
  - name: 'instanceGroupManager'
    type: ResourceRef
    description: |
      The instance group manager this instance config is part of.
    url_param_only: true
    required: true
    immutable: true
    resource: 'InstanceGroupManager'
    imports: 'name'
properties:
  - name: 'name'
    type: String
    description: |
      The name for this per-instance config and its corresponding instance.
    required: true
    immutable: true
  - name: 'preservedState'
    type: NestedObject
    description: 'The preserved state for this instance.'
    properties:
      - name: 'metadata'
        type: KeyValuePairs
        description: |
          Preserved metadata defined for this instance. This is a list of key->value pairs.
      - name: 'disk'
        type: Array
        description: |
          Stateful disks for the instance.
        api_name: disks
        is_set: true
        custom_flatten: 'templates/terraform/custom_flatten/preserved_state_disks.go.tmpl'
        custom_expand: 'templates/terraform/custom_expand/preserved_state_disks.go.tmpl'
        item_type:
          type: NestedObject
          properties:
            - name: 'deviceName'
              type: String
              description: |
                A unique device name that is reflected into the /dev/ tree of a Linux operating system running within the instance.
              required: true
            - name: 'source'
              type: String
              description: |
                The URI of an existing persistent disk to attach under the specified device-name in the format
                `projects/project-id/zones/zone/disks/disk-name`.
              required: true
            - name: 'mode'
              type: Enum
              description: |
                The mode of the disk.
              default_value: "READ_WRITE"
              enum_values:
                - 'READ_ONLY'
                - 'READ_WRITE'
            - name: 'deleteRule'
              type: Enum
              description: |
                A value that prescribes what should happen to the stateful disk when the VM instance is deleted.
                The available options are `NEVER` and `ON_PERMANENT_INSTANCE_DELETION`.
                `NEVER` - detach the disk when the VM is deleted, but do not delete the disk.
                `ON_PERMANENT_INSTANCE_DELETION` will delete the stateful disk when the VM is permanently
                deleted from the instance group.
              default_value: "NEVER"
              enum_values:
                - 'NEVER'
                - 'ON_PERMANENT_INSTANCE_DELETION'
      - name: 'internalIp'
        type: Map
        description: |
          Preserved internal IPs defined for this instance. This map is keyed with the name of the network interface.
        api_name: internalIPs
        key_name: 'interface_name'
        value_type:
          name: internalIp
          type: NestedObject
          properties:
            - name: 'autoDelete'
              type: Enum
              description: |
                These stateful IPs will never be released during autohealing, update or VM instance recreate operations. This flag is used to configure if the IP reservation should be deleted after it is no longer used by the group, e.g. when the given instance or the whole group is deleted.
              default_value: "NEVER"
              enum_values:
                - 'NEVER'
                - 'ON_PERMANENT_INSTANCE_DELETION'
            - name: 'ipAddress'
              type: NestedObject
              description: |
                Ip address representation
              properties:
                - name: 'address'
                  type: ResourceRef
                  description: |
                    The URL of the reservation for this IP address.
                  custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl'
                  resource: 'Address'
                  imports: 'selfLink'
      - name: 'externalIp'
        type: Map
        description: |
          Preserved external IPs defined for this instance. This map is keyed with the name of the network interface.
        api_name: externalIPs
        key_name: 'interface_name'
        value_type:
          name: externalIp
          type: NestedObject
          properties:
            - name: 'autoDelete'
              type: Enum
              description: |
                These stateful IPs will never be released during autohealing, update or VM instance recreate operations. This flag is used to configure if the IP reservation should be deleted after it is no longer used by the group, e.g. when the given instance or the whole group is deleted.
              default_value: "NEVER"
              enum_values:
                - 'NEVER'
                - 'ON_PERMANENT_INSTANCE_DELETION'
            - name: 'ipAddress'
              type: NestedObject
              description: |
                Ip address representation
              properties:
                - name: 'address'
                  type: ResourceRef
                  description: |
                    The URL of the reservation for this IP address.
                  custom_expand: 'templates/terraform/custom_expand/resourceref_with_validation.go.tmpl'
                  resource: 'Address'
                  imports: 'selfLink'
