// Copyright 2026 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package redis provides access to the Google Cloud Memorystore for Redis API.
//
// This package is DEPRECATED. Use package cloud.google.com/go/redis/apiv1 instead.
//
// For product documentation, see: https://cloud.google.com/memorystore/docs/redis/
//
// # Library status
//
// These client libraries are officially supported by Google. However, this
// library is considered complete and is in maintenance mode. This means
// that we will address critical bugs and security issues but will not add
// any new features.
//
// When possible, we recommend using our newer
// [Cloud Client Libraries for Go](https://pkg.go.dev/cloud.google.com/go)
// that are still actively being worked and iterated on.
//
// # Creating a client
//
// Usage example:
//
//	import "google.golang.org/api/redis/v1"
//	...
//	ctx := context.Background()
//	redisService, err := redis.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for
// authentication. For information on how to create and obtain Application
// Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// # Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API
// keys), use [google.golang.org/api/option.WithAPIKey]:
//
//	redisService, err := redis.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth
// flow, use [google.golang.org/api/option.WithTokenSource]:
//
//	config := &oauth2.Config{...}
//	// ...
//	token, err := config.Exchange(ctx, ...)
//	redisService, err := redis.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See [google.golang.org/api/option.ClientOption] for details on options.
package redis // import "google.golang.org/api/redis/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"log/slog"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	"github.com/googleapis/gax-go/v2/internallog"
	googleapi "google.golang.org/api/googleapi"
	internal "google.golang.org/api/internal"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = internaloption.WithDefaultEndpoint
var _ = internal.Version
var _ = internallog.New

const apiId = "redis:v1"
const apiName = "redis"
const apiVersion = "v1"
const basePath = "https://redis.googleapis.com/"
const basePathTemplate = "https://redis.UNIVERSE_DOMAIN/"
const mtlsBasePath = "https://redis.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See, edit, configure, and delete your Google Cloud data and see the email
	// address for your Google Account.
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := internaloption.WithDefaultScopes(
		"https://www.googleapis.com/auth/cloud-platform",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultEndpointTemplate(basePathTemplate))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	opts = append(opts, internaloption.EnableNewAuthLibrary())
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s := &Service{client: client, BasePath: basePath, logger: internaloption.GetLogger(opts)}
	s.Projects = NewProjectsService(s)
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	return NewService(context.TODO(), option.WithHTTPClient(client))
}

type Service struct {
	client    *http.Client
	logger    *slog.Logger
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Projects *ProjectsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	rs.Locations = NewProjectsLocationsService(s)
	return rs
}

type ProjectsService struct {
	s *Service

	Locations *ProjectsLocationsService
}

func NewProjectsLocationsService(s *Service) *ProjectsLocationsService {
	rs := &ProjectsLocationsService{s: s}
	rs.BackupCollections = NewProjectsLocationsBackupCollectionsService(s)
	rs.Clusters = NewProjectsLocationsClustersService(s)
	rs.Instances = NewProjectsLocationsInstancesService(s)
	rs.Operations = NewProjectsLocationsOperationsService(s)
	return rs
}

type ProjectsLocationsService struct {
	s *Service

	BackupCollections *ProjectsLocationsBackupCollectionsService

	Clusters *ProjectsLocationsClustersService

	Instances *ProjectsLocationsInstancesService

	Operations *ProjectsLocationsOperationsService
}

func NewProjectsLocationsBackupCollectionsService(s *Service) *ProjectsLocationsBackupCollectionsService {
	rs := &ProjectsLocationsBackupCollectionsService{s: s}
	rs.Backups = NewProjectsLocationsBackupCollectionsBackupsService(s)
	return rs
}

type ProjectsLocationsBackupCollectionsService struct {
	s *Service

	Backups *ProjectsLocationsBackupCollectionsBackupsService
}

func NewProjectsLocationsBackupCollectionsBackupsService(s *Service) *ProjectsLocationsBackupCollectionsBackupsService {
	rs := &ProjectsLocationsBackupCollectionsBackupsService{s: s}
	return rs
}

type ProjectsLocationsBackupCollectionsBackupsService struct {
	s *Service
}

func NewProjectsLocationsClustersService(s *Service) *ProjectsLocationsClustersService {
	rs := &ProjectsLocationsClustersService{s: s}
	return rs
}

type ProjectsLocationsClustersService struct {
	s *Service
}

func NewProjectsLocationsInstancesService(s *Service) *ProjectsLocationsInstancesService {
	rs := &ProjectsLocationsInstancesService{s: s}
	return rs
}

type ProjectsLocationsInstancesService struct {
	s *Service
}

func NewProjectsLocationsOperationsService(s *Service) *ProjectsLocationsOperationsService {
	rs := &ProjectsLocationsOperationsService{s: s}
	return rs
}

type ProjectsLocationsOperationsService struct {
	s *Service
}

// AOFConfig: Configuration of the AOF based persistence.
type AOFConfig struct {
	// AppendFsync: Optional. fsync configuration.
	//
	// Possible values:
	//   "APPEND_FSYNC_UNSPECIFIED" - Not set. Default: EVERYSEC
	//   "NO" - Never fsync. Normally Linux will flush data every 30 seconds with
	// this configuration, but it's up to the kernel's exact tuning.
	//   "EVERYSEC" - fsync every second. Fast enough, and you may lose 1 second of
	// data if there is a disaster
	//   "ALWAYS" - fsync every time new write commands are appended to the AOF. It
	// has the best data loss protection at the cost of performance
	AppendFsync string `json:"appendFsync,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AppendFsync") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AppendFsync") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s AOFConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AOFConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// AutomatedBackupConfig: The automated backup config for a cluster.
type AutomatedBackupConfig struct {
	// AutomatedBackupMode: Optional. The automated backup mode. If the mode is
	// disabled, the other fields will be ignored.
	//
	// Possible values:
	//   "AUTOMATED_BACKUP_MODE_UNSPECIFIED" - Default value. Automated backup
	// config is not specified.
	//   "DISABLED" - Automated backup config disabled.
	//   "ENABLED" - Automated backup config enabled.
	AutomatedBackupMode string `json:"automatedBackupMode,omitempty"`
	// FixedFrequencySchedule: Optional. Trigger automated backups at a fixed
	// frequency.
	FixedFrequencySchedule *FixedFrequencySchedule `json:"fixedFrequencySchedule,omitempty"`
	// Retention: Optional. How long to keep automated backups before the backups
	// are deleted. The value should be between 1 day and 365 days. If not
	// specified, the default value is 35 days.
	Retention string `json:"retention,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AutomatedBackupMode") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AutomatedBackupMode") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s AutomatedBackupConfig) MarshalJSON() ([]byte, error) {
	type NoMethod AutomatedBackupConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// AvailabilityConfiguration: Configuration for availability of database
// instance
type AvailabilityConfiguration struct {
	// AutomaticFailoverRoutingConfigured: Checks for existence of (multi-cluster)
	// routing configuration that allows automatic failover to a different
	// zone/region in case of an outage. Applicable to Bigtable resources.
	AutomaticFailoverRoutingConfigured bool `json:"automaticFailoverRoutingConfigured,omitempty"`
	// AvailabilityType: Availability type. Potential values: * `ZONAL`: The
	// instance serves data from only one zone. Outages in that zone affect data
	// accessibility. * `REGIONAL`: The instance can serve data from more than one
	// zone in a region (it is highly available).
	//
	// Possible values:
	//   "AVAILABILITY_TYPE_UNSPECIFIED"
	//   "ZONAL" - Zonal available instance.
	//   "REGIONAL" - Regional available instance.
	//   "MULTI_REGIONAL" - Multi regional instance
	//   "AVAILABILITY_TYPE_OTHER" - For rest of the other category
	AvailabilityType string `json:"availabilityType,omitempty"`
	// CrossRegionReplicaConfigured: Checks for resources that are configured to
	// have redundancy, and ongoing replication across regions
	CrossRegionReplicaConfigured bool `json:"crossRegionReplicaConfigured,omitempty"`
	ExternalReplicaConfigured    bool `json:"externalReplicaConfigured,omitempty"`
	PromotableReplicaConfigured  bool `json:"promotableReplicaConfigured,omitempty"`
	// ForceSendFields is a list of field names (e.g.
	// "AutomaticFailoverRoutingConfigured") to unconditionally include in API
	// requests. By default, fields with empty or default values are omitted from
	// API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g.
	// "AutomaticFailoverRoutingConfigured") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted from API
	// requests. See https://pkg.go.dev/google.golang.org/api#hdr-NullFields for
	// more details.
	NullFields []string `json:"-"`
}

