From 017cf8d100f3bac1f926ba4028b7cd9752dc0dd0 Mon Sep 17 00:00:00 2001 From: Nicolas Bigler Date: Tue, 21 Nov 2023 18:32:15 +0100 Subject: [PATCH] Add MariaDB service Signed-off-by: Nicolas Bigler --- apis/vshn/v1/dbaas_vshn_mariadb.go | 220 ++++++ apis/vshn/v1/zz_generated.deepcopy.go | 279 +++++++ apis/vshn/v1/zz_generated.managed.go | 60 ++ apis/vshn/v1/zz_generated.managedlist.go | 9 + boostrap/template.go | 76 ++ boostrap/template/api.txt | 241 ++++++ cmd/functions.go | 1 + crds/vshn.appcat.vshn.io_vshnmariadbs.yaml | 438 +++++++++++ crds/vshn.appcat.vshn.io_xvshnmariadbs.yaml | 709 ++++++++++++++++++ crds/vshn.appcat.vshn.io_xvshnminios.yaml | 154 ++-- go.mod | 7 +- go.sum | 8 +- mariadb.json | 8 + package/crossplane.yaml | 2 +- pkg/comp-functions/functions/common/netpol.go | 51 ++ pkg/comp-functions/functions/common/tls.go | 141 ++++ .../functions/vshnmariadb/mariadb_deploy.go | 263 +++++++ .../functions/vshnmariadb/register.go | 15 + pkg/scheme.go | 5 + 19 files changed, 2640 insertions(+), 47 deletions(-) create mode 100644 apis/vshn/v1/dbaas_vshn_mariadb.go create mode 100644 boostrap/template.go create mode 100644 boostrap/template/api.txt create mode 100644 crds/vshn.appcat.vshn.io_vshnmariadbs.yaml create mode 100644 crds/vshn.appcat.vshn.io_xvshnmariadbs.yaml create mode 100644 mariadb.json create mode 100644 pkg/comp-functions/functions/common/netpol.go create mode 100644 pkg/comp-functions/functions/common/tls.go create mode 100644 pkg/comp-functions/functions/vshnmariadb/mariadb_deploy.go create mode 100644 pkg/comp-functions/functions/vshnmariadb/register.go diff --git a/apis/vshn/v1/dbaas_vshn_mariadb.go b/apis/vshn/v1/dbaas_vshn_mariadb.go new file mode 100644 index 000000000..489cb27c5 --- /dev/null +++ b/apis/vshn/v1/dbaas_vshn_mariadb.go @@ -0,0 +1,220 @@ +package v1 + +import ( + "fmt" + + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + v1 "github.com/vshn/appcat/v4/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnmariadbs.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnmariadbs.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnmariadbs.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnmariadbs.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.tls.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_vshnmariadbs.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" + +// +kubebuilder:object:root=true + +// VSHNMariaDB is the API for creating MariaDB instances. +type VSHNMariaDB struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a VSHNMariaDB. + Spec VSHNMariaDBSpec `json:"spec"` + + // Status reflects the observed state of a VSHNMariaDB. + Status VSHNMariaDBStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true +type VSHNMariaDBList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []VSHNMariaDB `json:"items,omitempty"` +} + +// VSHNMariaDBSpec defines the desired state of a VSHNMariaDB. +type VSHNMariaDBSpec struct { + // Parameters are the configurable fields of a VSHNMariaDB. + Parameters VSHNMariaDBParameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +// VSHNMariaDBParameters are the configurable fields of a VSHNMariaDB. +type VSHNMariaDBParameters struct { + // Service contains MariaDB DBaaS specific properties + Service VSHNMariaDBServiceSpec `json:"service,omitempty"` + + // Size contains settings to control the sizing of a service. + Size VSHNSizeSpec `json:"size,omitempty"` + + // Scheduling contains settings to control the scheduling of an instance. + Scheduling VSHNDBaaSSchedulingSpec `json:"scheduling,omitempty"` + + // TLS contains settings to control tls traffic of a service. + TLS VSHNMariaDBTLSSpec `json:"tls,omitempty"` + + // Backup contains settings to control how the instance should get backed up. + Backup K8upBackupSpec `json:"backup,omitempty"` + + // Restore contains settings to control the restore of an instance. + Restore K8upRestoreSpec `json:"restore,omitempty"` + + // StorageClass configures the storageClass to use for the PVC used by MariaDB. + StorageClass string `json:"storageClass,omitempty"` + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance VSHNDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` +} + +// VSHNMariaDBServiceSpec contains MariaDB DBaaS specific properties +type VSHNMariaDBServiceSpec struct { + // +kubebuilder:validation:Enum="10.4";"10.5";"10.6";"10.9";"10.10";"10.11";"11.0";"11.1";"11.2"; + // +kubebuilder:default="11.2" + + // Version contains supported version of MariaDB. + // Multiple versions are supported. The latest version "11.2" is the default version. + Version string `json:"version,omitempty"` + + // MariadbSettings contains additional MariaDB settings. + MariadbSettings string `json:"mariadbSettings,omitempty"` + + // +kubebuilder:validation:Enum="besteffort";"guaranteed" + // +kubebuilder:default="besteffort" + + // ServiceLevel defines the service level of this service. Either Best Effort or Guaranteed Availability is allowed. + ServiceLevel VSHNDBaaSServiceLevel `json:"serviceLevel,omitempty"` + + // +kubebuilder:default="standalone" + // +kubebuilder:validation:Enum=replication;standalone + + // Mode configures the mode of MariaDB. + // Valid values are "replication" and "standalone". + Mode string `json:"mode,omitempty"` +} + +// VSHNMariaDBTLSSpec contains settings to control tls traffic of a service. +type VSHNMariaDBTLSSpec struct { + // +kubebuilder:default=true + + // TLSEnabled enables TLS traffic for the service + TLSEnabled bool `json:"enabled,omitempty"` + + // +kubebuilder:default=true + // TLSAuthClients enables client authentication requirement + TLSAuthClients bool `json:"authClients,omitempty"` +} + +// VSHNMariaDBStatus reflects the observed state of a VSHNMariaDB. +type VSHNMariaDBStatus struct { + NamespaceConditions []v1.Condition `json:"namespaceConditions,omitempty"` + SelfSignedIssuerConditions []v1.Condition `json:"selfSignedIssuerConditions,omitempty"` + LocalCAConditions []v1.Condition `json:"localCAConditions,omitempty"` + CaCertificateConditions []v1.Condition `json:"caCertificateConditions,omitempty"` + ServerCertificateConditions []v1.Condition `json:"serverCertificateConditions,omitempty"` + ClientCertificateConditions []v1.Condition `json:"clientCertificateConditions,omitempty"` + // InstanceNamespace contains the name of the namespace where the instance resides + InstanceNamespace string `json:"instanceNamespace,omitempty"` + // Schedules keeps track of random generated schedules, is overwriten by + // schedules set in the service's spec. + Schedules VSHNScheduleStatus `json:"schedules,omitempty"` +} + +func (v *VSHNMariaDB) GetClaimNamespace() string { + return v.GetLabels()["crossplane.io/claim-namespace"] +} + +func (v *VSHNMariaDB) GetInstanceNamespace() string { + return fmt.Sprintf("vshn-mariadb-%s", v.GetName()) +} + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true + +// XVSHNMariaDB represents the internal composite of this claim +type XVSHNMariaDB struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec XVSHNMariaDBSpec `json:"spec"` + Status XVSHNMariaDBStatus `json:"status,omitempty"` +} + +// XVSHNMariaDBSpec defines the desired state of a VSHNMariaDB. +type XVSHNMariaDBSpec struct { + // Parameters are the configurable fields of a VSHNMariaDB. + Parameters VSHNMariaDBParameters `json:"parameters,omitempty"` + + xpv1.ResourceSpec `json:",inline"` +} + +type XVSHNMariaDBStatus struct { + VSHNMariaDBStatus `json:",inline"` + xpv1.ResourceStatus `json:",inline"` +} + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true + +// XVSHNMariaDBList represents a list of composites +type XVSHNMariaDBList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []XVSHNMariaDB `json:"items"` +} + +// GetMaintenanceDayOfWeek returns the currently set day of week +func (n *VSHNMariaDB) GetMaintenanceDayOfWeek() string { + if n.Spec.Parameters.Maintenance.DayOfWeek != "" { + return n.Spec.Parameters.Maintenance.DayOfWeek + } + return n.Status.Schedules.Maintenance.DayOfWeek +} + +// GetMaintenanceTimeOfDay returns the currently set time of day +func (v *VSHNMariaDB) GetMaintenanceTimeOfDay() string { + if v.Spec.Parameters.Maintenance.TimeOfDay != "" { + return v.Spec.Parameters.Maintenance.TimeOfDay + } + return v.Status.Schedules.Maintenance.TimeOfDay +} + +// SetMaintenanceDayOfWeek sets the day of week to the given value +func (v *VSHNMariaDB) SetMaintenanceDayOfWeek(dow string) { + v.Status.Schedules.Maintenance.DayOfWeek = dow +} + +// SetMaintenanceTimeOfDay sets the time of day to the given value +func (v *VSHNMariaDB) SetMaintenanceTimeOfDay(tod string) { + v.Status.Schedules.Maintenance.TimeOfDay = tod +} + +// GetBackupSchedule returns the current backup schedule +func (v *VSHNMariaDB) GetBackupSchedule() string { + if v.Spec.Parameters.Backup.Schedule != "" { + return v.Spec.Parameters.Backup.Schedule + } + return v.Status.Schedules.Backup +} + +// SetBackupSchedule overwrites the current backup schedule +func (v *VSHNMariaDB) SetBackupSchedule(schedule string) { + v.Status.Schedules.Backup = schedule +} + +// GetFullMaintenanceSchedule returns +func (v *VSHNMariaDB) GetFullMaintenanceSchedule() VSHNDBaaSMaintenanceScheduleSpec { + schedule := v.Spec.Parameters.Maintenance + schedule.DayOfWeek = v.GetMaintenanceDayOfWeek() + schedule.TimeOfDay = v.GetMaintenanceTimeOfDay() + return schedule +} diff --git a/apis/vshn/v1/zz_generated.deepcopy.go b/apis/vshn/v1/zz_generated.deepcopy.go index 5991f4038..11ff2cbb6 100644 --- a/apis/vshn/v1/zz_generated.deepcopy.go +++ b/apis/vshn/v1/zz_generated.deepcopy.go @@ -143,6 +143,192 @@ func (in *VSHNDBaaSSizeRequestsSpec) DeepCopy() *VSHNDBaaSSizeRequestsSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNMariaDB) DeepCopyInto(out *VSHNMariaDB) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNMariaDB. +func (in *VSHNMariaDB) DeepCopy() *VSHNMariaDB { + if in == nil { + return nil + } + out := new(VSHNMariaDB) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSHNMariaDB) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNMariaDBList) DeepCopyInto(out *VSHNMariaDBList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]VSHNMariaDB, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNMariaDBList. +func (in *VSHNMariaDBList) DeepCopy() *VSHNMariaDBList { + if in == nil { + return nil + } + out := new(VSHNMariaDBList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *VSHNMariaDBList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNMariaDBParameters) DeepCopyInto(out *VSHNMariaDBParameters) { + *out = *in + out.Service = in.Service + out.Size = in.Size + in.Scheduling.DeepCopyInto(&out.Scheduling) + out.TLS = in.TLS + out.Backup = in.Backup + out.Restore = in.Restore + out.Maintenance = in.Maintenance +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNMariaDBParameters. +func (in *VSHNMariaDBParameters) DeepCopy() *VSHNMariaDBParameters { + if in == nil { + return nil + } + out := new(VSHNMariaDBParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNMariaDBServiceSpec) DeepCopyInto(out *VSHNMariaDBServiceSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNMariaDBServiceSpec. +func (in *VSHNMariaDBServiceSpec) DeepCopy() *VSHNMariaDBServiceSpec { + if in == nil { + return nil + } + out := new(VSHNMariaDBServiceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNMariaDBSpec) DeepCopyInto(out *VSHNMariaDBSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + out.WriteConnectionSecretToRef = in.WriteConnectionSecretToRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNMariaDBSpec. +func (in *VSHNMariaDBSpec) DeepCopy() *VSHNMariaDBSpec { + if in == nil { + return nil + } + out := new(VSHNMariaDBSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNMariaDBStatus) DeepCopyInto(out *VSHNMariaDBStatus) { + *out = *in + if in.NamespaceConditions != nil { + in, out := &in.NamespaceConditions, &out.NamespaceConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SelfSignedIssuerConditions != nil { + in, out := &in.SelfSignedIssuerConditions, &out.SelfSignedIssuerConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LocalCAConditions != nil { + in, out := &in.LocalCAConditions, &out.LocalCAConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.CaCertificateConditions != nil { + in, out := &in.CaCertificateConditions, &out.CaCertificateConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ServerCertificateConditions != nil { + in, out := &in.ServerCertificateConditions, &out.ServerCertificateConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ClientCertificateConditions != nil { + in, out := &in.ClientCertificateConditions, &out.ClientCertificateConditions + *out = make([]apisv1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.Schedules = in.Schedules +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNMariaDBStatus. +func (in *VSHNMariaDBStatus) DeepCopy() *VSHNMariaDBStatus { + if in == nil { + return nil + } + out := new(VSHNMariaDBStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VSHNMariaDBTLSSpec) DeepCopyInto(out *VSHNMariaDBTLSSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VSHNMariaDBTLSSpec. +func (in *VSHNMariaDBTLSSpec) DeepCopy() *VSHNMariaDBTLSSpec { + if in == nil { + return nil + } + out := new(VSHNMariaDBTLSSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VSHNMinio) DeepCopyInto(out *VSHNMinio) { *out = *in @@ -822,6 +1008,99 @@ func (in *VSHNSizeSpec) DeepCopy() *VSHNSizeSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNMariaDB) DeepCopyInto(out *XVSHNMariaDB) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNMariaDB. +func (in *XVSHNMariaDB) DeepCopy() *XVSHNMariaDB { + if in == nil { + return nil + } + out := new(XVSHNMariaDB) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *XVSHNMariaDB) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNMariaDBList) DeepCopyInto(out *XVSHNMariaDBList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]XVSHNMariaDB, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNMariaDBList. +func (in *XVSHNMariaDBList) DeepCopy() *XVSHNMariaDBList { + if in == nil { + return nil + } + out := new(XVSHNMariaDBList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *XVSHNMariaDBList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNMariaDBSpec) DeepCopyInto(out *XVSHNMariaDBSpec) { + *out = *in + in.Parameters.DeepCopyInto(&out.Parameters) + in.ResourceSpec.DeepCopyInto(&out.ResourceSpec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNMariaDBSpec. +func (in *XVSHNMariaDBSpec) DeepCopy() *XVSHNMariaDBSpec { + if in == nil { + return nil + } + out := new(XVSHNMariaDBSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *XVSHNMariaDBStatus) DeepCopyInto(out *XVSHNMariaDBStatus) { + *out = *in + in.VSHNMariaDBStatus.DeepCopyInto(&out.VSHNMariaDBStatus) + in.ResourceStatus.DeepCopyInto(&out.ResourceStatus) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new XVSHNMariaDBStatus. +func (in *XVSHNMariaDBStatus) DeepCopy() *XVSHNMariaDBStatus { + if in == nil { + return nil + } + out := new(XVSHNMariaDBStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *XVSHNMinio) DeepCopyInto(out *XVSHNMinio) { *out = *in diff --git a/apis/vshn/v1/zz_generated.managed.go b/apis/vshn/v1/zz_generated.managed.go index 47af7cb75..a132cec27 100644 --- a/apis/vshn/v1/zz_generated.managed.go +++ b/apis/vshn/v1/zz_generated.managed.go @@ -4,6 +4,66 @@ package v1 import xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" +// GetCondition of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) GetCondition(ct xpv1.ConditionType) xpv1.Condition { + return mg.Status.GetCondition(ct) +} + +// GetDeletionPolicy of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) GetDeletionPolicy() xpv1.DeletionPolicy { + return mg.Spec.DeletionPolicy +} + +// GetManagementPolicies of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) GetManagementPolicies() xpv1.ManagementPolicies { + return mg.Spec.ManagementPolicies +} + +// GetProviderConfigReference of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) GetProviderConfigReference() *xpv1.Reference { + return mg.Spec.ProviderConfigReference +} + +// GetPublishConnectionDetailsTo of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) GetPublishConnectionDetailsTo() *xpv1.PublishConnectionDetailsTo { + return mg.Spec.PublishConnectionDetailsTo +} + +// GetWriteConnectionSecretToReference of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) GetWriteConnectionSecretToReference() *xpv1.SecretReference { + return mg.Spec.WriteConnectionSecretToReference +} + +// SetConditions of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) SetConditions(c ...xpv1.Condition) { + mg.Status.SetConditions(c...) +} + +// SetDeletionPolicy of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) SetDeletionPolicy(r xpv1.DeletionPolicy) { + mg.Spec.DeletionPolicy = r +} + +// SetManagementPolicies of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) SetManagementPolicies(r xpv1.ManagementPolicies) { + mg.Spec.ManagementPolicies = r +} + +// SetProviderConfigReference of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) SetProviderConfigReference(r *xpv1.Reference) { + mg.Spec.ProviderConfigReference = r +} + +// SetPublishConnectionDetailsTo of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) SetPublishConnectionDetailsTo(r *xpv1.PublishConnectionDetailsTo) { + mg.Spec.PublishConnectionDetailsTo = r +} + +// SetWriteConnectionSecretToReference of this XVSHNMariaDB. +func (mg *XVSHNMariaDB) SetWriteConnectionSecretToReference(r *xpv1.SecretReference) { + mg.Spec.WriteConnectionSecretToReference = r +} + // GetCondition of this XVSHNMinio. func (mg *XVSHNMinio) GetCondition(ct xpv1.ConditionType) xpv1.Condition { return mg.Status.GetCondition(ct) diff --git a/apis/vshn/v1/zz_generated.managedlist.go b/apis/vshn/v1/zz_generated.managedlist.go index 44527ea03..fe1187a41 100644 --- a/apis/vshn/v1/zz_generated.managedlist.go +++ b/apis/vshn/v1/zz_generated.managedlist.go @@ -4,6 +4,15 @@ package v1 import resource "github.com/crossplane/crossplane-runtime/pkg/resource" +// GetItems of this XVSHNMariaDBList. +func (l *XVSHNMariaDBList) GetItems() []resource.Managed { + items := make([]resource.Managed, len(l.Items)) + for i := range l.Items { + items[i] = &l.Items[i] + } + return items +} + // GetItems of this XVSHNMinioList. func (l *XVSHNMinioList) GetItems() []resource.Managed { items := make([]resource.Managed, len(l.Items)) diff --git a/boostrap/template.go b/boostrap/template.go new file mode 100644 index 000000000..0e5c169e4 --- /dev/null +++ b/boostrap/template.go @@ -0,0 +1,76 @@ +package main + +import ( + "bytes" + "embed" + "encoding/json" + "fmt" + "io" + "os" + "strings" + "text/template" + + "github.com/iancoleman/strcase" +) + +type Service struct { + Name string `json:"name"` + NamePluralLower string + NameShort string + Backup bool `json:"backup"` + Restore bool `json:"restore"` + Maintenance bool `json:"maintenance"` + Tls bool `json:"tls"` + SettingsKey string `json:"settingsKey"` +} + +//go:embed template/api.txt +var apiGoTemplate embed.FS + +func main() { + args := os.Args[1:] + + f, err := os.Open(args[0]) + byteValue, _ := io.ReadAll(f) + + if err != nil { + fmt.Println(fmt.Errorf("cannot open config file: %v", err)) + } + + var renderer Service + + err = json.Unmarshal(byteValue, &renderer) + if err != nil { + fmt.Println(fmt.Errorf("cannot parse json in config file: %v", err)) + } + + if renderer.Name[len(renderer.Name)-1:] == "s" { + renderer.NamePluralLower = strings.ToLower(renderer.Name) + } else { + renderer.NamePluralLower = strings.ToLower(renderer.Name) + "s" + } + renderer.NameShort = strings.TrimLeft(strings.ToLower(renderer.Name), "vshn") + + funcMap := template.FuncMap{ + "CamelCase": strcase.ToCamel, + } + t, err := template.New("api.txt").Funcs(funcMap).ParseFS(apiGoTemplate, "template/api.txt") + + if err != nil { + fmt.Println(fmt.Errorf("cannot parse api go template: %v", err)) + } + buf := new(bytes.Buffer) + + err = t.ExecuteTemplate(buf, "api.txt", renderer) + + if err != nil { + fmt.Println(fmt.Errorf("cannot render api go template: %v", err)) + } + + apiFile := "apis/vshn/v1/dbaas_vshn_" + renderer.NameShort + ".go" + err = os.WriteFile(apiFile, buf.Bytes(), 0644) + if err != nil { + fmt.Println(fmt.Errorf("cannot write file '%s': %v", apiFile, err)) + } + +} diff --git a/boostrap/template/api.txt b/boostrap/template/api.txt new file mode 100644 index 000000000..b80dbd87a --- /dev/null +++ b/boostrap/template/api.txt @@ -0,0 +1,241 @@ +package v1 + +import ( + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + v1 "github.com/vshn/appcat/v4/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Workaround to make nested defaulting work. +// kubebuilder is unable to set a {} default +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_{{.NamePluralLower}}.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_{{.NamePluralLower}}.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.size.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_{{.NamePluralLower}}.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.service.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_{{.NamePluralLower}}.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.tls.default={})" +//go:generate yq -i e ../../generated/vshn.appcat.vshn.io_{{.NamePluralLower}}.yaml --expression "with(.spec.versions[]; .schema.openAPIV3Schema.properties.spec.properties.parameters.properties.backup.default={})" + +// +kubebuilder:object:root=true + +// {{.Name}} is the API for creating {{.NameShort}} instances. +type {{.Name}} struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of a {{.Name}}. + Spec {{.Name}}Spec `json:"spec"` + + // Status reflects the observed state of a {{.Name}}. + Status {{.Name}}Status `json:"status,omitempty"` +} + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true +type {{.Name}}List struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []{{.Name}} `json:"items,omitempty"` +} + +// {{.Name}}Spec defines the desired state of a {{.Name}}. +type {{.Name}}Spec struct { + // Parameters are the configurable fields of a {{.Name}}. + Parameters {{.Name}}Parameters `json:"parameters,omitempty"` + + // WriteConnectionSecretToRef references a secret to which the connection details will be written. + WriteConnectionSecretToRef v1.LocalObjectReference `json:"writeConnectionSecretToRef,omitempty"` +} + +// {{.Name}}Parameters are the configurable fields of a {{.Name}}. +type {{.Name}}Parameters struct { + // Service contains {{.NameShort}} DBaaS specific properties + Service {{.Name}}ServiceSpec `json:"service,omitempty"` + + // Size contains settings to control the sizing of a service. + Size VSHNSizeSpec `json:"size,omitempty"` + + // Scheduling contains settings to control the scheduling of an instance. + Scheduling VSHNDBaaSSchedulingSpec `json:"scheduling,omitempty"` +{{- if .Tls}} + + // TLS contains settings to control tls traffic of a service. + TLS {{.Name}}TLSSpec `json:"tls,omitempty"` +{{- end -}} +{{- if .Backup}} + + // Backup contains settings to control how the instance should get backed up. + Backup K8upBackupSpec `json:"backup,omitempty"` +{{- end -}} +{{- if .Restore}} + + // Restore contains settings to control the restore of an instance. + Restore K8upRestoreSpec `json:"restore,omitempty"` +{{- end -}} +{{- if .Maintenance}} + + // Maintenance contains settings to control the maintenance of an instance. + Maintenance VSHNDBaaSMaintenanceScheduleSpec `json:"maintenance,omitempty"` +{{- end -}} +} + +// {{.Name}}ServiceSpec contains {{.NameShort}} DBaaS specific properties +type {{.Name}}ServiceSpec struct { + // +kubebuilder:validation:Enum= + // +kubebuilder:default= + + // Version contains supported version of {{.NameShort}}. + // Multiple versions are supported. The latest version is the default version. + Version string `json:"version,omitempty"` + + // {{.SettingsKey | CamelCase}} contains additional {{.NameShort}} settings. + {{.SettingsKey | CamelCase}} string `json:"{{.SettingsKey}},omitempty"` + + // +kubebuilder:validation:Enum="besteffort";"guaranteed" + // +kubebuilder:default="besteffort" + + // ServiceLevel defines the service level of this service. Either Best Effort or Guaranteed Availability is allowed. + ServiceLevel VSHNDBaaSServiceLevel `json:"serviceLevel,omitempty"` +} + +// {{.Name}}SizeSpec contains settings to control the sizing of a service. +type {{.Name}}SizeSpec struct { + + // CPURequests defines the requests amount of Kubernetes CPUs for an instance. + CPURequests string `json:"cpuRequests,omitempty"` + + // CPULimits defines the limits amount of Kubernetes CPUs for an instance. + CPULimits string `json:"cpuLimits,omitempty"` + + // MemoryRequests defines the requests amount of memory in units of bytes for an instance. + MemoryRequests string `json:"memoryRequests,omitempty"` + + // MemoryLimits defines the limits amount of memory in units of bytes for an instance. + MemoryLimits string `json:"memoryLimits,omitempty"` + + // Disk defines the amount of disk space for an instance. + Disk string `json:"disk,omitempty"` + + // Plan is the name of the resource plan that defines the compute resources. + Plan string `json:"plan,omitempty"` +} + +{{if .Tls}} +// {{.Name}}TLSSpec contains settings to control tls traffic of a service. +type {{.Name}}TLSSpec struct { + // +kubebuilder:default=true + + // TLSEnabled enables TLS traffic for the service + TLSEnabled bool `json:"enabled,omitempty"` + + // +kubebuilder:default=true + // TLSAuthClients enables client authentication requirement + TLSAuthClients bool `json:"authClients,omitempty"` +} +{{end}} + +// {{.Name}}Status reflects the observed state of a {{.Name}}. +type {{.Name}}Status struct { + NamespaceConditions []v1.Condition `json:"namespaceConditions,omitempty"` + SelfSignedIssuerConditions []v1.Condition `json:"selfSignedIssuerConditions,omitempty"` + LocalCAConditions []v1.Condition `json:"localCAConditions,omitempty"` + CaCertificateConditions []v1.Condition `json:"caCertificateConditions,omitempty"` + ServerCertificateConditions []v1.Condition `json:"serverCertificateConditions,omitempty"` + ClientCertificateConditions []v1.Condition `json:"clientCertificateConditions,omitempty"` + // InstanceNamespace contains the name of the namespace where the instance resides + InstanceNamespace string `json:"instanceNamespace,omitempty"` + // Schedules keeps track of random generated schedules, is overwriten by + // schedules set in the service's spec. + Schedules VSHNScheduleStatus `json:"schedules,omitempty"` +} + +func (v *{{.Name}}) GetClaimNamespace() string { + return v.GetLabels()["crossplane.io/claim-namespace"] +} + +func (v *{{.Name}}) GetInstanceNamespace() string { + return fmt.Sprintf("vshn-{{.NameShort}}-%s", v.GetName()) +} + + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true + +// X{{.Name}} represents the internal composite of this claim +type X{{.Name}} struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec X{{.Name}}Spec `json:"spec"` + Status X{{.Name}}Status `json:"status,omitempty"` +} + +// X{{.Name}}Spec defines the desired state of a {{.Name}}. +type X{{.Name}}Spec struct { + // Parameters are the configurable fields of a {{.Name}}. + Parameters {{.Name}}Parameters `json:"parameters,omitempty"` + + xpv1.ResourceSpec `json:",inline"` +} + +type X{{.Name}}Status struct { + {{.Name}}Status `json:",inline"` + xpv1.ResourceStatus `json:",inline"` +} + +// +kubebuilder:object:generate=true +// +kubebuilder:object:root=true + +// X{{.Name}}List represents a list of composites +type X{{.Name}}List struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []X{{.Name}} `json:"items"` +} + +// GetMaintenanceDayOfWeek returns the currently set day of week +func (n *{{.Name}}) GetMaintenanceDayOfWeek() string { + if n.Spec.Parameters.Maintenance.DayOfWeek != "" { + return n.Spec.Parameters.Maintenance.DayOfWeek + } + return n.Status.Schedules.Maintenance.DayOfWeek +} + +// GetMaintenanceTimeOfDay returns the currently set time of day +func (v *{{.Name}}) GetMaintenanceTimeOfDay() string { + if v.Spec.Parameters.Maintenance.TimeOfDay != "" { + return v.Spec.Parameters.Maintenance.TimeOfDay + } + return v.Status.Schedules.Maintenance.TimeOfDay +} + +// SetMaintenanceDayOfWeek sets the day of week to the given value +func (v *{{.Name}}) SetMaintenanceDayOfWeek(dow string) { + v.Status.Schedules.Maintenance.DayOfWeek = dow +} + +// SetMaintenanceTimeOfDay sets the time of day to the given value +func (v *{{.Name}}) SetMaintenanceTimeOfDay(tod string) { + v.Status.Schedules.Maintenance.TimeOfDay = tod +} + +// GetBackupSchedule returns the current backup schedule +func (v *{{.Name}}) GetBackupSchedule() string { + if v.Spec.Parameters.Backup.Schedule != "" { + return v.Spec.Parameters.Backup.Schedule + } + return v.Status.Schedules.Backup +} + +// SetBackupSchedule overwrites the current backup schedule +func (v *{{.Name}}) SetBackupSchedule(schedule string) { + v.Status.Schedules.Backup = schedule +} + +// GetFullMaintenanceSchedule returns +func (v *{{.Name}}) GetFullMaintenanceSchedule() VSHNDBaaSMaintenanceScheduleSpec { + schedule := v.Spec.Parameters.Maintenance + schedule.DayOfWeek = v.GetMaintenanceDayOfWeek() + schedule.TimeOfDay = v.GetMaintenanceTimeOfDay() + return schedule +} diff --git a/cmd/functions.go b/cmd/functions.go index f57adf2d0..5677f4d90 100644 --- a/cmd/functions.go +++ b/cmd/functions.go @@ -6,6 +6,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/miniobucket" + _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnmariadb" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnminio" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnpostgres" _ "github.com/vshn/appcat/v4/pkg/comp-functions/functions/vshnredis" diff --git a/crds/vshn.appcat.vshn.io_vshnmariadbs.yaml b/crds/vshn.appcat.vshn.io_vshnmariadbs.yaml new file mode 100644 index 000000000..1745e3f55 --- /dev/null +++ b/crds/vshn.appcat.vshn.io_vshnmariadbs.yaml @@ -0,0 +1,438 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: vshnmariadbs.vshn.appcat.vshn.io +spec: + group: vshn.appcat.vshn.io + names: + kind: VSHNMariaDB + listKind: VSHNMariaDBList + plural: vshnmariadbs + singular: vshnmariadb + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: VSHNMariaDB is the API for creating MariaDB instances. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of a VSHNMariaDB. + properties: + parameters: + description: Parameters are the configurable fields of a VSHNMariaDB. + properties: + backup: + description: Backup contains settings to control how the instance should get backed up. + properties: + retention: + description: K8upRetentionPolicy describes the retention configuration for a K8up backup. + properties: + keepDaily: + default: 6 + type: integer + keepHourly: + type: integer + keepLast: + type: integer + keepMonthly: + type: integer + keepWeekly: + type: integer + keepYearly: + type: integer + type: object + schedule: + pattern: ^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$ + type: string + type: object + default: {} + maintenance: + description: Maintenance contains settings to control the maintenance of an instance. + properties: + dayOfWeek: + description: DayOfWeek specifies at which weekday the maintenance is held place. Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: 'TimeOfDay for installing updates in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + restore: + description: Restore contains settings to control the restore of an instance. + properties: + backupName: + description: BackupName is the name of the specific backup you want to restore. + type: string + claimName: + description: ClaimName specifies the name of the instance you want to restore from. The claim has to be in the same namespace as this new instance. + type: string + type: object + scheduling: + description: Scheduling contains settings to control the scheduling of an instance. + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a selector which must match a node’s labels for the pod to be scheduled on that node + type: object + type: object + service: + description: Service contains MariaDB DBaaS specific properties + properties: + mariadbSettings: + description: MariadbSettings contains additional MariaDB settings. + type: string + mode: + default: standalone + description: Mode configures the mode of MariaDB. Valid values are "replication" and "standalone". + enum: + - replication + - standalone + type: string + serviceLevel: + default: besteffort + description: ServiceLevel defines the service level of this service. Either Best Effort or Guaranteed Availability is allowed. + enum: + - besteffort + - guaranteed + type: string + version: + default: "11.2" + description: Version contains supported version of MariaDB. Multiple versions are supported. The latest version "11.2" is the default version. + enum: + - "10.4" + - "10.5" + - "10.6" + - "10.9" + - "10.10" + - "10.11" + - "11.0" + - "11.1" + - "11.2" + type: string + type: object + default: {} + size: + description: Size contains settings to control the sizing of a service. + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs for an instance. + type: string + disk: + description: Disk defines the amount of disk space for an instance. + type: string + memory: + description: Memory defines the amount of memory in units of bytes for an instance. + type: string + plan: + description: Plan is the name of the resource plan that defines the compute resources. + type: string + requests: + description: Requests defines CPU and memory requests for an instance + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs for an instance. + type: string + memory: + description: Memory defines the amount of memory in units of bytes for an instance. + type: string + type: object + type: object + default: {} + storageClass: + description: StorageClass configures the storageClass to use for the PVC used by MariaDB. + type: string + tls: + description: TLS contains settings to control tls traffic of a service. + properties: + authClients: + default: true + description: TLSAuthClients enables client authentication requirement + type: boolean + enabled: + default: true + description: TLSEnabled enables TLS traffic for the service + type: boolean + type: object + default: {} + type: object + default: {} + writeConnectionSecretToRef: + description: WriteConnectionSecretToRef references a secret to which the connection details will be written. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + status: + description: Status reflects the observed state of a VSHNMariaDB. + properties: + caCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + clientCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + instanceNamespace: + description: InstanceNamespace contains the name of the namespace where the instance resides + type: string + localCAConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + namespaceConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + schedules: + description: Schedules keeps track of random generated schedules, is overwriten by schedules set in the service's spec. + properties: + backup: + description: Backup keeps track of the backup schedule. + type: string + maintenance: + description: Maintenance keeps track of the maintenance schedule. + properties: + dayOfWeek: + description: DayOfWeek specifies at which weekday the maintenance is held place. Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: 'TimeOfDay for installing updates in UTC. Format: "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + type: object + selfSignedIssuerConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + serverCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/crds/vshn.appcat.vshn.io_xvshnmariadbs.yaml b/crds/vshn.appcat.vshn.io_xvshnmariadbs.yaml new file mode 100644 index 000000000..83815cf29 --- /dev/null +++ b/crds/vshn.appcat.vshn.io_xvshnmariadbs.yaml @@ -0,0 +1,709 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.13.0 + name: xvshnmariadbs.vshn.appcat.vshn.io +spec: + group: vshn.appcat.vshn.io + names: + kind: XVSHNMariaDB + listKind: XVSHNMariaDBList + plural: xvshnmariadbs + singular: xvshnmariadb + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: XVSHNMariaDB represents the internal composite of this claim + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: XVSHNMariaDBSpec defines the desired state of a VSHNMariaDB. + properties: + deletionPolicy: + default: Delete + description: 'DeletionPolicy specifies what will happen to the underlying + external when this managed resource is deleted - either "Delete" + or "Orphan" the external resource. This field is planned to be deprecated + in favor of the ManagementPolicies field in a future release. Currently, + both could be set independently and non-default values would be + honored if the feature flag is enabled. See the design doc for more + information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223' + enum: + - Orphan + - Delete + type: string + managementPolicies: + default: + - '*' + description: 'THIS IS A BETA FIELD. It is on by default but can be + opted out through a Crossplane feature flag. ManagementPolicies + specify the array of actions Crossplane is allowed to take on the + managed and external resources. This field is planned to replace + the DeletionPolicy field in a future release. Currently, both could + be set independently and non-default values would be honored if + the feature flag is enabled. If both are custom, the DeletionPolicy + field will be ignored. See the design doc for more information: + https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 + and this one: https://github.com/crossplane/crossplane/blob/444267e84783136daa93568b364a5f01228cacbe/design/one-pager-ignore-changes.md' + items: + description: A ManagementAction represents an action that the Crossplane + controllers can take on an external resource. + enum: + - Observe + - Create + - Update + - Delete + - LateInitialize + - '*' + type: string + type: array + parameters: + description: Parameters are the configurable fields of a VSHNMariaDB. + properties: + backup: + description: Backup contains settings to control how the instance + should get backed up. + properties: + retention: + description: K8upRetentionPolicy describes the retention configuration + for a K8up backup. + properties: + keepDaily: + default: 6 + type: integer + keepHourly: + type: integer + keepLast: + type: integer + keepMonthly: + type: integer + keepWeekly: + type: integer + keepYearly: + type: integer + type: object + schedule: + pattern: ^(\*|([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])|\*\/([0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9])) + (\*|([0-9]|1[0-9]|2[0-3])|\*\/([0-9]|1[0-9]|2[0-3])) (\*|([1-9]|1[0-9]|2[0-9]|3[0-1])|\*\/([1-9]|1[0-9]|2[0-9]|3[0-1])) + (\*|([1-9]|1[0-2])|\*\/([1-9]|1[0-2])) (\*|([0-6])|\*\/([0-6]))$ + type: string + type: object + maintenance: + description: Maintenance contains settings to control the maintenance + of an instance. + properties: + dayOfWeek: + description: DayOfWeek specifies at which weekday the maintenance + is held place. Allowed values are [monday, tuesday, wednesday, + thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: 'TimeOfDay for installing updates in UTC. Format: + "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + restore: + description: Restore contains settings to control the restore + of an instance. + properties: + backupName: + description: BackupName is the name of the specific backup + you want to restore. + type: string + claimName: + description: ClaimName specifies the name of the instance + you want to restore from. The claim has to be in the same + namespace as this new instance. + type: string + type: object + scheduling: + description: Scheduling contains settings to control the scheduling + of an instance. + properties: + nodeSelector: + additionalProperties: + type: string + description: NodeSelector is a selector which must match a + node’s labels for the pod to be scheduled on that node + type: object + type: object + service: + description: Service contains MariaDB DBaaS specific properties + properties: + mariadbSettings: + description: MariadbSettings contains additional MariaDB settings. + type: string + mode: + default: standalone + description: Mode configures the mode of MariaDB. Valid values + are "replication" and "standalone". + enum: + - replication + - standalone + type: string + serviceLevel: + default: besteffort + description: ServiceLevel defines the service level of this + service. Either Best Effort or Guaranteed Availability is + allowed. + enum: + - besteffort + - guaranteed + type: string + version: + default: "11.2" + description: Version contains supported version of MariaDB. + Multiple versions are supported. The latest version "11.2" + is the default version. + enum: + - "10.4" + - "10.5" + - "10.6" + - "10.9" + - "10.10" + - "10.11" + - "11.0" + - "11.1" + - "11.2" + type: string + type: object + size: + description: Size contains settings to control the sizing of a + service. + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs for + an instance. + type: string + disk: + description: Disk defines the amount of disk space for an + instance. + type: string + memory: + description: Memory defines the amount of memory in units + of bytes for an instance. + type: string + plan: + description: Plan is the name of the resource plan that defines + the compute resources. + type: string + requests: + description: Requests defines CPU and memory requests for + an instance + properties: + cpu: + description: CPU defines the amount of Kubernetes CPUs + for an instance. + type: string + memory: + description: Memory defines the amount of memory in units + of bytes for an instance. + type: string + type: object + type: object + storageClass: + description: StorageClass configures the storageClass to use for + the PVC used by MariaDB. + type: string + tls: + description: TLS contains settings to control tls traffic of a + service. + properties: + authClients: + default: true + description: TLSAuthClients enables client authentication + requirement + type: boolean + enabled: + default: true + description: TLSEnabled enables TLS traffic for the service + type: boolean + type: object + type: object + providerConfigRef: + default: + name: default + description: ProviderConfigReference specifies how the provider that + will be used to create, observe, update, and delete this managed + resource should be configured. + properties: + name: + description: Name of the referenced object. + type: string + policy: + description: Policies for referencing. + properties: + resolution: + default: Required + description: Resolution specifies whether resolution of this + reference is required. The default is 'Required', which + means the reconcile will fail if the reference cannot be + resolved. 'Optional' means this reference will be a no-op + if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: Resolve specifies when this reference should + be resolved. The default is 'IfNotPresent', which will attempt + to resolve the reference only when the corresponding field + is not present. Use 'Always' to resolve the reference on + every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + required: + - name + type: object + publishConnectionDetailsTo: + description: PublishConnectionDetailsTo specifies the connection secret + config which contains a name, metadata and a reference to secret + store config to which any connection details for this managed resource + should be written. Connection details frequently include the endpoint, + username, and password required to connect to the managed resource. + properties: + configRef: + default: + name: default + description: SecretStoreConfigRef specifies which secret store + config should be used for this ConnectionSecret. + properties: + name: + description: Name of the referenced object. + type: string + policy: + description: Policies for referencing. + properties: + resolution: + default: Required + description: Resolution specifies whether resolution of + this reference is required. The default is 'Required', + which means the reconcile will fail if the reference + cannot be resolved. 'Optional' means this reference + will be a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: Resolve specifies when this reference should + be resolved. The default is 'IfNotPresent', which will + attempt to resolve the reference only when the corresponding + field is not present. Use 'Always' to resolve the reference + on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + required: + - name + type: object + metadata: + description: Metadata is the metadata for connection secret. + properties: + annotations: + additionalProperties: + type: string + description: Annotations are the annotations to be added to + connection secret. - For Kubernetes secrets, this will be + used as "metadata.annotations". - It is up to Secret Store + implementation for others store types. + type: object + labels: + additionalProperties: + type: string + description: Labels are the labels/tags to be added to connection + secret. - For Kubernetes secrets, this will be used as "metadata.labels". + - It is up to Secret Store implementation for others store + types. + type: object + type: + description: Type is the SecretType for the connection secret. + - Only valid for Kubernetes Secret Stores. + type: string + type: object + name: + description: Name is the name of the connection secret. + type: string + required: + - name + type: object + writeConnectionSecretToRef: + description: WriteConnectionSecretToReference specifies the namespace + and name of a Secret to which any connection details for this managed + resource should be written. Connection details frequently include + the endpoint, username, and password required to connect to the + managed resource. This field is planned to be replaced in a future + release in favor of PublishConnectionDetailsTo. Currently, both + could be set independently and connection details would be published + to both without affecting each other. + properties: + name: + description: Name of the secret. + type: string + namespace: + description: Namespace of the secret. + type: string + required: + - name + - namespace + type: object + type: object + status: + properties: + caCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + clientCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + conditions: + description: Conditions of the resource. + items: + description: A Condition that may apply to a resource. + properties: + lastTransitionTime: + description: LastTransitionTime is the last time this condition + transitioned from one status to another. + format: date-time + type: string + message: + description: A Message containing details about this condition's + last transition from one status to another, if any. + type: string + reason: + description: A Reason for this condition's last transition from + one status to another. + type: string + status: + description: Status of this condition; is it currently True, + False, or Unknown? + type: string + type: + description: Type of this condition. At most one of each condition + type may apply to a resource at any point in time. + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceNamespace: + description: InstanceNamespace contains the name of the namespace + where the instance resides + type: string + localCAConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + namespaceConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + schedules: + description: Schedules keeps track of random generated schedules, + is overwriten by schedules set in the service's spec. + properties: + backup: + description: Backup keeps track of the backup schedule. + type: string + maintenance: + description: Maintenance keeps track of the maintenance schedule. + properties: + dayOfWeek: + description: DayOfWeek specifies at which weekday the maintenance + is held place. Allowed values are [monday, tuesday, wednesday, + thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: 'TimeOfDay for installing updates in UTC. Format: + "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object + type: object + selfSignedIssuerConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + serverCertificateConditions: + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/crds/vshn.appcat.vshn.io_xvshnminios.yaml b/crds/vshn.appcat.vshn.io_xvshnminios.yaml index d41b4f277..dfd6a0d88 100644 --- a/crds/vshn.appcat.vshn.io_xvshnminios.yaml +++ b/crds/vshn.appcat.vshn.io_xvshnminios.yaml @@ -340,50 +340,120 @@ spec: type: object status: properties: - spec: - description: ResourceStatus represents the observed state of a managed - resource. + conditions: + description: Conditions of the resource. + items: + description: A Condition that may apply to a resource. + properties: + lastTransitionTime: + description: LastTransitionTime is the last time this condition + transitioned from one status to another. + format: date-time + type: string + message: + description: A Message containing details about this condition's + last transition from one status to another, if any. + type: string + reason: + description: A Reason for this condition's last transition from + one status to another. + type: string + status: + description: Status of this condition; is it currently True, + False, or Unknown? + type: string + type: + description: Type of this condition. At most one of each condition + type may apply to a resource at any point in time. + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + instanceNamespace: + description: InstanceNamespace contains the name of the namespace + where the instance resides + type: string + namespaceConditions: + description: MinioConditions contains the status conditions of the + backing object. + items: + properties: + lastTransitionTime: + description: LastTransitionTime is the last time the condition + transitioned from one status to another. + format: date-time + type: string + message: + description: Message is a human-readable message indicating + details about the transition. + maxLength: 32768 + type: string + observedGeneration: + description: ObservedGeneration represents the .metadata.generation + that the condition was set based upon. For instance, if .metadata.generation + is currently 12, but the .status.conditions[x].observedGeneration + is 9, the condition is out of date with respect to the current + state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: Reason contains a programmatic identifier indicating + the reason for the condition's last transition. + maxLength: 1024 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: Status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: Type of condition. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + type: object + type: array + schedules: + description: Schedules keeps track of random generated schedules, + is overwriten by schedules set in the service's spec. properties: - conditions: - description: Conditions of the resource. - items: - description: A Condition that may apply to a resource. - properties: - lastTransitionTime: - description: LastTransitionTime is the last time this condition - transitioned from one status to another. - format: date-time - type: string - message: - description: A Message containing details about this condition's - last transition from one status to another, if any. - type: string - reason: - description: A Reason for this condition's last transition - from one status to another. - type: string - status: - description: Status of this condition; is it currently True, - False, or Unknown? - type: string - type: - description: Type of this condition. At most one of each - condition type may apply to a resource at any point in - time. - type: string - required: - - lastTransitionTime - - reason - - status - - type - type: object - type: array - x-kubernetes-list-map-keys: - - type - x-kubernetes-list-type: map + backup: + description: Backup keeps track of the backup schedule. + type: string + maintenance: + description: Maintenance keeps track of the maintenance schedule. + properties: + dayOfWeek: + description: DayOfWeek specifies at which weekday the maintenance + is held place. Allowed values are [monday, tuesday, wednesday, + thursday, friday, saturday, sunday] + enum: + - monday + - tuesday + - wednesday + - thursday + - friday + - saturday + - sunday + type: string + timeOfDay: + description: 'TimeOfDay for installing updates in UTC. Format: + "hh:mm:ss".' + pattern: ^([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$ + type: string + type: object type: object - required: - - spec type: object required: - spec diff --git a/go.mod b/go.mod index 9f8c35bc2..9fb4e8659 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( dario.cat/mergo v1.0.0 github.com/appuio/appuio-cloud-reporting v0.15.0 github.com/blang/semver/v4 v4.0.0 + github.com/cert-manager/cert-manager v1.13.2 github.com/crossplane-contrib/provider-kubernetes v0.10.0-rc.0.0.20230815142830-063004a06019 github.com/crossplane/crossplane v1.14.1 github.com/crossplane/crossplane-runtime v1.14.2 @@ -16,9 +17,10 @@ require ( github.com/deepmap/oapi-codegen v0.0.0-00010101000000-000000000000 github.com/go-logr/logr v1.3.0 github.com/go-logr/zapr v1.2.4 - github.com/golang/mock v1.4.4 + github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.3 github.com/hashicorp/go-version v1.6.0 + github.com/iancoleman/strcase v0.2.0 github.com/jackc/pgx/v5 v5.3.1 github.com/k8up-io/k8up/v2 v2.7.1 github.com/minio/minio-go/v7 v7.0.63 @@ -113,7 +115,6 @@ require ( github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20230516205744-dbecb1de8cfa // indirect github.com/google/safetext v0.0.0-20220905092116-b49f7bc46da2 // indirect github.com/huandu/xstrings v1.4.0 // indirect - github.com/iancoleman/strcase v0.2.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 // indirect @@ -124,7 +125,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.17 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect - github.com/onsi/ginkgo/v2 v2.12.0 // indirect github.com/pelletier/go-toml v1.9.4 // indirect github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -143,6 +143,7 @@ require ( k8s.io/apiserver v0.28.3 // indirect k8s.io/cli-runtime v0.28.2 // indirect k8s.io/gengo v0.0.0-20230829151522-9cce18d56c01 // indirect + sigs.k8s.io/gateway-api v0.8.0 // indirect ) require ( diff --git a/go.sum b/go.sum index ab758a32d..31f1e046c 100644 --- a/go.sum +++ b/go.sum @@ -158,6 +158,8 @@ github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7N github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cert-manager/cert-manager v1.13.2 h1:LG8+OLvxtc49CSyfjW7zHSyvlt7JVaHgRGyhfdvPpkk= +github.com/cert-manager/cert-manager v1.13.2/go.mod h1:AdfSU8muS+bj3C46YaD1VrlpXh672z5MeW/k1k5Sl1w= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chigopher/pathlib v0.15.0 h1:1pg96WL3iC1/YyWV4UJSl3E0GBf4B+h5amBtsbAAieY= @@ -323,8 +325,9 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -981,6 +984,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -1162,6 +1166,8 @@ sigs.k8s.io/controller-runtime v0.16.3 h1:2TuvuokmfXvDUamSx1SuAOO3eTyye+47mJCigw sigs.k8s.io/controller-runtime v0.16.3/go.mod h1:j7bialYoSn142nv9sCOJmQgDXQXxnroFU4VnX/brVJ0= sigs.k8s.io/controller-tools v0.13.0 h1:NfrvuZ4bxyolhDBt/rCZhDnx3M2hzlhgo5n3Iv2RykI= sigs.k8s.io/controller-tools v0.13.0/go.mod h1:5vw3En2NazbejQGCeWKRrE7q4P+CW8/klfVqP8QZkgA= +sigs.k8s.io/gateway-api v0.8.0 h1:isQQ3Jx2qFP7vaA3ls0846F0Amp9Eq14P08xbSwVbQg= +sigs.k8s.io/gateway-api v0.8.0/go.mod h1:okOnjPNBFbIS/Rw9kAhuIUaIkLhTKEu+ARIuXk2dgaM= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kind v0.20.0 h1:f0sc3v9mQbGnjBUaqSFST1dwIuiikKVGgoTwpoP33a8= diff --git a/mariadb.json b/mariadb.json new file mode 100644 index 000000000..571b50db6 --- /dev/null +++ b/mariadb.json @@ -0,0 +1,8 @@ +{ + "name": "VSHNMariaDB", + "backup": true, + "restore": true, + "maintenance": true, + "tls": true, + "settingsKey": "mariadbSettings" +} diff --git a/package/crossplane.yaml b/package/crossplane.yaml index bdfd61440..b2b254502 100644 --- a/package/crossplane.yaml +++ b/package/crossplane.yaml @@ -4,6 +4,6 @@ kind: Function metadata: name: function-appcat spec: - image: ghcr.io/vshn/appcat:change_xplane114 + image: ghcr.io/vshn/appcat:feature_mariadb crossplane: version: ">=1.14.0" diff --git a/pkg/comp-functions/functions/common/netpol.go b/pkg/comp-functions/functions/common/netpol.go new file mode 100644 index 000000000..7a2bbe55f --- /dev/null +++ b/pkg/comp-functions/functions/common/netpol.go @@ -0,0 +1,51 @@ +package common + +import ( + "context" + "fmt" + + "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" + netv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func CreateNetworkPolicy(ctx context.Context, sourceNs []string, instanceNs string, instance string, svc *runtime.ServiceRuntime) error { + + netPolPeer := []netv1.NetworkPolicyPeer{} + for _, ns := range sourceNs { + peer := netv1.NetworkPolicyPeer{ + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "kubernetes.io/metadata.name": ns, + }, + }, + } + netPolPeer = append(netPolPeer, peer) + } + + netPol := netv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance, + Namespace: instanceNs, + }, + Spec: netv1.NetworkPolicySpec{ + PolicyTypes: []netv1.PolicyType{ + "Ingress", + }, + PodSelector: metav1.LabelSelector{}, + Ingress: []netv1.NetworkPolicyIngressRule{ + { + From: netPolPeer, + }, + }, + }, + } + + err := svc.SetDesiredKubeObject(&netPol, instance+"-netpol") + if err != nil { + err = fmt.Errorf("cannot create networkPolicy object: %w", err) + return err + } + + return nil +} diff --git a/pkg/comp-functions/functions/common/tls.go b/pkg/comp-functions/functions/common/tls.go new file mode 100644 index 000000000..4fbb57628 --- /dev/null +++ b/pkg/comp-functions/functions/common/tls.go @@ -0,0 +1,141 @@ +package common + +import ( + "context" + "fmt" + "time" + + cmv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" + v1 "github.com/cert-manager/cert-manager/pkg/apis/meta/v1" + "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func CreateTlsCerts(ctx context.Context, ns string, instance string, svc *runtime.ServiceRuntime) error { + + selfSignedIssuer := &cmv1.Issuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance + "-selfsigned", + Namespace: ns, + }, + Spec: cmv1.IssuerSpec{ + IssuerConfig: cmv1.IssuerConfig{ + SelfSigned: &cmv1.SelfSignedIssuer{ + CRLDistributionPoints: []string{}, + }, + }, + }, + } + + err := svc.SetDesiredKubeObject(selfSignedIssuer, instance+"-selfsigned-issuer") + if err != nil { + err = fmt.Errorf("cannot create selfSignedIssuer object: %w", err) + return err + } + + caCert := &cmv1.Certificate{ + + ObjectMeta: metav1.ObjectMeta{ + Name: instance + "-ca", + Namespace: ns, + }, + Spec: cmv1.CertificateSpec{ + SecretName: "tls-ca-certificate", + Duration: &metav1.Duration{ + Duration: time.Duration(87600 * time.Hour), + }, + RenewBefore: &metav1.Duration{ + Duration: time.Duration(2400 * time.Hour), + }, + Subject: &cmv1.X509Subject{ + Organizations: []string{ + "vshn-appcat-ca", + }, + }, + IsCA: true, + PrivateKey: &cmv1.CertificatePrivateKey{ + Algorithm: cmv1.RSAKeyAlgorithm, + Encoding: cmv1.PKCS1, + Size: 4096, + }, + CommonName: instance + "-ca", + IssuerRef: v1.ObjectReference{ + Name: instance + "-selfsigned", + Kind: "Issuer", + Group: "cert-manager.io", + }, + }, + } + + err = svc.SetDesiredKubeObject(caCert, instance+"-ca-cert") + if err != nil { + err = fmt.Errorf("cannot create caCert object: %w", err) + return err + } + + caIssuer := &cmv1.Issuer{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance + "-ca", + Namespace: ns, + }, + Spec: cmv1.IssuerSpec{ + IssuerConfig: cmv1.IssuerConfig{ + CA: &cmv1.CAIssuer{ + SecretName: "tls-ca-certificate", + }, + }, + }, + } + + err = svc.SetDesiredKubeObject(caIssuer, instance+"-ca-issuer") + if err != nil { + err = fmt.Errorf("cannot create caIssuer object: %w", err) + return err + } + + serverCert := &cmv1.Certificate{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance + "-server", + Namespace: ns, + }, + Spec: cmv1.CertificateSpec{ + SecretName: "tls-server-certificate", + Duration: &metav1.Duration{ + Duration: time.Duration(87600 * time.Hour), + }, + RenewBefore: &metav1.Duration{ + Duration: time.Duration(2400 * time.Hour), + }, + Subject: &cmv1.X509Subject{ + Organizations: []string{ + "vshn-appcat-server", + }, + }, + IsCA: false, + PrivateKey: &cmv1.CertificatePrivateKey{ + Algorithm: cmv1.RSAKeyAlgorithm, + Encoding: cmv1.PKCS1, + Size: 4096, + }, + Usages: []cmv1.KeyUsage{"server auth", "client auth"}, + DNSNames: []string{ + instance + "." + ns + ".svc.cluster.local", + instance + "." + ns + ".svc", + }, + IssuerRef: v1.ObjectReference{ + Name: instance + "-ca", + Kind: "Issuer", + Group: "cert-manager.io", + }, + }, + } + + err = svc.SetDesiredKubeObject(serverCert, instance+"-server-cert") + if err != nil { + err = fmt.Errorf("cannot create serverCert object: %w", err) + return err + } + + return nil + +} diff --git a/pkg/comp-functions/functions/vshnmariadb/mariadb_deploy.go b/pkg/comp-functions/functions/vshnmariadb/mariadb_deploy.go new file mode 100644 index 000000000..c8f6d91a5 --- /dev/null +++ b/pkg/comp-functions/functions/vshnmariadb/mariadb_deploy.go @@ -0,0 +1,263 @@ +package vshnmariadb + +import ( + "context" + "encoding/json" + "fmt" + + xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1" + xfnproto "github.com/crossplane/function-sdk-go/proto/v1beta1" + xhelmbeta1 "github.com/vshn/appcat/v4/apis/helm/release/v1beta1" + vshnv1 "github.com/vshn/appcat/v4/apis/vshn/v1" + "github.com/vshn/appcat/v4/pkg/common/utils" + "github.com/vshn/appcat/v4/pkg/comp-functions/functions/common" + "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sruntime "k8s.io/apimachinery/pkg/runtime" + controllerruntime "sigs.k8s.io/controller-runtime" +) + +const ( + SLIBucketName = "vshn-test-bucket-for-sli" +) + +// DeployMariadb will add deploy the objects to deploy mariadb +func DeployMariadb(ctx context.Context, svc *runtime.ServiceRuntime) *xfnproto.Result { + + l := controllerruntime.LoggerFrom(ctx) + + comp := &vshnv1.VSHNMariaDB{} + err := svc.GetObservedComposite(comp) + if err != nil { + err = fmt.Errorf("cannot get observed composite: %w", err) + return runtime.NewFatalResult(err) + } + + l.Info("Creating namespace for mariadb instance") + err = createObjectNamespace(ctx, comp, svc) + if err != nil { + err = fmt.Errorf("cannot create mariadb namespace: %w", err) + return runtime.NewFatalResult(err) + } + + l.Info("Creating tls certificate for mariadb instance") + err = common.CreateTlsCerts(ctx, comp.GetInstanceNamespace(), comp.GetName(), svc) + if err != nil { + err = fmt.Errorf("cannot create tls certificate: %w", err) + return runtime.NewFatalResult(err) + } + + l.Info("Creating helm release for mariadb instance") + err = createObjectHelmRelease(ctx, comp, svc) + if err != nil { + err = fmt.Errorf("cannot create helm release: %w", err) + return runtime.NewFatalResult(err) + } + + l.Info("Creating network policies mariadb instance") + sourceNs := []string{comp.GetClaimNamespace()} + if svc.GetBoolFromCompositionConfig("slosEnabled") { + sourceNs = append(sourceNs, svc.Config.Data["slosNs"]) + } + err = common.CreateNetworkPolicy(ctx, sourceNs, comp.GetInstanceNamespace(), comp.GetName(), svc) + if err != nil { + err = fmt.Errorf("cannot create helm release: %w", err) + return runtime.NewFatalResult(err) + } + + l.Info("Get connection details from secret") + err = getConnectionDetails(ctx, comp, svc) + if err != nil { + if err == runtime.ErrNotFound { + return runtime.NewNormalResult("skipping sli bucket, connectiondetails not yet available") + } + err = fmt.Errorf("cannot get connection details: %w", err) + return runtime.NewFatalResult(fmt.Errorf("cannot get connection details: %w", err)) + } + return nil +} + +// Create the namespace for the mariadb instance +func createObjectNamespace(ctx context.Context, comp *vshnv1.VSHNMariaDB, svc *runtime.ServiceRuntime) error { + + ns := &corev1.Namespace{ + + ObjectMeta: metav1.ObjectMeta{ + Name: comp.GetInstanceNamespace(), + Labels: map[string]string{ + "appcat.vshn.io/servicename": "mariadb-standalone", + "appcat.vshn.io/claim-namespace": comp.GetClaimNamespace(), + "appuio.io/no-rbac-creation": "true", + "appuio.io/billing-name": "appcat-mariadb"}, + }, + } + + return svc.SetDesiredKubeObject(ns, comp.Name+"-ns") +} + +// Create the helm release for the mariadb instance +func createObjectHelmRelease(ctx context.Context, comp *vshnv1.VSHNMariaDB, svc *runtime.ServiceRuntime) error { + + plan := comp.Spec.Parameters.Size.GetPlan(svc.Config.Data["defaultPlan"]) + + resouces, err := utils.FetchPlansFromConfig(ctx, svc, plan) + if err != nil { + err = fmt.Errorf("cannot fetch plans from the composition config, maybe they are not set: %w", err) + return err + } + + reqMem := comp.Spec.Parameters.Size.Requests.Memory + reqCPU := comp.Spec.Parameters.Size.Requests.CPU + mem := comp.Spec.Parameters.Size.Memory + cpu := comp.Spec.Parameters.Size.CPU + disk := comp.Spec.Parameters.Size.Disk + + if reqMem == "" { + reqMem = resouces.MemoryRequests.String() + } + if reqCPU == "" { + reqCPU = resouces.CPURequests.String() + } + if mem == "" { + mem = resouces.MemoryLimits.String() + } + if cpu == "" { + cpu = resouces.CPULimits.String() + } + if disk == "" { + disk = resouces.Disk.String() + } + + values := map[string]interface{}{ + "fullnameOverride": comp.GetName(), + "replicaCount": 1, + "resources": map[string]interface{}{ + "requests": map[string]interface{}{ + "memory": reqMem, + "cpu": reqCPU, + }, + "limits": map[string]interface{}{ + "memory": mem, + "cpu": cpu, + }, + }, + "tls": map[string]interface{}{ + "enabled": true, + "certificatesSecret": "tls-server-certificate", + "certFilename": "tls.crt", + "certKeyFilename": "tls.key", + "certCAFilename": "ca.crt", + }, + "mariadbConfiguration": comp.Spec.Parameters.Service.MariadbSettings, + "persistence": map[string]interface{}{ + "size": disk, + "storageClass": comp.Spec.Parameters.StorageClass, + }, + "startupProbe": map[string]interface{}{ + "enabled": true, + }, + "metrics": map[string]interface{}{ + "enabled": true, + "containerSecurityContext": map[string]interface{}{ + "enabled": false, + }, + }, + "securityContext": map[string]interface{}{ + "enabled": false, + }, + "containerSecurityContext": map[string]interface{}{ + "enabled": false, + }, + "podSecurityContext": map[string]interface{}{ + "enabled": false, + }, + } + + vb, err := json.Marshal(values) + if err != nil { + err = fmt.Errorf("cannot marshal helm values: %w", err) + return err + } + + r := &xhelmbeta1.Release{ + ObjectMeta: metav1.ObjectMeta{ + Name: comp.GetName(), + }, + Spec: xhelmbeta1.ReleaseSpec{ + ForProvider: xhelmbeta1.ReleaseParameters{ + Chart: xhelmbeta1.ChartSpec{ + Repository: svc.Config.Data["chartRepository"], + Version: svc.Config.Data["chartVersion"], + Name: "mariadb-galera", + }, + Namespace: comp.GetInstanceNamespace(), + ValuesSpec: xhelmbeta1.ValuesSpec{ + Values: k8sruntime.RawExtension{ + Raw: vb, + }, + }, + }, + ResourceSpec: xpv1.ResourceSpec{ + ProviderConfigReference: &xpv1.Reference{ + Name: "helm", + }, + WriteConnectionSecretToReference: &xpv1.SecretReference{ + Name: comp.GetName() + "-connection", + Namespace: comp.GetInstanceNamespace(), + }, + }, + ConnectionDetails: []xhelmbeta1.ConnectionDetail{ + { + ObjectReference: corev1.ObjectReference{ + APIVersion: "v1", + Kind: "Secret", + Name: comp.GetName(), + Namespace: comp.GetInstanceNamespace(), + FieldPath: "data.mariadb-root-password", + }, + ToConnectionSecretKey: "MARIADB_PASSWORD", + }, + { + ObjectReference: corev1.ObjectReference{ + APIVersion: "v1", + Kind: "Service", + Name: comp.GetName(), + Namespace: comp.GetInstanceNamespace(), + FieldPath: "spec.ports[0].port", + }, + ToConnectionSecretKey: "MARIADB_PORT", + }, + { + ObjectReference: corev1.ObjectReference{ + APIVersion: "v1", + Kind: "Secret", + Name: "tls-server-certificate", + Namespace: comp.GetInstanceNamespace(), + FieldPath: "data[ca.crt]", + }, + ToConnectionSecretKey: "ca.crt", + SkipPartOfReleaseCheck: true, + }, + }, + }, + } + + err = svc.AddObservedConnectionDetails(comp.Name + "-release") + if err != nil { + return err + } + + return svc.SetDesiredComposedResourceWithName(r, comp.Name+"-release") +} + +func getConnectionDetails(ctx context.Context, comp *vshnv1.VSHNMariaDB, svc *runtime.ServiceRuntime) error { + mariadbHost := comp.GetName() + ".vshn-mariadb-" + comp.GetName() + ".svc.cluster.local" + mariadbURL := fmt.Sprintf("mysql://%s:%s", mariadbHost, svc.GetConnectionDetails()["MARIADB_PORT"]) + + svc.SetConnectionDetail("MARIADB_HOST", []byte(mariadbHost)) + svc.SetConnectionDetail("MARIADB_USERNAME", []byte("root")) + svc.SetConnectionDetail("MARIADB_URL", []byte(mariadbURL)) + + return nil +} diff --git a/pkg/comp-functions/functions/vshnmariadb/register.go b/pkg/comp-functions/functions/vshnmariadb/register.go new file mode 100644 index 000000000..e2f89b985 --- /dev/null +++ b/pkg/comp-functions/functions/vshnmariadb/register.go @@ -0,0 +1,15 @@ +package vshnmariadb + +import "github.com/vshn/appcat/v4/pkg/comp-functions/runtime" + +func init() { + runtime.RegisterService("mariadb", runtime.Service{ + Steps: []runtime.Step{ + + { + Name: "deploy", + Execute: DeployMariadb, + }, + }, + }) +} diff --git a/pkg/scheme.go b/pkg/scheme.go index 5dfa8f8d3..8ca91e13a 100644 --- a/pkg/scheme.go +++ b/pkg/scheme.go @@ -3,6 +3,7 @@ package pkg import ( xhelm "github.com/vshn/appcat/v4/apis/helm/release/v1beta1" + cmv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1" xkube "github.com/crossplane-contrib/provider-kubernetes/apis/object/v1alpha1" k8upv1 "github.com/k8up-io/k8up/v2/api/v1" promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" @@ -15,7 +16,9 @@ import ( appsv1 "k8s.io/api/apps/v1" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" + netv1 "k8s.io/api/networking/v1" rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/runtime" ) @@ -40,4 +43,6 @@ func AddToScheme(s *runtime.Scheme) { _ = minioproviderv1.SchemeBuilder.AddToScheme(s) _ = promv1.AddToScheme(s) _ = alertmanagerv1alpha1.AddToScheme(s) + _ = cmv1.SchemeBuilder.AddToScheme(s) + _ = netv1.AddToScheme(s) }