Skip to content

Commit

Permalink
redis resource spec was updated with privateLink
Browse files Browse the repository at this point in the history
  • Loading branch information
worryg0d authored and taaraora committed Aug 31, 2023
1 parent e38b77d commit 05bd37a
Show file tree
Hide file tree
Showing 20 changed files with 399 additions and 70 deletions.
62 changes: 52 additions & 10 deletions apis/clusters/v1beta1/redis_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,13 @@ import (
type RedisDataCentre struct {
DataCentre `json:",inline"`
MasterNodes int `json:"masterNodes"`

//+kubebuilder:validation:Minimum:=0
//+kubebuilder:validation:Maximum:=5
ReplicationFactor int `json:"replicationFactor,omitempty"`

//+kubebuilder:validation:MaxItems:=1
PrivateLink []*PrivateLink `json:"privateLink,omitempty"`
}

type RedisRestoreFrom struct {
Expand Down Expand Up @@ -67,11 +74,12 @@ type RedisSpec struct {
Cluster `json:",inline"`

// Enables client to node encryption
ClientEncryption bool `json:"clientEncryption,omitempty"`
PasswordAndUserAuth bool `json:"passwordAndUserAuth,omitempty"`
DataCentres []*RedisDataCentre `json:"dataCentres,omitempty"`
Description string `json:"description,omitempty"`
UserRefs []*UserReference `json:"userRefs,omitempty"`
ClientEncryption bool `json:"clientEncryption,omitempty"`
PasswordAndUserAuth bool `json:"passwordAndUserAuth,omitempty"`
//+kubebuilder:validation:MaxItems:=2
DataCentres []*RedisDataCentre `json:"dataCentres,omitempty"`
Description string `json:"description,omitempty"`
UserRefs []*UserReference `json:"userRefs,omitempty"`
}

// RedisStatus defines the observed state of Redis
Expand Down Expand Up @@ -174,8 +182,10 @@ func (rs *RedisSpec) DCsToInstAPI() (iDCs []*models.RedisDataCentre) {
Region: redisDC.Region,
ProviderAccountName: redisDC.ProviderAccountName,
},
MasterNodes: redisDC.MasterNodes,
ReplicaNodes: redisDC.NodesNumber,
MasterNodes: redisDC.MasterNodes,
ReplicaNodes: redisDC.NodesNumber,
PrivateLink: privateLinksToInstAPI(redisDC.PrivateLink),
ReplicationFactor: redisDC.ReplicationFactor,
}
iDCs = append(iDCs, iDC)
}
Expand Down Expand Up @@ -256,8 +266,10 @@ func (rs *RedisSpec) DCsFromInstAPI(iDCs []*models.RedisDataCentre) (dcs []*Redi
for _, iDC := range iDCs {
iDC.NumberOfNodes = iDC.ReplicaNodes
dcs = append(dcs, &RedisDataCentre{
DataCentre: rs.Cluster.DCFromInstAPI(iDC.DataCentre),
MasterNodes: iDC.MasterNodes,
DataCentre: rs.Cluster.DCFromInstAPI(iDC.DataCentre),
MasterNodes: iDC.MasterNodes,
PrivateLink: privateLinksFromInstAPI(iDC.PrivateLink),
ReplicationFactor: iDC.ReplicationFactor,
})
}
return
Expand All @@ -277,7 +289,10 @@ func (rs *RedisStatus) FromInstAPI(iRedis *models.RedisCluster) RedisStatus {

func (rs *RedisStatus) DCsFromInstAPI(iDCs []*models.RedisDataCentre) (dcs []*DataCentreStatus) {
for _, iDC := range iDCs {
dcs = append(dcs, rs.ClusterStatus.DCFromInstAPI(iDC.DataCentre))
dc := rs.ClusterStatus.DCFromInstAPI(iDC.DataCentre)
dc.PrivateLink = privateLinkStatusesFromInstAPI(iDC.PrivateLink)

dcs = append(dcs, dc)
}
return
}
Expand Down Expand Up @@ -331,6 +346,11 @@ func (rs *RedisSpec) validateDCsUpdate(oldSpec RedisSpec) error {
if newDC.NodesNumber < oldDC.NodesNumber {
return fmt.Errorf("deleting nodes is not supported. Number of nodes must be greater than: %v", oldDC.NodesNumber)
}

err = validatePrivateLinkUpdate(newDC.PrivateLink, oldDC.PrivateLink)
if err != nil {
return err
}
}
}
}
Expand Down Expand Up @@ -387,6 +407,11 @@ func (rdc *RedisDataCentre) ValidateCreate() error {
return err
}

err = rdc.ValidatePrivateLink()
if err != nil {
return err
}

return nil
}

Expand All @@ -402,6 +427,23 @@ func (rdc *RedisDataCentre) ValidateNodesNumber() error {
return nil
}

func (rdc *RedisDataCentre) ValidatePrivateLink() error {
if rdc.CloudProvider != models.AWSVPC && len(rdc.PrivateLink) > 0 {
return models.ErrPrivateLinkSupportedOnlyForAWS
}

return nil
}

func (rs *RedisSpec) ValidatePrivateLink() error {
if len(rs.DataCentres) > 1 &&
(rs.DataCentres[0].PrivateLink != nil || rs.DataCentres[1].PrivateLink != nil) {
return models.ErrPrivateLinkSupportedOnlyForSingleDC
}

return nil
}

func init() {
SchemeBuilder.Register(&Redis{}, &RedisList{})
}
9 changes: 9 additions & 0 deletions apis/clusters/v1beta1/redis_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ func (rv *redisValidator) ValidateCreate(ctx context.Context, obj runtime.Object
return err
}