func (s AvailabilityConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod AvailabilityConfiguration
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Backup: Backup of a cluster.
type Backup struct {
	// BackupFiles: Output only. List of backup files of the backup.
	BackupFiles []*BackupFile `json:"backupFiles,omitempty"`
	// BackupType: Output only. Type of the backup.
	//
	// Possible values:
	//   "BACKUP_TYPE_UNSPECIFIED" - The default value, not set.
	//   "ON_DEMAND" - On-demand backup.
	//   "AUTOMATED" - Automated backup.
	BackupType string `json:"backupType,omitempty"`
	// Cluster: Output only. Cluster resource path of this backup.
	Cluster string `json:"cluster,omitempty"`
	// ClusterUid: Output only. Cluster uid of this backup.
	ClusterUid string `json:"clusterUid,omitempty"`
	// CreateTime: Output only. The time when the backup was created.
	CreateTime string `json:"createTime,omitempty"`
	// EncryptionInfo: Output only. Encryption information of the backup.
	EncryptionInfo *EncryptionInfo `json:"encryptionInfo,omitempty"`
	// EngineVersion: Output only. redis-7.2, valkey-7.5
	EngineVersion string `json:"engineVersion,omitempty"`
	// ExpireTime: Output only. The time when the backup will expire.
	ExpireTime string `json:"expireTime,omitempty"`
	// Name: Identifier. Full resource path of the backup. the last part of the
	// name is the backup id with the following format: [YYYYMMDDHHMMSS]_[Shorted
	// Cluster UID] OR customer specified while backup cluster. Example:
	// 20240515123000_1234
	Name string `json:"name,omitempty"`
	// NodeType: Output only. Node type of the cluster.
	//
	// Possible values:
	//   "NODE_TYPE_UNSPECIFIED" - Node type unspecified
	//   "REDIS_SHARED_CORE_NANO" - Redis shared core nano node_type.
	//   "REDIS_HIGHMEM_MEDIUM" - Redis highmem medium node_type.
	//   "REDIS_HIGHMEM_XLARGE" - Redis highmem xlarge node_type.
	//   "REDIS_STANDARD_SMALL" - Redis standard small node_type.
	NodeType string `json:"nodeType,omitempty"`
	// ReplicaCount: Output only. Number of replicas for the cluster.
	ReplicaCount int64 `json:"replicaCount,omitempty"`
	// ShardCount: Output only. Number of shards for the cluster.
	ShardCount int64 `json:"shardCount,omitempty"`
	// State: Output only. State of the backup.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - The default value, not set.
	//   "CREATING" - The backup is being created.
	//   "ACTIVE" - The backup is active to be used.
	//   "DELETING" - The backup is being deleted.
	//   "SUSPENDED" - The backup is currently suspended due to reasons like
	// project deletion, billing account closure, etc.
	State string `json:"state,omitempty"`
	// TotalSizeBytes: Output only. Total size of the backup in bytes.
	TotalSizeBytes int64 `json:"totalSizeBytes,omitempty,string"`
	// Uid: Output only. System assigned unique identifier of the backup.
	Uid string `json:"uid,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "BackupFiles") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupFiles") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Backup) MarshalJSON() ([]byte, error) {
	type NoMethod Backup
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BackupClusterRequest: Request for [BackupCluster].
type BackupClusterRequest struct {
	// BackupId: Optional. The id of the backup to be created. If not specified,
	// the default value ([YYYYMMDDHHMMSS]_[Shortened Cluster UID] is used.
	BackupId string `json:"backupId,omitempty"`
	// Ttl: Optional. TTL for the backup to expire. Value range is 1 day to 100
	// years. If not specified, the default value is 100 years.
	Ttl string `json:"ttl,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BackupId") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupId") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BackupClusterRequest) MarshalJSON() ([]byte, error) {
	type NoMethod BackupClusterRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BackupCollection: BackupCollection of a cluster.
type BackupCollection struct {
	// Cluster: Output only. The full resource path of the cluster the backup
	// collection belongs to. Example:
	// projects/{project}/locations/{location}/clusters/{cluster}
	Cluster string `json:"cluster,omitempty"`
	// ClusterUid: Output only. The cluster uid of the backup collection.
	ClusterUid string `json:"clusterUid,omitempty"`
	// CreateTime: Output only. The time when the backup collection was created.
	CreateTime string `json:"createTime,omitempty"`
	// KmsKey: Output only. The KMS key used to encrypt the backups under this
	// backup collection.
	KmsKey string `json:"kmsKey,omitempty"`
	// LastBackupTime: Output only. The last time a backup was created in the
	// backup collection.
	LastBackupTime string `json:"lastBackupTime,omitempty"`
	// Name: Identifier. Full resource path of the backup collection.
	Name string `json:"name,omitempty"`
	// TotalBackupCount: Output only. Total number of backups in the backup
	// collection.
	TotalBackupCount int64 `json:"totalBackupCount,omitempty,string"`
	// TotalBackupSizeBytes: Output only. Total size of all backups in the backup
	// collection.
	TotalBackupSizeBytes int64 `json:"totalBackupSizeBytes,omitempty,string"`
	// Uid: Output only. System assigned unique identifier of the backup
	// collection.
	Uid string `json:"uid,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Cluster") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Cluster") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BackupCollection) MarshalJSON() ([]byte, error) {
	type NoMethod BackupCollection
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BackupConfiguration: Configuration for automatic backups
type BackupConfiguration struct {
	// AutomatedBackupEnabled: Whether customer visible automated backups are
	// enabled on the instance.
	AutomatedBackupEnabled bool `json:"automatedBackupEnabled,omitempty"`
	// BackupRetentionSettings: Backup retention settings.
	BackupRetentionSettings *RetentionSettings `json:"backupRetentionSettings,omitempty"`
	// PointInTimeRecoveryEnabled: Whether point-in-time recovery is enabled. This
	// is optional field, if the database service does not have this feature or
	// metadata is not available in control plane, this can be omitted.
	PointInTimeRecoveryEnabled bool `json:"pointInTimeRecoveryEnabled,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AutomatedBackupEnabled") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AutomatedBackupEnabled") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BackupConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod BackupConfiguration
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BackupDRConfiguration: BackupDRConfiguration to capture the backup and
// disaster recovery details of database resource.
type BackupDRConfiguration struct {
	// BackupdrManaged: Indicates if the resource is managed by BackupDR.
	BackupdrManaged bool `json:"backupdrManaged,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BackupdrManaged") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupdrManaged") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BackupDRConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod BackupDRConfiguration
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BackupDRMetadata: BackupDRMetadata contains information about the backup and
// disaster recovery metadata of a database resource.
type BackupDRMetadata struct {
	// BackupConfiguration: Backup configuration for this instance.
	BackupConfiguration *BackupConfiguration `json:"backupConfiguration,omitempty"`
	// BackupRun: Latest backup run information for this instance.
	BackupRun *BackupRun `json:"backupRun,omitempty"`
	// BackupdrConfiguration: BackupDR configuration for this instance.
	BackupdrConfiguration *BackupDRConfiguration `json:"backupdrConfiguration,omitempty"`
	// FullResourceName: Required. Full resource name of this instance.
	FullResourceName string `json:"fullResourceName,omitempty"`
	// LastRefreshTime: Required. Last time backup configuration was refreshed.
	LastRefreshTime string `json:"lastRefreshTime,omitempty"`
	// ResourceId: Required. Database resource id.
	ResourceId *DatabaseResourceId `json:"resourceId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BackupConfiguration") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupConfiguration") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BackupDRMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod BackupDRMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BackupFile: Backup is consisted of multiple backup files.
type BackupFile struct {
	// CreateTime: Output only. The time when the backup file was created.
	CreateTime string `json:"createTime,omitempty"`
	// FileName: Output only. e.g: .rdb
	FileName string `json:"fileName,omitempty"`
	// SizeBytes: Output only. Size of the backup file in bytes.
	SizeBytes int64 `json:"sizeBytes,omitempty,string"`
	// ForceSendFields is a list of field names (e.g. "CreateTime") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CreateTime") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BackupFile) MarshalJSON() ([]byte, error) {
	type NoMethod BackupFile
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// BackupRun: A backup run.
type BackupRun struct {
	// EndTime: The time the backup operation completed. REQUIRED
	EndTime string `json:"endTime,omitempty"`
	// Error: Information about why the backup operation failed. This is only
	// present if the run has the FAILED status. OPTIONAL
	Error *OperationError `json:"error,omitempty"`
	// StartTime: The time the backup operation started. REQUIRED
	StartTime string `json:"startTime,omitempty"`
	// Status: The status of this run. REQUIRED
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED"
	//   "SUCCESSFUL" - The backup was successful.
	//   "FAILED" - The backup was unsuccessful.
	Status string `json:"status,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EndTime") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s BackupRun) MarshalJSON() ([]byte, error) {
	type NoMethod BackupRun
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

type CertChain struct {
	// Certificates: The certificates that form the CA chain, from leaf to root
	// order.
	Certificates []string `json:"certificates,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Certificates") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Certificates") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s CertChain) MarshalJSON() ([]byte, error) {
	type NoMethod CertChain
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// CertificateAuthority: Redis cluster certificate authority
type CertificateAuthority struct {
	ManagedServerCa *ManagedCertificateAuthority `json:"managedServerCa,omitempty"`
	// Name: Identifier. Unique name of the resource in this scope including
	// project, location and cluster using the form:
	// `projects/{project}/locations/{location}/clusters/{cluster}/certificateAuthor
	// ity`
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "ManagedServerCa") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ManagedServerCa") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s CertificateAuthority) MarshalJSON() ([]byte, error) {
	type NoMethod CertificateAuthority
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Cluster: A cluster instance.
type Cluster struct {
	// AclPolicy: Optional. The ACL policy to be applied to the cluster.
	AclPolicy string `json:"aclPolicy,omitempty"`
	// AllowFewerZonesDeployment: Optional. Immutable. Deprecated, do not use.
	AllowFewerZonesDeployment bool `json:"allowFewerZonesDeployment,omitempty"`
	// AsyncClusterEndpointsDeletionEnabled: Optional. If true, cluster endpoints
	// that are created and registered by customers can be deleted asynchronously.
	// That is, such a cluster endpoint can be de-registered before the forwarding
	// rules in the cluster endpoint are deleted.
	AsyncClusterEndpointsDeletionEnabled bool `json:"asyncClusterEndpointsDeletionEnabled,omitempty"`
	// AuthorizationMode: Optional. The authorization mode of the Redis cluster. If
	// not provided, auth feature is disabled for the cluster.
	//
	// Possible values:
	//   "AUTH_MODE_UNSPECIFIED" - Not set.
	//   "AUTH_MODE_IAM_AUTH" - IAM basic authorization mode
	//   "AUTH_MODE_DISABLED" - Authorization disabled mode
	AuthorizationMode string `json:"authorizationMode,omitempty"`
	// AutomatedBackupConfig: Optional. The automated backup config for the
	// cluster.
	AutomatedBackupConfig *AutomatedBackupConfig `json:"automatedBackupConfig,omitempty"`
	// AvailableMaintenanceVersions: Output only. This field is used to determine
	// the available maintenance versions for the self service update.
	AvailableMaintenanceVersions []string `json:"availableMaintenanceVersions,omitempty"`
	// BackupCollection: Optional. Output only. The backup collection full resource
	// name. Example:
	// projects/{project}/locations/{location}/backupCollections/{collection}
	BackupCollection string `json:"backupCollection,omitempty"`
	// ClusterEndpoints: Optional. A list of cluster endpoints.
	ClusterEndpoints []*ClusterEndpoint `json:"clusterEndpoints,omitempty"`
	// CreateTime: Output only. The timestamp associated with the cluster creation
	// request.
	CreateTime string `json:"createTime,omitempty"`
	// CrossClusterReplicationConfig: Optional. Cross cluster replication config.
	CrossClusterReplicationConfig *CrossClusterReplicationConfig `json:"crossClusterReplicationConfig,omitempty"`
	// DeletionProtectionEnabled: Optional. The delete operation will fail when the
	// value is set to true.
	DeletionProtectionEnabled bool `json:"deletionProtectionEnabled,omitempty"`
	// DiscoveryEndpoints: Output only. Endpoints created on each given network,
	// for Redis clients to connect to the cluster. Currently only one discovery
	// endpoint is supported.
	DiscoveryEndpoints []*DiscoveryEndpoint `json:"discoveryEndpoints,omitempty"`
	// EffectiveMaintenanceVersion: Output only. This field represents the actual
	// maintenance version of the cluster.
	EffectiveMaintenanceVersion string `json:"effectiveMaintenanceVersion,omitempty"`
	// EncryptionInfo: Output only. Encryption information of the data at rest of
	// the cluster.
	EncryptionInfo *EncryptionInfo `json:"encryptionInfo,omitempty"`
	// GcsSource: Optional. Backups stored in Cloud Storage buckets. The Cloud
	// Storage buckets need to be the same region as the clusters. Read permission
	// is required to import from the provided Cloud Storage objects.
	GcsSource *GcsBackupSource `json:"gcsSource,omitempty"`
	// KmsKey: Optional. The KMS key used to encrypt the at-rest data of the
	// cluster.
	KmsKey string `json:"kmsKey,omitempty"`
	// Labels: Optional. Labels to represent user-provided metadata.
	Labels map[string]string `json:"labels,omitempty"`
	// MaintenancePolicy: Optional. ClusterMaintenancePolicy determines when to
	// allow or deny updates.
	MaintenancePolicy *ClusterMaintenancePolicy `json:"maintenancePolicy,omitempty"`
	// MaintenanceSchedule: Output only. ClusterMaintenanceSchedule Output only
	// Published maintenance schedule.
	MaintenanceSchedule *ClusterMaintenanceSchedule `json:"maintenanceSchedule,omitempty"`
	// MaintenanceVersion: Optional. This field can be used to trigger self service
	// update to indicate the desired maintenance version. The input to this field
	// can be determined by the available_maintenance_versions field.
	MaintenanceVersion string `json:"maintenanceVersion,omitempty"`
	// ManagedBackupSource: Optional. Backups generated and managed by memorystore
	// service.
	ManagedBackupSource *ManagedBackupSource `json:"managedBackupSource,omitempty"`
	// Name: Required. Identifier. Unique name of the resource in this scope
	// including project and location using the form:
	// `projects/{project_id}/locations/{location_id}/clusters/{cluster_id}`
	Name string `json:"name,omitempty"`
	// NodeType: Optional. The type of a redis node in the cluster. NodeType
	// determines the underlying machine-type of a redis node.
	//
	// Possible values:
	//   "NODE_TYPE_UNSPECIFIED" - Node type unspecified
	//   "REDIS_SHARED_CORE_NANO" - Redis shared core nano node_type.
	//   "REDIS_HIGHMEM_MEDIUM" - Redis highmem medium node_type.
	//   "REDIS_HIGHMEM_XLARGE" - Redis highmem xlarge node_type.
	//   "REDIS_STANDARD_SMALL" - Redis standard small node_type.
	NodeType string `json:"nodeType,omitempty"`
	// OndemandMaintenance: Optional. Input only. Ondemand maintenance for the
	// cluster. This field can be used to trigger ondemand critical update on the
	// cluster.
	OndemandMaintenance bool `json:"ondemandMaintenance,omitempty"`
	// PersistenceConfig: Optional. Persistence config (RDB, AOF) for the cluster.
	PersistenceConfig *ClusterPersistenceConfig `json:"persistenceConfig,omitempty"`
	// PreciseSizeGb: Output only. Precise value of redis memory size in GB for the
	// entire cluster.
	PreciseSizeGb float64 `json:"preciseSizeGb,omitempty"`
	// PscConfigs: Optional. Each PscConfig configures the consumer network where
	// IPs will be designated to the cluster for client access through Private
	// Service Connect Automation. Currently, only one PscConfig is supported.
	PscConfigs []*PscConfig `json:"pscConfigs,omitempty"`
	// PscConnections: Output only. The list of PSC connections that are
	// auto-created through service connectivity automation.
	PscConnections []*PscConnection `json:"pscConnections,omitempty"`
	// PscServiceAttachments: Output only. Service attachment details to configure
	// Psc connections
	PscServiceAttachments []*PscServiceAttachment `json:"pscServiceAttachments,omitempty"`
	// RedisConfigs: Optional. Key/Value pairs of customer overrides for mutable
	// Redis Configs
	RedisConfigs map[string]string `json:"redisConfigs,omitempty"`
	// ReplicaCount: Optional. The number of replica nodes per shard.
	ReplicaCount int64 `json:"replicaCount,omitempty"`
	// RotateServerCertificate: Optional. Input only. Rotate the server
	// certificates.
	RotateServerCertificate bool `json:"rotateServerCertificate,omitempty"`
	// SatisfiesPzi: Optional. Output only. Reserved for future use.
	SatisfiesPzi bool `json:"satisfiesPzi,omitempty"`
	// SatisfiesPzs: Optional. Output only. Reserved for future use.
	SatisfiesPzs bool `json:"satisfiesPzs,omitempty"`
	// ServerCaMode: Optional. Server CA mode for the cluster.
	//
	// Possible values:
	//   "SERVER_CA_MODE_UNSPECIFIED" - Server CA mode not specified.
	//   "SERVER_CA_MODE_GOOGLE_MANAGED_PER_INSTANCE_CA" - Each cluster has its own
	// Google managed CA.
	//   "SERVER_CA_MODE_GOOGLE_MANAGED_SHARED_CA" - The cluster uses Google
	// managed shared CA in the region.
	//   "SERVER_CA_MODE_CUSTOMER_MANAGED_CAS_CA" - The cluster uses customer
	// managed CA from CAS.
	ServerCaMode string `json:"serverCaMode,omitempty"`
	// ServerCaPool: Optional. Customer-managed CA pool for the cluster. Only
	// applicable for BYOCA i.e. if server_ca_mode is
	// SERVER_CA_MODE_CUSTOMER_MANAGED_CAS_CA. Format:
	// "projects/{project}/locations/{region}/caPools/{ca_pool}".
	ServerCaPool string `json:"serverCaPool,omitempty"`
	// ShardCount: Optional. Number of shards for the Redis cluster.
	ShardCount int64 `json:"shardCount,omitempty"`
	// SimulateMaintenanceEvent: Optional. Input only. Simulate a maintenance
	// event.
	SimulateMaintenanceEvent bool `json:"simulateMaintenanceEvent,omitempty"`
	// SizeGb: Output only. Redis memory size in GB for the entire cluster rounded
	// up to the next integer.
	SizeGb int64 `json:"sizeGb,omitempty"`
	// State: Output only. The current state of this cluster. Can be CREATING,
	// READY, UPDATING, DELETING and SUSPENDED
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Not set.
	//   "CREATING" - Redis cluster is being created.
	//   "ACTIVE" - Redis cluster has been created and is fully usable.
	//   "UPDATING" - Redis cluster configuration is being updated.
	//   "DELETING" - Redis cluster is being deleted.
	State string `json:"state,omitempty"`
	// StateInfo: Output only. Additional information about the current state of
	// the cluster.
	StateInfo *StateInfo `json:"stateInfo,omitempty"`
	// TransitEncryptionMode: Optional. The in-transit encryption for the Redis
	// cluster. If not provided, encryption is disabled for the cluster.
	//
	// Possible values:
	//   "TRANSIT_ENCRYPTION_MODE_UNSPECIFIED" - In-transit encryption not set.
	//   "TRANSIT_ENCRYPTION_MODE_DISABLED" - In-transit encryption disabled.
	//   "TRANSIT_ENCRYPTION_MODE_SERVER_AUTHENTICATION" - Use server managed
	// encryption for in-transit encryption.
	TransitEncryptionMode string `json:"transitEncryptionMode,omitempty"`
	// Uid: Output only. System assigned, unique identifier for the cluster.
	Uid string `json:"uid,omitempty"`
	// ZoneDistributionConfig: Optional. This config will be used to determine how
	// the customer wants us to distribute cluster resources within the region.
	ZoneDistributionConfig *ZoneDistributionConfig `json:"zoneDistributionConfig,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "AclPolicy") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AclPolicy") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Cluster) MarshalJSON() ([]byte, error) {
	type NoMethod Cluster
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

func (s *Cluster) UnmarshalJSON(data []byte) error {
	type NoMethod Cluster
	var s1 struct {
		PreciseSizeGb gensupport.JSONFloat64 `json:"preciseSizeGb"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.PreciseSizeGb = float64(s1.PreciseSizeGb)
	return nil
}

// ClusterEndpoint: ClusterEndpoint consists of PSC connections that are
// created as a group in each VPC network for accessing the cluster. In each
// group, there shall be one connection for each service attachment in the
// cluster.
type ClusterEndpoint struct {
	// Connections: Required. A group of PSC connections. They are created in the
	// same VPC network, one for each service attachment in the cluster.
	Connections []*ConnectionDetail `json:"connections,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Connections") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Connections") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ClusterEndpoint) MarshalJSON() ([]byte, error) {
	type NoMethod ClusterEndpoint
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ClusterMaintenancePolicy: Maintenance policy per cluster.
type ClusterMaintenancePolicy struct {
	// CreateTime: Output only. The time when the policy was created i.e.
	// Maintenance Window or Deny Period was assigned.
	CreateTime string `json:"createTime,omitempty"`
	// UpdateTime: Output only. The time when the policy was updated i.e.
	// Maintenance Window or Deny Period was updated.
	UpdateTime string `json:"updateTime,omitempty"`
	// WeeklyMaintenanceWindow: Optional. Maintenance window that is applied to
	// resources covered by this policy. Minimum 1. For the current version, the
	// maximum number of weekly_maintenance_window is expected to be one.
	WeeklyMaintenanceWindow []*ClusterWeeklyMaintenanceWindow `json:"weeklyMaintenanceWindow,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CreateTime") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CreateTime") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ClusterMaintenancePolicy) MarshalJSON() ([]byte, error) {
	type NoMethod ClusterMaintenancePolicy
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ClusterMaintenanceSchedule: Upcoming maintenance schedule.
type ClusterMaintenanceSchedule struct {
	// EndTime: Output only. The end time of any upcoming scheduled maintenance for
	// this instance.
	EndTime string `json:"endTime,omitempty"`
	// StartTime: Output only. The start time of any upcoming scheduled maintenance
	// for this instance.
	StartTime string `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EndTime") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ClusterMaintenanceSchedule) MarshalJSON() ([]byte, error) {
	type NoMethod ClusterMaintenanceSchedule
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ClusterPersistenceConfig: Configuration of the persistence functionality.
type ClusterPersistenceConfig struct {
	// AofConfig: Optional. AOF configuration. This field will be ignored if mode
	// is not AOF.
	AofConfig *AOFConfig `json:"aofConfig,omitempty"`
	// Mode: Optional. The mode of persistence.
	//
	// Possible values:
	//   "PERSISTENCE_MODE_UNSPECIFIED" - Not set.
	//   "DISABLED" - Persistence is disabled, and any snapshot data is deleted.
	//   "RDB" - RDB based persistence is enabled.
	//   "AOF" - AOF based persistence is enabled.
	Mode string `json:"mode,omitempty"`
	// RdbConfig: Optional. RDB configuration. This field will be ignored if mode
	// is not RDB.
	RdbConfig *RDBConfig `json:"rdbConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AofConfig") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AofConfig") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ClusterPersistenceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod ClusterPersistenceConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ClusterWeeklyMaintenanceWindow: Time window specified for weekly operations.
type ClusterWeeklyMaintenanceWindow struct {
	// Day: Optional. Allows to define schedule that runs specified day of the
	// week.
	//
	// Possible values:
	//   "DAY_OF_WEEK_UNSPECIFIED" - The day of the week is unspecified.
	//   "MONDAY" - Monday
	//   "TUESDAY" - Tuesday
	//   "WEDNESDAY" - Wednesday
	//   "THURSDAY" - Thursday
	//   "FRIDAY" - Friday
	//   "SATURDAY" - Saturday
	//   "SUNDAY" - Sunday
	Day string `json:"day,omitempty"`
	// StartTime: Optional. Start time of the window in UTC.
	StartTime *TimeOfDay `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Day") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Day") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ClusterWeeklyMaintenanceWindow) MarshalJSON() ([]byte, error) {
	type NoMethod ClusterWeeklyMaintenanceWindow
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Compliance: Contains compliance information about a security standard
// indicating unmet recommendations.
type Compliance struct {
	// Standard: Industry-wide compliance standards or benchmarks, such as CIS,
	// PCI, and OWASP.
	Standard string `json:"standard,omitempty"`
	// Version: Version of the standard or benchmark, for example, 1.1
	Version string `json:"version,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Standard") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Standard") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Compliance) MarshalJSON() ([]byte, error) {
	type NoMethod Compliance
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConfigBasedSignalData: Config based signal data. This is used to send
// signals to Condor which are based on the DB level configurations. These will
// be used to send signals for self managed databases.
type ConfigBasedSignalData struct {
	// FullResourceName: Required. Full Resource name of the source resource.
	FullResourceName string `json:"fullResourceName,omitempty"`
	// LastRefreshTime: Required. Last time signal was refreshed
	LastRefreshTime string `json:"lastRefreshTime,omitempty"`
	// ResourceId: Database resource id.
	ResourceId *DatabaseResourceId `json:"resourceId,omitempty"`
	// SignalBoolValue: Signal data for boolean signals.
	SignalBoolValue bool `json:"signalBoolValue,omitempty"`
	// SignalType: Required. Signal type of the signal
	//
	// Possible values:
	//   "SIGNAL_TYPE_UNSPECIFIED" - Unspecified signal type.
	//   "SIGNAL_TYPE_OUTDATED_MINOR_VERSION" - Outdated Minor Version
	//   "SIGNAL_TYPE_DATABASE_AUDITING_DISABLED" - Represents database auditing is
	// disabled.
	//   "SIGNAL_TYPE_NO_ROOT_PASSWORD" - Represents if a database has a password
	// configured for the root account or not.
	//   "SIGNAL_TYPE_EXPOSED_TO_PUBLIC_ACCESS" - Represents if a resource is
	// exposed to public access.
	//   "SIGNAL_TYPE_UNENCRYPTED_CONNECTIONS" - Represents if a resources requires
	// all incoming connections to use SSL or not.
	//   "SIGNAL_TYPE_EXTENDED_SUPPORT" - Represents if a resource version is in
	// extended support.
	//   "SIGNAL_TYPE_NO_AUTOMATED_BACKUP_POLICY" - Represents if a resource has no
	// automated backup policy.
	//   "SIGNAL_TYPE_VERSION_NEARING_END_OF_LIFE" - Represents if a resource
	// version is nearing end of life.
	//   "SIGNAL_TYPE_LAST_BACKUP_OLD" - Represents if the last backup of a
	// resource is older than 24 hours.
	//   "SIGNAL_TYPE_NOT_PROTECTED_BY_AUTOMATIC_FAILOVER" - Represents if a
	// resource is not protected by automatic failover.
	SignalType string `json:"signalType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "FullResourceName") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "FullResourceName") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConfigBasedSignalData) MarshalJSON() ([]byte, error) {
	type NoMethod ConfigBasedSignalData
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ConnectionDetail: Detailed information of each PSC connection.
type ConnectionDetail struct {
	// PscAutoConnection: Detailed information of a PSC connection that is created
	// through service connectivity automation.
	PscAutoConnection *PscAutoConnection `json:"pscAutoConnection,omitempty"`
	// PscConnection: Detailed information of a PSC connection that is created by
	// the customer who owns the cluster.
	PscConnection *PscConnection `json:"pscConnection,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PscAutoConnection") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "PscAutoConnection") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ConnectionDetail) MarshalJSON() ([]byte, error) {
	type NoMethod ConnectionDetail
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// CrossClusterReplicationConfig: Cross cluster replication config.
type CrossClusterReplicationConfig struct {
	// ClusterRole: Output only. The role of the cluster in cross cluster
	// replication.
	//
	// Possible values:
	//   "CLUSTER_ROLE_UNSPECIFIED" - Cluster role is not set. The behavior is
	// equivalent to NONE.
	//   "NONE" - This cluster does not participate in cross cluster replication.
	// It is an independent cluster and does not replicate to or from any other
	// clusters.
	//   "PRIMARY" - A cluster that allows both reads and writes. Any data written
	// to this cluster is also replicated to the attached secondary clusters.
	//   "SECONDARY" - A cluster that allows only reads and replicates data from a
	// primary cluster.
	ClusterRole string `json:"clusterRole,omitempty"`
	// Membership: Output only. An output only view of all the member clusters
	// participating in the cross cluster replication. This view will be provided
	// by every member cluster irrespective of its cluster role(primary or
	// secondary). A primary cluster can provide information about all the
	// secondary clusters replicating from it. However, a secondary cluster only
	// knows about the primary cluster from which it is replicating. However, for
	// scenarios, where the primary cluster is unavailable(e.g. regional outage), a
	// GetCluster request can be sent to any other member cluster and this field
	// will list all the member clusters participating in cross cluster
	// replication.
	Membership *Membership `json:"membership,omitempty"`
	// PrimaryCluster: Details of the primary cluster that is used as the
	// replication source for this secondary cluster. This field is only set for a
	// secondary cluster.
	PrimaryCluster *RemoteCluster `json:"primaryCluster,omitempty"`
	// SecondaryClusters: List of secondary clusters that are replicating from this
	// primary cluster. This field is only set for a primary cluster.
	SecondaryClusters []*RemoteCluster `json:"secondaryClusters,omitempty"`
	// UpdateTime: Output only. The last time cross cluster replication config was
	// updated.
	UpdateTime string `json:"updateTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ClusterRole") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ClusterRole") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s CrossClusterReplicationConfig) MarshalJSON() ([]byte, error) {
	type NoMethod CrossClusterReplicationConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// CustomMetadataData: Any custom metadata associated with the resource. e.g. A
// spanner instance can have multiple databases with its own unique metadata.
// Information for these individual databases can be captured in custom
// metadata data
type CustomMetadataData struct {
	// InternalResourceMetadata: Metadata for individual internal resources in an
	// instance. e.g. spanner instance can have multiple databases with unique
	// configuration.
	InternalResourceMetadata []*InternalResourceMetadata `json:"internalResourceMetadata,omitempty"`
	// ForceSendFields is a list of field names (e.g. "InternalResourceMetadata")
	// to unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "InternalResourceMetadata") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s CustomMetadataData) MarshalJSON() ([]byte, error) {
	type NoMethod CustomMetadataData
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseResourceFeed: DatabaseResourceFeed is the top level proto to be used
// to ingest different database resource level events into Condor platform.
// Next ID: 13
type DatabaseResourceFeed struct {
	// BackupdrMetadata: BackupDR metadata is used to ingest metadata from
	// BackupDR.
	BackupdrMetadata *BackupDRMetadata `json:"backupdrMetadata,omitempty"`
	// ConfigBasedSignalData: Config based signal data is used to ingest signals
	// that are generated based on the configuration of the database resource.
	ConfigBasedSignalData *ConfigBasedSignalData `json:"configBasedSignalData,omitempty"`
	// DatabaseResourceSignalData: Database resource signal data is used to ingest
	// signals from database resource signal feeds.
	DatabaseResourceSignalData *DatabaseResourceSignalData `json:"databaseResourceSignalData,omitempty"`
	// FeedTimestamp: Required. Timestamp when feed is generated.
	FeedTimestamp string `json:"feedTimestamp,omitempty"`
	// FeedType: Required. Type feed to be ingested into condor
	//
	// Possible values:
	//   "FEEDTYPE_UNSPECIFIED"
	//   "RESOURCE_METADATA" - Database resource metadata feed from control plane
	//   "OBSERVABILITY_DATA" - Database resource monitoring data
	//   "SECURITY_FINDING_DATA" - Database resource security health signal data
	//   "RECOMMENDATION_SIGNAL_DATA" - Database resource recommendation signal
	// data
	//   "CONFIG_BASED_SIGNAL_DATA" - Database config based signal data
	//   "BACKUPDR_METADATA" - Database resource metadata from BackupDR
	//   "DATABASE_RESOURCE_SIGNAL_DATA" - Database resource signal data
	FeedType                 string                                    `json:"feedType,omitempty"`
	ObservabilityMetricData  *ObservabilityMetricData                  `json:"observabilityMetricData,omitempty"`
	RecommendationSignalData *DatabaseResourceRecommendationSignalData `json:"recommendationSignalData,omitempty"`
	ResourceHealthSignalData *DatabaseResourceHealthSignalData         `json:"resourceHealthSignalData,omitempty"`
	// ResourceId: Primary key associated with the Resource. resource_id is
	// available in individual feed level as well.
	ResourceId       *DatabaseResourceId       `json:"resourceId,omitempty"`
	ResourceMetadata *DatabaseResourceMetadata `json:"resourceMetadata,omitempty"`
	// SkipIngestion: Optional. If true, the feed won't be ingested by DB Center.
	// This indicates that the feed is intentionally skipped. For example, BackupDR
	// feeds are only needed for resources integrated with DB Center (e.g.,
	// CloudSQL, AlloyDB). Feeds for non-integrated resources (e.g., Compute
	// Engine, Persistent Disk) can be skipped.
	SkipIngestion bool `json:"skipIngestion,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BackupdrMetadata") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupdrMetadata") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseResourceFeed) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseResourceFeed
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseResourceHealthSignalData: Common model for database resource health
// signal data.
type DatabaseResourceHealthSignalData struct {
	// AdditionalMetadata: Any other additional metadata
	AdditionalMetadata googleapi.RawMessage `json:"additionalMetadata,omitempty"`
	// Compliance: Industry standards associated with this signal; if this signal
	// is an issue, that could be a violation of the associated industry
	// standard(s). For example, AUTO_BACKUP_DISABLED signal is associated with CIS
	// GCP 1.1, CIS GCP 1.2, CIS GCP 1.3, NIST 800-53 and ISO-27001 compliance
	// standards. If a database resource does not have automated backup enable, it
	// will violate these following industry standards.
	Compliance []*Compliance `json:"compliance,omitempty"`
	// Description: Description associated with signal
	Description string `json:"description,omitempty"`
	// EventTime: Required. The last time at which the event described by this
	// signal took place
	EventTime string `json:"eventTime,omitempty"`
	// ExternalUri: The external-uri of the signal, using which more information
	// about this signal can be obtained. In GCP, this will take user to SCC page
	// to get more details about signals.
	ExternalUri string `json:"externalUri,omitempty"`
	// Location: This is used to identify the location of the resource. Example:
	// "us-central1"
	Location string `json:"location,omitempty"`
	// Name: Required. The name of the signal, ex: PUBLIC_SQL_INSTANCE,
	// SQL_LOG_ERROR_VERBOSITY etc.
	Name string `json:"name,omitempty"`
	// Provider: Cloud provider name. Ex: GCP/AWS/Azure/OnPrem/SelfManaged
	//
	// Possible values:
	//   "PROVIDER_UNSPECIFIED"
	//   "GCP" - Google cloud platform provider
	//   "AWS" - Amazon web service
	//   "AZURE" - Azure web service
	//   "ONPREM" - On-prem database resources.
	//   "SELFMANAGED" - Self-managed database provider. These are resources on a
	// cloud platform, e.g., database resource installed in a GCE VM, but not a
	// managed database service.
	//   "PROVIDER_OTHER" - For the rest of the other categories. Other refers to
	// the rest of other database service providers, this could be smaller cloud
	// provider. This needs to be provided when the provider is known, but it is
	// not present in the existing set of enum values.
	Provider string `json:"provider,omitempty"`
	// ResourceContainer: Closest parent container of this resource. In GCP,
	// 'container' refers to a Cloud Resource Manager project. It must be resource
	// name of a Cloud Resource Manager project with the format of "provider//",
	// such as "projects/123". For GCP provided resources, number should be project
	// number.
	ResourceContainer string `json:"resourceContainer,omitempty"`
	// ResourceName: Required. Database resource name associated with the signal.
	// Resource name to follow CAIS resource_name format as noted here
	// go/condor-common-datamodel
	ResourceName string `json:"resourceName,omitempty"`
	// SignalClass: Required. The class of the signal, such as if it's a THREAT or
	// VULNERABILITY.
	//
	// Possible values:
	//   "CLASS_UNSPECIFIED" - Unspecified signal class.
	//   "THREAT" - Describes unwanted or malicious activity.
	//   "VULNERABILITY" - Describes a potential weakness in software that
	// increases risk to Confidentiality & Integrity & Availability.
	//   "MISCONFIGURATION" - Describes a potential weakness in cloud
	// resource/asset configuration that increases risk.
	//   "OBSERVATION" - Describes a security observation that is for informational
	// purposes.
	//   "ERROR" - Describes an error that prevents some SCC functionality.
	SignalClass string `json:"signalClass,omitempty"`
	// SignalId: Required. Unique identifier for the signal. This is an unique id
	// which would be mainatined by partner to identify a signal.
	SignalId string `json:"signalId,omitempty"`
	// SignalSeverity: The severity of the signal, such as if it's a HIGH or LOW
	// severity.
	//
	// Possible values:
	//   "SIGNAL_SEVERITY_UNSPECIFIED" - This value is used for findings when a
	// source doesn't write a severity value.
	//   "CRITICAL" - A critical vulnerability is easily discoverable by an
	// external actor, exploitable.
	//   "HIGH" - A high risk vulnerability can be easily discovered and exploited
	// in combination with other vulnerabilities.
	//   "MEDIUM" - A medium risk vulnerability could be used by an actor to gain
	// access to resources or privileges that enable them to eventually gain access
	// and the ability to execute arbitrary code or exfiltrate data.
	//   "LOW" - A low risk vulnerability hampers a security organization's ability
	// to detect vulnerabilities or active threats in their deployment.
	SignalSeverity string `json:"signalSeverity,omitempty"`
	// SignalType: Required. Type of signal, for example,
	// `AVAILABLE_IN_MULTIPLE_ZONES`, `LOGGING_MOST_ERRORS`, etc.
	//
	// Possible values:
	//   "SIGNAL_TYPE_UNSPECIFIED" - Unspecified.
	//   "SIGNAL_TYPE_NOT_PROTECTED_BY_AUTOMATIC_FAILOVER" - Represents if a
	// resource is protected by automatic failover. Checks for resources that are
	// configured to have redundancy within a region that enables automatic
	// failover.
	//   "SIGNAL_TYPE_GROUP_NOT_REPLICATING_ACROSS_REGIONS" - Represents if a group
	// is replicating across regions. Checks for resources that are configured to
	// have redundancy, and ongoing replication, across regions.
	//   "SIGNAL_TYPE_NOT_AVAILABLE_IN_MULTIPLE_ZONES" - Represents if the resource
	// is available in multiple zones or not.
	//   "SIGNAL_TYPE_NOT_AVAILABLE_IN_MULTIPLE_REGIONS" - Represents if a resource
	// is available in multiple regions.
	//   "SIGNAL_TYPE_NO_PROMOTABLE_REPLICA" - Represents if a resource has a
	// promotable replica.
	//   "SIGNAL_TYPE_NO_AUTOMATED_BACKUP_POLICY" - Represents if a resource has an
	// automated backup policy.
	//   "SIGNAL_TYPE_SHORT_BACKUP_RETENTION" - Represents if a resources has a
	// short backup retention period.
	//   "SIGNAL_TYPE_LAST_BACKUP_FAILED" - Represents if the last backup of a
	// resource failed.
	//   "SIGNAL_TYPE_LAST_BACKUP_OLD" - Represents if the last backup of a
	// resource is older than some threshold value.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_2_0" - Represents if a resource
	// violates CIS GCP Foundation 2.0.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_1_3" - Represents if a resource
	// violates CIS GCP Foundation 1.3.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_1_2" - Represents if a resource
	// violates CIS GCP Foundation 1.2.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_1_1" - Represents if a resource
	// violates CIS GCP Foundation 1.1.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_1_0" - Represents if a resource
	// violates CIS GCP Foundation 1.0.
	//   "SIGNAL_TYPE_VIOLATES_CIS_CONTROLS_V8_0" - Represents if a resource
	// violates CIS Controls 8.0.
	//   "SIGNAL_TYPE_VIOLATES_NIST_800_53" - Represents if a resource violates
	// NIST 800-53.
	//   "SIGNAL_TYPE_VIOLATES_NIST_800_53_R5" - Represents if a resource violates
	// NIST 800-53 R5.
	//   "SIGNAL_TYPE_VIOLATES_NIST_CYBERSECURITY_FRAMEWORK_V1_0" - Represents if a
	// resource violates NIST Cybersecurity Framework 1.0.
	//   "SIGNAL_TYPE_VIOLATES_ISO_27001" - Represents if a resource violates
	// ISO-27001.
	//   "SIGNAL_TYPE_VIOLATES_ISO_27001_V2022" - Represents if a resource violates
	// ISO 27001 2022.
	//   "SIGNAL_TYPE_VIOLATES_PCI_DSS_V3_2_1" - Represents if a resource violates
	// PCI-DSS v3.2.1.
	//   "SIGNAL_TYPE_VIOLATES_PCI_DSS_V4_0" - Represents if a resource violates
	// PCI-DSS v4.0.
	//   "SIGNAL_TYPE_VIOLATES_CLOUD_CONTROLS_MATRIX_V4" - Represents if a resource
	// violates Cloud Controls Matrix v4.0.
	//   "SIGNAL_TYPE_VIOLATES_HIPAA" - Represents if a resource violates HIPAA.
	//   "SIGNAL_TYPE_VIOLATES_SOC2_V2017" - Represents if a resource violates SOC2
	// v2017.
	//   "SIGNAL_TYPE_LOGS_NOT_OPTIMIZED_FOR_TROUBLESHOOTING" - Represents if
	// log_checkpoints database flag for a Cloud SQL for PostgreSQL instance is not
	// set to on.
	//   "SIGNAL_TYPE_QUERY_DURATIONS_NOT_LOGGED" - Represents if the log_duration
	// database flag for a Cloud SQL for PostgreSQL instance is not set to on.
	//   "SIGNAL_TYPE_VERBOSE_ERROR_LOGGING" - Represents if the
	// log_error_verbosity database flag for a Cloud SQL for PostgreSQL instance is
	// not set to default or stricter (default or terse).
	//   "SIGNAL_TYPE_QUERY_LOCK_WAITS_NOT_LOGGED" - Represents if the
	// log_lock_waits database flag for a Cloud SQL for PostgreSQL instance is not
	// set to on.
	//   "SIGNAL_TYPE_LOGGING_MOST_ERRORS" - Represents if the
	// log_min_error_statement database flag for a Cloud SQL for PostgreSQL
	// instance is not set appropriately.
	//   "SIGNAL_TYPE_LOGGING_ONLY_CRITICAL_ERRORS" - Represents if the
	// log_min_error_statement database flag for a Cloud SQL for PostgreSQL
	// instance does not have an appropriate severity level.
	//   "SIGNAL_TYPE_MINIMAL_ERROR_LOGGING" - Represents if the log_min_messages
	// database flag for a Cloud SQL for PostgreSQL instance is not set to warning
	// or another recommended value.
	//   "SIGNAL_TYPE_QUERY_STATISTICS_LOGGED" - Represents if the databaseFlags
	// property of instance metadata for the log_executor_status field is set to
	// on.
	//   "SIGNAL_TYPE_EXCESSIVE_LOGGING_OF_CLIENT_HOSTNAME" - Represents if the
	// log_hostname database flag for a Cloud SQL for PostgreSQL instance is not
	// set to off.
	//   "SIGNAL_TYPE_EXCESSIVE_LOGGING_OF_PARSER_STATISTICS" - Represents if the
	// log_parser_stats database flag for a Cloud SQL for PostgreSQL instance is
	// not set to off.
	//   "SIGNAL_TYPE_EXCESSIVE_LOGGING_OF_PLANNER_STATISTICS" - Represents if the
	// log_planner_stats database flag for a Cloud SQL for PostgreSQL instance is
	// not set to off.
	//   "SIGNAL_TYPE_NOT_LOGGING_ONLY_DDL_STATEMENTS" - Represents if the
	// log_statement database flag for a Cloud SQL for PostgreSQL instance is not
	// set to DDL (all data definition statements).
	//   "SIGNAL_TYPE_LOGGING_QUERY_STATISTICS" - Represents if the
	// log_statement_stats database flag for a Cloud SQL for PostgreSQL instance is
	// not set to off.
	//   "SIGNAL_TYPE_NOT_LOGGING_TEMPORARY_FILES" - Represents if the
	// log_temp_files database flag for a Cloud SQL for PostgreSQL instance is not
	// set to "0". (NOTE: 0 = ON)
	//   "SIGNAL_TYPE_CONNECTION_MAX_NOT_CONFIGURED" - Represents if the user
	// connections database flag for a Cloud SQL for SQL Server instance is
	// configured.
	//   "SIGNAL_TYPE_USER_OPTIONS_CONFIGURED" - Represents if the user options
	// database flag for Cloud SQL SQL Server instance is configured or not.
	//   "SIGNAL_TYPE_EXPOSED_TO_PUBLIC_ACCESS" - Represents if a resource is
	// exposed to public access.
	//   "SIGNAL_TYPE_UNENCRYPTED_CONNECTIONS" - Represents if a resources requires
	// all incoming connections to use SSL or not.
	//   "SIGNAL_TYPE_NO_ROOT_PASSWORD" - Represents if a Cloud SQL database has a
	// password configured for the root account or not.
	//   "SIGNAL_TYPE_WEAK_ROOT_PASSWORD" - Represents if a Cloud SQL database has
	// a weak password configured for the root account.
	//   "SIGNAL_TYPE_ENCRYPTION_KEY_NOT_CUSTOMER_MANAGED" - Represents if a SQL
	// database instance is not encrypted with customer-managed encryption keys
	// (CMEK).
	//   "SIGNAL_TYPE_SERVER_AUTHENTICATION_NOT_REQUIRED" - Represents if The
	// contained database authentication database flag for a Cloud SQL for SQL
	// Server instance is not set to off.
	//   "SIGNAL_TYPE_EXPOSED_BY_OWNERSHIP_CHAINING" - Represents if the
	// cross_db_ownership_chaining database flag for a Cloud SQL for SQL Server
	// instance is not set to off.
	//   "SIGNAL_TYPE_EXPOSED_TO_EXTERNAL_SCRIPTS" - Represents if he external
	// scripts enabled database flag for a Cloud SQL for SQL Server instance is not
	// set to off.
	//   "SIGNAL_TYPE_EXPOSED_TO_LOCAL_DATA_LOADS" - Represents if the local_infile
	// database flag for a Cloud SQL for MySQL instance is not set to off.
	//   "SIGNAL_TYPE_CONNECTION_ATTEMPTS_NOT_LOGGED" - Represents if the
	// log_connections database flag for a Cloud SQL for PostgreSQL instance is not
	// set to on.
	//   "SIGNAL_TYPE_DISCONNECTIONS_NOT_LOGGED" - Represents if the
	// log_disconnections database flag for a Cloud SQL for PostgreSQL instance is
	// not set to on.
	//   "SIGNAL_TYPE_LOGGING_EXCESSIVE_STATEMENT_INFO" - Represents if the
	// log_min_duration_statement database flag for a Cloud SQL for PostgreSQL
	// instance is not set to -1.
	//   "SIGNAL_TYPE_EXPOSED_TO_REMOTE_ACCESS" - Represents if the remote access
	// database flag for a Cloud SQL for SQL Server instance is not set to off.
	//   "SIGNAL_TYPE_DATABASE_NAMES_EXPOSED" - Represents if the
	// skip_show_database database flag for a Cloud SQL for MySQL instance is not
	// set to on.
	//   "SIGNAL_TYPE_SENSITIVE_TRACE_INFO_NOT_MASKED" - Represents if the 3625
	// (trace flag) database flag for a Cloud SQL for SQL Server instance is not
	// set to on.
	//   "SIGNAL_TYPE_PUBLIC_IP_ENABLED" - Represents if public IP is enabled.
	//   "SIGNAL_TYPE_IDLE" - Represents Idle instance helps to reduce costs.
	//   "SIGNAL_TYPE_OVERPROVISIONED" - Represents instances that are
	// unnecessarily large for given workload.
	//   "SIGNAL_TYPE_HIGH_NUMBER_OF_OPEN_TABLES" - Represents high number of
	// concurrently opened tables.
	//   "SIGNAL_TYPE_HIGH_NUMBER_OF_TABLES" - Represents high table count close to
	// SLA limit.
	//   "SIGNAL_TYPE_HIGH_TRANSACTION_ID_UTILIZATION" - Represents high number of
	// unvacuumed transactions
	//   "SIGNAL_TYPE_UNDERPROVISIONED" - Represents need for more CPU and/or
	// memory
	//   "SIGNAL_TYPE_OUT_OF_DISK" - Represents out of disk.
	//   "SIGNAL_TYPE_SERVER_CERTIFICATE_NEAR_EXPIRY" - Represents server
	// certificate is near expiry.
	//   "SIGNAL_TYPE_DATABASE_AUDITING_DISABLED" - Represents database auditing is
	// disabled.
	//   "SIGNAL_TYPE_RESTRICT_AUTHORIZED_NETWORKS" - Represents not restricted to
	// authorized networks.
	//   "SIGNAL_TYPE_VIOLATE_POLICY_RESTRICT_PUBLIC_IP" - Represents violate org
	// policy restrict public ip.
	//   "SIGNAL_TYPE_QUOTA_LIMIT" - Cluster nearing quota limit
	//   "SIGNAL_TYPE_NO_PASSWORD_POLICY" - No password policy set on resources
	//   "SIGNAL_TYPE_CONNECTIONS_PERFORMANCE_IMPACT" - Performance impact of
	// connections settings
	//   "SIGNAL_TYPE_TMP_TABLES_PERFORMANCE_IMPACT" - Performance impact of
	// temporary tables settings
	//   "SIGNAL_TYPE_TRANS_LOGS_PERFORMANCE_IMPACT" - Performance impact of
	// transaction logs settings
	//   "SIGNAL_TYPE_HIGH_JOINS_WITHOUT_INDEXES" - Performance impact of high
	// joins without indexes
	//   "SIGNAL_TYPE_SUPERUSER_WRITING_TO_USER_TABLES" - Detects events where a
	// Cloud SQL superuser (postgres for PostgreSQL servers or root for MySQL
	// users) writes to non-system tables.
	//   "SIGNAL_TYPE_USER_GRANTED_ALL_PERMISSIONS" - Detects events where a
	// database user or role has been granted all privileges to a database, or to
	// all tables, procedures, or functions in a schema.
	//   "SIGNAL_TYPE_DATA_EXPORT_TO_EXTERNAL_CLOUD_STORAGE_BUCKET" - Detects if
	// database instance data exported to a Cloud Storage bucket outside of the
	// organization.
	//   "SIGNAL_TYPE_DATA_EXPORT_TO_PUBLIC_CLOUD_STORAGE_BUCKET" - Detects if
	// database instance data exported to a Cloud Storage bucket that is owned by
	// the organization and is publicly accessible.
	//   "SIGNAL_TYPE_WEAK_PASSWORD_HASH_ALGORITHM" - Detects if a database
	// instance is using a weak password hash algorithm.
	//   "SIGNAL_TYPE_NO_USER_PASSWORD_POLICY" - Detects if a database instance has
	// no user password policy set.
	//   "SIGNAL_TYPE_HOT_NODE" - Detects if a database instance/cluster has a hot
	// node.
	//   "SIGNAL_TYPE_NO_POINT_IN_TIME_RECOVERY" - Detects if a database instance
	// has no point in time recovery enabled.
	//   "SIGNAL_TYPE_RESOURCE_SUSPENDED" - Detects if a database instance/cluster
	// is suspended.
	//   "SIGNAL_TYPE_EXPENSIVE_COMMANDS" - Detects that expensive commands are
	// being run on a database instance impacting overall performance.
	//   "SIGNAL_TYPE_NO_MAINTENANCE_POLICY_CONFIGURED" - Indicates that the
	// instance does not have a maintenance policy configured.
	//   "SIGNAL_TYPE_NO_DELETION_PROTECTION" - Deletion Protection Disabled for
	// the resource
	//   "SIGNAL_TYPE_INEFFICIENT_QUERY" - Indicates that the instance has
	// inefficient queries detected.
	//   "SIGNAL_TYPE_READ_INTENSIVE_WORKLOAD" - Indicates that the instance has
	// read intensive workload.
	//   "SIGNAL_TYPE_MEMORY_LIMIT" - Indicates that the instance is nearing memory
	// limit.
	//   "SIGNAL_TYPE_MAX_SERVER_MEMORY" - Indicates that the instance's max server
	// memory is configured higher than the recommended value.
	//   "SIGNAL_TYPE_LARGE_ROWS" - Indicates that the database has large rows
	// beyond the recommended limit.
	//   "SIGNAL_TYPE_HIGH_WRITE_PRESSURE" - Heavy write pressure on the database
	// rows.
	//   "SIGNAL_TYPE_HIGH_READ_PRESSURE" - Heavy read pressure on the database
	// rows.
	//   "SIGNAL_TYPE_ENCRYPTION_ORG_POLICY_NOT_SATISFIED" - Encryption org policy
	// not satisfied.
	//   "SIGNAL_TYPE_LOCATION_ORG_POLICY_NOT_SATISFIED" - Location org policy not
	// satisfied.
	//   "SIGNAL_TYPE_OUTDATED_MINOR_VERSION" - Outdated DB minor version.
	//   "SIGNAL_TYPE_SCHEMA_NOT_OPTIMIZED" - Schema not optimized.
	//   "SIGNAL_TYPE_MANY_IDLE_CONNECTIONS" - High number of idle connections.
	//   "SIGNAL_TYPE_REPLICATION_LAG" - Replication delay.
	//   "SIGNAL_TYPE_OUTDATED_VERSION" - Outdated version.
	//   "SIGNAL_TYPE_OUTDATED_CLIENT" - Outdated client.
	//   "SIGNAL_TYPE_DATABOOST_DISABLED" - Databoost is disabled.
	//   "SIGNAL_TYPE_RECOMMENDED_MAINTENANCE_POLICIES" - Recommended maintenance
	// policy.
	//   "SIGNAL_TYPE_EXTENDED_SUPPORT" - Resource version is in extended support.
	//   "SIGNAL_TYPE_PERFORMANCE_KPI_CHANGE" - Change in performance KPIs.
	//   "SIGNAL_TYPE_VERSION_NEARING_END_OF_LIFE" - Database version nearing end
	// of life.
	SignalType string `json:"signalType,omitempty"`
	// Possible values:
	//   "STATE_UNSPECIFIED" - Unspecified state.
	//   "ACTIVE" - The signal requires attention and has not been addressed yet.
	//   "RESOLVED" - The signal has been fixed, triaged as a non-issue or
	// otherwise addressed and is no longer active.
	//   "MUTED" - The signal has been muted.
	State string `json:"state,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AdditionalMetadata") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AdditionalMetadata") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseResourceHealthSignalData) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseResourceHealthSignalData
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseResourceId: DatabaseResourceId will serve as primary key for any
// resource ingestion event.
type DatabaseResourceId struct {
	// Provider: Required. Cloud provider name. Ex:
	// GCP/AWS/Azure/OnPrem/SelfManaged
	//
	// Possible values:
	//   "PROVIDER_UNSPECIFIED"
	//   "GCP" - Google cloud platform provider
	//   "AWS" - Amazon web service
	//   "AZURE" - Azure web service
	//   "ONPREM" - On-prem database resources.
	//   "SELFMANAGED" - Self-managed database provider. These are resources on a
	// cloud platform, e.g., database resource installed in a GCE VM, but not a
	// managed database service.
	//   "PROVIDER_OTHER" - For the rest of the other categories. Other refers to
	// the rest of other database service providers, this could be smaller cloud
	// provider. This needs to be provided when the provider is known, but it is
	// not present in the existing set of enum values.
	Provider string `json:"provider,omitempty"`
	// ProviderDescription: Optional. Needs to be used only when the provider is
	// PROVIDER_OTHER.
	ProviderDescription string `json:"providerDescription,omitempty"`
	// ResourceType: Required. The type of resource this ID is identifying. Ex
	// go/keep-sorted start alloydb.googleapis.com/Cluster,
	// alloydb.googleapis.com/Instance, bigtableadmin.googleapis.com/Cluster,
	// bigtableadmin.googleapis.com/Instance compute.googleapis.com/Instance
	// firestore.googleapis.com/Database, redis.googleapis.com/Instance,
	// redis.googleapis.com/Cluster,
	// oracledatabase.googleapis.com/CloudExadataInfrastructure
	// oracledatabase.googleapis.com/CloudVmCluster
	// oracledatabase.googleapis.com/AutonomousDatabase
	// spanner.googleapis.com/Instance, spanner.googleapis.com/Database,
	// sqladmin.googleapis.com/Instance, go/keep-sorted end REQUIRED Please refer
	// go/condor-common-datamodel
	ResourceType string `json:"resourceType,omitempty"`
	// UniqueId: Required. A service-local token that distinguishes this resource
	// from other resources within the same service.
	UniqueId string `json:"uniqueId,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Provider") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Provider") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseResourceId) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseResourceId
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseResourceMetadata: Common model for database resource instance
// metadata. Next ID: 31
type DatabaseResourceMetadata struct {
	// AvailabilityConfiguration: Availability configuration for this instance
	AvailabilityConfiguration *AvailabilityConfiguration `json:"availabilityConfiguration,omitempty"`
	// BackupConfiguration: Backup configuration for this instance
	BackupConfiguration *BackupConfiguration `json:"backupConfiguration,omitempty"`
	// BackupRun: Latest backup run information for this instance
	BackupRun *BackupRun `json:"backupRun,omitempty"`
	// BackupdrConfiguration: Optional. BackupDR Configuration for the resource.
	BackupdrConfiguration *BackupDRConfiguration `json:"backupdrConfiguration,omitempty"`
	// CreationTime: The creation time of the resource, i.e. the time when resource
	// is created and recorded in partner service.
	CreationTime string `json:"creationTime,omitempty"`
	// CurrentState: Current state of the instance.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED"
	//   "HEALTHY" - The instance is running.
	//   "UNHEALTHY" - Instance being created, updated, deleted or under
	// maintenance
	//   "SUSPENDED" - When instance is suspended
	//   "DELETED" - Instance is deleted.
	//   "STATE_OTHER" - For rest of the other category
	//   "STOPPED" - Instance is in STOPPED state.
	CurrentState string `json:"currentState,omitempty"`
	// CustomMetadata: Any custom metadata associated with the resource
	CustomMetadata *CustomMetadataData `json:"customMetadata,omitempty"`
	// Edition: Optional. Edition represents whether the instance is ENTERPRISE or
	// ENTERPRISE_PLUS. This information is core to Cloud SQL only and is used to
	// identify the edition of the instance.
	//
	// Possible values:
	//   "EDITION_UNSPECIFIED" - Default, to make it consistent with instance
	// edition enum.
	//   "EDITION_ENTERPRISE" - Represents the enterprise edition.
	//   "EDITION_ENTERPRISE_PLUS" - Represents the enterprise plus edition.
	//   "EDITION_STANDARD" - Represents the standard edition.
	Edition string `json:"edition,omitempty"`
	// Entitlements: Entitlements associated with the resource
	Entitlements []*Entitlement `json:"entitlements,omitempty"`
	// ExpectedState: The state that the instance is expected to be in. For
	// example, an instance state can transition to UNHEALTHY due to wrong patch
	// update, while the expected state will remain at the HEALTHY.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED"
	//   "HEALTHY" - The instance is running.
	//   "UNHEALTHY" - Instance being created, updated, deleted or under
	// maintenance
	//   "SUSPENDED" - When instance is suspended
	//   "DELETED" - Instance is deleted.
	//   "STATE_OTHER" - For rest of the other category
	//   "STOPPED" - Instance is in STOPPED state.
	ExpectedState string `json:"expectedState,omitempty"`
	// GcbdrConfiguration: GCBDR configuration for the resource.
	GcbdrConfiguration *GCBDRConfiguration `json:"gcbdrConfiguration,omitempty"`
	// Id: Required. Unique identifier for a Database resource
	Id *DatabaseResourceId `json:"id,omitempty"`
	// InstanceType: The type of the instance. Specified at creation time.
	//
	// Possible values:
	//   "INSTANCE_TYPE_UNSPECIFIED" - Unspecified.
	//   "SUB_RESOURCE_TYPE_UNSPECIFIED" - For rest of the other categories.
	//   "PRIMARY" - A regular primary database instance.
	//   "SECONDARY" - A cluster or an instance acting as a secondary.
	//   "READ_REPLICA" - An instance acting as a read-replica.
	//   "OTHER" - For rest of the other categories.
	//   "SUB_RESOURCE_TYPE_PRIMARY" - A regular primary database instance.
	//   "SUB_RESOURCE_TYPE_SECONDARY" - A cluster or an instance acting as a
	// secondary.
	//   "SUB_RESOURCE_TYPE_READ_REPLICA" - An instance acting as a read-replica.
	//   "SUB_RESOURCE_TYPE_EXTERNAL_PRIMARY" - An instance acting as an external
	// primary.
	//   "SUB_RESOURCE_TYPE_READ_POOL" - An instance acting as Read Pool.
	//   "SUB_RESOURCE_TYPE_RESERVATION" - Represents a reservation resource.
	//   "SUB_RESOURCE_TYPE_DATASET" - Represents a dataset resource.
	//   "SUB_RESOURCE_TYPE_OTHER" - For rest of the other categories.
	InstanceType string `json:"instanceType,omitempty"`
	// IsDeletionProtectionEnabled: Optional. Whether deletion protection is
	// enabled for this resource.
	IsDeletionProtectionEnabled bool `json:"isDeletionProtectionEnabled,omitempty"`
	// Location: The resource location. REQUIRED
	Location string `json:"location,omitempty"`
	// MachineConfiguration: Machine configuration for this resource.
	MachineConfiguration *MachineConfiguration `json:"machineConfiguration,omitempty"`
	// MaintenanceInfo: Optional. Maintenance info for the resource.
	MaintenanceInfo *ResourceMaintenanceInfo `json:"maintenanceInfo,omitempty"`
	// PrimaryResourceId: Identifier for this resource's immediate parent/primary
	// resource if the current resource is a replica or derived form of another
	// Database resource. Else it would be NULL. REQUIRED if the immediate parent
	// exists when first time resource is getting ingested, otherwise optional.
	PrimaryResourceId *DatabaseResourceId `json:"primaryResourceId,omitempty"`
	// PrimaryResourceLocation: Primary resource location. REQUIRED if the
	// immediate parent exists when first time resource is getting ingested,
	// otherwise optional.
	PrimaryResourceLocation string `json:"primaryResourceLocation,omitempty"`
	// Product: The product this resource represents.
	Product *Product `json:"product,omitempty"`
	// ResourceContainer: Closest parent Cloud Resource Manager container of this
	// resource. It must be resource name of a Cloud Resource Manager project with
	// the format of "/", such as "projects/123". For GCP provided resources,
	// number should be project number.
	ResourceContainer string `json:"resourceContainer,omitempty"`
	// ResourceFlags: Optional. List of resource flags for the database resource.
	ResourceFlags []*ResourceFlags `json:"resourceFlags,omitempty"`
	// ResourceName: Required. Different from DatabaseResourceId.unique_id, a
	// resource name can be reused over time. That is, after a resource named "ABC"
	// is deleted, the name "ABC" can be used to to create a new resource within
	// the same source. Resource name to follow CAIS resource_name format as noted
	// here go/condor-common-datamodel
	ResourceName string `json:"resourceName,omitempty"`
	// SuspensionReason: Optional. Suspension reason for the resource.
	//
	// Possible values:
	//   "SUSPENSION_REASON_UNSPECIFIED" - Suspension reason is unspecified.
	//   "WIPEOUT_HIDE_EVENT" - Wipeout hide event.
	//   "WIPEOUT_PURGE_EVENT" - Wipeout purge event.
	//   "BILLING_DISABLED" - Billing disabled for project
	//   "ABUSER_DETECTED" - Abuse detected for resource
	//   "ENCRYPTION_KEY_INACCESSIBLE" - Encryption key inaccessible.
	//   "REPLICATED_CLUSTER_ENCRYPTION_KEY_INACCESSIBLE" - Replicated cluster
	// encryption key inaccessible.
	SuspensionReason string `json:"suspensionReason,omitempty"`
	// TagsSet: Optional. Tags associated with this resources.
	TagsSet *Tags `json:"tagsSet,omitempty"`
	// UpdationTime: The time at which the resource was updated and recorded at
	// partner service.
	UpdationTime string `json:"updationTime,omitempty"`
	// UserLabelSet: User-provided labels associated with the resource
	UserLabelSet *UserLabels `json:"userLabelSet,omitempty"`
	// Zone: The resource zone. This is only applicable for zonal resources and
	// will be empty for regional and multi-regional resources.
	Zone string `json:"zone,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AvailabilityConfiguration")
	// to unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AvailabilityConfiguration") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseResourceMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseResourceMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseResourceRecommendationSignalData: Common model for database resource
// recommendation signal data.
type DatabaseResourceRecommendationSignalData struct {
	// AdditionalMetadata: Optional. Any other additional metadata specific to
	// recommendation
	AdditionalMetadata googleapi.RawMessage `json:"additionalMetadata,omitempty"`
	// LastRefreshTime: Required. last time recommendationw as refreshed
	LastRefreshTime string `json:"lastRefreshTime,omitempty"`
	// RecommendationState: Required. Recommendation state
	//
	// Possible values:
	//   "UNSPECIFIED"
	//   "ACTIVE" - Recommendation is active and can be applied. ACTIVE
	// recommendations can be marked as CLAIMED, SUCCEEDED, or FAILED.
	//   "CLAIMED" - Recommendation is in claimed state. Recommendations content is
	// immutable and cannot be updated by Google. CLAIMED recommendations can be
	// marked as CLAIMED, SUCCEEDED, or FAILED.
	//   "SUCCEEDED" - Recommendation is in succeeded state. Recommendations
	// content is immutable and cannot be updated by Google. SUCCEEDED
	// recommendations can be marked as SUCCEEDED, or FAILED.
	//   "FAILED" - Recommendation is in failed state. Recommendations content is
	// immutable and cannot be updated by Google. FAILED recommendations can be
	// marked as SUCCEEDED, or FAILED.
	//   "DISMISSED" - Recommendation is in dismissed state. Recommendation content
	// can be updated by Google. DISMISSED recommendations can be marked as ACTIVE.
	RecommendationState string `json:"recommendationState,omitempty"`
	// Recommender: Required. Name of recommendation. Examples:
	// organizations/1234/locations/us-central1/recommenders/google.cloudsql.instanc
	// e.PerformanceRecommender/recommendations/9876
	Recommender string `json:"recommender,omitempty"`
	// RecommenderId: Required. ID of recommender. Examples:
	// "google.cloudsql.instance.PerformanceRecommender"
	RecommenderId string `json:"recommenderId,omitempty"`
	// RecommenderSubtype: Required. Contains an identifier for a subtype of
	// recommendations produced for the same recommender. Subtype is a function of
	// content and impact, meaning a new subtype might be added when significant
	// changes to `content` or `primary_impact.category` are introduced. See the
	// Recommenders section to see a list of subtypes for a given Recommender.
	// Examples: For recommender =
	// "google.cloudsql.instance.PerformanceRecommender", recommender_subtype can
	// be
	// "MYSQL_HIGH_NUMBER_OF_OPEN_TABLES_BEST_PRACTICE"/"POSTGRES_HIGH_TRANSACTION_I
	// D_UTILIZATION_BEST_PRACTICE"
	RecommenderSubtype string `json:"recommenderSubtype,omitempty"`
	// ResourceName: Required. Database resource name associated with the signal.
	// Resource name to follow CAIS resource_name format as noted here
	// go/condor-common-datamodel
	ResourceName string `json:"resourceName,omitempty"`
	// SignalType: Required. Type of signal, for example, `SIGNAL_TYPE_IDLE`,
	// `SIGNAL_TYPE_HIGH_NUMBER_OF_TABLES`, etc.
	//
	// Possible values:
	//   "SIGNAL_TYPE_UNSPECIFIED" - Unspecified.
	//   "SIGNAL_TYPE_NOT_PROTECTED_BY_AUTOMATIC_FAILOVER" - Represents if a
	// resource is protected by automatic failover. Checks for resources that are
	// configured to have redundancy within a region that enables automatic
	// failover.
	//   "SIGNAL_TYPE_GROUP_NOT_REPLICATING_ACROSS_REGIONS" - Represents if a group
	// is replicating across regions. Checks for resources that are configured to
	// have redundancy, and ongoing replication, across regions.
	//   "SIGNAL_TYPE_NOT_AVAILABLE_IN_MULTIPLE_ZONES" - Represents if the resource
	// is available in multiple zones or not.
	//   "SIGNAL_TYPE_NOT_AVAILABLE_IN_MULTIPLE_REGIONS" - Represents if a resource
	// is available in multiple regions.
	//   "SIGNAL_TYPE_NO_PROMOTABLE_REPLICA" - Represents if a resource has a
	// promotable replica.
	//   "SIGNAL_TYPE_NO_AUTOMATED_BACKUP_POLICY" - Represents if a resource has an
	// automated backup policy.
	//   "SIGNAL_TYPE_SHORT_BACKUP_RETENTION" - Represents if a resources has a
	// short backup retention period.
	//   "SIGNAL_TYPE_LAST_BACKUP_FAILED" - Represents if the last backup of a
	// resource failed.
	//   "SIGNAL_TYPE_LAST_BACKUP_OLD" - Represents if the last backup of a
	// resource is older than some threshold value.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_2_0" - Represents if a resource
	// violates CIS GCP Foundation 2.0.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_1_3" - Represents if a resource
	// violates CIS GCP Foundation 1.3.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_1_2" - Represents if a resource
	// violates CIS GCP Foundation 1.2.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_1_1" - Represents if a resource
	// violates CIS GCP Foundation 1.1.
	//   "SIGNAL_TYPE_VIOLATES_CIS_GCP_FOUNDATION_1_0" - Represents if a resource
	// violates CIS GCP Foundation 1.0.
	//   "SIGNAL_TYPE_VIOLATES_CIS_CONTROLS_V8_0" - Represents if a resource
	// violates CIS Controls 8.0.
	//   "SIGNAL_TYPE_VIOLATES_NIST_800_53" - Represents if a resource violates
	// NIST 800-53.
	//   "SIGNAL_TYPE_VIOLATES_NIST_800_53_R5" - Represents if a resource violates
	// NIST 800-53 R5.
	//   "SIGNAL_TYPE_VIOLATES_NIST_CYBERSECURITY_FRAMEWORK_V1_0" - Represents if a
	// resource violates NIST Cybersecurity Framework 1.0.
	//   "SIGNAL_TYPE_VIOLATES_ISO_27001" - Represents if a resource violates
	// ISO-27001.
	//   "SIGNAL_TYPE_VIOLATES_ISO_27001_V2022" - Represents if a resource violates
	// ISO 27001 2022.
	//   "SIGNAL_TYPE_VIOLATES_PCI_DSS_V3_2_1" - Represents if a resource violates
	// PCI-DSS v3.2.1.
	//   "SIGNAL_TYPE_VIOLATES_PCI_DSS_V4_0" - Represents if a resource violates
	// PCI-DSS v4.0.
	//   "SIGNAL_TYPE_VIOLATES_CLOUD_CONTROLS_MATRIX_V4" - Represents if a resource
	// violates Cloud Controls Matrix v4.0.
	//   "SIGNAL_TYPE_VIOLATES_HIPAA" - Represents if a resource violates HIPAA.
	//   "SIGNAL_TYPE_VIOLATES_SOC2_V2017" - Represents if a resource violates SOC2
	// v2017.
	//   "SIGNAL_TYPE_LOGS_NOT_OPTIMIZED_FOR_TROUBLESHOOTING" - Represents if
	// log_checkpoints database flag for a Cloud SQL for PostgreSQL instance is not
	// set to on.
	//   "SIGNAL_TYPE_QUERY_DURATIONS_NOT_LOGGED" - Represents if the log_duration
	// database flag for a Cloud SQL for PostgreSQL instance is not set to on.
	//   "SIGNAL_TYPE_VERBOSE_ERROR_LOGGING" - Represents if the
	// log_error_verbosity database flag for a Cloud SQL for PostgreSQL instance is
	// not set to default or stricter (default or terse).
	//   "SIGNAL_TYPE_QUERY_LOCK_WAITS_NOT_LOGGED" - Represents if the
	// log_lock_waits database flag for a Cloud SQL for PostgreSQL instance is not
	// set to on.
	//   "SIGNAL_TYPE_LOGGING_MOST_ERRORS" - Represents if the
	// log_min_error_statement database flag for a Cloud SQL for PostgreSQL
	// instance is not set appropriately.
	//   "SIGNAL_TYPE_LOGGING_ONLY_CRITICAL_ERRORS" - Represents if the
	// log_min_error_statement database flag for a Cloud SQL for PostgreSQL
	// instance does not have an appropriate severity level.
	//   "SIGNAL_TYPE_MINIMAL_ERROR_LOGGING" - Represents if the log_min_messages
	// database flag for a Cloud SQL for PostgreSQL instance is not set to warning
	// or another recommended value.
	//   "SIGNAL_TYPE_QUERY_STATISTICS_LOGGED" - Represents if the databaseFlags
	// property of instance metadata for the log_executor_status field is set to
	// on.
	//   "SIGNAL_TYPE_EXCESSIVE_LOGGING_OF_CLIENT_HOSTNAME" - Represents if the
	// log_hostname database flag for a Cloud SQL for PostgreSQL instance is not
	// set to off.
	//   "SIGNAL_TYPE_EXCESSIVE_LOGGING_OF_PARSER_STATISTICS" - Represents if the
	// log_parser_stats database flag for a Cloud SQL for PostgreSQL instance is
	// not set to off.
	//   "SIGNAL_TYPE_EXCESSIVE_LOGGING_OF_PLANNER_STATISTICS" - Represents if the
	// log_planner_stats database flag for a Cloud SQL for PostgreSQL instance is
	// not set to off.
	//   "SIGNAL_TYPE_NOT_LOGGING_ONLY_DDL_STATEMENTS" - Represents if the
	// log_statement database flag for a Cloud SQL for PostgreSQL instance is not
	// set to DDL (all data definition statements).
	//   "SIGNAL_TYPE_LOGGING_QUERY_STATISTICS" - Represents if the
	// log_statement_stats database flag for a Cloud SQL for PostgreSQL instance is
	// not set to off.
	//   "SIGNAL_TYPE_NOT_LOGGING_TEMPORARY_FILES" - Represents if the
	// log_temp_files database flag for a Cloud SQL for PostgreSQL instance is not
	// set to "0". (NOTE: 0 = ON)
	//   "SIGNAL_TYPE_CONNECTION_MAX_NOT_CONFIGURED" - Represents if the user
	// connections database flag for a Cloud SQL for SQL Server instance is
	// configured.
	//   "SIGNAL_TYPE_USER_OPTIONS_CONFIGURED" - Represents if the user options
	// database flag for Cloud SQL SQL Server instance is configured or not.
	//   "SIGNAL_TYPE_EXPOSED_TO_PUBLIC_ACCESS" - Represents if a resource is
	// exposed to public access.
	//   "SIGNAL_TYPE_UNENCRYPTED_CONNECTIONS" - Represents if a resources requires
	// all incoming connections to use SSL or not.
	//   "SIGNAL_TYPE_NO_ROOT_PASSWORD" - Represents if a Cloud SQL database has a
	// password configured for the root account or not.
	//   "SIGNAL_TYPE_WEAK_ROOT_PASSWORD" - Represents if a Cloud SQL database has
	// a weak password configured for the root account.
	//   "SIGNAL_TYPE_ENCRYPTION_KEY_NOT_CUSTOMER_MANAGED" - Represents if a SQL
	// database instance is not encrypted with customer-managed encryption keys
	// (CMEK).
	//   "SIGNAL_TYPE_SERVER_AUTHENTICATION_NOT_REQUIRED" - Represents if The
	// contained database authentication database flag for a Cloud SQL for SQL
	// Server instance is not set to off.
	//   "SIGNAL_TYPE_EXPOSED_BY_OWNERSHIP_CHAINING" - Represents if the
	// cross_db_ownership_chaining database flag for a Cloud SQL for SQL Server
	// instance is not set to off.
	//   "SIGNAL_TYPE_EXPOSED_TO_EXTERNAL_SCRIPTS" - Represents if he external
	// scripts enabled database flag for a Cloud SQL for SQL Server instance is not
	// set to off.
	//   "SIGNAL_TYPE_EXPOSED_TO_LOCAL_DATA_LOADS" - Represents if the local_infile
	// database flag for a Cloud SQL for MySQL instance is not set to off.
	//   "SIGNAL_TYPE_CONNECTION_ATTEMPTS_NOT_LOGGED" - Represents if the
	// log_connections database flag for a Cloud SQL for PostgreSQL instance is not
	// set to on.
	//   "SIGNAL_TYPE_DISCONNECTIONS_NOT_LOGGED" - Represents if the
	// log_disconnections database flag for a Cloud SQL for PostgreSQL instance is
	// not set to on.
	//   "SIGNAL_TYPE_LOGGING_EXCESSIVE_STATEMENT_INFO" - Represents if the
	// log_min_duration_statement database flag for a Cloud SQL for PostgreSQL
	// instance is not set to -1.
	//   "SIGNAL_TYPE_EXPOSED_TO_REMOTE_ACCESS" - Represents if the remote access
	// database flag for a Cloud SQL for SQL Server instance is not set to off.
	//   "SIGNAL_TYPE_DATABASE_NAMES_EXPOSED" - Represents if the
	// skip_show_database database flag for a Cloud SQL for MySQL instance is not
	// set to on.
	//   "SIGNAL_TYPE_SENSITIVE_TRACE_INFO_NOT_MASKED" - Represents if the 3625
	// (trace flag) database flag for a Cloud SQL for SQL Server instance is not
	// set to on.
	//   "SIGNAL_TYPE_PUBLIC_IP_ENABLED" - Represents if public IP is enabled.
	//   "SIGNAL_TYPE_IDLE" - Represents Idle instance helps to reduce costs.
	//   "SIGNAL_TYPE_OVERPROVISIONED" - Represents instances that are
	// unnecessarily large for given workload.
	//   "SIGNAL_TYPE_HIGH_NUMBER_OF_OPEN_TABLES" - Represents high number of
	// concurrently opened tables.
	//   "SIGNAL_TYPE_HIGH_NUMBER_OF_TABLES" - Represents high table count close to
	// SLA limit.
	//   "SIGNAL_TYPE_HIGH_TRANSACTION_ID_UTILIZATION" - Represents high number of
	// unvacuumed transactions
	//   "SIGNAL_TYPE_UNDERPROVISIONED" - Represents need for more CPU and/or
	// memory
	//   "SIGNAL_TYPE_OUT_OF_DISK" - Represents out of disk.
	//   "SIGNAL_TYPE_SERVER_CERTIFICATE_NEAR_EXPIRY" - Represents server
	// certificate is near expiry.
	//   "SIGNAL_TYPE_DATABASE_AUDITING_DISABLED" - Represents database auditing is
	// disabled.
	//   "SIGNAL_TYPE_RESTRICT_AUTHORIZED_NETWORKS" - Represents not restricted to
	// authorized networks.
	//   "SIGNAL_TYPE_VIOLATE_POLICY_RESTRICT_PUBLIC_IP" - Represents violate org
	// policy restrict public ip.
	//   "SIGNAL_TYPE_QUOTA_LIMIT" - Cluster nearing quota limit
	//   "SIGNAL_TYPE_NO_PASSWORD_POLICY" - No password policy set on resources
	//   "SIGNAL_TYPE_CONNECTIONS_PERFORMANCE_IMPACT" - Performance impact of
	// connections settings
	//   "SIGNAL_TYPE_TMP_TABLES_PERFORMANCE_IMPACT" - Performance impact of
	// temporary tables settings
	//   "SIGNAL_TYPE_TRANS_LOGS_PERFORMANCE_IMPACT" - Performance impact of
	// transaction logs settings
	//   "SIGNAL_TYPE_HIGH_JOINS_WITHOUT_INDEXES" - Performance impact of high
	// joins without indexes
	//   "SIGNAL_TYPE_SUPERUSER_WRITING_TO_USER_TABLES" - Detects events where a
	// Cloud SQL superuser (postgres for PostgreSQL servers or root for MySQL
	// users) writes to non-system tables.
	//   "SIGNAL_TYPE_USER_GRANTED_ALL_PERMISSIONS" - Detects events where a
	// database user or role has been granted all privileges to a database, or to
	// all tables, procedures, or functions in a schema.
	//   "SIGNAL_TYPE_DATA_EXPORT_TO_EXTERNAL_CLOUD_STORAGE_BUCKET" - Detects if
	// database instance data exported to a Cloud Storage bucket outside of the
	// organization.
	//   "SIGNAL_TYPE_DATA_EXPORT_TO_PUBLIC_CLOUD_STORAGE_BUCKET" - Detects if
	// database instance data exported to a Cloud Storage bucket that is owned by
	// the organization and is publicly accessible.
	//   "SIGNAL_TYPE_WEAK_PASSWORD_HASH_ALGORITHM" - Detects if a database
	// instance is using a weak password hash algorithm.
	//   "SIGNAL_TYPE_NO_USER_PASSWORD_POLICY" - Detects if a database instance has
	// no user password policy set.
	//   "SIGNAL_TYPE_HOT_NODE" - Detects if a database instance/cluster has a hot
	// node.
	//   "SIGNAL_TYPE_NO_POINT_IN_TIME_RECOVERY" - Detects if a database instance
	// has no point in time recovery enabled.
	//   "SIGNAL_TYPE_RESOURCE_SUSPENDED" - Detects if a database instance/cluster
	// is suspended.
	//   "SIGNAL_TYPE_EXPENSIVE_COMMANDS" - Detects that expensive commands are
	// being run on a database instance impacting overall performance.
	//   "SIGNAL_TYPE_NO_MAINTENANCE_POLICY_CONFIGURED" - Indicates that the
	// instance does not have a maintenance policy configured.
	//   "SIGNAL_TYPE_NO_DELETION_PROTECTION" - Deletion Protection Disabled for
	// the resource
	//   "SIGNAL_TYPE_INEFFICIENT_QUERY" - Indicates that the instance has
	// inefficient queries detected.
	//   "SIGNAL_TYPE_READ_INTENSIVE_WORKLOAD" - Indicates that the instance has
	// read intensive workload.
	//   "SIGNAL_TYPE_MEMORY_LIMIT" - Indicates that the instance is nearing memory
	// limit.
	//   "SIGNAL_TYPE_MAX_SERVER_MEMORY" - Indicates that the instance's max server
	// memory is configured higher than the recommended value.
	//   "SIGNAL_TYPE_LARGE_ROWS" - Indicates that the database has large rows
	// beyond the recommended limit.
	//   "SIGNAL_TYPE_HIGH_WRITE_PRESSURE" - Heavy write pressure on the database
	// rows.
	//   "SIGNAL_TYPE_HIGH_READ_PRESSURE" - Heavy read pressure on the database
	// rows.
	//   "SIGNAL_TYPE_ENCRYPTION_ORG_POLICY_NOT_SATISFIED" - Encryption org policy
	// not satisfied.
	//   "SIGNAL_TYPE_LOCATION_ORG_POLICY_NOT_SATISFIED" - Location org policy not
	// satisfied.
	//   "SIGNAL_TYPE_OUTDATED_MINOR_VERSION" - Outdated DB minor version.
	//   "SIGNAL_TYPE_SCHEMA_NOT_OPTIMIZED" - Schema not optimized.
	//   "SIGNAL_TYPE_MANY_IDLE_CONNECTIONS" - High number of idle connections.
	//   "SIGNAL_TYPE_REPLICATION_LAG" - Replication delay.
	//   "SIGNAL_TYPE_OUTDATED_VERSION" - Outdated version.
	//   "SIGNAL_TYPE_OUTDATED_CLIENT" - Outdated client.
	//   "SIGNAL_TYPE_DATABOOST_DISABLED" - Databoost is disabled.
	//   "SIGNAL_TYPE_RECOMMENDED_MAINTENANCE_POLICIES" - Recommended maintenance
	// policy.
	//   "SIGNAL_TYPE_EXTENDED_SUPPORT" - Resource version is in extended support.
	//   "SIGNAL_TYPE_PERFORMANCE_KPI_CHANGE" - Change in performance KPIs.
	//   "SIGNAL_TYPE_VERSION_NEARING_END_OF_LIFE" - Database version nearing end
	// of life.
	SignalType string `json:"signalType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AdditionalMetadata") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AdditionalMetadata") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseResourceRecommendationSignalData) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseResourceRecommendationSignalData
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DatabaseResourceSignalData: Database resource signal data. This is used to
// send signals to Condor which are based on the DB/Instance/Fleet level
// configurations. These will be used to send signals for all inventory types.
// Next ID: 10
type DatabaseResourceSignalData struct {
	// BackupRun: Deprecated: Use signal_metadata_list instead.
	BackupRun *BackupRun `json:"backupRun,omitempty"`
	// FullResourceName: Required. Full Resource name of the source resource.
	FullResourceName string `json:"fullResourceName,omitempty"`
	// LastRefreshTime: Required. Last time signal was refreshed
	LastRefreshTime string `json:"lastRefreshTime,omitempty"`
	// Location: Resource location.
	Location string `json:"location,omitempty"`
	// ResourceId: Database resource id.
	ResourceId *DatabaseResourceId `json:"resourceId,omitempty"`
	// SignalBoolValue: Deprecated: Use signal_metadata_list instead.
	SignalBoolValue bool `json:"signalBoolValue,omitempty"`
	// SignalMetadataList: This will support array of OneOf signal metadata
	// information for a given signal type.
	SignalMetadataList []*SignalMetadata `json:"signalMetadataList,omitempty"`
	// SignalState: Required. Output only. Signal state of the signal
	//
	// Possible values:
	//   "SIGNAL_STATE_UNSPECIFIED" - Unspecified signal state.
	//   "ACTIVE" - Signal is active and requires attention.
	//   "INACTIVE" - Signal is inactive and does not require attention.
	//   "DISMISSED" - Signal is dismissed by the user and should not be shown to
	// the user again.
	SignalState string `json:"signalState,omitempty"`
	// SignalType: Required. Signal type of the signal
	//
	// Possible values:
	//   "SIGNAL_TYPE_UNSPECIFIED" - Unspecified signal type.
	//   "SIGNAL_TYPE_OUTDATED_MINOR_VERSION" - Outdated Minor Version
	//   "SIGNAL_TYPE_DATABASE_AUDITING_DISABLED" - Represents database auditing is
	// disabled.
	//   "SIGNAL_TYPE_NO_ROOT_PASSWORD" - Represents if a database has a password
	// configured for the root account or not.
	//   "SIGNAL_TYPE_EXPOSED_TO_PUBLIC_ACCESS" - Represents if a resource is
	// exposed to public access.
	//   "SIGNAL_TYPE_UNENCRYPTED_CONNECTIONS" - Represents if a resources requires
	// all incoming connections to use SSL or not.
	//   "SIGNAL_TYPE_EXTENDED_SUPPORT" - Represents if a resource version is in
	// extended support.
	//   "SIGNAL_TYPE_NO_AUTOMATED_BACKUP_POLICY" - Represents if a resource has no
	// automated backup policy.
	//   "SIGNAL_TYPE_VERSION_NEARING_END_OF_LIFE" - Represents if a resource
	// version is nearing end of life.
	//   "SIGNAL_TYPE_LAST_BACKUP_OLD" - Represents if the last backup of a
	// resource is older than 24 hours.
	//   "SIGNAL_TYPE_NOT_PROTECTED_BY_AUTOMATIC_FAILOVER" - Represents if a
	// resource is not protected by automatic failover.
	SignalType string `json:"signalType,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BackupRun") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupRun") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DatabaseResourceSignalData) MarshalJSON() ([]byte, error) {
	type NoMethod DatabaseResourceSignalData
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Date: Represents a whole or partial calendar date, such as a birthday. The
// time of day and time zone are either specified elsewhere or are
// insignificant. The date is relative to the Gregorian Calendar. This can
// represent one of the following: * A full date, with non-zero year, month,
// and day values. * A month and day, with a zero year (for example, an
// anniversary). * A year on its own, with a zero month and a zero day. * A
// year and month, with a zero day (for example, a credit card expiration
// date). Related types: * google.type.TimeOfDay * google.type.DateTime *
// google.protobuf.Timestamp
type Date struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and month,
	// or 0 to specify a year by itself or a year and month where the day isn't
	// significant.
	Day int64 `json:"day,omitempty"`
	// Month: Month of a year. Must be from 1 to 12, or 0 to specify a year without
	// a month and day.
	Month int64 `json:"month,omitempty"`
	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a date
	// without a year.
	Year int64 `json:"year,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Day") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Day") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Date) MarshalJSON() ([]byte, error) {
	type NoMethod Date
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// DiscoveryEndpoint: Endpoints on each network, for Redis clients to connect
// to the cluster.
type DiscoveryEndpoint struct {
	// Address: Output only. Address of the exposed Redis endpoint used by clients
	// to connect to the service. The address could be either IP or hostname.
	Address string `json:"address,omitempty"`
	// Port: Output only. The port number of the exposed Redis endpoint.
	Port int64 `json:"port,omitempty"`
	// PscConfig: Output only. Customer configuration for where the endpoint is
	// created and accessed from.
	PscConfig *PscConfig `json:"pscConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Address") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Address") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s DiscoveryEndpoint) MarshalJSON() ([]byte, error) {
	type NoMethod DiscoveryEndpoint
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Empty: A generic empty message that you can re-use to avoid defining
// duplicated empty messages in your APIs. A typical example is to use it as
// the request or the response type of an API method. For instance: service Foo
// { rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); }
type Empty struct {
	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
}

// EncryptionInfo: EncryptionInfo describes the encryption information of a
// cluster or a backup.
type EncryptionInfo struct {
	// EncryptionType: Output only. Type of encryption.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Encryption type not specified. Defaults to
	// GOOGLE_DEFAULT_ENCRYPTION.
	//   "GOOGLE_DEFAULT_ENCRYPTION" - The data is encrypted at rest with a key
	// that is fully managed by Google. No key version will be populated. This is
	// the default state.
	//   "CUSTOMER_MANAGED_ENCRYPTION" - The data is encrypted at rest with a key
	// that is managed by the customer. KMS key versions will be populated.
	EncryptionType string `json:"encryptionType,omitempty"`
	// KmsKeyPrimaryState: Output only. The state of the primary version of the KMS
	// key perceived by the system. This field is not populated in backups.
	//
	// Possible values:
	//   "KMS_KEY_STATE_UNSPECIFIED" - The default value. This value is unused.
	//   "ENABLED" - The KMS key is enabled and correctly configured.
	//   "PERMISSION_DENIED" - Permission denied on the KMS key.
	//   "DISABLED" - The KMS key is disabled.
	//   "DESTROYED" - The KMS key is destroyed.
	//   "DESTROY_SCHEDULED" - The KMS key is scheduled to be destroyed.
	//   "EKM_KEY_UNREACHABLE_DETECTED" - The EKM key is unreachable.
	//   "BILLING_DISABLED" - Billing is disabled for the project.
	//   "UNKNOWN_FAILURE" - All other unknown failures.
	KmsKeyPrimaryState string `json:"kmsKeyPrimaryState,omitempty"`
	// KmsKeyVersions: Output only. KMS key versions that are being used to protect
	// the data at-rest.
	KmsKeyVersions []string `json:"kmsKeyVersions,omitempty"`
	// LastUpdateTime: Output only. The most recent time when the encryption info
	// was updated.
	LastUpdateTime string `json:"lastUpdateTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EncryptionType") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EncryptionType") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s EncryptionInfo) MarshalJSON() ([]byte, error) {
	type NoMethod EncryptionInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Entitlement: Proto representing the access that a user has to a specific
// feature/service. NextId: 3.
type Entitlement struct {
	// EntitlementState: The current state of user's accessibility to a
	// feature/benefit.
	//
	// Possible values:
	//   "ENTITLEMENT_STATE_UNSPECIFIED"
	//   "ENTITLED" - User is entitled to a feature/benefit, but whether it has
	// been successfully provisioned is decided by provisioning state.
	//   "REVOKED" - User is entitled to a feature/benefit, but it was requested to
	// be revoked. Whether the revoke has been successful is decided by
	// provisioning state.
	EntitlementState string `json:"entitlementState,omitempty"`
	// Type: An enum that represents the type of this entitlement.
	//
	// Possible values:
	//   "ENTITLEMENT_TYPE_UNSPECIFIED" - The entitlement type is unspecified.
	//   "GEMINI" - The root entitlement representing Gemini package ownership.This
	// will no longer be supported in the future.
	//   "NATIVE" - The entitlement representing Native Tier, This will be the
	// default Entitlement going forward with GCA Enablement.
	//   "GCA_STANDARD" - The entitlement representing GCA-Standard Tier.
	Type string `json:"type,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EntitlementState") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EntitlementState") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Entitlement) MarshalJSON() ([]byte, error) {
	type NoMethod Entitlement
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ExportBackupRequest: Request for [ExportBackup].
type ExportBackupRequest struct {
	// GcsBucket: Google Cloud Storage bucket, like "my-bucket".
	GcsBucket string `json:"gcsBucket,omitempty"`
	// ForceSendFields is a list of field names (e.g. "GcsBucket") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "GcsBucket") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ExportBackupRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ExportBackupRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ExportInstanceRequest: Request for Export.
type ExportInstanceRequest struct {
	// OutputConfig: Required. Specify data to be exported.
	OutputConfig *OutputConfig `json:"outputConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "OutputConfig") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "OutputConfig") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ExportInstanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ExportInstanceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FailoverInstanceRequest: Request for Failover.
type FailoverInstanceRequest struct {
	// DataProtectionMode: Optional. Available data protection modes that the user
	// can choose. If it's unspecified, data protection mode will be
	// LIMITED_DATA_LOSS by default.
	//
	// Possible values:
	//   "DATA_PROTECTION_MODE_UNSPECIFIED" - Defaults to LIMITED_DATA_LOSS if a
	// data protection mode is not specified.
	//   "LIMITED_DATA_LOSS" - Instance failover will be protected with data loss
	// control. More specifically, the failover will only be performed if the
	// current replication offset diff between primary and replica is under a
	// certain threshold.
	//   "FORCE_DATA_LOSS" - Instance failover will be performed without data loss
	// control.
	DataProtectionMode string `json:"dataProtectionMode,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DataProtectionMode") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DataProtectionMode") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FailoverInstanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod FailoverInstanceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// FixedFrequencySchedule: This schedule allows the backup to be triggered at a
// fixed frequency (currently only daily is supported).
type FixedFrequencySchedule struct {
	// StartTime: Required. The start time of every automated backup in UTC. It
	// must be set to the start of an hour. This field is required.
	StartTime *TimeOfDay `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "StartTime") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "StartTime") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s FixedFrequencySchedule) MarshalJSON() ([]byte, error) {
	type NoMethod FixedFrequencySchedule
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GCBDRConfiguration: GCBDR Configuration for the resource.
type GCBDRConfiguration struct {
	// GcbdrManaged: Whether the resource is managed by GCBDR.
	GcbdrManaged bool `json:"gcbdrManaged,omitempty"`
	// ForceSendFields is a list of field names (e.g. "GcbdrManaged") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "GcbdrManaged") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GCBDRConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod GCBDRConfiguration
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GcsBackupSource: Backups stored in Cloud Storage buckets. The Cloud Storage
// buckets need to be the same region as the clusters.
type GcsBackupSource struct {
	// Uris: Optional. URIs of the Cloud Storage objects to import. Example:
	// gs://bucket1/object1, gs://bucket2/folder2/object2
	Uris []string `json:"uris,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Uris") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Uris") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GcsBackupSource) MarshalJSON() ([]byte, error) {
	type NoMethod GcsBackupSource
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GcsDestination: The Cloud Storage location for the output content
type GcsDestination struct {
	// Uri: Required. Data destination URI (e.g. 'gs://my_bucket/my_object').
	// Existing files will be overwritten.
	Uri string `json:"uri,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Uri") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Uri") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GcsDestination) MarshalJSON() ([]byte, error) {
	type NoMethod GcsDestination
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GcsSource: The Cloud Storage location for the input content
type GcsSource struct {
	// Uri: Required. Source data URI. (e.g. 'gs://my_bucket/my_object').
	Uri string `json:"uri,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Uri") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Uri") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GcsSource) MarshalJSON() ([]byte, error) {
	type NoMethod GcsSource
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudRedisV1LocationMetadata: This location metadata represents
// additional configuration options for a given location where a Redis instance
// may be created. All fields are output only. It is returned as content of the
// `google.cloud.location.Location.metadata` field.
type GoogleCloudRedisV1LocationMetadata struct {
	// AvailableZones: Output only. The set of available zones in the location. The
	// map is keyed by the lowercase ID of each zone, as defined by GCE. These keys
	// can be specified in `location_id` or `alternative_location_id` fields when
	// creating a Redis instance.
	AvailableZones map[string]GoogleCloudRedisV1ZoneMetadata `json:"availableZones,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AvailableZones") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AvailableZones") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GoogleCloudRedisV1LocationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudRedisV1LocationMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudRedisV1OperationMetadata: Represents the v1 metadata of the
// long-running operation.
type GoogleCloudRedisV1OperationMetadata struct {
	// ApiVersion: API version.
	ApiVersion string `json:"apiVersion,omitempty"`
	// CancelRequested: Specifies if cancellation was requested for the operation.
	CancelRequested bool `json:"cancelRequested,omitempty"`
	// CreateTime: Creation timestamp.
	CreateTime string `json:"createTime,omitempty"`
	// EndTime: End timestamp.
	EndTime string `json:"endTime,omitempty"`
	// StatusDetail: Operation status details.
	StatusDetail string `json:"statusDetail,omitempty"`
	// Target: Operation target.
	Target string `json:"target,omitempty"`
	// Verb: Operation verb.
	Verb string `json:"verb,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ApiVersion") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ApiVersion") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s GoogleCloudRedisV1OperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudRedisV1OperationMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// GoogleCloudRedisV1ZoneMetadata: Defines specific information for a
// particular zone. Currently empty and reserved for future use only.
type GoogleCloudRedisV1ZoneMetadata struct {
}

// ImportInstanceRequest: Request for Import.
type ImportInstanceRequest struct {
	// InputConfig: Required. Specify data to be imported.
	InputConfig *InputConfig `json:"inputConfig,omitempty"`
	// ForceSendFields is a list of field names (e.g. "InputConfig") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "InputConfig") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ImportInstanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod ImportInstanceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// InputConfig: The input content
type InputConfig struct {
	// GcsSource: Google Cloud Storage location where input content is located.
	GcsSource *GcsSource `json:"gcsSource,omitempty"`
	// ForceSendFields is a list of field names (e.g. "GcsSource") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "GcsSource") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s InputConfig) MarshalJSON() ([]byte, error) {
	type NoMethod InputConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Instance: A Memorystore for Redis instance.
type Instance struct {
	// AlternativeLocationId: Optional. If specified, at least one node will be
	// provisioned in this zone in addition to the zone specified in location_id.
	// Only applicable to standard tier. If provided, it must be a different zone
	// from the one provided in [location_id]. Additional nodes beyond the first 2
	// will be placed in zones selected by the service.
	AlternativeLocationId string `json:"alternativeLocationId,omitempty"`
	// AuthEnabled: Optional. Indicates whether OSS Redis AUTH is enabled for the
	// instance. If set to "true" AUTH is enabled on the instance. Default value is
	// "false" meaning AUTH is disabled.
	AuthEnabled bool `json:"authEnabled,omitempty"`
	// AuthorizedNetwork: Optional. The full name of the Google Compute Engine
	// network (https://cloud.google.com/vpc/docs/vpc) to which the instance is
	// connected. If left unspecified, the `default` network will be used.
	AuthorizedNetwork string `json:"authorizedNetwork,omitempty"`
	// AvailableMaintenanceVersions: Optional. The available maintenance versions
	// that an instance could update to.
	AvailableMaintenanceVersions []string `json:"availableMaintenanceVersions,omitempty"`
	// ConnectMode: Optional. The network connect mode of the Redis instance. If
	// not provided, the connect mode defaults to DIRECT_PEERING.
	//
	// Possible values:
	//   "CONNECT_MODE_UNSPECIFIED" - Not set.
	//   "DIRECT_PEERING" - Connect via direct peering to the Memorystore for Redis
	// hosted service.
	//   "PRIVATE_SERVICE_ACCESS" - Connect your Memorystore for Redis instance
	// using Private Service Access. Private services access provides an IP address
	// range for multiple Google Cloud services, including Memorystore.
	ConnectMode string `json:"connectMode,omitempty"`
	// CreateTime: Output only. The time the instance was created.
	CreateTime string `json:"createTime,omitempty"`
	// CurrentLocationId: Output only. The current zone where the Redis primary
	// node is located. In basic tier, this will always be the same as
	// [location_id]. In standard tier, this can be the zone of any node in the
	// instance.
	CurrentLocationId string `json:"currentLocationId,omitempty"`
	// CustomerManagedKey: Optional. The KMS key reference that the customer
	// provides when trying to create the instance.
	CustomerManagedKey string `json:"customerManagedKey,omitempty"`
	// DisplayName: An arbitrary and optional user-provided name for the instance.
	DisplayName string `json:"displayName,omitempty"`
	// Host: Output only. Hostname or IP address of the exposed Redis endpoint used
	// by clients to connect to the service.
	Host string `json:"host,omitempty"`
	// Labels: Resource labels to represent user provided metadata
	Labels map[string]string `json:"labels,omitempty"`
	// LocationId: Optional. The zone where the instance will be provisioned. If
	// not provided, the service will choose a zone from the specified region for
	// the instance. For standard tier, additional nodes will be added across
	// multiple zones for protection against zonal failures. If specified, at least
	// one node will be provisioned in this zone.
	LocationId string `json:"locationId,omitempty"`
	// MaintenancePolicy: Optional. The maintenance policy for the instance. If not
	// provided, maintenance events can be performed at any time.
	MaintenancePolicy *MaintenancePolicy `json:"maintenancePolicy,omitempty"`
	// MaintenanceSchedule: Output only. Date and time of upcoming maintenance
	// events which have been scheduled.
	MaintenanceSchedule *MaintenanceSchedule `json:"maintenanceSchedule,omitempty"`
	// MaintenanceVersion: Optional. The self service update maintenance version.
	// The version is date based such as "20210712_00_00".
	MaintenanceVersion string `json:"maintenanceVersion,omitempty"`
	// MemorySizeGb: Required. Redis memory size in GiB.
	MemorySizeGb int64 `json:"memorySizeGb,omitempty"`
	// Name: Required. Unique name of the resource in this scope including project
	// and location using the form:
	// `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
	// Note: Redis instances are managed and addressed at regional level so
	// location_id here refers to a GCP region; however, users may choose which
	// specific zone (or collection of zones for cross-zone instances) an instance
	// should be provisioned in. Refer to location_id and alternative_location_id
	// fields for more details.
	Name string `json:"name,omitempty"`
	// Nodes: Output only. Info per node.
	Nodes []*NodeInfo `json:"nodes,omitempty"`
	// PersistenceConfig: Optional. Persistence configuration parameters
	PersistenceConfig *PersistenceConfig `json:"persistenceConfig,omitempty"`
	// PersistenceIamIdentity: Output only. Cloud IAM identity used by import /
	// export operations to transfer data to/from Cloud Storage. Format is
	// "serviceAccount:". The value may change over time for a given instance so
	// should be checked before each import/export operation.
	PersistenceIamIdentity string `json:"persistenceIamIdentity,omitempty"`
	// Port: Output only. The port number of the exposed Redis endpoint.
	Port int64 `json:"port,omitempty"`
	// ReadEndpoint: Output only. Hostname or IP address of the exposed readonly
	// Redis endpoint. Standard tier only. Targets all healthy replica nodes in
	// instance. Replication is asynchronous and replica nodes will exhibit some
	// lag behind the primary. Write requests must target 'host'.
	ReadEndpoint string `json:"readEndpoint,omitempty"`
	// ReadEndpointPort: Output only. The port number of the exposed readonly redis
	// endpoint. Standard tier only. Write requests should target 'port'.
	ReadEndpointPort int64 `json:"readEndpointPort,omitempty"`
	// ReadReplicasMode: Optional. Read replicas mode for the instance. Defaults to
	// READ_REPLICAS_DISABLED.
	//
	// Possible values:
	//   "READ_REPLICAS_MODE_UNSPECIFIED" - If not set, Memorystore Redis backend
	// will default to READ_REPLICAS_DISABLED.
	//   "READ_REPLICAS_DISABLED" - If disabled, read endpoint will not be provided
	// and the instance cannot scale up or down the number of replicas.
	//   "READ_REPLICAS_ENABLED" - If enabled, read endpoint will be provided and
	// the instance can scale up and down the number of replicas. Not valid for
	// basic tier.
	ReadReplicasMode string `json:"readReplicasMode,omitempty"`
	// RedisConfigs: Optional. Redis configuration parameters, according to Redis
	// configuration
	// (https://redis.io/docs/latest/operate/oss_and_stack/management/config/).
	// Currently, the only supported parameters are: Redis version 3.2 and newer: *
	// maxmemory-policy * notify-keyspace-events Redis version 4.0 and newer: *
	// activedefrag * lfu-decay-time * lfu-log-factor * maxmemory-gb Redis version
	// 5.0 and newer: * stream-node-max-bytes * stream-node-max-entries
	RedisConfigs map[string]string `json:"redisConfigs,omitempty"`
	// RedisVersion: Optional. The version of Redis software. If not provided, the
	// default version will be used. Currently, the supported values are: *
	// `REDIS_3_2` for Redis 3.2 compatibility * `REDIS_4_0` for Redis 4.0
	// compatibility * `REDIS_5_0` for Redis 5.0 compatibility * `REDIS_6_X` for
	// Redis 6.x compatibility * `REDIS_7_0` for Redis 7.0 compatibility (default)
	// * `REDIS_7_2` for Redis 7.2 compatibility
	RedisVersion string `json:"redisVersion,omitempty"`
	// ReplicaCount: Optional. The number of replica nodes. The valid range for the
	// Standard Tier with read replicas enabled is [1-5] and defaults to 2. If read
	// replicas are not enabled for a Standard Tier instance, the only valid value
	// is 1 and the default is 1. The valid value for basic tier is 0 and the
	// default is also 0.
	ReplicaCount int64 `json:"replicaCount,omitempty"`
	// ReservedIpRange: Optional. For DIRECT_PEERING mode, the CIDR range of
	// internal addresses that are reserved for this instance. Range must be unique
	// and non-overlapping with existing subnets in an authorized network. For
	// PRIVATE_SERVICE_ACCESS mode, the name of one allocated IP address ranges
	// associated with this private service access connection. If not provided, the
	// service will choose an unused /29 block, for example, 10.0.0.0/29 or
	// 192.168.0.0/29. For READ_REPLICAS_ENABLED the default block size is /28.
	ReservedIpRange string `json:"reservedIpRange,omitempty"`
	// SatisfiesPzi: Optional. Output only. Reserved for future use.
	SatisfiesPzi bool `json:"satisfiesPzi,omitempty"`
	// SatisfiesPzs: Optional. Output only. Reserved for future use.
	SatisfiesPzs bool `json:"satisfiesPzs,omitempty"`
	// SecondaryIpRange: Optional. Additional IP range for node placement. Required
	// when enabling read replicas on an existing instance. For DIRECT_PEERING mode
	// value must be a CIDR range of size /28, or "auto". For
	// PRIVATE_SERVICE_ACCESS mode value must be the name of an allocated address
	// range associated with the private service access connection, or "auto".
	SecondaryIpRange string `json:"secondaryIpRange,omitempty"`
	// ServerCaCerts: Output only. List of server CA certificates for the instance.
	ServerCaCerts []*TlsCertificate `json:"serverCaCerts,omitempty"`
	// State: Output only. The current state of this instance.
	//
	// Possible values:
	//   "STATE_UNSPECIFIED" - Not set.
	//   "CREATING" - Redis instance is being created.
	//   "READY" - Redis instance has been created and is fully usable.
	//   "UPDATING" - Redis instance configuration is being updated. Certain kinds
	// of updates may cause the instance to become unusable while the update is in
	// progress.
	//   "DELETING" - Redis instance is being deleted.
	//   "REPAIRING" - Redis instance is being repaired and may be unusable.
	//   "MAINTENANCE" - Maintenance is being performed on this Redis instance.
	//   "IMPORTING" - Redis instance is importing data (availability may be
	// affected).
	//   "FAILING_OVER" - Redis instance is failing over (availability may be
	// affected).
	State string `json:"state,omitempty"`
	// StatusMessage: Output only. Additional information about the current status
	// of this instance, if available.
	StatusMessage string `json:"statusMessage,omitempty"`
	// SuspensionReasons: Optional. reasons that causes instance in "SUSPENDED"
	// state.
	//
	// Possible values:
	//   "SUSPENSION_REASON_UNSPECIFIED" - Not set.
	//   "CUSTOMER_MANAGED_KEY_ISSUE" - Something wrong with the CMEK key provided
	// by customer.
	SuspensionReasons []string `json:"suspensionReasons,omitempty"`
	// Tags: Optional. Input only. Immutable. Tag keys/values directly bound to
	// this resource. For example: "123/environment": "production",
	// "123/costCenter": "marketing"
	Tags map[string]string `json:"tags,omitempty"`
	// Tier: Required. The service tier of the instance.
	//
	// Possible values:
	//   "TIER_UNSPECIFIED" - Not set.
	//   "BASIC" - BASIC tier: standalone instance
	//   "STANDARD_HA" - STANDARD_HA tier: highly available primary/replica
	// instances
	Tier string `json:"tier,omitempty"`
	// TransitEncryptionMode: Optional. The TLS mode of the Redis instance. If not
	// provided, TLS is disabled for the instance.
	//
	// Possible values:
	//   "TRANSIT_ENCRYPTION_MODE_UNSPECIFIED" - Not set.
	//   "SERVER_AUTHENTICATION" - Client to Server traffic encryption enabled with
	// server authentication.
	//   "DISABLED" - TLS is disabled for the instance.
	TransitEncryptionMode string `json:"transitEncryptionMode,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "AlternativeLocationId") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AlternativeLocationId") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Instance) MarshalJSON() ([]byte, error) {
	type NoMethod Instance
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// InstanceAuthString: Instance AUTH string details.
type InstanceAuthString struct {
	// AuthString: AUTH string set on the instance.
	AuthString string `json:"authString,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "AuthString") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AuthString") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s InstanceAuthString) MarshalJSON() ([]byte, error) {
	type NoMethod InstanceAuthString
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// InternalResourceMetadata: Metadata for individual internal resources in an
// instance. e.g. spanner instance can have multiple databases with unique
// configuration settings. Similarly bigtable can have multiple clusters within
// same bigtable instance.
type InternalResourceMetadata struct {
	// BackupConfiguration: Backup configuration for this database
	BackupConfiguration *BackupConfiguration `json:"backupConfiguration,omitempty"`
	// BackupRun: Information about the last backup attempt for this database
	BackupRun *BackupRun `json:"backupRun,omitempty"`
	// IsDeletionProtectionEnabled: Whether deletion protection is enabled for this
	// internal resource.
	IsDeletionProtectionEnabled bool                `json:"isDeletionProtectionEnabled,omitempty"`
	Product                     *Product            `json:"product,omitempty"`
	ResourceId                  *DatabaseResourceId `json:"resourceId,omitempty"`
	// ResourceName: Required. internal resource name for spanner this will be
	// database name
	// e.g."spanner.googleapis.com/projects/123/abc/instances/inst1/databases/db1"
	ResourceName string `json:"resourceName,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BackupConfiguration") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupConfiguration") to include
	// in API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s InternalResourceMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod InternalResourceMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListBackupCollectionsResponse: Response for [ListBackupCollections].
type ListBackupCollectionsResponse struct {
	// BackupCollections: A list of backupCollections in the project. If the
	// `location_id` in the parent field of the request is "-", all regions
	// available to the project are queried, and the results aggregated. If in such
	// an aggregated query a location is unavailable, a placeholder
	// backupCollection entry is included in the response with the `name` field set
	// to a value of the form
	// `projects/{project_id}/locations/{location_id}/backupCollections/`- and the
	// `status` field set to ERROR and `status_message` field set to "location not
	// available for ListBackupCollections".
	BackupCollections []*BackupCollection `json:"backupCollections,omitempty"`
	// NextPageToken: Token to retrieve the next page of results, or empty if there
	// are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "BackupCollections") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupCollections") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListBackupCollectionsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListBackupCollectionsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListBackupsResponse: Response for [ListBackups].
type ListBackupsResponse struct {
	// Backups: A list of backups in the project.
	Backups []*Backup `json:"backups,omitempty"`
	// NextPageToken: Token to retrieve the next page of results, or empty if there
	// are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Unreachable: Backups that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Backups") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Backups") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListBackupsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListBackupsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListClustersResponse: Response for ListClusters.
type ListClustersResponse struct {
	// Clusters: A list of Redis clusters in the project in the specified location,
	// or across all locations. If the `location_id` in the parent field of the
	// request is "-", all regions available to the project are queried, and the
	// results aggregated. If in such an aggregated query a location is
	// unavailable, a placeholder Redis entry is included in the response with the
	// `name` field set to a value of the form
	// `projects/{project_id}/locations/{location_id}/clusters/`- and the `status`
	// field set to ERROR and `status_message` field set to "location not available
	// for ListClusters".
	Clusters []*Cluster `json:"clusters,omitempty"`
	// NextPageToken: Token to retrieve the next page of results, or empty if there
	// are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Clusters") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Clusters") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListClustersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListClustersResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListInstancesResponse: Response for ListInstances.
type ListInstancesResponse struct {
	// Instances: A list of Redis instances in the project in the specified
	// location, or across all locations. If the `location_id` in the parent field
	// of the request is "-", all regions available to the project are queried, and
	// the results aggregated. If in such an aggregated query a location is
	// unavailable, a placeholder Redis entry is included in the response with the
	// `name` field set to a value of the form
	// `projects/{project_id}/locations/{location_id}/instances/`- and the `status`
	// field set to ERROR and `status_message` field set to "location not available
	// for ListInstances".
	Instances []*Instance `json:"instances,omitempty"`
	// NextPageToken: Token to retrieve the next page of results, or empty if there
	// are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Unreachable: Locations that could not be reached.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Instances") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Instances") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListInstancesResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListInstancesResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListLocationsResponse: The response message for Locations.ListLocations.
type ListLocationsResponse struct {
	// Locations: A list of locations that matches the specified filter in the
	// request.
	Locations []*Location `json:"locations,omitempty"`
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Locations") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Locations") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListLocationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListLocationsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ListOperationsResponse: The response message for Operations.ListOperations.
type ListOperationsResponse struct {
	// NextPageToken: The standard List next-page token.
	NextPageToken string `json:"nextPageToken,omitempty"`
	// Operations: A list of operations that matches the specified filter in the
	// request.
	Operations []*Operation `json:"operations,omitempty"`
	// Unreachable: Unordered list. Unreachable resources. Populated when the
	// request sets `ListOperationsRequest.return_partial_success` and reads across
	// collections. For example, when attempting to list all resources across all
	// supported locations.
	Unreachable []string `json:"unreachable,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "NextPageToken") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ListOperationsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListOperationsResponse
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Location: A resource that represents a Google Cloud location.
type Location struct {
	// DisplayName: The friendly name for this location, typically a nearby city
	// name. For example, "Tokyo".
	DisplayName string `json:"displayName,omitempty"`
	// Labels: Cross-service attributes for the location. For example
	// {"cloud.googleapis.com/region": "us-east1"}
	Labels map[string]string `json:"labels,omitempty"`
	// LocationId: Resource ID for the region. For example: "us-east1".
	LocationId string `json:"locationId,omitempty"`
	// Metadata: Output only. The set of available zones in the location. The map
	// is keyed by the lowercase ID of each zone, as defined by Compute Engine.
	// These keys can be specified in `location_id` or `alternative_location_id`
	// fields when creating a Redis instance.
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`
	// Name: Full resource name for the region. For example:
	// "projects/example-project/locations/us-east1".
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "DisplayName") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DisplayName") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Location) MarshalJSON() ([]byte, error) {
	type NoMethod Location
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MachineConfiguration: MachineConfiguration describes the configuration of a
// machine specific to Database Resource.
type MachineConfiguration struct {
	// BaselineSlots: Optional. Baseline slots for BigQuery Reservations. Baseline
	// slots are in increments of 50.
	BaselineSlots int64 `json:"baselineSlots,omitempty,string"`
	// CpuCount: The number of CPUs. Deprecated. Use vcpu_count instead.
	// TODO(b/342344482) add proto validations again after bug fix.
	CpuCount int64 `json:"cpuCount,omitempty"`
	// MaxReservationSlots: Optional. Max slots for BigQuery Reservations. Max
	// slots are in increments of 50.
	MaxReservationSlots int64 `json:"maxReservationSlots,omitempty,string"`
	// MemorySizeInBytes: Memory size in bytes. TODO(b/342344482) add proto
	// validations again after bug fix.
	MemorySizeInBytes int64 `json:"memorySizeInBytes,omitempty,string"`
	// ShardCount: Optional. Number of shards (if applicable).
	ShardCount int64 `json:"shardCount,omitempty"`
	// VcpuCount: Optional. The number of vCPUs. TODO(b/342344482) add proto
	// validations again after bug fix.
	VcpuCount float64 `json:"vcpuCount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BaselineSlots") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BaselineSlots") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MachineConfiguration) MarshalJSON() ([]byte, error) {
	type NoMethod MachineConfiguration
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

func (s *MachineConfiguration) UnmarshalJSON(data []byte) error {
	type NoMethod MachineConfiguration
	var s1 struct {
		VcpuCount gensupport.JSONFloat64 `json:"vcpuCount"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.VcpuCount = float64(s1.VcpuCount)
	return nil
}

// MaintenancePolicy: Maintenance policy for an instance.
type MaintenancePolicy struct {
	// CreateTime: Output only. The time when the policy was created.
	CreateTime string `json:"createTime,omitempty"`
	// Description: Optional. Description of what this policy is for. Create/Update
	// methods return INVALID_ARGUMENT if the length is greater than 512.
	Description string `json:"description,omitempty"`
	// UpdateTime: Output only. The time when the policy was last updated.
	UpdateTime string `json:"updateTime,omitempty"`
	// WeeklyMaintenanceWindow: Optional. Maintenance window that is applied to
	// resources covered by this policy. Minimum 1. For the current version, the
	// maximum number of weekly_window is expected to be one.
	WeeklyMaintenanceWindow []*WeeklyMaintenanceWindow `json:"weeklyMaintenanceWindow,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CreateTime") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CreateTime") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MaintenancePolicy) MarshalJSON() ([]byte, error) {
	type NoMethod MaintenancePolicy
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// MaintenanceSchedule: Upcoming maintenance schedule. If no maintenance is
// scheduled, fields are not populated.
type MaintenanceSchedule struct {
	// CanReschedule: If the scheduled maintenance can be rescheduled, default is
	// true.
	CanReschedule bool `json:"canReschedule,omitempty"`
	// EndTime: Output only. The end time of any upcoming scheduled maintenance for
	// this instance.
	EndTime string `json:"endTime,omitempty"`
	// ScheduleDeadlineTime: Output only. The deadline that the maintenance
	// schedule start time can not go beyond, including reschedule.
	ScheduleDeadlineTime string `json:"scheduleDeadlineTime,omitempty"`
	// StartTime: Output only. The start time of any upcoming scheduled maintenance
	// for this instance.
	StartTime string `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CanReschedule") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CanReschedule") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s MaintenanceSchedule) MarshalJSON() ([]byte, error) {
	type NoMethod MaintenanceSchedule
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ManagedBackupSource: Backups that generated and managed by memorystore.
type ManagedBackupSource struct {
	// Backup: Optional. Example:
	// //redis.googleapis.com/projects/{project}/locations/{location}/backupCollecti
	// ons/{collection}/backups/{backup} A shorter version (without the prefix) of
	// the backup name is also supported, like
	// projects/{project}/locations/{location}/backupCollections/{collection}/backup
	// s/{backup_id} In this case, it assumes the backup is under
	// redis.googleapis.com.
	Backup string `json:"backup,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Backup") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Backup") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ManagedBackupSource) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedBackupSource
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

type ManagedCertificateAuthority struct {
	// CaCerts: The PEM encoded CA certificate chains for redis managed server
	// authentication
	CaCerts []*CertChain `json:"caCerts,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CaCerts") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CaCerts") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ManagedCertificateAuthority) MarshalJSON() ([]byte, error) {
	type NoMethod ManagedCertificateAuthority
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Membership: An output only view of all the member clusters participating in
// the cross cluster replication.
type Membership struct {
	// PrimaryCluster: Output only. The primary cluster that acts as the source of
	// replication for the secondary clusters.
	PrimaryCluster *RemoteCluster `json:"primaryCluster,omitempty"`
	// SecondaryClusters: Output only. The list of secondary clusters replicating
	// from the primary cluster.
	SecondaryClusters []*RemoteCluster `json:"secondaryClusters,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PrimaryCluster") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "PrimaryCluster") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Membership) MarshalJSON() ([]byte, error) {
	type NoMethod Membership
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// NodeInfo: Node specific properties.
type NodeInfo struct {
	// Id: Output only. Node identifying string. e.g. 'node-0', 'node-1'
	Id string `json:"id,omitempty"`
	// Zone: Output only. Location of the node.
	Zone string `json:"zone,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Id") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Id") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s NodeInfo) MarshalJSON() ([]byte, error) {
	type NoMethod NodeInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

type ObservabilityMetricData struct {
	// AggregationType: Required. Type of aggregation performed on the metric.
	//
	// Possible values:
	//   "AGGREGATION_TYPE_UNSPECIFIED" - Unspecified aggregation type.
	//   "PEAK" - PEAK aggregation type.
	//   "P99" - P99 aggregation type.
	//   "P95" - P95 aggregation type.
	//   "CURRENT" - current aggregation type.
	AggregationType string `json:"aggregationType,omitempty"`
	// MetricType: Required. Type of metric like CPU, Memory, etc.
	//
	// Possible values:
	//   "METRIC_TYPE_UNSPECIFIED" - Unspecified metric type.
	//   "CPU_UTILIZATION" - CPU utilization for a resource. The value is a
	// fraction between 0.0 and 1.0 (may momentarily exceed 1.0 in some cases).
	//   "MEMORY_UTILIZATION" - Memory utilization for a resource. The value is a
	// fraction between 0.0 and 1.0 (may momentarily exceed 1.0 in some cases).
	//   "NETWORK_CONNECTIONS" - Number of network connections for a resource.
	//   "STORAGE_UTILIZATION" - Storage utilization for a resource. The value is a
	// fraction between 0.0 and 1.0 (may momentarily exceed 1.0 in some cases).
	//   "STORAGE_USED_BYTES" - Sotrage used by a resource.
	//   "NODE_COUNT" - Node count for a resource. It represents the number of node
	// units in a bigtable/spanner instance.
	//   "MEMORY_USED_BYTES" - Memory used by a resource (in bytes).
	//   "PROCESSING_UNIT_COUNT" - Processing units used by a resource. It
	// represents the number of processing units in a spanner instance.
	MetricType string `json:"metricType,omitempty"`
	// ObservationTime: Required. The time the metric value was observed.
	ObservationTime string `json:"observationTime,omitempty"`
	// ResourceName: Required. Database resource name associated with the signal.
	// Resource name to follow CAIS resource_name format as noted here
	// go/condor-common-datamodel
	ResourceName string `json:"resourceName,omitempty"`
	// Value: Required. Value of the metric type.
	Value *TypedValue `json:"value,omitempty"`
	// ForceSendFields is a list of field names (e.g. "AggregationType") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "AggregationType") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ObservabilityMetricData) MarshalJSON() ([]byte, error) {
	type NoMethod ObservabilityMetricData
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Operation: This resource represents a long-running operation that is the
// result of a network API call.
type Operation struct {
	// Done: If the value is `false`, it means the operation is still in progress.
	// If `true`, the operation is completed, and either `error` or `response` is
	// available.
	Done bool `json:"done,omitempty"`
	// Error: The error result of the operation in case of failure or cancellation.
	Error *Status `json:"error,omitempty"`
	// Metadata: { `createTime`: The time the operation was created. `endTime`: The
	// time the operation finished running. `target`: Server-defined resource path
	// for the target of the operation. `verb`: Name of the verb executed by the
	// operation. `statusDetail`: Human-readable status of the operation, if any.
	// `cancelRequested`: Identifies whether the user has requested cancellation of
	// the operation. Operations that have successfully been cancelled have
	// Operation.error value with a google.rpc.Status.code of 1, corresponding to
	// `Code.CANCELLED`. `apiVersion`: API version used to start the operation. }
	Metadata googleapi.RawMessage `json:"metadata,omitempty"`
	// Name: The server-assigned name, which is only unique within the same service
	// that originally returns it. If you use the default HTTP mapping, the `name`
	// should be a resource name ending with `operations/{unique_id}`.
	Name string `json:"name,omitempty"`
	// Response: The normal, successful response of the operation. If the original
	// method returns no data on success, such as `Delete`, the response is
	// `google.protobuf.Empty`. If the original method is standard
	// `Get`/`Create`/`Update`, the response should be the resource. For other
	// methods, the response should have the type `XxxResponse`, where `Xxx` is the
	// original method name. For example, if the original method name is
	// `TakeSnapshot()`, the inferred response type is `TakeSnapshotResponse`.
	Response googleapi.RawMessage `json:"response,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "Done") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Done") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Operation) MarshalJSON() ([]byte, error) {
	type NoMethod Operation
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// OperationError: An error that occurred during a backup creation operation.
type OperationError struct {
	// Code: Identifies the specific error that occurred. REQUIRED
	Code string `json:"code,omitempty"`
	// Possible values:
	//   "OPERATION_ERROR_TYPE_UNSPECIFIED" - UNSPECIFIED means product type is not
	// known or available.
	//   "KMS_KEY_ERROR" - key destroyed, expired, not found, unreachable or
	// permission denied.
	//   "DATABASE_ERROR" - Database is not accessible
	//   "STOCKOUT_ERROR" - The zone or region does not have sufficient resources
	// to handle the request at the moment
	//   "CANCELLATION_ERROR" - User initiated cancellation
	//   "SQLSERVER_ERROR" - SQL server specific error
	//   "INTERNAL_ERROR" - Any other internal error.
	ErrorType string `json:"errorType,omitempty"`
	// Message: Additional information about the error encountered. REQUIRED
	Message string `json:"message,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Code") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Code") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s OperationError) MarshalJSON() ([]byte, error) {
	type NoMethod OperationError
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// OperationMetadata: Pre-defined metadata fields.
type OperationMetadata struct {
	// ApiVersion: Output only. API version used to start the operation.
	ApiVersion string `json:"apiVersion,omitempty"`
	// CreateTime: Output only. The time the operation was created.
	CreateTime string `json:"createTime,omitempty"`
	// EndTime: Output only. The time the operation finished running.
	EndTime string `json:"endTime,omitempty"`
	// RequestedCancellation: Output only. Identifies whether the user has
	// requested cancellation of the operation. Operations that have successfully
	// been cancelled have Operation.error value with a google.rpc.Status.code of
	// 1, corresponding to `Code.CANCELLED`.
	RequestedCancellation bool `json:"requestedCancellation,omitempty"`
	// StatusMessage: Output only. Human-readable status of the operation, if any.
	StatusMessage string `json:"statusMessage,omitempty"`
	// Target: Output only. Server-defined resource path for the target of the
	// operation.
	Target string `json:"target,omitempty"`
	// Verb: Output only. Name of the verb executed by the operation.
	Verb string `json:"verb,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ApiVersion") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ApiVersion") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s OperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod OperationMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// OutputConfig: The output content
type OutputConfig struct {
	// GcsDestination: Google Cloud Storage destination for output content.
	GcsDestination *GcsDestination `json:"gcsDestination,omitempty"`
	// ForceSendFields is a list of field names (e.g. "GcsDestination") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "GcsDestination") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s OutputConfig) MarshalJSON() ([]byte, error) {
	type NoMethod OutputConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PersistenceConfig: Configuration of the persistence functionality.
type PersistenceConfig struct {
	// PersistenceMode: Optional. Controls whether Persistence features are
	// enabled. If not provided, the existing value will be used.
	//
	// Possible values:
	//   "PERSISTENCE_MODE_UNSPECIFIED" - Not set.
	//   "DISABLED" - Persistence is disabled for the instance, and any existing
	// snapshots are deleted.
	//   "RDB" - RDB based Persistence is enabled.
	PersistenceMode string `json:"persistenceMode,omitempty"`
	// RdbNextSnapshotTime: Output only. The next time that a snapshot attempt is
	// scheduled to occur.
	RdbNextSnapshotTime string `json:"rdbNextSnapshotTime,omitempty"`
	// RdbSnapshotPeriod: Optional. Period between RDB snapshots. Snapshots will be
	// attempted every period starting from the provided snapshot start time. For
	// example, a start time of 01/01/2033 06:45 and SIX_HOURS snapshot period will
	// do nothing until 01/01/2033, and then trigger snapshots every day at 06:45,
	// 12:45, 18:45, and 00:45 the next day, and so on. If not provided,
	// TWENTY_FOUR_HOURS will be used as default.
	//
	// Possible values:
	//   "SNAPSHOT_PERIOD_UNSPECIFIED" - Not set.
	//   "ONE_HOUR" - Snapshot every 1 hour.
	//   "SIX_HOURS" - Snapshot every 6 hours.
	//   "TWELVE_HOURS" - Snapshot every 12 hours.
	//   "TWENTY_FOUR_HOURS" - Snapshot every 24 hours.
	RdbSnapshotPeriod string `json:"rdbSnapshotPeriod,omitempty"`
	// RdbSnapshotStartTime: Optional. Date and time that the first snapshot
	// was/will be attempted, and to which future snapshots will be aligned. If not
	// provided, the current time will be used.
	RdbSnapshotStartTime string `json:"rdbSnapshotStartTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "PersistenceMode") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "PersistenceMode") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PersistenceConfig) MarshalJSON() ([]byte, error) {
	type NoMethod PersistenceConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Product: Product specification for Condor resources.
type Product struct {
	// Engine: The specific engine that the underlying database is running.
	//
	// Possible values:
	//   "ENGINE_UNSPECIFIED" - UNSPECIFIED means engine type is not known or
	// available.
	//   "ENGINE_MYSQL" - MySQL binary running as an engine in the database
	// instance.
	//   "MYSQL" - MySQL binary running as engine in database instance.
	//   "ENGINE_POSTGRES" - Postgres binary running as engine in database
	// instance.
	//   "POSTGRES" - Postgres binary running as engine in database instance.
	//   "ENGINE_SQL_SERVER" - SQLServer binary running as engine in database
	// instance.
	//   "SQL_SERVER" - SQLServer binary running as engine in database instance.
	//   "ENGINE_NATIVE" - Native database binary running as engine in instance.
	//   "NATIVE" - Native database binary running as engine in instance.
	//   "ENGINE_CLOUD_SPANNER_WITH_POSTGRES_DIALECT" - Cloud Spanner with
	// PostgreSQL dialect.
	//   "ENGINE_CLOUD_SPANNER_WITH_GOOGLESQL_DIALECT" - Cloud Spanner with Google
	// SQL dialect.
	//   "ENGINE_MEMORYSTORE_FOR_REDIS" - Memorystore with Redis dialect.
	//   "ENGINE_MEMORYSTORE_FOR_REDIS_CLUSTER" - Memorystore with Redis cluster
	// dialect.
	//   "ENGINE_OTHER" - Other refers to rest of other database engine. This is to
	// be when engine is known, but it is not present in this enum.
	//   "ENGINE_FIRESTORE_WITH_NATIVE_MODE" - Firestore with native mode.
	//   "ENGINE_FIRESTORE_WITH_DATASTORE_MODE" - Firestore with datastore mode.
	//   "ENGINE_FIRESTORE_WITH_MONGODB_COMPATIBILITY_MODE" - Firestore with
	// MongoDB compatibility mode.
	//   "ENGINE_EXADATA_ORACLE" - Oracle Exadata engine.
	//   "ENGINE_ADB_SERVERLESS_ORACLE" - Oracle Autonomous DB Serverless engine.
	Engine string `json:"engine,omitempty"`
	// MinorVersion: Minor version of the underlying database engine. Example
	// values: For MySQL, it could be "8.0.32", "5.7.32" etc.. For Postgres, it
	// could be "14.3", "15.3" etc..
	MinorVersion string `json:"minorVersion,omitempty"`
	// Type: Type of specific database product. It could be CloudSQL, AlloyDB etc..
	//
	// Possible values:
	//   "PRODUCT_TYPE_UNSPECIFIED" - UNSPECIFIED means product type is not known
	// or available.
	//   "PRODUCT_TYPE_CLOUD_SQL" - Cloud SQL product area in GCP
	//   "CLOUD_SQL" - Cloud SQL product area in GCP
	//   "PRODUCT_TYPE_ALLOYDB" - AlloyDB product area in GCP
	//   "ALLOYDB" - AlloyDB product area in GCP
	//   "PRODUCT_TYPE_SPANNER" - Spanner product area in GCP
	//   "PRODUCT_TYPE_ON_PREM" - On premises database product.
	//   "ON_PREM" - On premises database product.
	//   "PRODUCT_TYPE_MEMORYSTORE" - Memorystore product area in GCP
	//   "PRODUCT_TYPE_BIGTABLE" - Bigtable product area in GCP
	//   "PRODUCT_TYPE_FIRESTORE" - Firestore product area in GCP.
	//   "PRODUCT_TYPE_COMPUTE_ENGINE" - Compute Engine self managed databases
	//   "PRODUCT_TYPE_ORACLE_ON_GCP" - Oracle product area in GCP
	//   "PRODUCT_TYPE_BIGQUERY" - BigQuery product area in GCP
	//   "PRODUCT_TYPE_OTHER" - Other refers to rest of other product type. This is
	// to be when product type is known, but it is not present in this enum.
	Type string `json:"type,omitempty"`
	// Version: Version of the underlying database engine. Example values: For
	// MySQL, it could be "8.0", "5.7" etc.. For Postgres, it could be "14", "15"
	// etc..
	Version string `json:"version,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Engine") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Engine") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Product) MarshalJSON() ([]byte, error) {
	type NoMethod Product
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PscAutoConnection: Details of consumer resources in a PSC connection that is
// created through Service Connectivity Automation.
type PscAutoConnection struct {
	// Address: Output only. The IP allocated on the consumer network for the PSC
	// forwarding rule.
	Address string `json:"address,omitempty"`
	// ConnectionType: Output only. Type of the PSC connection.
	//
	// Possible values:
	//   "CONNECTION_TYPE_UNSPECIFIED" - Cluster endpoint Type is not set
	//   "CONNECTION_TYPE_DISCOVERY" - Cluster endpoint that will be used as for
	// cluster topology discovery.
	//   "CONNECTION_TYPE_PRIMARY" - Cluster endpoint that will be used as primary
	// endpoint to access primary.
	//   "CONNECTION_TYPE_READER" - Cluster endpoint that will be used as reader
	// endpoint to access replicas.
	ConnectionType string `json:"connectionType,omitempty"`
	// ForwardingRule: Output only. The URI of the consumer side forwarding rule.
	// Example:
	// projects/{projectNumOrId}/regions/us-east1/forwardingRules/{resourceId}.
	ForwardingRule string `json:"forwardingRule,omitempty"`
	// Network: Required. The consumer network where the IP address resides, in the
	// form of projects/{project_id}/global/networks/{network_id}.
	Network string `json:"network,omitempty"`
	// ProjectId: Required. The consumer project_id where the forwarding rule is
	// created from.
	ProjectId string `json:"projectId,omitempty"`
	// PscConnectionId: Output only. The PSC connection id of the forwarding rule
	// connected to the service attachment.
	PscConnectionId string `json:"pscConnectionId,omitempty"`
	// PscConnectionStatus: Output only. The status of the PSC connection. Please
	// note that this value is updated periodically. Please use Private Service
	// Connect APIs for the latest status.
	//
	// Possible values:
	//   "PSC_CONNECTION_STATUS_UNSPECIFIED" - PSC connection status is not
	// specified.
	//   "PSC_CONNECTION_STATUS_ACTIVE" - The connection is active
	//   "PSC_CONNECTION_STATUS_NOT_FOUND" - Connection not found
	PscConnectionStatus string `json:"pscConnectionStatus,omitempty"`
	// ServiceAttachment: Output only. The service attachment which is the target
	// of the PSC connection, in the form of
	// projects/{project-id}/regions/{region}/serviceAttachments/{service-attachment
	// -id}.
	ServiceAttachment string `json:"serviceAttachment,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Address") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Address") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PscAutoConnection) MarshalJSON() ([]byte, error) {
	type NoMethod PscAutoConnection
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

type PscConfig struct {
	// Network: Required. The network where the IP address of the discovery
	// endpoint will be reserved, in the form of
	// projects/{network_project}/global/networks/{network_id}.
	Network string `json:"network,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Network") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Network") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PscConfig) MarshalJSON() ([]byte, error) {
	type NoMethod PscConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PscConnection: Details of consumer resources in a PSC connection.
type PscConnection struct {
	// Address: Required. The IP allocated on the consumer network for the PSC
	// forwarding rule.
	Address string `json:"address,omitempty"`
	// ConnectionType: Output only. Type of the PSC connection.
	//
	// Possible values:
	//   "CONNECTION_TYPE_UNSPECIFIED" - Cluster endpoint Type is not set
	//   "CONNECTION_TYPE_DISCOVERY" - Cluster endpoint that will be used as for
	// cluster topology discovery.
	//   "CONNECTION_TYPE_PRIMARY" - Cluster endpoint that will be used as primary
	// endpoint to access primary.
	//   "CONNECTION_TYPE_READER" - Cluster endpoint that will be used as reader
	// endpoint to access replicas.
	ConnectionType string `json:"connectionType,omitempty"`
	// ForwardingRule: Required. The URI of the consumer side forwarding rule.
	// Example:
	// projects/{projectNumOrId}/regions/us-east1/forwardingRules/{resourceId}.
	ForwardingRule string `json:"forwardingRule,omitempty"`
	// Network: Required. The consumer network where the IP address resides, in the
	// form of projects/{project_id}/global/networks/{network_id}.
	Network string `json:"network,omitempty"`
	// Port: Output only. port will only be set for Primary/Reader or Discovery
	// endpoint.
	Port int64 `json:"port,omitempty"`
	// ProjectId: Optional. Project ID of the consumer project where the forwarding
	// rule is created in.
	ProjectId string `json:"projectId,omitempty"`
	// PscConnectionId: Required. The PSC connection id of the forwarding rule
	// connected to the service attachment.
	PscConnectionId string `json:"pscConnectionId,omitempty"`
	// PscConnectionStatus: Output only. The status of the PSC connection. Please
	// note that this value is updated periodically. To get the latest status of a
	// PSC connection, follow
	// https://cloud.google.com/vpc/docs/configure-private-service-connect-services#endpoint-details.
	//
	// Possible values:
	//   "PSC_CONNECTION_STATUS_UNSPECIFIED" - PSC connection status is not
	// specified.
	//   "PSC_CONNECTION_STATUS_ACTIVE" - The connection is active
	//   "PSC_CONNECTION_STATUS_NOT_FOUND" - Connection not found
	PscConnectionStatus string `json:"pscConnectionStatus,omitempty"`
	// ServiceAttachment: Required. The service attachment which is the target of
	// the PSC connection, in the form of
	// projects/{project-id}/regions/{region}/serviceAttachments/{service-attachment
	// -id}.
	ServiceAttachment string `json:"serviceAttachment,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Address") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Address") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PscConnection) MarshalJSON() ([]byte, error) {
	type NoMethod PscConnection
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// PscServiceAttachment: Configuration of a service attachment of the cluster,
// for creating PSC connections.
type PscServiceAttachment struct {
	// ConnectionType: Output only. Type of a PSC connection targeting this service
	// attachment.
	//
	// Possible values:
	//   "CONNECTION_TYPE_UNSPECIFIED" - Cluster endpoint Type is not set
	//   "CONNECTION_TYPE_DISCOVERY" - Cluster endpoint that will be used as for
	// cluster topology discovery.
	//   "CONNECTION_TYPE_PRIMARY" - Cluster endpoint that will be used as primary
	// endpoint to access primary.
	//   "CONNECTION_TYPE_READER" - Cluster endpoint that will be used as reader
	// endpoint to access replicas.
	ConnectionType string `json:"connectionType,omitempty"`
	// ServiceAttachment: Output only. Service attachment URI which your
	// self-created PscConnection should use as target
	ServiceAttachment string `json:"serviceAttachment,omitempty"`
	// ForceSendFields is a list of field names (e.g. "ConnectionType") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ConnectionType") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s PscServiceAttachment) MarshalJSON() ([]byte, error) {
	type NoMethod PscServiceAttachment
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RDBConfig: Configuration of the RDB based persistence.
type RDBConfig struct {
	// RdbSnapshotPeriod: Optional. Period between RDB snapshots.
	//
	// Possible values:
	//   "SNAPSHOT_PERIOD_UNSPECIFIED" - Not set.
	//   "ONE_HOUR" - One hour.
	//   "SIX_HOURS" - Six hours.
	//   "TWELVE_HOURS" - Twelve hours.
	//   "TWENTY_FOUR_HOURS" - Twenty four hours.
	RdbSnapshotPeriod string `json:"rdbSnapshotPeriod,omitempty"`
	// RdbSnapshotStartTime: Optional. The time that the first snapshot was/will be
	// attempted, and to which future snapshots will be aligned. If not provided,
	// the current time will be used.
	RdbSnapshotStartTime string `json:"rdbSnapshotStartTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RdbSnapshotPeriod") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RdbSnapshotPeriod") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RDBConfig) MarshalJSON() ([]byte, error) {
	type NoMethod RDBConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ReconciliationOperationMetadata: Operation metadata returned by the CLH
// during resource state reconciliation.
type ReconciliationOperationMetadata struct {
	// DeleteResource: DEPRECATED. Use exclusive_action instead.
	DeleteResource bool `json:"deleteResource,omitempty"`
	// ExclusiveAction: Excluisive action returned by the CLH.
	//
	// Possible values:
	//   "UNKNOWN_REPAIR_ACTION" - Unknown repair action.
	//   "DELETE" - The resource has to be deleted. When using this bit, the CLH
	// should fail the operation. DEPRECATED. Instead use DELETE_RESOURCE
	// OperationSignal in SideChannel.
	//   "RETRY" - This resource could not be repaired but the repair should be
	// tried again at a later time. This can happen if there is a dependency that
	// needs to be resolved first- e.g. if a parent resource must be repaired
	// before a child resource.
	ExclusiveAction string `json:"exclusiveAction,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DeleteResource") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DeleteResource") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ReconciliationOperationMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod ReconciliationOperationMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RegionalCertChain: The certificates that form the CA chain, from leaf to
// root order.
type RegionalCertChain struct {
	// Certificates: The certificates that form the CA chain, from leaf to root
	// order.
	Certificates []string `json:"certificates,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Certificates") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Certificates") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RegionalCertChain) MarshalJSON() ([]byte, error) {
	type NoMethod RegionalCertChain
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RegionalManagedCertificateAuthority: CA certificate chains for redis managed
// server authentication.
type RegionalManagedCertificateAuthority struct {
	// CaCerts: The PEM encoded CA certificate chains for redis managed server
	// authentication
	CaCerts []*RegionalCertChain `json:"caCerts,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CaCerts") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CaCerts") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RegionalManagedCertificateAuthority) MarshalJSON() ([]byte, error) {
	type NoMethod RegionalManagedCertificateAuthority
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RemoteCluster: Details of the remote cluster associated with this cluster in
// a cross cluster replication setup.
type RemoteCluster struct {
	// Cluster: Output only. The full resource path of the remote cluster in the
	// format: projects//locations//clusters/
	Cluster string `json:"cluster,omitempty"`
	// Uid: Output only. The unique identifier of the remote cluster.
	Uid string `json:"uid,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Cluster") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Cluster") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RemoteCluster) MarshalJSON() ([]byte, error) {
	type NoMethod RemoteCluster
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RescheduleClusterMaintenanceRequest: Request for rescheduling a cluster
// maintenance.
type RescheduleClusterMaintenanceRequest struct {
	// RescheduleType: Required. If reschedule type is SPECIFIC_TIME, must set up
	// schedule_time as well.
	//
	// Possible values:
	//   "RESCHEDULE_TYPE_UNSPECIFIED" - Not set.
	//   "IMMEDIATE" - If the user wants to schedule the maintenance to happen now.
	//   "SPECIFIC_TIME" - If the user wants to reschedule the maintenance to a
	// specific time.
	RescheduleType string `json:"rescheduleType,omitempty"`
	// ScheduleTime: Optional. Timestamp when the maintenance shall be rescheduled
	// to if reschedule_type=SPECIFIC_TIME, in RFC 3339 format, for example
	// `2012-11-15T16:19:00.094Z`.
	ScheduleTime string `json:"scheduleTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RescheduleType") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RescheduleType") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RescheduleClusterMaintenanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RescheduleClusterMaintenanceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// RescheduleMaintenanceRequest: Request for RescheduleMaintenance.
type RescheduleMaintenanceRequest struct {
	// RescheduleType: Required. If reschedule type is SPECIFIC_TIME, must set up
	// schedule_time as well.
	//
	// Possible values:
	//   "RESCHEDULE_TYPE_UNSPECIFIED" - Not set.
	//   "IMMEDIATE" - If the user wants to schedule the maintenance to happen now.
	//   "NEXT_AVAILABLE_WINDOW" - If the user wants to use the existing
	// maintenance policy to find the next available window.
	//   "SPECIFIC_TIME" - If the user wants to reschedule the maintenance to a
	// specific time.
	RescheduleType string `json:"rescheduleType,omitempty"`
	// ScheduleTime: Optional. Timestamp when the maintenance shall be rescheduled
	// to if reschedule_type=SPECIFIC_TIME, in RFC 3339 format, for example
	// `2012-11-15T16:19:00.094Z`.
	ScheduleTime string `json:"scheduleTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RescheduleType") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RescheduleType") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RescheduleMaintenanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod RescheduleMaintenanceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ResourceFlags: Message type for storing resource flags.
type ResourceFlags struct {
	// Key: Optional. Key of the resource flag.
	Key string `json:"key,omitempty"`
	// Value: Optional. Value of the resource flag.
	Value string `json:"value,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Key") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Key") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ResourceFlags) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceFlags
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ResourceMaintenanceDenySchedule: Deny maintenance period for the database
// resource. It specifies the time range during which the maintenance cannot
// start. This is configured by the customer.
type ResourceMaintenanceDenySchedule struct {
	// EndDate: Optional. Deny period end date.
	EndDate *Date `json:"endDate,omitempty"`
	// StartDate: Optional. The start date of the deny maintenance period.
	StartDate *Date `json:"startDate,omitempty"`
	// Time: Optional. Time in UTC when the deny period starts on start_date and
	// ends on end_date.
	Time *TimeOfDay `json:"time,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndDate") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EndDate") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ResourceMaintenanceDenySchedule) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceMaintenanceDenySchedule
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ResourceMaintenanceInfo: MaintenanceInfo to capture the maintenance details
// of database resource.
type ResourceMaintenanceInfo struct {
	// CurrentVersionReleaseDate: Optional. The date when the current maintenance
	// version was released.
	CurrentVersionReleaseDate *Date `json:"currentVersionReleaseDate,omitempty"`
	// DenyMaintenanceSchedules: Optional. List of Deny maintenance period for the
	// database resource.
	DenyMaintenanceSchedules []*ResourceMaintenanceDenySchedule `json:"denyMaintenanceSchedules,omitempty"`
	// IsInstanceStopped: Optional. Whether the instance is in stopped state. This
	// information is temporarily being captured in maintenanceInfo, till STOPPED
	// state is supported by DB Center.
	IsInstanceStopped bool `json:"isInstanceStopped,omitempty"`
	// MaintenanceSchedule: Optional. Maintenance window for the database resource.
	MaintenanceSchedule *ResourceMaintenanceSchedule `json:"maintenanceSchedule,omitempty"`
	// MaintenanceState: Output only. Current state of maintenance on the database
	// resource.
	//
	// Possible values:
	//   "MAINTENANCE_STATE_UNSPECIFIED" - Unspecified state.
	//   "CREATING" - Database resource is being created.
	//   "READY" - Database resource has been created and is ready to use.
	//   "UPDATING" - Database resource is being updated.
	//   "REPAIRING" - Database resource is unheathy and under repair.
	//   "DELETING" - Database resource is being deleted.
	//   "ERROR" - Database resource encountered an error and is in indeterministic
	// state.
	MaintenanceState string `json:"maintenanceState,omitempty"`
	// MaintenanceVersion: Optional. Current Maintenance version of the database
	// resource. Example: "MYSQL_8_0_41.R20250531.01_15"
	MaintenanceVersion string `json:"maintenanceVersion,omitempty"`
	// UpcomingMaintenance: Optional. Upcoming maintenance for the database
	// resource. This field is populated once SLM generates and publishes upcoming
	// maintenance window.
	UpcomingMaintenance *UpcomingMaintenance `json:"upcomingMaintenance,omitempty"`
	// ForceSendFields is a list of field names (e.g. "CurrentVersionReleaseDate")
	// to unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "CurrentVersionReleaseDate") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ResourceMaintenanceInfo) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceMaintenanceInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ResourceMaintenanceSchedule: Maintenance window for the database resource.
// It specifies preferred time and day of the week and phase in some cases,
// when the maintenance can start. This is configured by the customer.
type ResourceMaintenanceSchedule struct {
	// Day: Optional. Preferred day of the week for maintenance, e.g. MONDAY,
	// TUESDAY, etc.
	//
	// Possible values:
	//   "DAY_OF_WEEK_UNSPECIFIED" - The day of the week is unspecified.
	//   "MONDAY" - Monday
	//   "TUESDAY" - Tuesday
	//   "WEDNESDAY" - Wednesday
	//   "THURSDAY" - Thursday
	//   "FRIDAY" - Friday
	//   "SATURDAY" - Saturday
	//   "SUNDAY" - Sunday
	Day string `json:"day,omitempty"`
	// Phase: Optional. Phase of the maintenance window. This is to capture order
	// of maintenance. For example, for Cloud SQL resources, this can be used to
	// capture if the maintenance window is in Week1, Week2, Week5, etc. Non
	// production resources are usually part of early phase. For more details,
	// refer to Cloud SQL resources -
	// https://cloud.google.com/sql/docs/mysql/maintenance
	//
	// Possible values:
	//   "PHASE_UNSPECIFIED" - Phase is unspecified.
	//   "ANY" - Any phase.
	//   "WEEK1" - Week 1.
	//   "WEEK2" - Week 2.
	//   "WEEK5" - Week 5.
	Phase string `json:"phase,omitempty"`
	// Time: Optional. Preferred time to start the maintenance operation on the
	// specified day.
	Time *TimeOfDay `json:"time,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Day") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Day") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ResourceMaintenanceSchedule) MarshalJSON() ([]byte, error) {
	type NoMethod ResourceMaintenanceSchedule
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

type RetentionSettings struct {
	// DurationBasedRetention: Duration based retention period i.e. 172800 seconds
	// (2 days)
	DurationBasedRetention string `json:"durationBasedRetention,omitempty"`
	QuantityBasedRetention int64  `json:"quantityBasedRetention,omitempty"`
	// RetentionUnit: The unit that 'retained_backups' represents.
	//
	// Possible values:
	//   "RETENTION_UNIT_UNSPECIFIED" - Backup retention unit is unspecified, will
	// be treated as COUNT.
	//   "COUNT" - Retention will be by count, eg. "retain the most recent 7
	// backups".
	//   "TIME" - Retention will be by Time, eg. "retain backups till a specific
	// time" i.e. till 2024-05-01T00:00:00Z.
	//   "DURATION" - Retention will be by duration, eg. "retain the backups for
	// 172800 seconds (2 days)".
	//   "RETENTION_UNIT_OTHER" - For rest of the other category
	RetentionUnit      string `json:"retentionUnit,omitempty"`
	TimeBasedRetention string `json:"timeBasedRetention,omitempty"`
	// TimestampBasedRetentionTime: Timestamp based retention period i.e.
	// 2024-05-01T00:00:00Z
	TimestampBasedRetentionTime string `json:"timestampBasedRetentionTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "DurationBasedRetention") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "DurationBasedRetention") to
	// include in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s RetentionSettings) MarshalJSON() ([]byte, error) {
	type NoMethod RetentionSettings
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SharedRegionalCertificateAuthority: Shared regional certificate authority
type SharedRegionalCertificateAuthority struct {
	// ManagedServerCa: CA certificate chains for redis managed server
	// authentication.
	ManagedServerCa *RegionalManagedCertificateAuthority `json:"managedServerCa,omitempty"`
	// Name: Identifier. Unique name of the resource in this scope including
	// project and location using the form:
	// `projects/{project}/locations/{location}/sharedRegionalCertificateAuthority`
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the server.
	googleapi.ServerResponse `json:"-"`
	// ForceSendFields is a list of field names (e.g. "ManagedServerCa") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "ManagedServerCa") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SharedRegionalCertificateAuthority) MarshalJSON() ([]byte, error) {
	type NoMethod SharedRegionalCertificateAuthority
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// SignalMetadata: SignalMetadata contains one of the signal metadata proto
// messages associated with a SignalType. This proto will be mapped to
// SignalMetadata message in storage.proto. Next ID: 3
type SignalMetadata struct {
	// BackupRun: Signal data for backup runs.
	BackupRun *BackupRun `json:"backupRun,omitempty"`
	// SignalBoolValue: Signal data for boolean signals.
	SignalBoolValue bool `json:"signalBoolValue,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BackupRun") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BackupRun") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s SignalMetadata) MarshalJSON() ([]byte, error) {
	type NoMethod SignalMetadata
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// StateInfo: Represents additional information about the state of the cluster.
type StateInfo struct {
	// UpdateInfo: Describes ongoing update on the cluster when cluster state is
	// UPDATING.
	UpdateInfo *UpdateInfo `json:"updateInfo,omitempty"`
	// ForceSendFields is a list of field names (e.g. "UpdateInfo") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "UpdateInfo") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s StateInfo) MarshalJSON() ([]byte, error) {
	type NoMethod StateInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Status: The `Status` type defines a logical error model that is suitable for
// different programming environments, including REST APIs and RPC APIs. It is
// used by gRPC (https://github.com/grpc). Each `Status` message contains three
// pieces of data: error code, error message, and error details. You can find
// out more about this error model and how to work with it in the API Design
// Guide (https://cloud.google.com/apis/design/errors).
type Status struct {
	// Code: The status code, which should be an enum value of google.rpc.Code.
	Code int64 `json:"code,omitempty"`
	// Details: A list of messages that carry the error details. There is a common
	// set of message types for APIs to use.
	Details []googleapi.RawMessage `json:"details,omitempty"`
	// Message: A developer-facing error message, which should be in English. Any
	// user-facing error message should be localized and sent in the
	// google.rpc.Status.details field, or localized by the client.
	Message string `json:"message,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Code") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Code") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Status) MarshalJSON() ([]byte, error) {
	type NoMethod Status
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// Tags: Message type for storing tags. Tags provide a way to create
// annotations for resources, and in some cases conditionally allow or deny
// policies based on whether a resource has a specific tag.
type Tags struct {
	// Tags: The Tag key/value mappings.
	Tags map[string]string `json:"tags,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Tags") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Tags") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s Tags) MarshalJSON() ([]byte, error) {
	type NoMethod Tags
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// TimeOfDay: Represents a time of day. The date and time zone are either not
// significant or are specified elsewhere. An API may choose to allow leap
// seconds. Related types are google.type.Date and `google.protobuf.Timestamp`.
type TimeOfDay struct {
	// Hours: Hours of a day in 24 hour format. Must be greater than or equal to 0
	// and typically must be less than or equal to 23. An API may choose to allow
	// the value "24:00:00" for scenarios like business closing time.
	Hours int64 `json:"hours,omitempty"`
	// Minutes: Minutes of an hour. Must be greater than or equal to 0 and less
	// than or equal to 59.
	Minutes int64 `json:"minutes,omitempty"`
	// Nanos: Fractions of seconds, in nanoseconds. Must be greater than or equal
	// to 0 and less than or equal to 999,999,999.
	Nanos int64 `json:"nanos,omitempty"`
	// Seconds: Seconds of a minute. Must be greater than or equal to 0 and
	// typically must be less than or equal to 59. An API may allow the value 60 if
	// it allows leap-seconds.
	Seconds int64 `json:"seconds,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Hours") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Hours") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s TimeOfDay) MarshalJSON() ([]byte, error) {
	type NoMethod TimeOfDay
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// TlsCertificate: TlsCertificate Resource
type TlsCertificate struct {
	// Cert: PEM representation.
	Cert string `json:"cert,omitempty"`
	// CreateTime: Output only. The time when the certificate was created in RFC
	// 3339 (https://tools.ietf.org/html/rfc3339) format, for example
	// `2020-05-18T00:00:00.094Z`.
	CreateTime string `json:"createTime,omitempty"`
	// ExpireTime: Output only. The time when the certificate expires in RFC 3339
	// (https://tools.ietf.org/html/rfc3339) format, for example
	// `2020-05-18T00:00:00.094Z`.
	ExpireTime string `json:"expireTime,omitempty"`
	// SerialNumber: Serial number, as extracted from the certificate.
	SerialNumber string `json:"serialNumber,omitempty"`
	// Sha1Fingerprint: Sha1 Fingerprint of the certificate.
	Sha1Fingerprint string `json:"sha1Fingerprint,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Cert") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Cert") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s TlsCertificate) MarshalJSON() ([]byte, error) {
	type NoMethod TlsCertificate
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// TypedValue: TypedValue represents the value of a metric type. It can either
// be a double, an int64, a string or a bool.
type TypedValue struct {
	// BoolValue: For boolean value
	BoolValue bool `json:"boolValue,omitempty"`
	// DoubleValue: For double value
	DoubleValue float64 `json:"doubleValue,omitempty"`
	// Int64Value: For integer value
	Int64Value int64 `json:"int64Value,omitempty,string"`
	// StringValue: For string value
	StringValue string `json:"stringValue,omitempty"`
	// ForceSendFields is a list of field names (e.g. "BoolValue") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "BoolValue") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s TypedValue) MarshalJSON() ([]byte, error) {
	type NoMethod TypedValue
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

func (s *TypedValue) UnmarshalJSON(data []byte) error {
	type NoMethod TypedValue
	var s1 struct {
		DoubleValue gensupport.JSONFloat64 `json:"doubleValue"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DoubleValue = float64(s1.DoubleValue)
	return nil
}

// UpcomingMaintenance: Upcoming maintenance for the database resource. This is
// generated by SLM once the upcoming maintenance schedule is published.
type UpcomingMaintenance struct {
	// EndTime: Optional. The end time of the upcoming maintenance.
	EndTime string `json:"endTime,omitempty"`
	// StartTime: Optional. The start time of the upcoming maintenance.
	StartTime string `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "EndTime") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "EndTime") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s UpcomingMaintenance) MarshalJSON() ([]byte, error) {
	type NoMethod UpcomingMaintenance
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// UpdateInfo: Represents information about an updating cluster.
type UpdateInfo struct {
	// TargetNodeType: Target node type for redis cluster.
	//
	// Possible values:
	//   "NODE_TYPE_UNSPECIFIED" - Node type unspecified
	//   "REDIS_SHARED_CORE_NANO" - Redis shared core nano node_type.
	//   "REDIS_HIGHMEM_MEDIUM" - Redis highmem medium node_type.
	//   "REDIS_HIGHMEM_XLARGE" - Redis highmem xlarge node_type.
	//   "REDIS_STANDARD_SMALL" - Redis standard small node_type.
	TargetNodeType string `json:"targetNodeType,omitempty"`
	// TargetReplicaCount: Target number of replica nodes per shard.
	TargetReplicaCount int64 `json:"targetReplicaCount,omitempty"`
	// TargetShardCount: Target number of shards for redis cluster
	TargetShardCount int64 `json:"targetShardCount,omitempty"`
	// ForceSendFields is a list of field names (e.g. "TargetNodeType") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "TargetNodeType") to include in
	// API requests with the JSON null value. By default, fields with empty values
	// are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s UpdateInfo) MarshalJSON() ([]byte, error) {
	type NoMethod UpdateInfo
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// UpgradeInstanceRequest: Request for UpgradeInstance.
type UpgradeInstanceRequest struct {
	// RedisVersion: Required. Specifies the target version of Redis software to
	// upgrade to.
	RedisVersion string `json:"redisVersion,omitempty"`
	// ForceSendFields is a list of field names (e.g. "RedisVersion") to
	// unconditionally include in API requests. By default, fields with empty or
	// default values are omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "RedisVersion") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s UpgradeInstanceRequest) MarshalJSON() ([]byte, error) {
	type NoMethod UpgradeInstanceRequest
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// UserLabels: Message type for storing user labels. User labels are used to
// tag App Engine resources, allowing users to search for resources matching a
// set of labels and to aggregate usage data by labels.
type UserLabels struct {
	Labels map[string]string `json:"labels,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Labels") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Labels") to include in API
	// requests with the JSON null value. By default, fields with empty values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s UserLabels) MarshalJSON() ([]byte, error) {
	type NoMethod UserLabels
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// WeeklyMaintenanceWindow: Time window in which disruptive maintenance updates
// occur. Non-disruptive updates can occur inside or outside this window.
type WeeklyMaintenanceWindow struct {
	// Day: Required. The day of week that maintenance updates occur.
	//
	// Possible values:
	//   "DAY_OF_WEEK_UNSPECIFIED" - The day of the week is unspecified.
	//   "MONDAY" - Monday
	//   "TUESDAY" - Tuesday
	//   "WEDNESDAY" - Wednesday
	//   "THURSDAY" - Thursday
	//   "FRIDAY" - Friday
	//   "SATURDAY" - Saturday
	//   "SUNDAY" - Sunday
	Day string `json:"day,omitempty"`
	// Duration: Output only. Duration of the maintenance window. The current
	// window is fixed at 1 hour.
	Duration string `json:"duration,omitempty"`
	// StartTime: Required. Start time of the window in UTC time.
	StartTime *TimeOfDay `json:"startTime,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Day") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Day") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s WeeklyMaintenanceWindow) MarshalJSON() ([]byte, error) {
	type NoMethod WeeklyMaintenanceWindow
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

// ZoneDistributionConfig: Zone distribution config for allocation of cluster
// resources.
type ZoneDistributionConfig struct {
	// Mode: Optional. The mode of zone distribution. Defaults to MULTI_ZONE, when
	// not specified.
	//
	// Possible values:
	//   "ZONE_DISTRIBUTION_MODE_UNSPECIFIED" - Not Set. Default: MULTI_ZONE
	//   "MULTI_ZONE" - Distribute all resources across 3 zones picked at random,
	// within the region.
	//   "SINGLE_ZONE" - Distribute all resources in a single zone. The zone field
	// must be specified, when this mode is selected.
	Mode string `json:"mode,omitempty"`
	// Zone: Optional. When SINGLE ZONE distribution is selected, zone field would
	// be used to allocate all resources in that zone. This is not applicable to
	// MULTI_ZONE, and would be ignored for MULTI_ZONE clusters.
	Zone string `json:"zone,omitempty"`
	// ForceSendFields is a list of field names (e.g. "Mode") to unconditionally
	// include in API requests. By default, fields with empty or default values are
	// omitted from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-ForceSendFields for more
	// details.
	ForceSendFields []string `json:"-"`
	// NullFields is a list of field names (e.g. "Mode") to include in API requests
	// with the JSON null value. By default, fields with empty values are omitted
	// from API requests. See
	// https://pkg.go.dev/google.golang.org/api#hdr-NullFields for more details.
	NullFields []string `json:"-"`
}

func (s ZoneDistributionConfig) MarshalJSON() ([]byte, error) {
	type NoMethod ZoneDistributionConfig
	return gensupport.MarshalJSON(NoMethod(s), s.ForceSendFields, s.NullFields)
}

type ProjectsLocationsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets information about a location.
//
// - name: Resource name for the location.
func (r *ProjectsLocationsService) Get(name string) *ProjectsLocationsGetCall {
	c := &ProjectsLocationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsGetCall) Context(ctx context.Context) *ProjectsLocationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *Location.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsGetCall) Do(opts ...googleapi.CallOption) (*Location, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Location{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsGetSharedRegionalCertificateAuthorityCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetSharedRegionalCertificateAuthority: Gets the details of regional
// certificate authority information for Redis cluster.
//
//   - name: Regional certificate authority resource name using the form:
//     `projects/{project_id}/locations/{location_id}/sharedRegionalCertificateAut
//     hority` where `location_id` refers to a Google Cloud region.
func (r *ProjectsLocationsService) GetSharedRegionalCertificateAuthority(name string) *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall {
	c := &ProjectsLocationsGetSharedRegionalCertificateAuthorityCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall) Fields(s ...googleapi.Field) *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall) IfNoneMatch(entityTag string) *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall) Context(ctx context.Context) *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.getSharedRegionalCertificateAuthority", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.getSharedRegionalCertificateAuthority" call.
// Any non-2xx status code is an error. Response headers are in either
// *SharedRegionalCertificateAuthority.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsGetSharedRegionalCertificateAuthorityCall) Do(opts ...googleapi.CallOption) (*SharedRegionalCertificateAuthority, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &SharedRegionalCertificateAuthority{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.getSharedRegionalCertificateAuthority", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsListCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists information about the supported locations for this service. This
// method can be called in two ways: * **List all public locations:** Use the
// path `GET /v1/locations`. * **List project-visible locations:** Use the path
// `GET /v1/projects/{project_id}/locations`. This may include public locations
// as well as private or other locations specifically visible to the project.
//
// - name: The resource that owns the locations collection, if applicable.
func (r *ProjectsLocationsService) List(name string) *ProjectsLocationsListCall {
	c := &ProjectsLocationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// ExtraLocationTypes sets the optional parameter "extraLocationTypes": Do not
// use this field. It is unsupported and is ignored unless explicitly
// documented otherwise. This is primarily for internal usage.
func (c *ProjectsLocationsListCall) ExtraLocationTypes(extraLocationTypes ...string) *ProjectsLocationsListCall {
	c.urlParams_.SetMulti("extraLocationTypes", append([]string{}, extraLocationTypes...))
	return c
}

// Filter sets the optional parameter "filter": A filter to narrow down results
// to a preferred subset. The filtering language accepts strings like
// "displayName=tokyo", and is documented in more detail in AIP-160
// (https://google.aip.dev/160).
func (c *ProjectsLocationsListCall) Filter(filter string) *ProjectsLocationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of
// results to return. If not set, the service selects a default.
func (c *ProjectsLocationsListCall) PageSize(pageSize int64) *ProjectsLocationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": A page token received
// from the `next_page_token` field in the response. Send that page token to
// receive the subsequent page.
func (c *ProjectsLocationsListCall) PageToken(pageToken string) *ProjectsLocationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsListCall) Context(ctx context.Context) *ProjectsLocationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/locations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListLocationsResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsListCall) Do(opts ...googleapi.CallOption) (*ListLocationsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &ListLocationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsListCall) Pages(ctx context.Context, f func(*ListLocationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

type ProjectsLocationsBackupCollectionsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get a backup collection.
//
//   - name: Redis backupCollection resource name using the form:
//     `projects/{project_id}/locations/{location_id}/backupCollections/{backup_co
//     llection_id}` where `location_id` refers to a Google Cloud region.
func (r *ProjectsLocationsBackupCollectionsService) Get(name string) *ProjectsLocationsBackupCollectionsGetCall {
	c := &ProjectsLocationsBackupCollectionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsBackupCollectionsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsBackupCollectionsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsBackupCollectionsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsBackupCollectionsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsBackupCollectionsGetCall) Context(ctx context.Context) *ProjectsLocationsBackupCollectionsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsBackupCollectionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsBackupCollectionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.backupCollections.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *BackupCollection.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsBackupCollectionsGetCall) Do(opts ...googleapi.CallOption) (*BackupCollection, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &BackupCollection{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsBackupCollectionsListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all backup collections owned by a consumer project in either the
// specified location (region) or all locations. If `location_id` is specified
// as `-` (wildcard), then all regions available to the project are queried,
// and the results are aggregated.
//
//   - parent: The resource name of the backupCollection location using the form:
//     `projects/{project_id}/locations/{location_id}` where `location_id` refers
//     to a Google Cloud region.
func (r *ProjectsLocationsBackupCollectionsService) List(parent string) *ProjectsLocationsBackupCollectionsListCall {
	c := &ProjectsLocationsBackupCollectionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of items
// to return. If not specified, a default value of 1000 will be used by the
// service. Regardless of the page_size value, the response may include a
// partial list and a caller should only rely on response's `next_page_token`
// to determine if there are more clusters left to be queried.
func (c *ProjectsLocationsBackupCollectionsListCall) PageSize(pageSize int64) *ProjectsLocationsBackupCollectionsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The `next_page_token`
// value returned from a previous [ListBackupCollections] request, if any.
func (c *ProjectsLocationsBackupCollectionsListCall) PageToken(pageToken string) *ProjectsLocationsBackupCollectionsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsBackupCollectionsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsBackupCollectionsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsBackupCollectionsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsBackupCollectionsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsBackupCollectionsListCall) Context(ctx context.Context) *ProjectsLocationsBackupCollectionsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsBackupCollectionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsBackupCollectionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/backupCollections")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.backupCollections.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListBackupCollectionsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ProjectsLocationsBackupCollectionsListCall) Do(opts ...googleapi.CallOption) (*ListBackupCollectionsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &ListBackupCollectionsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsBackupCollectionsListCall) Pages(ctx context.Context, f func(*ListBackupCollectionsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

type ProjectsLocationsBackupCollectionsBackupsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a specific backup.
//
//   - name: Redis backup resource name using the form:
//     `projects/{project_id}/locations/{location_id}/backupCollections/{backup_co
//     llection_id}/backups/{backup_id}`.
func (r *ProjectsLocationsBackupCollectionsBackupsService) Delete(name string) *ProjectsLocationsBackupCollectionsBackupsDeleteCall {
	c := &ProjectsLocationsBackupCollectionsBackupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// RequestId sets the optional parameter "requestId": Idempotent request UUID.
func (c *ProjectsLocationsBackupCollectionsBackupsDeleteCall) RequestId(requestId string) *ProjectsLocationsBackupCollectionsBackupsDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsBackupCollectionsBackupsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsBackupCollectionsBackupsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsBackupCollectionsBackupsDeleteCall) Context(ctx context.Context) *ProjectsLocationsBackupCollectionsBackupsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsBackupCollectionsBackupsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsBackupCollectionsBackupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.backups.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.backupCollections.backups.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsBackupCollectionsBackupsDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.backups.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsBackupCollectionsBackupsExportCall struct {
	s                   *Service
	name                string
	exportbackuprequest *ExportBackupRequest
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// Export: Exports a specific backup to a customer target Cloud Storage URI.
//
//   - name: Redis backup resource name using the form:
//     `projects/{project_id}/locations/{location_id}/backupCollections/{backup_co
//     llection_id}/backups/{backup_id}`.
func (r *ProjectsLocationsBackupCollectionsBackupsService) Export(name string, exportbackuprequest *ExportBackupRequest) *ProjectsLocationsBackupCollectionsBackupsExportCall {
	c := &ProjectsLocationsBackupCollectionsBackupsExportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.exportbackuprequest = exportbackuprequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsBackupCollectionsBackupsExportCall) Fields(s ...googleapi.Field) *ProjectsLocationsBackupCollectionsBackupsExportCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsBackupCollectionsBackupsExportCall) Context(ctx context.Context) *ProjectsLocationsBackupCollectionsBackupsExportCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsBackupCollectionsBackupsExportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsBackupCollectionsBackupsExportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.exportbackuprequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:export")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.backups.export", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.backupCollections.backups.export" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsBackupCollectionsBackupsExportCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.backups.export", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsBackupCollectionsBackupsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the details of a specific backup.
//
//   - name: Redis backup resource name using the form:
//     `projects/{project_id}/locations/{location_id}/backupCollections/{backup_co
//     llection_id}/backups/{backup_id}`.
func (r *ProjectsLocationsBackupCollectionsBackupsService) Get(name string) *ProjectsLocationsBackupCollectionsBackupsGetCall {
	c := &ProjectsLocationsBackupCollectionsBackupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsBackupCollectionsBackupsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsBackupCollectionsBackupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsBackupCollectionsBackupsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsBackupCollectionsBackupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsBackupCollectionsBackupsGetCall) Context(ctx context.Context) *ProjectsLocationsBackupCollectionsBackupsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsBackupCollectionsBackupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsBackupCollectionsBackupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.backups.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.backupCollections.backups.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *Backup.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsBackupCollectionsBackupsGetCall) Do(opts ...googleapi.CallOption) (*Backup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Backup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.backups.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsBackupCollectionsBackupsListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all backups owned by a backup collection.
//
//   - parent: The resource name of the backupCollection using the form:
//     `projects/{project_id}/locations/{location_id}/backupCollections/{backup_co
//     llection_id}`.
func (r *ProjectsLocationsBackupCollectionsBackupsService) List(parent string) *ProjectsLocationsBackupCollectionsBackupsListCall {
	c := &ProjectsLocationsBackupCollectionsBackupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of items
// to return. If not specified, a default value of 1000 will be used by the
// service. Regardless of the page_size value, the response may include a
// partial list and a caller should only rely on response's `next_page_token`
// to determine if there are more clusters left to be queried.
func (c *ProjectsLocationsBackupCollectionsBackupsListCall) PageSize(pageSize int64) *ProjectsLocationsBackupCollectionsBackupsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The `next_page_token`
// value returned from a previous [ListBackupCollections] request, if any.
func (c *ProjectsLocationsBackupCollectionsBackupsListCall) PageToken(pageToken string) *ProjectsLocationsBackupCollectionsBackupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsBackupCollectionsBackupsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsBackupCollectionsBackupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsBackupCollectionsBackupsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsBackupCollectionsBackupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsBackupCollectionsBackupsListCall) Context(ctx context.Context) *ProjectsLocationsBackupCollectionsBackupsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsBackupCollectionsBackupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsBackupCollectionsBackupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/backups")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.backups.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.backupCollections.backups.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListBackupsResponse.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsBackupCollectionsBackupsListCall) Do(opts ...googleapi.CallOption) (*ListBackupsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &ListBackupsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.backupCollections.backups.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsBackupCollectionsBackupsListCall) Pages(ctx context.Context, f func(*ListBackupsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

type ProjectsLocationsClustersBackupCall struct {
	s                    *Service
	name                 string
	backupclusterrequest *BackupClusterRequest
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Backup: Backup Redis Cluster. If this is the first time a backup is being
// created, a backup collection will be created at the backend, and this backup
// belongs to this collection. Both collection and backup will have a resource
// name. Backup will be executed for each shard. A replica (primary if nonHA)
// will be selected to perform the execution. Backup call will be rejected if
// there is an ongoing backup or update operation. Be aware that during
// preview, if the cluster's internal software version is too old, critical
// update will be performed before actual backup. Once the internal software
// version is updated to the minimum version required by the backup feature,
// subsequent backups will not require critical update. After preview, there
// will be no critical update needed for backup.
//
//   - name: Redis cluster resource name using the form:
//     `projects/{project_id}/locations/{location_id}/clusters/{cluster_id}`
//     where `location_id` refers to a Google Cloud region.
func (r *ProjectsLocationsClustersService) Backup(name string, backupclusterrequest *BackupClusterRequest) *ProjectsLocationsClustersBackupCall {
	c := &ProjectsLocationsClustersBackupCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.backupclusterrequest = backupclusterrequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsClustersBackupCall) Fields(s ...googleapi.Field) *ProjectsLocationsClustersBackupCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsClustersBackupCall) Context(ctx context.Context) *ProjectsLocationsClustersBackupCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsClustersBackupCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsClustersBackupCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.backupclusterrequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:backup")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.backup", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.clusters.backup" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsClustersBackupCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.backup", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsClustersCreateCall struct {
	s          *Service
	parent     string
	cluster    *Cluster
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a Redis cluster based on the specified properties. The
// creation is executed asynchronously and callers may check the returned
// operation to track its progress. Once the operation is completed the Redis
// cluster will be fully functional. The completed longrunning.Operation will
// contain the new cluster object in the response field. The returned operation
// is automatically deleted after a few hours, so there is no need to call
// DeleteOperation.
//
//   - parent: The resource name of the cluster location using the form:
//     `projects/{project_id}/locations/{location_id}` where `location_id` refers
//     to a Google Cloud region.
func (r *ProjectsLocationsClustersService) Create(parent string, cluster *Cluster) *ProjectsLocationsClustersCreateCall {
	c := &ProjectsLocationsClustersCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.cluster = cluster
	return c
}

// ClusterId sets the optional parameter "clusterId": Required. The logical
// name of the Redis cluster in the customer project with the following
// restrictions: * Must contain only lowercase letters, numbers, and hyphens. *
// Must start with a letter. * Must be between 1-63 characters. * Must end with
// a number or a letter. * Must be unique within the customer project /
// location
func (c *ProjectsLocationsClustersCreateCall) ClusterId(clusterId string) *ProjectsLocationsClustersCreateCall {
	c.urlParams_.Set("clusterId", clusterId)
	return c
}

// RequestId sets the optional parameter "requestId": Idempotent request UUID.
func (c *ProjectsLocationsClustersCreateCall) RequestId(requestId string) *ProjectsLocationsClustersCreateCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsClustersCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsClustersCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsClustersCreateCall) Context(ctx context.Context) *ProjectsLocationsClustersCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsClustersCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsClustersCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.cluster)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/clusters")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.clusters.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsClustersCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsClustersDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a specific Redis cluster. Cluster stops serving and data is
// deleted.
//
//   - name: Redis cluster resource name using the form:
//     `projects/{project_id}/locations/{location_id}/clusters/{cluster_id}`
//     where `location_id` refers to a Google Cloud region.
func (r *ProjectsLocationsClustersService) Delete(name string) *ProjectsLocationsClustersDeleteCall {
	c := &ProjectsLocationsClustersDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// RequestId sets the optional parameter "requestId": Idempotent request UUID.
func (c *ProjectsLocationsClustersDeleteCall) RequestId(requestId string) *ProjectsLocationsClustersDeleteCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsClustersDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsClustersDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsClustersDeleteCall) Context(ctx context.Context) *ProjectsLocationsClustersDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsClustersDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsClustersDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.clusters.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsClustersDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsClustersGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the details of a specific Redis cluster.
//
//   - name: Redis cluster resource name using the form:
//     `projects/{project_id}/locations/{location_id}/clusters/{cluster_id}`
//     where `location_id` refers to a Google Cloud region.
func (r *ProjectsLocationsClustersService) Get(name string) *ProjectsLocationsClustersGetCall {
	c := &ProjectsLocationsClustersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsClustersGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsClustersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsClustersGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsClustersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsClustersGetCall) Context(ctx context.Context) *ProjectsLocationsClustersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsClustersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsClustersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.clusters.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *Cluster.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsClustersGetCall) Do(opts ...googleapi.CallOption) (*Cluster, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Cluster{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsClustersGetCertificateAuthorityCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetCertificateAuthority: Gets the details of certificate authority
// information for Redis cluster.
//
//   - name: Redis cluster certificate authority resource name using the form:
//     `projects/{project_id}/locations/{location_id}/clusters/{cluster_id}/certif
//     icateAuthority` where `location_id` refers to a Google Cloud region.
func (r *ProjectsLocationsClustersService) GetCertificateAuthority(name string) *ProjectsLocationsClustersGetCertificateAuthorityCall {
	c := &ProjectsLocationsClustersGetCertificateAuthorityCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsClustersGetCertificateAuthorityCall) Fields(s ...googleapi.Field) *ProjectsLocationsClustersGetCertificateAuthorityCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsClustersGetCertificateAuthorityCall) IfNoneMatch(entityTag string) *ProjectsLocationsClustersGetCertificateAuthorityCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsClustersGetCertificateAuthorityCall) Context(ctx context.Context) *ProjectsLocationsClustersGetCertificateAuthorityCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsClustersGetCertificateAuthorityCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsClustersGetCertificateAuthorityCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.getCertificateAuthority", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.clusters.getCertificateAuthority" call.
// Any non-2xx status code is an error. Response headers are in either
// *CertificateAuthority.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsClustersGetCertificateAuthorityCall) Do(opts ...googleapi.CallOption) (*CertificateAuthority, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &CertificateAuthority{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.getCertificateAuthority", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsClustersListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all Redis clusters owned by a project in either the specified
// location (region) or all locations. The location should have the following
// format: * `projects/{project_id}/locations/{location_id}` If `location_id`
// is specified as `-` (wildcard), then all regions available to the project
// are queried, and the results are aggregated.
//
//   - parent: The resource name of the cluster location using the form:
//     `projects/{project_id}/locations/{location_id}` where `location_id` refers
//     to a Google Cloud region.
func (r *ProjectsLocationsClustersService) List(parent string) *ProjectsLocationsClustersListCall {
	c := &ProjectsLocationsClustersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of items
// to return. If not specified, a default value of 1000 will be used by the
// service. Regardless of the page_size value, the response may include a
// partial list and a caller should only rely on response's `next_page_token`
// to determine if there are more clusters left to be queried.
func (c *ProjectsLocationsClustersListCall) PageSize(pageSize int64) *ProjectsLocationsClustersListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The `next_page_token`
// value returned from a previous ListClusters request, if any.
func (c *ProjectsLocationsClustersListCall) PageToken(pageToken string) *ProjectsLocationsClustersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsClustersListCall) Fields(s ...googleapi.Field) *ProjectsLocationsClustersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsClustersListCall) IfNoneMatch(entityTag string) *ProjectsLocationsClustersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsClustersListCall) Context(ctx context.Context) *ProjectsLocationsClustersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsClustersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsClustersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/clusters")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.clusters.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListClustersResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsClustersListCall) Do(opts ...googleapi.CallOption) (*ListClustersResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &ListClustersResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsClustersListCall) Pages(ctx context.Context, f func(*ListClustersResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

type ProjectsLocationsClustersPatchCall struct {
	s          *Service
	name       string
	cluster    *Cluster
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates the metadata and configuration of a specific Redis cluster.
// Completed longrunning.Operation will contain the new cluster object in the
// response field. The returned operation is automatically deleted after a few
// hours, so there is no need to call DeleteOperation.
//
//   - name: Identifier. Unique name of the resource in this scope including
//     project and location using the form:
//     `projects/{project_id}/locations/{location_id}/clusters/{cluster_id}`.
func (r *ProjectsLocationsClustersService) Patch(name string, cluster *Cluster) *ProjectsLocationsClustersPatchCall {
	c := &ProjectsLocationsClustersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.cluster = cluster
	return c
}

// RequestId sets the optional parameter "requestId": Idempotent request UUID.
func (c *ProjectsLocationsClustersPatchCall) RequestId(requestId string) *ProjectsLocationsClustersPatchCall {
	c.urlParams_.Set("requestId", requestId)
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. Mask of
// fields to update. At least one path must be supplied in this field. The
// elements of the repeated paths field may only include these fields from
// Cluster: * `size_gb` * `replica_count` * `cluster_endpoints`
func (c *ProjectsLocationsClustersPatchCall) UpdateMask(updateMask string) *ProjectsLocationsClustersPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsClustersPatchCall) Fields(s ...googleapi.Field) *ProjectsLocationsClustersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsClustersPatchCall) Context(ctx context.Context) *ProjectsLocationsClustersPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsClustersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsClustersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.cluster)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.clusters.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsClustersPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsClustersRescheduleClusterMaintenanceCall struct {
	s                                   *Service
	name                                string
	rescheduleclustermaintenancerequest *RescheduleClusterMaintenanceRequest
	urlParams_                          gensupport.URLParams
	ctx_                                context.Context
	header_                             http.Header
}

// RescheduleClusterMaintenance: Reschedules upcoming maintenance event.
//
//   - name: Redis Cluster instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/clusters/{cluster_id}`
//     where `location_id` refers to a Google Cloud region.
func (r *ProjectsLocationsClustersService) RescheduleClusterMaintenance(name string, rescheduleclustermaintenancerequest *RescheduleClusterMaintenanceRequest) *ProjectsLocationsClustersRescheduleClusterMaintenanceCall {
	c := &ProjectsLocationsClustersRescheduleClusterMaintenanceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.rescheduleclustermaintenancerequest = rescheduleclustermaintenancerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsClustersRescheduleClusterMaintenanceCall) Fields(s ...googleapi.Field) *ProjectsLocationsClustersRescheduleClusterMaintenanceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsClustersRescheduleClusterMaintenanceCall) Context(ctx context.Context) *ProjectsLocationsClustersRescheduleClusterMaintenanceCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsClustersRescheduleClusterMaintenanceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsClustersRescheduleClusterMaintenanceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.rescheduleclustermaintenancerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:rescheduleClusterMaintenance")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.rescheduleClusterMaintenance", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.clusters.rescheduleClusterMaintenance" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsClustersRescheduleClusterMaintenanceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.clusters.rescheduleClusterMaintenance", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesCreateCall struct {
	s          *Service
	parent     string
	instance   *Instance
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Create: Creates a Redis instance based on the specified tier and memory
// size. By default, the instance is accessible from the project's default
// network (https://cloud.google.com/vpc/docs/vpc). The creation is executed
// asynchronously and callers may check the returned operation to track its
// progress. Once the operation is completed the Redis instance will be fully
// functional. Completed longrunning.Operation will contain the new instance
// object in the response field. The returned operation is automatically
// deleted after a few hours, so there is no need to call DeleteOperation.
//
//   - parent: The resource name of the instance location using the form:
//     `projects/{project_id}/locations/{location_id}` where `location_id` refers
//     to a GCP region.
func (r *ProjectsLocationsInstancesService) Create(parent string, instance *Instance) *ProjectsLocationsInstancesCreateCall {
	c := &ProjectsLocationsInstancesCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.instance = instance
	return c
}

// InstanceId sets the optional parameter "instanceId": Required. The logical
// name of the Redis instance in the customer project with the following
// restrictions: * Must contain only lowercase letters, numbers, and hyphens. *
// Must start with a letter. * Must be between 1-40 characters. * Must end with
// a number or a letter. * Must be unique within the customer project /
// location
func (c *ProjectsLocationsInstancesCreateCall) InstanceId(instanceId string) *ProjectsLocationsInstancesCreateCall {
	c.urlParams_.Set("instanceId", instanceId)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesCreateCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesCreateCall) Context(ctx context.Context) *ProjectsLocationsInstancesCreateCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesCreateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.instance)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/instances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.create", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.create" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesCreateCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.create", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a specific Redis instance. Instance stops serving and data
// is deleted.
//
//   - name: Redis instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     where `location_id` refers to a GCP region.
func (r *ProjectsLocationsInstancesService) Delete(name string) *ProjectsLocationsInstancesDeleteCall {
	c := &ProjectsLocationsInstancesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesDeleteCall) Context(ctx context.Context) *ProjectsLocationsInstancesDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesDeleteCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesExportCall struct {
	s                     *Service
	name                  string
	exportinstancerequest *ExportInstanceRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Export: Export Redis instance data into a Redis RDB format file in Cloud
// Storage. Redis will continue serving during this operation. The returned
// operation is automatically deleted after a few hours, so there is no need to
// call DeleteOperation.
//
//   - name: Redis instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     where `location_id` refers to a GCP region.
func (r *ProjectsLocationsInstancesService) Export(name string, exportinstancerequest *ExportInstanceRequest) *ProjectsLocationsInstancesExportCall {
	c := &ProjectsLocationsInstancesExportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.exportinstancerequest = exportinstancerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesExportCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesExportCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesExportCall) Context(ctx context.Context) *ProjectsLocationsInstancesExportCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesExportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesExportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.exportinstancerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:export")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.export", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.export" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesExportCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.export", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesFailoverCall struct {
	s                       *Service
	name                    string
	failoverinstancerequest *FailoverInstanceRequest
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Failover: Initiates a failover of the primary node to current replica node
// for a specific STANDARD tier Cloud Memorystore for Redis instance.
//
//   - name: Redis instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     where `location_id` refers to a GCP region.
func (r *ProjectsLocationsInstancesService) Failover(name string, failoverinstancerequest *FailoverInstanceRequest) *ProjectsLocationsInstancesFailoverCall {
	c := &ProjectsLocationsInstancesFailoverCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.failoverinstancerequest = failoverinstancerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesFailoverCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesFailoverCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesFailoverCall) Context(ctx context.Context) *ProjectsLocationsInstancesFailoverCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesFailoverCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesFailoverCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.failoverinstancerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:failover")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.failover", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.failover" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesFailoverCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.failover", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the details of a specific Redis instance.
//
//   - name: Redis instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     where `location_id` refers to a GCP region.
func (r *ProjectsLocationsInstancesService) Get(name string) *ProjectsLocationsInstancesGetCall {
	c := &ProjectsLocationsInstancesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsInstancesGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsInstancesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesGetCall) Context(ctx context.Context) *ProjectsLocationsInstancesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *Instance.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesGetCall) Do(opts ...googleapi.CallOption) (*Instance, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Instance{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesGetAuthStringCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// GetAuthString: Gets the AUTH string for a Redis instance. If AUTH is not
// enabled for the instance the response will be empty. This information is not
// included in the details returned to GetInstance.
//
//   - name: Redis instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     where `location_id` refers to a GCP region.
func (r *ProjectsLocationsInstancesService) GetAuthString(name string) *ProjectsLocationsInstancesGetAuthStringCall {
	c := &ProjectsLocationsInstancesGetAuthStringCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesGetAuthStringCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesGetAuthStringCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsInstancesGetAuthStringCall) IfNoneMatch(entityTag string) *ProjectsLocationsInstancesGetAuthStringCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesGetAuthStringCall) Context(ctx context.Context) *ProjectsLocationsInstancesGetAuthStringCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesGetAuthStringCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesGetAuthStringCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/authString")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.getAuthString", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.getAuthString" call.
// Any non-2xx status code is an error. Response headers are in either
// *InstanceAuthString.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsInstancesGetAuthStringCall) Do(opts ...googleapi.CallOption) (*InstanceAuthString, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &InstanceAuthString{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.getAuthString", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesImportCall struct {
	s                     *Service
	name                  string
	importinstancerequest *ImportInstanceRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
	header_               http.Header
}

// Import: Import a Redis RDB snapshot file from Cloud Storage into a Redis
// instance. Redis may stop serving during this operation. Instance state will
// be IMPORTING for entire operation. When complete, the instance will contain
// only data from the imported file. The returned operation is automatically
// deleted after a few hours, so there is no need to call DeleteOperation.
//
//   - name: Redis instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     where `location_id` refers to a GCP region.
func (r *ProjectsLocationsInstancesService) Import(name string, importinstancerequest *ImportInstanceRequest) *ProjectsLocationsInstancesImportCall {
	c := &ProjectsLocationsInstancesImportCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.importinstancerequest = importinstancerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesImportCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesImportCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesImportCall) Context(ctx context.Context) *ProjectsLocationsInstancesImportCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesImportCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesImportCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.importinstancerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:import")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.import", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.import" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesImportCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.import", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesListCall struct {
	s            *Service
	parent       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists all Redis instances owned by a project in either the specified
// location (region) or all locations. The location should have the following
// format: * `projects/{project_id}/locations/{location_id}` If `location_id`
// is specified as `-` (wildcard), then all regions available to the project
// are queried, and the results are aggregated.
//
//   - parent: The resource name of the instance location using the form:
//     `projects/{project_id}/locations/{location_id}` where `location_id` refers
//     to a GCP region.
func (r *ProjectsLocationsInstancesService) List(parent string) *ProjectsLocationsInstancesListCall {
	c := &ProjectsLocationsInstancesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number of items
// to return. If not specified, a default value of 1000 will be used by the
// service. Regardless of the page_size value, the response may include a
// partial list and a caller should only rely on response's `next_page_token`
// to determine if there are more instances left to be queried.
func (c *ProjectsLocationsInstancesListCall) PageSize(pageSize int64) *ProjectsLocationsInstancesListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The `next_page_token`
// value returned from a previous ListInstances request, if any.
func (c *ProjectsLocationsInstancesListCall) PageToken(pageToken string) *ProjectsLocationsInstancesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesListCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsInstancesListCall) IfNoneMatch(entityTag string) *ProjectsLocationsInstancesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesListCall) Context(ctx context.Context) *ProjectsLocationsInstancesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/instances")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListInstancesResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsInstancesListCall) Do(opts ...googleapi.CallOption) (*ListInstancesResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &ListInstancesResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsInstancesListCall) Pages(ctx context.Context, f func(*ListInstancesResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

type ProjectsLocationsInstancesPatchCall struct {
	s          *Service
	name       string
	instance   *Instance
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Patch: Updates the metadata and configuration of a specific Redis instance.
// Completed longrunning.Operation will contain the new instance object in the
// response field. The returned operation is automatically deleted after a few
// hours, so there is no need to call DeleteOperation.
//
//   - name: Unique name of the resource in this scope including project and
//     location using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     Note: Redis instances are managed and addressed at regional level so
//     location_id here refers to a GCP region; however, users may choose which
//     specific zone (or collection of zones for cross-zone instances) an
//     instance should be provisioned in. Refer to location_id and
//     alternative_location_id fields for more details.
func (r *ProjectsLocationsInstancesService) Patch(name string, instance *Instance) *ProjectsLocationsInstancesPatchCall {
	c := &ProjectsLocationsInstancesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.instance = instance
	return c
}

// UpdateMask sets the optional parameter "updateMask": Required. Mask of
// fields to update. At least one path must be supplied in this field. The
// elements of the repeated paths field may only include these fields from
// Instance: * `displayName` * `labels` * `memorySizeGb` * `redisConfig` *
// `replica_count`
func (c *ProjectsLocationsInstancesPatchCall) UpdateMask(updateMask string) *ProjectsLocationsInstancesPatchCall {
	c.urlParams_.Set("updateMask", updateMask)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesPatchCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesPatchCall) Context(ctx context.Context) *ProjectsLocationsInstancesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.instance)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.patch", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.patch" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesPatchCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.patch", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesRescheduleMaintenanceCall struct {
	s                            *Service
	name                         string
	reschedulemaintenancerequest *RescheduleMaintenanceRequest
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// RescheduleMaintenance: Reschedule maintenance for a given instance in a
// given project and location.
//
//   - name: Redis instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     where `location_id` refers to a GCP region.
func (r *ProjectsLocationsInstancesService) RescheduleMaintenance(name string, reschedulemaintenancerequest *RescheduleMaintenanceRequest) *ProjectsLocationsInstancesRescheduleMaintenanceCall {
	c := &ProjectsLocationsInstancesRescheduleMaintenanceCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.reschedulemaintenancerequest = reschedulemaintenancerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesRescheduleMaintenanceCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesRescheduleMaintenanceCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesRescheduleMaintenanceCall) Context(ctx context.Context) *ProjectsLocationsInstancesRescheduleMaintenanceCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesRescheduleMaintenanceCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesRescheduleMaintenanceCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.reschedulemaintenancerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:rescheduleMaintenance")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.rescheduleMaintenance", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.rescheduleMaintenance" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesRescheduleMaintenanceCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.rescheduleMaintenance", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsInstancesUpgradeCall struct {
	s                      *Service
	name                   string
	upgradeinstancerequest *UpgradeInstanceRequest
	urlParams_             gensupport.URLParams
	ctx_                   context.Context
	header_                http.Header
}

// Upgrade: Upgrades Redis instance to the newer Redis version specified in the
// request.
//
//   - name: Redis instance resource name using the form:
//     `projects/{project_id}/locations/{location_id}/instances/{instance_id}`
//     where `location_id` refers to a GCP region.
func (r *ProjectsLocationsInstancesService) Upgrade(name string, upgradeinstancerequest *UpgradeInstanceRequest) *ProjectsLocationsInstancesUpgradeCall {
	c := &ProjectsLocationsInstancesUpgradeCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.upgradeinstancerequest = upgradeinstancerequest
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsInstancesUpgradeCall) Fields(s ...googleapi.Field) *ProjectsLocationsInstancesUpgradeCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsInstancesUpgradeCall) Context(ctx context.Context) *ProjectsLocationsInstancesUpgradeCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsInstancesUpgradeCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsInstancesUpgradeCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "application/json", c.header_)
	body, err := googleapi.WithoutDataWrapper.JSONBuffer(c.upgradeinstancerequest)
	if err != nil {
		return nil, err
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:upgrade")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.upgrade", "request", internallog.HTTPRequest(req, body.Bytes()))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.instances.upgrade" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsInstancesUpgradeCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.instances.upgrade", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsOperationsCancelCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Cancel: Starts asynchronous cancellation on a long-running operation. The
// server makes a best effort to cancel the operation, but success is not
// guaranteed. If the server doesn't support this method, it returns
// `google.rpc.Code.UNIMPLEMENTED`. Clients can use Operations.GetOperation or
// other methods to check whether the cancellation succeeded or whether the
// operation completed despite cancellation. On successful cancellation, the
// operation is not deleted; instead, it becomes an operation with an
// Operation.error value with a google.rpc.Status.code of `1`, corresponding to
// `Code.CANCELLED`.
//
// - name: The name of the operation resource to be cancelled.
func (r *ProjectsLocationsOperationsService) Cancel(name string) *ProjectsLocationsOperationsCancelCall {
	c := &ProjectsLocationsOperationsCancelCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsOperationsCancelCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsCancelCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsOperationsCancelCall) Context(ctx context.Context) *ProjectsLocationsOperationsCancelCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsOperationsCancelCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsCancelCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}:cancel")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.operations.cancel", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.operations.cancel" call.
