Skip to content

Commit

Permalink
Add cronjob to periodically purge the DB
Browse files Browse the repository at this point in the history
The cron schedule and the age at which records are purged are
configurable in the CRD, with the same default values chosen
for TripleO based deployments.
  • Loading branch information
ASBishop committed Nov 21, 2023
1 parent 7ff5f68 commit d0de27a
Show file tree
Hide file tree
Showing 13 changed files with 287 additions and 46 deletions.
13 changes: 13 additions & 0 deletions api/bases/cinder.openstack.org_cinders.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,21 @@ spec:
databaseUser:
default: cinder
type: string
dbPurge:
properties:
age:
default: 30
minimum: 1
type: integer
schedule:
default: 1 0 * * *
type: string
type: object
debug:
properties:
dbPurge:
default: false
type: boolean
dbSync:
default: false
type: boolean
Expand Down
55 changes: 41 additions & 14 deletions api/v1beta1/cinder_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ package v1beta1

import (
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
"github.com/openstack-k8s-operators/lib-common/modules/storage"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const (
// CinderUserID - Kolla's cinder UID comes from the 'cinder-user' in
// https://github.com/openstack/kolla/blob/master/kolla/common/users.py
CinderUserID = 42407
// CinderGroupID - Kolla's cinder GID
CinderGroupID = 42407

// DbSyncHash hash
DbSyncHash = "dbsync"

Expand All @@ -40,6 +45,11 @@ const (
CinderSchedulerContainerImage = "quay.io/podified-antelope-centos9/openstack-cinder-scheduler:current-podified"
// CinderVolumeContainerImage is the fall-back container image for CinderVolume
CinderVolumeContainerImage = "quay.io/podified-antelope-centos9/openstack-cinder-volume:current-podified"

// DBPurgeDefaultAge - Default age, in days, for purging deleted DB records
DBPurgeDefaultAge = 30
// DBPurgeDefaultSchedule - Default cron schedule for purging the DB
DBPurgeDefaultSchedule = "1 0 * * *"
)

// CinderSpec defines the desired state of Cinder
Expand Down Expand Up @@ -123,6 +133,10 @@ type CinderSpec struct {
// NodeSelector here acts as a default value and can be overridden by service
// specific NodeSelector Settings.
NodeSelector map[string]string `json:"nodeSelector,omitempty"`

// +kubebuilder:validation:Optional
// DBPurge parameters -
DBPurge DBPurge `json:"dbPurge,omitempty"`
}

// CinderStatus defines the observed state of Cinder
Expand Down Expand Up @@ -172,6 +186,32 @@ type Cinder struct {
Status CinderStatus `json:"status,omitempty"`
}

// DBPurge struct is used to model the parameters exposed to the Cinder cronJob
type DBPurge struct {
// +kubebuilder:validation:Optional
// +kubebuilder:default=30
// +kubebuilder:validation:Minimum=1
// Age is the DBPurgeAge parameter and indicates the number of days of purging DB records
Age int `json:"age"`
// +kubebuilder:validation:Optional
// +kubebuilder:default="1 0 * * *"
// Schedule defines the crontab format string to schedule the DBPurge cronJob
Schedule string `json:"schedule"`
}

// CinderDebug contains flags related to multiple debug activities. See the
// individual comments for what this means for each flag.
type CinderDebug struct {
// +kubebuilder:validation:Optional
// +kubebuilder:default=false
// DBSync pauses the dbSync container prior to executing the db_sync command.
DBSync bool `json:"dbSync"`
// +kubebuilder:validation:Optional
// +kubebuilder:default=false
// DBPurge increases log verbosity by executing the db_purge command with "--debug".
DBPurge bool `json:"dbPurge"`
}

//+kubebuilder:object:root=true

// CinderList contains a list of Cinder
Expand Down Expand Up @@ -231,16 +271,3 @@ func (instance Cinder) RbacNamespace() string {
func (instance Cinder) RbacResourceName() string {
return "cinder-" + instance.Name
}

// SetupDefaults - initializes any CRD field defaults based on environment variables (the defaulting mechanism itself is implemented via webhooks)
func SetupDefaults() {
// Acquire environmental defaults and initialize Cinder defaults with them
cinderDefaults := CinderDefaults{
APIContainerImageURL: util.GetEnvVar("RELATED_IMAGE_CINDER_API_IMAGE_URL_DEFAULT", CinderAPIContainerImage),
BackupContainerImageURL: util.GetEnvVar("RELATED_IMAGE_CINDER_BACKUP_IMAGE_URL_DEFAULT", CinderBackupContainerImage),
SchedulerContainerImageURL: util.GetEnvVar("RELATED_IMAGE_CINDER_SCHEDULER_IMAGE_URL_DEFAULT", CinderSchedulerContainerImage),
VolumeContainerImageURL: util.GetEnvVar("RELATED_IMAGE_CINDER_VOLUME_IMAGE_URL_DEFAULT", CinderVolumeContainerImage),
}

SetupCinderDefaults(cinderDefaults)
}
26 changes: 22 additions & 4 deletions api/v1beta1/cinder_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"github.com/openstack-k8s-operators/lib-common/modules/common/util"
)

// CinderDefaults -
Expand All @@ -34,17 +35,27 @@ type CinderDefaults struct {
BackupContainerImageURL string
SchedulerContainerImageURL string
VolumeContainerImageURL string
DBPurgeAge int
DBPurgeSchedule string
}

var cinderDefaults CinderDefaults

// log is for logging in this package.
var cinderlog = logf.Log.WithName("cinder-resource")

// SetupCinderDefaults - initialize Cinder spec defaults for use with either internal or external webhooks
func SetupCinderDefaults(defaults CinderDefaults) {
cinderDefaults = defaults
cinderlog.Info("Cinder defaults initialized", "defaults", defaults)
// SetupDefaults - initialize Cinder spec defaults for use with either internal or external webhooks
func SetupDefaults() {
cinderDefaults = CinderDefaults{
APIContainerImageURL: util.GetEnvVar("RELATED_IMAGE_CINDER_API_IMAGE_URL_DEFAULT", CinderAPIContainerImage),
BackupContainerImageURL: util.GetEnvVar("RELATED_IMAGE_CINDER_BACKUP_IMAGE_URL_DEFAULT", CinderBackupContainerImage),
SchedulerContainerImageURL: util.GetEnvVar("RELATED_IMAGE_CINDER_SCHEDULER_IMAGE_URL_DEFAULT", CinderSchedulerContainerImage),
VolumeContainerImageURL: util.GetEnvVar("RELATED_IMAGE_CINDER_VOLUME_IMAGE_URL_DEFAULT", CinderVolumeContainerImage),
DBPurgeAge: DBPurgeDefaultAge,
DBPurgeSchedule: DBPurgeDefaultSchedule,
}

cinderlog.Info("Cinder defaults initialized", "defaults", cinderDefaults)
}

// SetupWebhookWithManager sets up the webhook with the Manager
Expand Down Expand Up @@ -86,6 +97,13 @@ func (spec *CinderSpec) Default() {
// This is required, as the loop variable is a by-value copy
spec.CinderVolumes[index] = cinderVolume
}

if spec.DBPurge.Age == 0 {
spec.DBPurge.Age = cinderDefaults.DBPurgeAge
}
if spec.DBPurge.Schedule == "" {
spec.DBPurge.Schedule = cinderDefaults.DBPurgeSchedule
}
}

// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
Expand Down
9 changes: 0 additions & 9 deletions api/v1beta1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,15 +101,6 @@ type PasswordSelector struct {
Service string `json:"service"`
}

// CinderDebug indicates whether certain stages of Cinder deployment should
// pause in debug mode
type CinderDebug struct {
// +kubebuilder:validation:Optional
// +kubebuilder:default=false
// dbSync enable debug
DBSync bool `json:"dbSync"`
}

// CinderServiceDebug indicates whether certain stages of Cinder service
// deployment should pause in debug mode
type CinderServiceDebug struct {
Expand Down
16 changes: 16 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

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

13 changes: 13 additions & 0 deletions config/crd/bases/cinder.openstack.org_cinders.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -365,8 +365,21 @@ spec:
databaseUser:
default: cinder
type: string
dbPurge:
properties:
age:
default: 30
minimum: 1
type: integer
schedule:
default: 1 0 * * *
type: string
type: object
debug:
properties:
dbPurge:
default: false
type: boolean
dbSync:
default: false
type: boolean
Expand Down
12 changes: 12 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,18 @@ rules:
- patch
- update
- watch
- apiGroups:
- batch
resources:
- cronjobs
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- batch
resources:
Expand Down
25 changes: 25 additions & 0 deletions controllers/cinder_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
keystonev1 "github.com/openstack-k8s-operators/keystone-operator/api/v1beta1"
"github.com/openstack-k8s-operators/lib-common/modules/common"
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
cronjob "github.com/openstack-k8s-operators/lib-common/modules/common/cronjob"
"github.com/openstack-k8s-operators/lib-common/modules/common/endpoint"
"github.com/openstack-k8s-operators/lib-common/modules/common/env"
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
Expand Down Expand Up @@ -109,6 +110,7 @@ type CinderReconciler struct {
// +kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneapis,verbs=get;list;watch
// +kubebuilder:rbac:groups=rabbitmq.openstack.org,resources=transporturls,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch
// +kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=get;list;watch;create;update;patch;delete;

// service account, role, rolebinding
// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update
Expand Down Expand Up @@ -183,6 +185,7 @@ func (r *CinderReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
condition.UnknownCondition(cinderv1beta1.CinderSchedulerReadyCondition, condition.InitReason, cinderv1beta1.CinderSchedulerReadyInitMessage),
condition.UnknownCondition(cinderv1beta1.CinderBackupReadyCondition, condition.InitReason, cinderv1beta1.CinderBackupReadyInitMessage),
condition.UnknownCondition(cinderv1beta1.CinderVolumeReadyCondition, condition.InitReason, cinderv1beta1.CinderVolumeReadyInitMessage),
condition.UnknownCondition(condition.CronJobReadyCondition, condition.InitReason, condition.CronJobReadyInitMessage),
condition.UnknownCondition(condition.DeploymentReadyCondition, condition.InitReason, condition.DeploymentReadyInitMessage),
condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage),
// service account, role, rolebinding conditions
Expand Down Expand Up @@ -300,6 +303,7 @@ func (r *CinderReconciler) SetupWithManager(mgr ctrl.Manager) error {
Owns(&cinderv1beta1.CinderVolume{}).
Owns(&rabbitmqv1.TransportURL{}).
Owns(&batchv1.Job{}).
Owns(&batchv1.CronJob{}).
Owns(&corev1.Secret{}).
Owns(&corev1.ServiceAccount{}).
Owns(&rbacv1.Role{}).
Expand Down Expand Up @@ -819,6 +823,27 @@ func (r *CinderReconciler) reconcileNormal(ctx context.Context, instance *cinder
return ctrl.Result{}, err
}

// create CronJob
cronjobDef := cinder.CronJob(instance, serviceLabels, serviceAnnotations)
cronjob := cronjob.NewCronJob(
cronjobDef,
5*time.Second,
)

ctrlResult, err = cronjob.CreateOrPatch(ctx, helper)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.CronJobReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.CronJobReadyErrorMessage,
err.Error()))
return ctrlResult, err
}

instance.Status.Conditions.MarkTrue(condition.CronJobReadyCondition, condition.CronJobReadyMessage)
// create CronJob - end

r.Log.Info(fmt.Sprintf("Reconciled Service '%s' successfully", instance.Name))
return ctrl.Result{}, nil
}
Expand Down
Loading

0 comments on commit d0de27a

Please sign in to comment.