Skip to content

Reconciler with old controller gen #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Nov 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c5309ba
Try to run a minimal cluster
LimKianAn Nov 17, 2020
233abdc
Update controller-gen
LimKianAn Nov 18, 2020
eb04445
Small adjustments to make deployment of a zalando resource at least s…
majst01 Nov 18, 2020
8920b7e
Merge
majst01 Nov 18, 2020
0c61ec5
Fetch the instance before creation
LimKianAn Nov 18, 2020
c09af0b
Replace postgre_controller.go with the one in the repo
LimKianAn Nov 18, 2020
8c14d80
Create a minimal zalando cluster
LimKianAn Nov 19, 2020
76bb14e
Replace zalando's repo with the fork
LimKianAn Nov 19, 2020
6c90831
Use unstructured
LimKianAn Nov 20, 2020
2c597c5
Slightly reworked unstructered create request, be more structured
majst01 Nov 20, 2020
5807093
Complete the minimal mapping of CRDs
LimKianAn Nov 20, 2020
4cd4063
Implement spec and status update
LimKianAn Nov 23, 2020
db16cbc
Implement deleting zalando postgresal
LimKianAn Nov 24, 2020
cbe6082
Use pointers for members
LimKianAn Nov 25, 2020
ced9832
Refactoring
eberlep Nov 25, 2020
9d51090
Merge pull request #5 from fi-ts/reconciler-with-old-controller-gen-r…
LimKianAn Nov 25, 2020
074f03a
Update only when it's not freshly created
LimKianAn Nov 25, 2020
455a5a9
Merge
LimKianAn Nov 25, 2020
2f7fed8
Use correct logger in method
eberlep Nov 25, 2020
4045493
Merge branch 'reconciler-with-old-controller-gen' of github.com:fi-ts…
LimKianAn Nov 25, 2020
f220a83
Use namespaced-name directly
LimKianAn Nov 25, 2020
1f9a0e3
Implement finalizers
LimKianAn Nov 25, 2020
4213976
Conform to the review
LimKianAn Nov 30, 2020
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
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# postgres-controller
A small controller which act as bridge between zalando-postgres-operator

A small controller which act as a bridge between the zalando-postgres-operator and our postgres Resource.

## Run an example on kind-cluster
```
# Intall zalando dependencies

```bash
# Install zalando dependencies
k apply -k github.com/zalando/postgres-operator/manifests

# Install cert-manager
Expand All @@ -22,4 +24,4 @@ make deploy

# Apply an example of our CRD Postgres
k apply -f config/samples/database_v1_postgres.yaml
```
```
121 changes: 107 additions & 14 deletions api/v1/postgres_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,19 @@ limitations under the License.
package v1

