From feabae5b5f6fcaac9a3e99e23a266fe900ae2834 Mon Sep 17 00:00:00 2001 From: Andrew Jakubowski Date: Fri, 15 Sep 2023 15:14:02 -0700 Subject: [PATCH] Implemented support for TLS and ServerCA handling for cloudmemorystore Signed-off-by: Andrew Jakubowski --- .../cloudmemorystore_instance_types.go | 38 ++++++++++++++++++ apis/cache/v1beta1/zz_generated.deepcopy.go | 25 ++++++++++++ ...ossplane.io_cloudmemorystoreinstances.yaml | 40 +++++++++++++++++++ .../cloudmemorystore/cloudmemorystore.go | 11 +++++ .../cloudmemorystore/cloudmemorystore_test.go | 26 +++++++++++- 5 files changed, 138 insertions(+), 2 deletions(-) diff --git a/apis/cache/v1beta1/cloudmemorystore_instance_types.go b/apis/cache/v1beta1/cloudmemorystore_instance_types.go index 43e57754a..b88e3434d 100644 --- a/apis/cache/v1beta1/cloudmemorystore_instance_types.go +++ b/apis/cache/v1beta1/cloudmemorystore_instance_types.go @@ -38,6 +38,14 @@ type CloudMemorystoreInstanceParameters struct { // +immutable Tier string `json:"tier"` + // TransitEncryptionMode specifies TLS encryption mode for Redis service. + // For TRANSIT_ENCRYPTION_MODE_UNSPECIFIED the TLS in transit encryption is not set. + // If set to SERVER_AUTHENTICATION the client-to-server traffic encryption is enabled. + // Encryption is disabled if the value is DISABLED + // https://cloud.google.com/memorystore/docs/redis/about-in-transit-encryption + // +optional + TransitEncryptionMode *string `json:"transitEncryptionMode,omitempty"` + // Redis memory size in GiB. MemorySizeGB int64 `json:"memorySizeGb"` @@ -135,6 +143,29 @@ type CloudMemorystoreInstanceParameters struct { AuthEnabled *bool `json:"authEnabled,omitempty"` } +// ServerCACertsObservation Observability Resource which is fetched from the hyperscaler +type ServerCACertsObservation struct { + + // Cert is the certificate in the PEM format. + 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"` +} + // CloudMemorystoreInstanceObservation is used to show the observed state of the // CloudMemorystore resource on GCP. type CloudMemorystoreInstanceObservation struct { @@ -195,6 +226,13 @@ type CloudMemorystoreInstanceObservation struct { // for a given instance so should be checked before each import/export // operation. PersistenceIAMIdentity string `json:"persistenceIamIdentity,omitempty"` + + // Status of in tranit encyption mode the redis service is configured with + TransitEncryptionMode string `json:"transitEncryptionMode,omitempty"` + + // ServerCaCerts: Output only. List of server CA certificates for the + // instance. + ServerCaCerts []ServerCACertsObservation `json:"serverCaCerts,omitempty"` } // A CloudMemorystoreInstanceSpec defines the desired state of a diff --git a/apis/cache/v1beta1/zz_generated.deepcopy.go b/apis/cache/v1beta1/zz_generated.deepcopy.go index 410337b5f..850c8adb7 100644 --- a/apis/cache/v1beta1/zz_generated.deepcopy.go +++ b/apis/cache/v1beta1/zz_generated.deepcopy.go @@ -91,6 +91,11 @@ func (in *CloudMemorystoreInstanceObservation) DeepCopyInto(out *CloudMemorystor in, out := &in.CreateTime, &out.CreateTime *out = (*in).DeepCopy() } + if in.ServerCaCerts != nil { + in, out := &in.ServerCaCerts, &out.ServerCaCerts + *out = make([]ServerCACertsObservation, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CloudMemorystoreInstanceObservation. @@ -106,6 +111,11 @@ func (in *CloudMemorystoreInstanceObservation) DeepCopy() *CloudMemorystoreInsta // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CloudMemorystoreInstanceParameters) DeepCopyInto(out *CloudMemorystoreInstanceParameters) { *out = *in + if in.TransitEncryptionMode != nil { + in, out := &in.TransitEncryptionMode, &out.TransitEncryptionMode + *out = new(string) + **out = **in + } if in.DisplayName != nil { in, out := &in.DisplayName, &out.DisplayName *out = new(string) @@ -205,3 +215,18 @@ func (in *CloudMemorystoreInstanceStatus) DeepCopy() *CloudMemorystoreInstanceSt in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerCACertsObservation) DeepCopyInto(out *ServerCACertsObservation) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerCACertsObservation. +func (in *ServerCACertsObservation) DeepCopy() *ServerCACertsObservation { + if in == nil { + return nil + } + out := new(ServerCACertsObservation) + in.DeepCopyInto(out) + return out +} diff --git a/package/crds/cache.gcp.crossplane.io_cloudmemorystoreinstances.yaml b/package/crds/cache.gcp.crossplane.io_cloudmemorystoreinstances.yaml index 597b9c687..b42ddc1d3 100644 --- a/package/crds/cache.gcp.crossplane.io_cloudmemorystoreinstances.yaml +++ b/package/crds/cache.gcp.crossplane.io_cloudmemorystoreinstances.yaml @@ -157,6 +157,13 @@ spec: - BASIC - STANDARD_HA type: string + transitEncryptionMode: + description: TransitEncryptionMode specifies TLS encryption mode + for Redis service. For TRANSIT_ENCRYPTION_MODE_UNSPECIFIED the + TLS in transit encryption is not set. If set to SERVER_AUTHENTICATION + the client-to-server traffic encryption is enabled. Encryption + is disabled if the value is DISABLED https://cloud.google.com/memorystore/docs/redis/about-in-transit-encryption + type: string required: - memorySizeGb - region @@ -375,6 +382,35 @@ spec: description: The port number of the exposed Redis endpoint. format: int64 type: integer + serverCaCerts: + description: 'ServerCaCerts: Output only. List of server CA certificates + for the instance.' + items: + description: ServerCACertsObservation Observability Resource + which is fetched from the hyperscaler + properties: + cert: + description: Cert is the certificate in the PEM format. + type: string + createTime: + description: '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`.' + type: string + expireTime: + description: '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`.' + type: string + serialNumber: + description: 'SerialNumber: Serial number, as extracted + from the certificate.' + type: string + sha1Fingerprint: + description: 'Sha1Fingerprint: Sha1 Fingerprint of the certificate.' + type: string + type: object + type: array state: description: "State: Output only. The current state of this instance. \n Possible values: \"STATE_UNSPECIFIED\" - Not set. \"CREATING\" @@ -393,6 +429,10 @@ spec: description: Additional information about the current status of this instance, if available. type: string + transitEncryptionMode: + description: Status of in tranit encyption mode the redis service + is configured with + type: string type: object conditions: description: Conditions of the resource. diff --git a/pkg/clients/cloudmemorystore/cloudmemorystore.go b/pkg/clients/cloudmemorystore/cloudmemorystore.go index fe6d6a799..cb7363052 100644 --- a/pkg/clients/cloudmemorystore/cloudmemorystore.go +++ b/pkg/clients/cloudmemorystore/cloudmemorystore.go @@ -78,6 +78,7 @@ func GenerateRedisInstance(name string, s v1beta1.CloudMemorystoreInstanceParame r.AuthorizedNetwork = gcp.StringValue(s.AuthorizedNetwork) r.ConnectMode = gcp.StringValue(s.ConnectMode) r.AuthEnabled = gcp.BoolValue(s.AuthEnabled) + r.TransitEncryptionMode = gcp.StringValue(s.TransitEncryptionMode) } // GenerateObservation is used to produce an observation object from GCP's Redis @@ -91,6 +92,16 @@ func GenerateObservation(r redis.Instance) v1beta1.CloudMemorystoreInstanceObser State: r.State, StatusMessage: r.StatusMessage, PersistenceIAMIdentity: r.PersistenceIamIdentity, + TransitEncryptionMode: r.TransitEncryptionMode, + } + for _, val := range r.ServerCaCerts { + o.ServerCaCerts = append(o.ServerCaCerts, v1beta1.ServerCACertsObservation{ + Cert: val.Cert, + CreateTime: val.CreateTime, + ExpireTime: val.ExpireTime, + SerialNumber: val.SerialNumber, + Sha1Fingerprint: val.Sha1Fingerprint, + }) } t, err := time.Parse(time.RFC3339, r.CreateTime) if err != nil { diff --git a/pkg/clients/cloudmemorystore/cloudmemorystore_test.go b/pkg/clients/cloudmemorystore/cloudmemorystore_test.go index 7950c4d1f..0d9e486f7 100644 --- a/pkg/clients/cloudmemorystore/cloudmemorystore_test.go +++ b/pkg/clients/cloudmemorystore/cloudmemorystore_test.go @@ -31,8 +31,9 @@ const ( var ( authorizedNetwork = "default" - - redisConfigs = map[string]string{"cool": "socool"} + redisVersion = "REDIS_6_X" + redisConfigs = map[string]string{"cool": "socool"} + tlsMode = "SERVER_AUTHENTICATION" ) func TestIsUpToDate(t *testing.T) { @@ -139,6 +140,27 @@ func TestIsUpToDate(t *testing.T) { }, want: want{upToDate: true, isErr: false}, }, + { + name: "TlsEnabled", + id: fullName, + kube: &v1beta1.CloudMemorystoreInstance{ + Spec: v1beta1.CloudMemorystoreInstanceSpec{ + ForProvider: v1beta1.CloudMemorystoreInstanceParameters{ + RedisVersion: &redisVersion, + MemorySizeGB: memorySizeGB, + TransitEncryptionMode: &tlsMode, + }, + }, + }, + gcp: &redis.Instance{ + Name: fullName, + RedisVersion: redisVersion, + MemorySizeGb: memorySizeGB, + AuthorizedNetwork: authorizedNetwork, + TransitEncryptionMode: tlsMode, + }, + want: want{upToDate: true, isErr: false}, + }, } for _, tc := range cases {