# 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: 'Cluster'
description: 'A managed alloydb cluster.'
references:
  guides:
    'AlloyDB': 'https://cloud.google.com/alloydb/docs/'
  api: 'https://cloud.google.com/alloydb/docs/reference/rest/v1/projects.locations.clusters/create'
docs:
  note: |
    Users can promote a secondary cluster to a primary cluster with the help of `cluster_type`.
    To promote, users have to set the `cluster_type` property as `PRIMARY` and remove the `secondary_config` field from cluster configuration.
    [See Example](https://github.com/hashicorp/terraform-provider-google/pull/16413).

    Switchover is supported in terraform by refreshing the state of the terraform configurations.
    The switchover operation still needs to be called outside of terraform.
    After the switchover operation is completed successfully:
      1. Refresh the state of the AlloyDB resources by running `terraform apply -refresh-only --auto-approve` .
      2. Manually update the terraform configuration file(s) to match the actual state of the resources by modifying the `cluster_type` and `secondary_config` fields.
      3. Verify the sync of terraform state by running `terraform plan` and ensure that the infrastructure matches the configuration and no changes are required.
base_url: 'projects/{{project}}/locations/{{location}}/clusters'
self_link: 'projects/{{project}}/locations/{{location}}/clusters/{{cluster_id}}'
mutex: 'projects/{{project}}'
create_url: 'projects/{{project}}/locations/{{location}}/clusters?clusterId={{cluster_id}}'
update_verb: 'PATCH'
update_mask: true
import_format:
  - 'projects/{{project}}/locations/{{location}}/clusters/{{cluster_id}}'
  - '{{cluster_id}}'
timeouts:
  insert_minutes: 120
  update_minutes: 120
  delete_minutes: 120
autogen_async: true
async:
  actions: ['create', 'delete', 'update']
  type: 'OpAsync'
  operation:
    base_url: '{{op_id}}'
    timeouts:
      insert_minutes: 120
      update_minutes: 120
      delete_minutes: 120
  result:
    resource_inside_response: false
custom_code:
  pre_create: 'templates/terraform/pre_create/alloydb_cluster.go.tmpl'
  pre_update: 'templates/terraform/pre_update/alloydb_cluster.go.tmpl'
  pre_delete: 'templates/terraform/pre_delete/alloydb_cluster.go.tmpl'
# Skipping the sweeper because we need to force-delete clusters.
exclude_sweeper: true
examples:
  - name: 'alloydb_cluster_basic'
    primary_resource_id: 'default'
    vars:
      alloydb_cluster_name: 'alloydb-cluster'
  - name: 'alloydb_cluster_before_upgrade'
    primary_resource_id: 'default'
    vars:
      alloydb_cluster_name: 'alloydb-cluster'
      alloydb_instance_name: 'alloydb-instance'
      network_name: 'alloydb-network'
  - name: 'alloydb_cluster_after_upgrade'
    primary_resource_id: 'default'
    vars:
      alloydb_cluster_name: 'alloydb-cluster'
      alloydb_instance_name: 'alloydb-instance'
      network_name: 'alloydb-network'
  - name: 'alloydb_cluster_full'
    primary_resource_id: 'full'
    vars:
      alloydb_cluster_name: 'alloydb-cluster-full'
  - name: 'alloydb_cluster_restore'
    primary_resource_id: 'source'
    vars:
      alloydb_cluster_name: 'alloydb-source-cluster'
      alloydb_backup_restored_cluster_name: 'alloydb-backup-restored'
      alloydb_pitr_restored_cluster_name: 'alloydb-pitr-restored'
      alloydb_backup_id: 'alloydb-backup'
      alloydb_instance_name: 'alloydb-instance'
      network_name: 'alloydb-network'
    test_vars_overrides:
      'network_name': 'acctest.BootstrapSharedTestNetwork(t, "alloydb-instance-basic")'
    ignore_read_extra:
      - 'reconciling'
      - 'update_time'
    exclude_test: true
  - name: 'alloydb_secondary_cluster_basic'
    primary_resource_id: 'secondary'
    vars:
      alloydb_primary_cluster_name: 'alloydb-primary-cluster'
      alloydb_primary_instance_name: 'alloydb-primary-instance'
      alloydb_secondary_cluster_name: 'alloydb-secondary-cluster'
    exclude_test: true
  - name: 'alloydb_secondary_cluster_basic_test'
    primary_resource_id: 'secondary'
    vars:
      alloydb_primary_cluster_name: 'alloydb-primary-cluster'
      alloydb_primary_instance_name: 'alloydb-primary-instance'
      alloydb_secondary_cluster_name: 'alloydb-secondary-cluster'
      network_name: 'alloydb-network'
    test_vars_overrides:
      'network_name': 'acctest.BootstrapSharedServiceNetworkingConnection(t, "alloydbinstance-network-config-1")'
    exclude_docs: true
virtual_fields:
  - name: 'deletion_policy'
    description: |
      Policy to determine if the cluster should be deleted forcefully.
      Deleting a cluster forcefully, deletes the cluster and all its associated instances within the cluster.
      Deleting a Secondary cluster with a secondary instance REQUIRES setting deletion_policy = "FORCE" otherwise an error is returned. This is needed as there is no support to delete just the secondary instance, and the only way to delete secondary instance is to delete the associated secondary cluster forcefully which also deletes the secondary instance.
      Possible values: DEFAULT, FORCE
    type: String
    default_value: "DEFAULT"
  - name: 'skip_await_major_version_upgrade'
    type: Boolean
    default_value: true
    description: |
      Set to true to skip awaiting on the major version upgrade of the cluster.
      Possible values: true, false
      Default value: "true"
parameters:
  - name: 'clusterId'
    type: String
    description: |
      The ID of the alloydb cluster.
    url_param_only: true
    required: true
    immutable: true
  - name: 'location'
    type: String
    description: |
      The location where the alloydb cluster should reside.
    url_param_only: true
    required: true
    immutable: true
properties:
  - name: 'name'
    type: String
    description: |
      The name of the cluster resource.
    output: true
  - name: 'uid'
    type: String
    description: |
      The system-generated UID of the resource.
    output: true
  - name: 'labels'
    type: KeyValueLabels
    description: 'User-defined labels for the alloydb cluster.'
  - name: 'encryptionConfig'
    type: NestedObject
    description: |
      EncryptionConfig describes the encryption config of a cluster or a backup that is encrypted with a CMEK (customer-managed encryption key).
    properties:
      - name: 'kmsKeyName'
        type: String
        description: |
          The fully-qualified resource name of the KMS key. Each Cloud KMS key is regionalized and has the following format: projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME].
        immutable: true
  - name: 'encryptionInfo'
    type: NestedObject
    description: |
      EncryptionInfo describes the encryption information of a cluster or a backup.
    output: true
    properties:
      - name: 'encryptionType'
        type: Enum
        description: 'Output only. Type of encryption.'
        output: true
        enum_values:
          - 'TYPE_UNSPECIFIED'
          - 'GOOGLE_DEFAULT_ENCRYPTION'
          - 'CUSTOMER_MANAGED_ENCRYPTION'
      - name: 'kmsKeyVersions'
        type: Array
        description: |
          Output only. Cloud KMS key versions that are being used to protect the database or the backup.
        output: true
        item_type:
          type: String
  - name: 'continuousBackupInfo'
    type: NestedObject
    description: |
      ContinuousBackupInfo describes the continuous backup properties of a cluster.
    output: true
    properties:
      - name: 'enabledTime'
        type: String
        description: |
          When ContinuousBackup was most recently enabled. Set to null if ContinuousBackup is not enabled.
        output: true
      - name: 'schedule'
        type: Array
        description: |
          Days of the week on which a continuous backup is taken. Output only field. Ignored if passed into the request.
        output: true
        item_type:
          type: String
      - name: 'earliestRestorableTime'
        type: String
        description: |
          The earliest restorable time that can be restored to. Output only field.
        output: true
      - name: 'encryptionInfo'
        type: NestedObject
        description: |
          Output only. The encryption information for the WALs and backups required for ContinuousBackup.
        output: true
        properties:
          - name: 'encryptionType'
            type: String
            description: 'Output only. Type of encryption.'
            output: true
          - name: 'kmsKeyVersions'
            type: Array
            description: |
              Output only. Cloud KMS key versions that are being used to protect the database or the backup.
            output: true
            item_type:
              type: String
  - name: 'networkConfig'
    type: NestedObject
    description: |
      Metadata related to network configuration.
    default_from_api: true
    properties:
      - name: 'network'
        type: String
        description: |
          The resource link for the VPC network in which cluster resources are created and from which they are accessible via Private IP. The network must belong to the same project as the cluster.
          It is specified in the form: "projects/{projectNumber}/global/networks/{network_id}".
        exactly_one_of:
          - 'network_config.0.network'
          - 'psc_config.0.psc_enabled'
        diff_suppress_func: 'tpgresource.ProjectNumberDiffSuppress'
      - name: 'allocatedIpRange'
        type: String
        description: |
          The name of the allocated IP range for the private IP AlloyDB cluster. For example: "google-managed-services-default".
          If set, the instance IPs for this cluster will be created in the allocated range.
  - name: 'displayName'
    type: String
    description: |
      User-settable and human-readable display name for the Cluster.
  - name: 'etag'
    type: String
    description: 'For Resource freshness validation (https://google.aip.dev/154)'
  - name: 'reconciling'
    type: Boolean
    description: |
      Output only. Reconciling (https://google.aip.dev/128#reconciliation).
      Set to true if the current state of Cluster does not match the user's intended state, and the service is actively updating the resource to reconcile them.
      This can happen due to user-triggered updates or system actions like failover or maintenance.
    output: true
  - name: 'state'
    type: String
    description: 'Output only. The current serving state of the cluster.'
    output: true
  - name: 'annotations'
    type: KeyValueAnnotations
    description: |
      Annotations to allow client tools to store small amount of arbitrary data. This is distinct from labels. https://google.aip.dev/128
      An object containing a list of "key": value pairs. Example: { "name": "wrench", "mass": "1.3kg", "count": "3" }.
  - name: 'databaseVersion'
    type: String
    description: |
      The database engine major version. This is an optional field and it's populated at the Cluster creation time.
      Note: Changing this field to a higer version results in upgrading the AlloyDB cluster which is an irreversible change.
    default_from_api: true
  - name: 'pscConfig'
    type: NestedObject
    description: 'Configuration for Private Service Connect (PSC) for the cluster.'
    properties:
      - name: 'pscEnabled'
        type: Boolean
        description: 'Create an instance that allows connections from Private Service Connect endpoints to the instance.'
      - name: 'serviceOwnedProjectNumber'
        type: Integer
        description: |
          The project number that needs to be allowlisted on the network attachment to enable outbound connectivity, if the network attachment is configured to ACCEPT_MANUAL connections.
          In case the network attachment is configured to ACCEPT_AUTOMATIC, this project number does not need to be allowlisted explicitly.
        output: true
  - name: 'initialUser'
    type: NestedObject
    description: |
      Initial user to setup during cluster creation.
    ignore_read: true
    custom_flatten: 'templates/terraform/custom_flatten/alloydb_cluster_input_user_flatten.go.tmpl'
    properties:
      - name: 'user'
        type: String
        description: |
          The database username.
      - name: 'password'
        type: String
        description: |
          The initial password for the user.
        required: true
        sensitive: true
  - name: 'restoreBackupSource'
    type: NestedObject
    description: |
      The source when restoring from a backup. Conflicts with 'restore_continuous_backup_source', both can't be set together.
    immutable: true
    ignore_read: true
    conflicts:
      - restore_continuous_backup_source
    properties:
      - name: 'backupName'
        type: String
        description: |
          The name of the backup that this cluster is restored from.
        required: true
        immutable: true
  - name: 'restoreContinuousBackupSource'
    type: NestedObject
    description: |
      The source when restoring via point in time recovery (PITR). Conflicts with 'restore_backup_source', both can't be set together.
    immutable: true
    ignore_read: true
    conflicts:
      - restore_backup_source
    properties:
      - name: 'cluster'
        type: String
        description: |
          The name of the source cluster that this cluster is restored from.
        required: true
        immutable: true
      - name: 'pointInTime'
        type: String
        description: |
          The point in time that this cluster is restored to, in RFC 3339 format.
        required: true
        immutable: true
  - name: 'continuousBackupConfig'
    type: NestedObject
    description: |
      The continuous backup config for this cluster.

      If no policy is provided then the default policy will be used. The default policy takes one backup a day and retains backups for 14 days.
    default_from_api: true
    properties:
      - name: 'enabled'
        type: Boolean
        description: |
          Whether continuous backup recovery is enabled. If not set, defaults to true.
        send_empty_value: true
        default_value: true
      - name: 'recoveryWindowDays'
        type: Integer
        description: |
          The numbers of days that are eligible to restore from using PITR. To support the entire recovery window, backups and logs are retained for one day more than the recovery window.

          If not set, defaults to 14 days.
        default_from_api: true
      - name: 'encryptionConfig'
        type: NestedObject
        description: |
          EncryptionConfig describes the encryption config of a cluster or a backup that is encrypted with a CMEK (customer-managed encryption key).
        properties:
          - name: 'kmsKeyName'
            type: String
            description: |
              The fully-qualified resource name of the KMS key. Each Cloud KMS key is regionalized and has the following format: projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME].
  - name: 'automatedBackupPolicy'
    type: NestedObject
    description: |
      The automated backup policy for this cluster. AutomatedBackupPolicy is disabled by default.
    default_from_api: true
    properties:
      - name: 'backupWindow'
        type: String
        description: |
          The length of the time window during which a backup can be taken. If a backup does not succeed within this time window, it will be canceled and considered failed.

          The backup window must be at least 5 minutes long. There is no upper bound on the window. If not set, it will default to 1 hour.

          A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".
        default_from_api: true
      - name: 'location'
        type: String
        description: |
          The location where the backup will be stored. Currently, the only supported option is to store the backup in the same region as the cluster.
        default_from_api: true
      - name: 'labels'
        type: KeyValuePairs
        description:
          'Labels to apply to backups created using this configuration.'
      - name: 'encryptionConfig'
        type: NestedObject
        description: |
          EncryptionConfig describes the encryption config of a cluster or a backup that is encrypted with a CMEK (customer-managed encryption key).
        properties:
          - name: 'kmsKeyName'
            type: String
            description: |
              The fully-qualified resource name of the KMS key. Each Cloud KMS key is regionalized and has the following format: projects/[PROJECT]/locations/[REGION]/keyRings/[RING]/cryptoKeys/[KEY_NAME].
      - name: 'weeklySchedule'
        type: NestedObject
        description: 'Weekly schedule for the Backup.'
        default_from_api: true
        properties:
          - name: 'daysOfWeek'
            type: Array
            description: 'The days of the week to perform a backup. At least one day of the week must be provided.'
            item_type:
              type: Enum
              description: 'The days of the week to perform a backup. At least one day of the week must be provided.'
              enum_values:
                - 'MONDAY'
                - 'TUESDAY'
                - 'WEDNESDAY'
                - 'THURSDAY'
                - 'FRIDAY'
                - 'SATURDAY'
                - 'SUNDAY'
            min_size: 1
          - name: 'startTimes'
            type: Array
            description: |
              The times during the day to start a backup. At least one start time must be provided. The start times are assumed to be in UTC and to be an exact hour (e.g., 04:00:00).
            required: true
            custom_flatten: 'templates/terraform/custom_flatten/alloydb_cluster_input_automated_backup_policy_start_times_flatten.go.tmpl'
            item_type:
              type: NestedObject
              properties:
                - name: 'hours'
                  type: Integer
                  description: |
                    Hours of day in 24 hour format. Should be from 0 to 23. An API may choose to allow the value "24:00:00" for scenarios like business closing time.
                - name: 'minutes'
                  type: Integer
                  description: |
                    Minutes of hour of day. Currently, only the value 0 is supported.
                - name: 'seconds'
                  type: Integer
                  description: |
                    Seconds of minutes of the time. Currently, only the value 0 is supported.
                - name: 'nanos'
                  type: Integer
                  description: |
                    Fractions of seconds in nanoseconds. Currently, only the value 0 is supported.
      - name: 'timeBasedRetention'
        type: NestedObject
        description: |
          Time-based Backup retention policy. Conflicts with 'quantity_based_retention', both can't be set together.
        conflicts:
          - automated_backup_policy.0.quantity_based_retention
        properties:
          - name: 'retentionPeriod'
            type: String
            description: |
              The retention period.
              A duration in seconds with up to nine fractional digits, terminated by 's'. Example: "3.5s".
      - name: 'quantityBasedRetention'
        type: NestedObject
        description: |
          Quantity-based Backup retention policy to retain recent backups. Conflicts with 'time_based_retention', both can't be set together.
        conflicts:
          - automated_backup_policy.0.time_based_retention
        properties:
          - name: 'count'
            type: Integer
            description: |
              The number of backups to retain.
      - name: 'enabled'
        type: Boolean
        description: |
          Whether automated backups are enabled.
        default_from_api: true
  - name: 'backupSource'
    type: NestedObject
    description: 'Cluster created from backup.'
    output: true
    properties:
      - name: 'backupName'
        type: String
        description: 'The name of the backup resource.'
  - name: 'migrationSource'
    type: NestedObject
    description: 'Cluster created via DMS migration.'
    output: true
    properties:
      - name: 'hostPort'
        type: String
        description:
          'The host and port of the on-premises instance in host:port format'
      - name: 'referenceId'
        type: String
        description:
          'Place holder for the external source identifier(e.g DMS job name)
          that created the cluster.'
      - name: 'sourceType'
        type: String
        description: 'Type of migration source.'
  - name: 'clusterType'
    type: Enum
    description: |
      The type of cluster. If not set, defaults to PRIMARY.
    default_value: "PRIMARY"
    enum_values:
      - 'PRIMARY'
      - 'SECONDARY'
  - name: 'secondaryConfig'
    type: NestedObject
    description: |
      Configuration of the secondary cluster for Cross Region Replication. This should be set if and only if the cluster is of type SECONDARY.
    properties:
      - name: 'primaryClusterName'
        type: String
        description: |
          Name of the primary cluster must be in the format
          'projects/{project}/locations/{location}/clusters/{cluster_id}'
        required: true
  - name: 'maintenanceUpdatePolicy'
    type: NestedObject
    description: |
      MaintenanceUpdatePolicy defines the policy for system updates.
    properties:
      - name: 'maintenanceWindows'
        type: Array
        description: |
          Preferred windows to perform maintenance. Currently limited to 1.
        item_type:
          description: |
            specifies a preferred day and time for maintenance.
          type: NestedObject
          properties:
            - name: 'day'
              type: Enum
              description: |
                Preferred day of the week for maintenance, e.g. MONDAY, TUESDAY, etc.
              required: true
              enum_values:
                - 'MONDAY'
                - 'TUESDAY'
                - 'WEDNESDAY'
                - 'THURSDAY'
                - 'FRIDAY'
                - 'SATURDAY'
                - 'SUNDAY'
            - name: 'startTime'
              type: NestedObject
              description: |
                Preferred time to start the maintenance operation on the specified day. Maintenance will start within 1 hour of this time.
              required: true
              properties:
                - name: 'hours'
                  type: Integer
                  description: |
                    Hours of day in 24 hour format. Should be from 0 to 23.
                  required: true
                - name: 'minutes'
                  type: Integer
                  description: |
                    Minutes of hour of day. Currently, only the value 0 is supported.
                - name: 'seconds'
                  type: Integer
                  description: |
                    Seconds of minutes of the time. Currently, only the value 0 is supported.
                - name: 'nanos'
                  type: Integer
                  description: |
                    Fractions of seconds in nanoseconds. Currently, only the value 0 is supported.
  - name: 'subscriptionType'
    type: Enum
    description: |
      The subscrition type of cluster.
    default_from_api: true
    enum_values:
      - 'TRIAL'
      - 'STANDARD'
  - name: 'trialMetadata'
    type: NestedObject
    description: |
      Contains information and all metadata related to TRIAL clusters.
    output: true
    properties:
      - name: 'startTime'
        type: String
        description: |
          Start time of the trial cluster.
      - name: 'endTime'
        type: String
        description: |
          End time of the trial cluster.
      - name: 'upgradeTime'
        type: String
        description: |
          Upgrade time of the trial cluster to standard cluster.
      - name: 'graceEndTime'
        type: String
        description: |
          Grace end time of the trial cluster.
