Skip to content
This repository was archived by the owner on May 30, 2025. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions apis/database/v1beta1/cloudsql_instance_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ type CloudSQLInstanceParameters struct {
// the suspension.
// +optional
SuspensionReason []string `json:"suspensionReason,omitempty"`

// Read-replica configuration for connecting to the primary instance.
// +optional
ReplicaConfiguration *ReplicaConfiguration `json:"replicaConfiguration,omitempty"`
}

// Settings is Cloud SQL database instance settings.
Expand Down Expand Up @@ -408,6 +412,86 @@ type OnPremisesConfiguration struct {
HostPort string `json:"hostPort"`
}

// ReplicaConfiguration Read-replica configuration for connecting to the primary instance.
type ReplicaConfiguration struct {
// FailoverTarget: Specifies if the replica is the failover target. If
// the field is set to *true* the replica will be designated as a
// failover replica.
// +optional
FailoverTarget *bool `json:"failoverTarget,omitempty"`

// MysqlReplicaConfiguration: MySQL specific configuration when
// replicating from a MySQL on-premises primary instance. Replication
// configuration information such as the username, password,
// certificates, and keys are not stored in the instance metadata. The
// configuration information is used only to set up the replication
// connection and is stored by MySQL in a file named **master.info** in
// the data directory.
// +optional
MysqlReplicaConfiguration *MySqlReplicaConfiguration `json:"mysqlReplicaConfiguration,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a possibility that other database types could be supported in the future? Asking because on terraform side no dedicated parameter for Mysql, rather there is only a note that replica_configuration is only valid for mysql:
https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance#ca_certificate

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
MysqlReplicaConfiguration *MySqlReplicaConfiguration `json:"mysqlReplicaConfiguration,omitempty"`
MySQLReplicaConfiguration *MySQLReplicaConfiguration `json:"mySQLReplicaConfiguration,omitempty"`

}

// MySqlReplicaConfiguration: Read-replica configuration specific to
// MySQL databases. https://cloud.google.com/sql/docs/mysql/admin-api/rest/v1/instances#ReplicaConfiguration
type MySqlReplicaConfiguration struct {

// SecretRef: Kubernetes Secret containing all credentials for MySqlReplicaConfiguration
// +optional
SecretRef *xpv1.SecretReference `json:"secretRef,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of putting all configurations in a secret and receiving which parameter represented by which key, I would suggest to have separate fields for sensitive ones. For example:

PasswordSecretRef *v1.SecretKeySelector `json:"passwordSecretRef,omitempty" tf:"-"`

This would still allow us to keep all information in a single secret but would be more explicit and flexible, for example, client cert key can be in secret A but ca cert can be in secret B.

And we can keep non sensitive ones, e.g. username, simply in spec. For public keys, I am a bit unsure though, since even it is not sensitive, I believe would be hard to maintain in the spec.

Copy link
Author

@mcbenjemaa mcbenjemaa Jan 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely that's great.
But, I'm wondering about controller implementation.

This will end up checking each secretRef provided and fetch it accordingly,
thinking about, in each reconciliation loop, the controller will fetch those secrets as user provided.
Isn't a bit noisy... (for controller perspective, as this will be implemented in the Observe())

Copy link
Contributor

@turkenh turkenh Jan 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's a good point.

However, controller runtime's caching would help with this and we won't (really) fetch those secrets (or that secret, if all put into 1 with different keys) in each reconcile from API Server.


// CaCertificateKey: key in the secret representing PEM representation of the trusted CA's x509
// certificate.
// +optional
CaCertificateKey *string `json:"caCertificateKey,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
CaCertificateKey *string `json:"caCertificateKey,omitempty"`
CACertificateKey *string `json:"caCertificateKey,omitempty"`


// ClientCertificateKey: key in the secret representing PEM representation of the replica's x509
// certificate.
// +optional
ClientCertificateKey *string `json:"clientCertificateKey,omitempty"`

// ClientKey: key in the secret representing PEM representation of the replica's private key. The
// corresponsing public key is encoded in the client's certificate.
// +optional
ClientKey *string `json:"clientKey,omitempty"`

// ConnectRetryInterval: Seconds to wait between connect retries.
// MySQL's default is 60 seconds.
// +optional
ConnectRetryInterval *int64 `json:"connectRetryInterval,omitempty"`

// DumpFilePath: Path to a SQL dump file in Google Cloud Storage from
// which the replica instance is to be created. The URI is in the form
// gs://bucketName/fileName. Compressed gzip files (.gz) are also
// supported. Dumps have the binlog co-ordinates from which replication
// begins. This can be accomplished by setting --master-data to 1 when
// using mysqldump.
// +optional
DumpFilePath *string `json:"dumpFilePath,omitempty"`

// MasterHeartbeatPeriod: Interval in milliseconds between replication
// heartbeats.
// +optional
MasterHeartbeatPeriod *int64 `json:"masterHeartbeatPeriod,omitempty"`

// Password: key in the secret representing the password for the replication connection.
// +optional
PasswordKey *string `json:"passwordKey,omitempty"`

// SslCipher: A list of permissible ciphers to use for SSL encryption.
// +optional
SslCipher *string `json:"sslCipher,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
SslCipher *string `json:"sslCipher,omitempty"`
SSLCipher *string `json:"sslCipher,omitempty"`


// Username: key in the secret representing the username for the replication connection.
// +optional
UsernameKey *string `json:"usernameKey,omitempty"`

// VerifyServerCertificate: Whether or not to check the primary
// instance's Common Name value in the certificate that it sends during
// the SSL handshake.
// +optional
VerifyServerCertificate *bool `json:"verifyServerCertificate,omitempty"`
}