// Any non-2xx status code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsOperationsCancelCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.operations.cancel", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsOperationsDeleteCall struct {
	s          *Service
	name       string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes a long-running operation. This method indicates that the
// client is no longer interested in the operation result. It does not cancel
// the operation. If the server doesn't support this method, it returns
// `google.rpc.Code.UNIMPLEMENTED`.
//
// - name: The name of the operation resource to be deleted.
func (r *ProjectsLocationsOperationsService) Delete(name string) *ProjectsLocationsOperationsDeleteCall {
	c := &ProjectsLocationsOperationsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsOperationsDeleteCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsOperationsDeleteCall) Context(ctx context.Context) *ProjectsLocationsOperationsDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsOperationsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.operations.delete", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.operations.delete" call.
// Any non-2xx status code is an error. Response headers are in either
// *Empty.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsOperationsDeleteCall) Do(opts ...googleapi.CallOption) (*Empty, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Empty{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.operations.delete", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsOperationsGetCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets the latest state of a long-running operation. Clients can use this
// method to poll the operation result at intervals as recommended by the API
// service.
//
// - name: The name of the operation resource.
func (r *ProjectsLocationsOperationsService) Get(name string) *ProjectsLocationsOperationsGetCall {
	c := &ProjectsLocationsOperationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsOperationsGetCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsOperationsGetCall) IfNoneMatch(entityTag string) *ProjectsLocationsOperationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsOperationsGetCall) Context(ctx context.Context) *ProjectsLocationsOperationsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsOperationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.operations.get", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.operations.get" call.