import (
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.

// +kubebuilder:object:root=true
// +kubebuilder:printcolumn:name="Name",type=string,JSONPath=`.spec.name`
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.version`
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.description`

// Postgres is the Schema for the postgres API
type Postgres struct {
Expand All @@ -44,37 +48,36 @@ type PostgresSpec struct {
// Description
Description string `json:"description,omitempty"`
// ProjectID metal project ID
ProjectID string `json:"project_id,omitempty"`
ProjectID string `json:"projectID,omitempty"`
// Tenant metal tenant
Tenant string `json:"tenant,omitempty"`
// PartitionID the partition where the database is created
PartitionID string `json:"partition_id,omitempty"`
PartitionID string `json:"partitionID,omitempty"`
// NumberOfInstances number of replicas
NumberOfInstances int32 `json:"number_of_instances,omitempty"`
// Version is the postgres version
NumberOfInstances int32 `json:"numberOfInstances,omitempty"`
// Version is the version of Postgre-as-a-Service
Version string `json:"version,omitempty"`
// Size of the database
Size Size `json:"size,omitempty"`
Size *Size `json:"size,omitempty"`
// Maintenance defines automatic maintenance of the database
Maintenance Maintenance `json:"maintenance,omitempty"`
Maintenance *Maintenance `json:"maintenance,omitempty"`
// Backup parametes of the database backup
Backup Backup `json:"backup,omitempty"`
Backup *Backup `json:"backup,omitempty"`
// AccessList defines access restrictions
AccessList AccessList `json:"access_list,omitempty"`
AccessList *AccessList `json:"accessList,omitempty"`
}

// AccessList defines the type of restrictions to access the database
type AccessList struct {
// SourceRanges defines a list of prefixes in CIDR Notation e.g. 1.2.3.0/24
// FIXME implement validation if source is a parsable CIDR
SourceRanges []string `json:"source_ranges,omitempty"`
SourceRanges []string `json:"sourceRanges,omitempty"`
}

// Backup configure parametes of the database backup
type Backup struct {
// Retention defines how many days a backup will persist
Retention int32 `json:"retention,omitempty"`

// Schedule defines how often a backup should be made, in cron format
Schedule string `json:"schedule,omitempty"`
}
Expand All @@ -84,9 +87,9 @@ type Size struct {
// CPU is in the format as pod.spec.resource.request.cpu
CPU string `json:"cpu,omitempty"`
// SharedBuffer of the database
SharedBuffer string `json:"shared_buffer,omitempty"`
SharedBuffer string `json:"sharedBuffer,omitempty"`
// StorageSize the amount of Storage this database will get
StorageSize string `json:"storage_size,omitempty"`
StorageSize string `json:"storageSize,omitempty"`
}

// Weekday defines a weekday or everyday
Expand Down Expand Up @@ -114,13 +117,14 @@ type Maintenance struct {
// Weekday defines when the operator is allowed to do maintenance
Weekday Weekday `json:"weekday,omitempty"`
// TimeWindow defines when the maintenance should happen
TimeWindow TimeWindow `json:"time_window,omitempty"`
TimeWindow TimeWindow `json:"timeWindow,omitempty"`
}

// PostgresStatus defines the observed state of Postgres
type PostgresStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Description string `json:"description,omitempty"`
}

// +kubebuilder:object:root=true
Expand All @@ -137,6 +141,95 @@ func (p *Postgres) IsBeingDeleted() bool {
return !p.ObjectMeta.DeletionTimestamp.IsZero()
}

func (p *Postgres) ToKey() *types.NamespacedName {
return &types.NamespacedName{
Namespace: p.Namespace,
Name: p.Name,
}
}
func (p *Postgres) ToZalandoPostgres() *ZalandoPostgres {
return &ZalandoPostgres{
TypeMeta: ZalandoPostgresTypeMeta,
ObjectMeta: metav1.ObjectMeta{
Name: p.Spec.ProjectID + "-" + p.Name, // todo: Need another rule of naming. UID is not allowed by the operator.
Namespace: p.Namespace, // todo: Use Spec.ProjectID once ns creation is implemented.
},
Spec: ZalandoPostgresSpec{
MaintenanceWindows: func() []MaintenanceWindow {
if p.Spec.Maintenance == nil {
return nil
}
isEvery := p.Spec.Maintenance.Weekday == All
return []MaintenanceWindow{
{Everyday: isEvery,
Weekday: func() time.Weekday {
if isEvery {
return time.Weekday(0)
}
return time.Weekday(p.Spec.Maintenance.Weekday)
}(),
StartTime: p.Spec.Maintenance.TimeWindow.Start,
EndTime: p.Spec.Maintenance.TimeWindow.End,
},
}
}(),
NumberOfInstances: p.Spec.NumberOfInstances,
PostgresqlParam: PostgresqlParam{PgVersion: p.Spec.Version},
Resources: func() *Resources {
if p.Spec.Size.CPU == "" {
return nil
}
return &Resources{
ResourceRequests: &ResourceDescription{
CPU: p.Spec.Size.CPU,
},
ResourceLimits: &ResourceDescription{}, // todo: Fill it out.
}
}(),
TeamID: p.Spec.ProjectID,
Volume: Volume{Size: p.Spec.Size.StorageSize},
},
}
}

const PostgresFinalizerName = "postgres.finalizers.database.fits.cloud"

func (p *Postgres) HasFinalizer(finalizerName string) bool {
return containsElem(p.ObjectMeta.Finalizers, finalizerName)
}

func (p *Postgres) AddFinalizer(finalizerName string) {
p.ObjectMeta.Finalizers = append(p.ObjectMeta.Finalizers, finalizerName)
}

func (p *Postgres) RemoveFinalizer(finalizerName string) {
p.ObjectMeta.Finalizers = removeElem(p.ObjectMeta.Finalizers, finalizerName)
}

func containsElem(ss []string, s string) bool {
for _, elem := range ss {
if elem == s {
return true
}
}
return false
}

func removeElem(ss []string, s string) (out []string) {
for _, elem := range ss {
if elem == s {
continue
}
out = append(out, elem)
}
return
}

// Only names starting with the `TeamID` of the `Postgresql` are acceptable.
func (p *Postgres) toZalandoPostgresName() string {
return p.Spec.ProjectID + "-" + string(p.UID)
}

func init() {
SchemeBuilder.Register(&Postgres{}, &PostgresList{})
}
14 changes: 7 additions & 7 deletions api/v1/postgresprofile_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ type PostgresProfileSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

NumberOfInstances []int `json:"number_of_instances,omitempty"`
NumberOfInstances []int `json:"numberOfInstances,omitempty"`
Operators []Operator `json:"operators,omitempty"`
Sizes []Size `json:"sizes,omitempty"`
Versions []string `json:"versions,omitempty"`

DefaultBackup Backup `json:"default_backup,omitempty"`
DefaultMaintenance Maintenance `json:"default_maintenance,omitempty"`
DefaultNumberOfInstances int `json:"default_number_of_instances,omitempty"`
DefaultOperator Operator `json:"default_operator,omitempty"`
DefaultSize Size `json:"default_size,omitempty"`
DefaultVersion string `json:"default_version,omitempty"`
DefaultBackup Backup `json:"defaultBackup,omitempty"`
DefaultMaintenance Maintenance `json:"defaultMaintenance,omitempty"`
DefaultNumberOfInstances int `json:"defaultNumberOfInstances,omitempty"`
DefaultOperator Operator `json:"defaultOperator,omitempty"`
DefaultSize Size `json:"defaultSize,omitempty"`
DefaultVersion string `json:"defaultVersion,omitempty"`
}