// CloudSQLInstanceObservation is used to show the observed state of the Cloud SQL resource on GCP.
type CloudSQLInstanceObservation struct {
// BackendType: FIRST_GEN: First Generation instance. MySQL
Expand Down
21 changes: 21 additions & 0 deletions examples/database/cloudsql_mysql.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: database.gcp.crossplane.io/v1beta1
kind: CloudSQLInstance
metadata:
name: mysql-instance
spec:
forProvider:
databaseVersion: MYSQL_5_7
region: us-west2
replicaNames:
- "mysql-replica"
settings:
tier: db-custom-1-3840
dataDiskSizeGb: 20
backupConfiguration:
binaryLogEnabled: true
enabled: true
providerConfigRef:
name: default
writeConnectionSecretToRef:
name: example-cloudsql-connection-details
namespace: crossplane-system
25 changes: 25 additions & 0 deletions examples/database/cloudsql_mysql_replica.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: database.gcp.crossplane.io/v1beta1
kind: CloudSQLInstance
metadata:
name: mysql-replica
spec:
forProvider:
databaseVersion: MYSQL_5_7
region: us-west2
settings:
tier: db-custom-1-3840
dataDiskSizeGb: 20
masterInstanceName: mysql-instance
replicaConfiguration:
failoverTarget: false
mysqlReplicaConfiguration:
secretRef:
name: cloudsql-replica-creds
namespace: default
usernameKey: "username"
passwordKey: "password"
Comment on lines +15 to +20
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned in the previous comment, by convention, the following API is preferable since it is more explicit and flexible:

Suggested change
mysqlReplicaConfiguration:
secretRef:
name: cloudsql-replica-creds
namespace: default
usernameKey: "username"
passwordKey: "password"
mysqlReplicaConfiguration:
username: admin
passwordSecretRef:
name: cloudsql-replica-creds
namespace: default
key: password
caCertificateSecretRef:
name: cloudsql-replica-certs
namespace: default
key: ca.crt
clientCertificateSecretRef:
name: cloudsql-replica-certs
namespace: default
key: tls.crt
clientKeyCertificateSecretRef:
name: cloudsql-replica-certs
namespace: default
key: tls.key

providerConfigRef:
name: default
writeConnectionSecretToRef:
name: example-cloudsql-replica-connection-details
namespace: crossplane-system
85 changes: 85 additions & 0 deletions package/crds/database.gcp.crossplane.io_cloudsqlinstances.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,91 @@ spec:
or Second Generation). The region can not be changed after instance
creation.'
type: string
replicaConfiguration:
description: Read-replica configuration for connecting to the
primary instance.
properties:
failoverTarget:
description: 'FailoverTarget: Specifies if the replica is
the failover target. If the field is set to *true* the replica
will be designated as a failover replica.'
type: boolean
mysqlReplicaConfiguration:
description: 'MysqlReplicaConfiguration: MySQL specific configuration
when replicating from a MySQL on-premises primary instance.
Replication configuration information such as the username,
password, certificates, and keys are not stored in the instance
metadata. The configuration information is used only to
set up the replication connection and is stored by MySQL
in a file named **master.info** in the data directory.'
properties:
caCertificateKey:
description: 'CaCertificateKey: key in the secret representing
PEM representation of the trusted CA''s x509 certificate.'
type: string
clientCertificateKey:
description: 'ClientCertificateKey: key in the secret
representing PEM representation of the replica''s x509
certificate.'
type: string
clientKey:
description: 'ClientKey: key in the secret representing
PEM representation of the replica''s private key. The
corresponsing public key is encoded in the client''s
certificate.'
type: string
connectRetryInterval:
description: 'ConnectRetryInterval: Seconds to wait between
connect retries. MySQL''s default is 60 seconds.'
format: int64
type: integer
dumpFilePath:
description: 'DumpFilePath: Path to a SQL dump file in
Google Cloud Storage from which the replica instance
is to be created. The URI is in the form gs://bucketName/fileName.
Compressed gzip files (.gz) are also supported. Dumps
have the binlog co-ordinates from which replication
begins. This can be accomplished by setting --master-data
to 1 when using mysqldump.'
type: string
masterHeartbeatPeriod:
description: 'MasterHeartbeatPeriod: Interval in milliseconds
between replication heartbeats.'
format: int64
type: integer
passwordKey:
description: 'Password: key in the secret representing
the password for the replication connection.'
type: string
secretRef:
description: 'SecretRef: Kubernetes Secret containing
all credentials for MySqlReplicaConfiguration'
properties:
name:
description: Name of the secret.
type: string
namespace:
description: Namespace of the secret.
type: string
required:
- name
- namespace
type: object
sslCipher:
description: 'SslCipher: A list of permissible ciphers
to use for SSL encryption.'
type: string
usernameKey:
description: 'Username: key in the secret representing
the username for the replication connection.'
type: string
verifyServerCertificate:
description: 'VerifyServerCertificate: Whether or not
to check the primary instance''s Common Name value in
the certificate that it sends during the SSL handshake.'
type: boolean
type: object
type: object
replicaNames:
description: 'ReplicaNames: The replicas of the instance.'
items:
Expand Down
Loading