// Any non-2xx status code is an error. Response headers are in either
// *Operation.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was returned.
func (c *ProjectsLocationsOperationsGetCall) Do(opts ...googleapi.CallOption) (*Operation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &Operation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.operations.get", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

type ProjectsLocationsOperationsListCall struct {
	s            *Service
	name         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists operations that match the specified filter in the request. If
// the server doesn't support this method, it returns `UNIMPLEMENTED`.
//
// - name: The name of the operation's parent resource.
func (r *ProjectsLocationsOperationsService) List(name string) *ProjectsLocationsOperationsListCall {
	c := &ProjectsLocationsOperationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Filter sets the optional parameter "filter": The standard list filter.
func (c *ProjectsLocationsOperationsListCall) Filter(filter string) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("filter", filter)
	return c
}

// PageSize sets the optional parameter "pageSize": The standard list page
// size.
func (c *ProjectsLocationsOperationsListCall) PageSize(pageSize int64) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The standard list page
// token.
func (c *ProjectsLocationsOperationsListCall) PageToken(pageToken string) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ReturnPartialSuccess sets the optional parameter "returnPartialSuccess":
// When set to `true`, operations that are reachable are returned as normal,
// and those that are unreachable are returned in the
// ListOperationsResponse.unreachable field. This can only be `true` when
// reading across collections. For example, when `parent` is set to
// "projects/example/locations/-". This field is not supported by default and
// will result in an `UNIMPLEMENTED` error if set unless explicitly documented
// otherwise in service or product specific documentation.
func (c *ProjectsLocationsOperationsListCall) ReturnPartialSuccess(returnPartialSuccess bool) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("returnPartialSuccess", fmt.Sprint(returnPartialSuccess))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse for more
// details.
func (c *ProjectsLocationsOperationsListCall) Fields(s ...googleapi.Field) *ProjectsLocationsOperationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets an optional parameter which makes the operation fail if the
// object's ETag matches the given value. This is useful for getting updates
// only after the object has changed since the last request.
func (c *ProjectsLocationsOperationsListCall) IfNoneMatch(entityTag string) *ProjectsLocationsOperationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method.
func (c *ProjectsLocationsOperationsListCall) Context(ctx context.Context) *ProjectsLocationsOperationsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns a http.Header that can be modified by the caller to add
// headers to the request.
func (c *ProjectsLocationsOperationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsLocationsOperationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := gensupport.SetHeaders(c.s.userAgent(), "", c.header_)
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+name}/operations")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, nil)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	c.s.logger.DebugContext(c.ctx_, "api request", "serviceName", apiName, "rpcName", "redis.projects.locations.operations.list", "request", internallog.HTTPRequest(req, nil))
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "redis.projects.locations.operations.list" call.
// Any non-2xx status code is an error. Response headers are in either
// *ListOperationsResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified was
// returned.
func (c *ProjectsLocationsOperationsListCall) Do(opts ...googleapi.CallOption) (*ListOperationsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, gensupport.WrapError(&googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		})
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, gensupport.WrapError(err)
	}
	ret := &ListOperationsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	b, err := gensupport.DecodeResponseBytes(target, res)
	if err != nil {
		return nil, err
	}
	c.s.logger.DebugContext(c.ctx_, "api response", "serviceName", apiName, "rpcName", "redis.projects.locations.operations.list", "response", internallog.HTTPResponse(res, b))
	return ret, nil
}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ProjectsLocationsOperationsListCall) Pages(ctx context.Context, f func(*ListOperationsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken"))
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}