err = r.Spec.ValidatePrivateLink()
if err != nil {
return err
}

appVersions, err := rv.API.ListAppVersions(models.RedisAppKind)
if err != nil {
return fmt.Errorf("cannot list versions for kind: %v, err: %w",
Expand All @@ -112,6 +117,10 @@ func (rv *redisValidator) ValidateCreate(ctx context.Context, obj runtime.Object
if err != nil {
return err
}

if !r.Spec.PrivateNetworkCluster && dc.PrivateLink != nil {
return models.ErrPrivateLinkOnlyWithPrivateNetworkCluster
}
}

return nil
Expand Down
83 changes: 78 additions & 5 deletions apis/clusters/v1beta1/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,12 @@ type DataCentre struct {
}

type DataCentreStatus struct {
ID string `json:"id,omitempty"`
Status string `json:"status,omitempty"`
Nodes []*Node `json:"nodes,omitempty"`
NodeNumber int `json:"nodeNumber,omitempty"`
EncryptionKeyID string `json:"encryptionKeyId,omitempty"`
ID string `json:"id,omitempty"`
Status string `json:"status,omitempty"`
Nodes []*Node `json:"nodes,omitempty"`
NodeNumber int `json:"nodeNumber,omitempty"`
EncryptionKeyID string `json:"encryptionKeyId,omitempty"`
PrivateLink PrivateLinkStatuses `json:"privateLink,omitempty"`
}

type Node struct {
Expand Down Expand Up @@ -123,9 +124,69 @@ type PatchRequest struct {
}

type PrivateLink struct {
//+kubebuilder:validation:MinLength:=3
AdvertisedHostname string `json:"advertisedHostname"`
}

type privateLinkStatus struct {
AdvertisedHostname string `json:"advertisedHostname"`
EndPointServiceID string `json:"endPointServiceId,omitempty"`
EndPointServiceName string `json:"endPointServiceName,omitempty"`
}

type PrivateLinkStatuses []*privateLinkStatus

func (p1 PrivateLinkStatuses) Equal(p2 PrivateLinkStatuses) bool {
if len(p1) != len(p2) {
return false
}

for _, link2 := range p2 {
for _, link1 := range p1 {
if *link2 != *link1 {
return false
}
}
}

return true
}

func privateLinksToInstAPI(p []*PrivateLink) []*models.PrivateLink {
links := make([]*models.PrivateLink, 0, len(p))
for _, link := range p {
links = append(links, &models.PrivateLink{
AdvertisedHostname: link.AdvertisedHostname,
})
}

return links
}

func privateLinksFromInstAPI(p []*models.PrivateLink) []*PrivateLink {
k8sPLs := make([]*PrivateLink, 0, len(p))
for _, link := range p {
k8sPLs = append(k8sPLs, &PrivateLink{
AdvertisedHostname: link.AdvertisedHostname,
})
}

return k8sPLs
}

func privateLinkStatusesFromInstAPI(iPLs []*models.PrivateLink) PrivateLinkStatuses {
k8sPLs := make(PrivateLinkStatuses, 0, len(iPLs))
for _, link := range iPLs {
k8sPLs = append(k8sPLs, &privateLinkStatus{
AdvertisedHostname: link.AdvertisedHostname,
EndPointServiceID: link.EndPointServiceID,
EndPointServiceName: link.EndPointServiceName,
})
}

return k8sPLs
}

type PrivateLinkV1 struct {
IAMPrincipalARNs []string `json:"iamPrincipalARNs"`
}
Expand Down Expand Up @@ -517,6 +578,18 @@ func arePrivateLinksEqual(a, b []*PrivateLink) bool {
return true
}

func (cs *ClusterStatus) PrivateLinkStatusesEqual(iStatus *ClusterStatus) bool {
for _, iDC := range iStatus.DataCentres {
for _, k8sDC := range cs.DataCentres {
if !iDC.PrivateLink.Equal(k8sDC.PrivateLink) {
return false
}
}
}

return true
}

type UserReference struct {
Namespace string `json:"namespace"`
Name string `json:"name"`
Expand Down
14 changes: 14 additions & 0 deletions apis/clusters/v1beta1/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,17 @@ func validateTagsUpdate(new, old map[string]string) error {

return nil
}

func validatePrivateLinkUpdate(new, old []*PrivateLink) error {
if len(old) != len(new) {
return models.ErrImmutablePrivateLink
}

for i, oldPrivateLink := range old {
if *oldPrivateLink != *new[i] {
return models.ErrImmutablePrivateLink
}
}

return nil
}
47 changes: 47 additions & 0 deletions apis/clusters/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions config/crd/bases/clusters.instaclustr.com_cadences.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ spec:
items:
properties:
advertisedHostname:
minLength: 3
type: string
required:
- advertisedHostname
Expand Down Expand Up @@ -311,6 +312,19 @@ spec:
type: string
type: object
type: array
privateLink:
items:
properties:
advertisedHostname:
type: string
endPointServiceId:
type: string
endPointServiceName:
type: string
required:
- advertisedHostname
type: object
type: array
status:
type: string
type: object
Expand Down
13 changes: 13 additions & 0 deletions config/crd/bases/clusters.instaclustr.com_cassandras.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,19 @@ spec:
type: string
type: object
type: array
privateLink:
items:
properties:
advertisedHostname:
type: string
endPointServiceId:
type: string
endPointServiceName:
type: string
required:
- advertisedHostname
type: object
type: array
status:
type: string
type: object
Expand Down
Loading

0 comments on commit 05bd37a

Please sign in to comment.