// Operator defines which provider of the operator should be used and its version
Expand Down
98 changes: 98 additions & 0 deletions api/v1/zalandopostgres_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package v1

import (
"time"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
)

// ZalandoPostgresTypeMeta is the `TypeMeta` of the zalando's `Postgresql` type.
// Only this `TypeMeta` should be used for the resources in this file.
var ZalandoPostgresTypeMeta = metav1.TypeMeta{
APIVersion: "acid.zalan.do/v1",
Kind: "postgresql",
}

// +kubebuilder:object:root=true

type ZalandoPostgres struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ZalandoPostgresSpec `json:"spec"`
Status ZalandoPostgresStatus `json:"status,omitempty"`
}

type ZalandoPostgresSpec struct {
MaintenanceWindows []MaintenanceWindow `json:"maintenanceWindows,omitempty"`
NumberOfInstances int32 `json:"numberOfInstances"`
PostgresqlParam PostgresqlParam `json:"postgresql"`
Resources *Resources `json:"resources,omitempty"`
TeamID string `json:"teamId"`
Volume Volume `json:"volume"`
}

type MaintenanceWindow struct {
Everyday bool `json:"everyday,omitempty"`
Weekday time.Weekday `json:"weekday,omitempty"`
StartTime metav1.Time `json:"startTime,omitempty"`
EndTime metav1.Time `json:"endTime,omitempty"`
}

type PostgresqlParam struct {
PgVersion string `json:"version"`
}

type Resources struct {
ResourceRequests *ResourceDescription `json:"requests,omitempty"`
ResourceLimits *ResourceDescription `json:"limits,omitempty"`
}

type ResourceDescription struct {
CPU string `json:"cpu,omitempty"`
Memory string `json:"memory,omitempty"`
}

type Volume struct {
Size string `json:"size"`
}

type ZalandoPostgresStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Following zalando postgresql, `P`ostgresClusterStatus in JSON.
PostgresClusterStatus string `json:"PostgresClusterStatus"`
}

// +kubebuilder:object:root=true

// ZalandoPostgresList contains a list of Postgres
type ZalandoPostgresList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ZalandoPostgres `json:"items"`
}

func (z *ZalandoPostgres) ToKey() *types.NamespacedName {
return &types.NamespacedName{
Namespace: z.Namespace,
Name: z.Name,
}
}

func (z *ZalandoPostgres) ToUnstructured() (*unstructured.Unstructured, error) {
u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(z)
if err != nil {
return nil, err
}
return &unstructured.Unstructured{
Object: u,
}, nil
}

func init() {
SchemeBuilder.Register(&ZalandoPostgres{}, &ZalandoPostgresList{})
}
Loading