feat(nextcloud): add imaginary service for previews
All checks were successful
/ publish (push) Successful in 16s

This commit is contained in:
unteem 2024-11-28 09:32:15 +01:00
parent 994b4f1062
commit f7f930bf5a
6 changed files with 215 additions and 11 deletions

View file

@ -45,6 +45,9 @@ type NextcloudSpec struct {
//+kubebuilder:validation:Optional //+kubebuilder:validation:Optional
DisableSSO bool `json:"disableSSO"` DisableSSO bool `json:"disableSSO"`
//+kubebuilder:validation:Optional
EnablePreviews bool `json:"enablePreviews,omitempty"`
} }
// NextcloudStatus defines the observed state of Nextcloud // NextcloudStatus defines the observed state of Nextcloud

View file

@ -57,6 +57,8 @@ spec:
properties: properties:
disableSSO: disableSSO:
type: boolean type: boolean
enablePreviews:
type: boolean
envFrom: envFrom:
items: items:
description: EnvFromSource represents the source of a set of ConfigMaps description: EnvFromSource represents the source of a set of ConfigMaps

View file

@ -145,6 +145,12 @@ func (r *NextcloudReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
return ctrl.Result{}, err return ctrl.Result{}, err
} }
if nextcloud.Spec.EnablePreviews {
if err := r.reconcilePreviews(ctx, &nextcloud, &resources); err != nil {
return ctrl.Result{}, err
}
}
err = lshr.OnInstall(&nextcloud, func() error { err = lshr.OnInstall(&nextcloud, func() error {
log.Info("Installing") log.Info("Installing")
job, err := r.reconcileInstallJob(ctx, &nextcloud, &resources) job, err := r.reconcileInstallJob(ctx, &nextcloud, &resources)
@ -179,16 +185,6 @@ func (r *NextcloudReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
return ctrl.Result{}, err return ctrl.Result{}, err
} }
// err = r.reconcilePodDisruptionBudget(ctx, &nextcloud)
// if err != nil {
// return ctrl.Result{}, err
// }
// _, err = r.reconcileHpa(ctx, &nextcloud, dep)
// if err != nil {
// return ctrl.Result{}, err
// }
_, err = r.reconcileService(ctx, &nextcloud) _, err = r.reconcileService(ctx, &nextcloud)
if err != nil { if err != nil {
return ctrl.Result{}, err return ctrl.Result{}, err

View file

@ -24,6 +24,7 @@ import (
appsv1alpha1 "libre.sh/api/apps/v1alpha1" appsv1alpha1 "libre.sh/api/apps/v1alpha1"
lshcore "libre.sh/api/core/v1alpha1" lshcore "libre.sh/api/core/v1alpha1"
lshmeta "libre.sh/api/meta/v1alpha1" lshmeta "libre.sh/api/meta/v1alpha1"
lshr "libre.sh/pkg/controller-runtime"
) )
func (r *NextcloudReconciler) getEnvVars(nextcloud *appsv1alpha1.Nextcloud, resources *nextcloudResources) []corev1.EnvVar { func (r *NextcloudReconciler) getEnvVars(nextcloud *appsv1alpha1.Nextcloud, resources *nextcloudResources) []corev1.EnvVar {
@ -388,6 +389,37 @@ func (r *NextcloudReconciler) getEnvVars(nextcloud *appsv1alpha1.Nextcloud, reso
}, },
} }
envs = append(envs, ssoEnvs...) envs = append(envs, ssoEnvs...)
if nextcloud.Spec.EnablePreviews {
envs = append(envs, []corev1.EnvVar{
{
Name: "PREVIEWS_ENABLED",
Value: "true",
},
{
Name: "PREVIEWS_URL",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: lshr.GetResourceName(nextcloud, "previews"),
},
Key: lshmeta.SecretURLKey,
},
},
},
{
Name: "PREVIEWS_KEY",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: lshr.GetResourceName(nextcloud, "previews"),
},
Key: lshmeta.SecretPasswordKey,
},
},
},
}...)
}
} }
return envs return envs

View file

@ -33,7 +33,9 @@ func (r *NextcloudReconciler) reconcileService(ctx context.Context, nextcloud *l
var service corev1.Service var service corev1.Service
lshr.SetResourceNamespacedName(nextcloud, &service) lshr.SetResourceNamespacedName(nextcloud, &service)
err := lshr.CreateOrPatch(ctx, r, &service, func() error { err := lshr.CreateOrPatch(ctx, r, &service, func() error {
lshr.ApplyLabels(nextcloud, &service, nil) lshr.ApplyLabels(nextcloud, &service, &lshr.LabelOpts{
Component: "app",
})
service.Spec.Selector = lshr.ExtractLabelSelector(&service) service.Spec.Selector = lshr.ExtractLabelSelector(&service)
service.Spec.Ports = []corev1.ServicePort{ service.Spec.Ports = []corev1.ServicePort{
{ {

View file

@ -0,0 +1,169 @@
/*
Copyright 2024 IndieHosters.
Licensed under the EUPL, Version 1.2 or later (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apps
import (
"context"
"fmt"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/rand"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
appsv1alpha1 "libre.sh/api/apps/v1alpha1"
lshapps "libre.sh/api/apps/v1alpha1"
lshmeta "libre.sh/api/meta/v1alpha1"
lshr "libre.sh/pkg/controller-runtime"
)
func (r *NextcloudReconciler) reconcilePreviews(ctx context.Context, nextcloud *appsv1alpha1.Nextcloud, resources *nextcloudResources) error {
if err := r.reconcilePreviewsSecret(ctx, nextcloud, resources); err != nil {
return err
}
if err := r.reconcilePreviewsService(ctx, nextcloud); err != nil {
return err
}
return r.reconcilePreviewsDeployment(ctx, nextcloud, resources)
}
func (r *NextcloudReconciler) reconcilePreviewsDeployment(ctx context.Context, nextcloud *appsv1alpha1.Nextcloud, resources *nextcloudResources) error {
var deployment appsv1.Deployment
lshr.SetResourceNamespacedName(nextcloud, &deployment, "previews")
return lshr.CreateOrPatch(ctx, r, &deployment, func() error {
lshr.ApplyLabels(nextcloud, &deployment, &lshr.LabelOpts{
Component: "previews",
Version: lshr.GetVersion(nextcloud),
})
deployment.Spec.Selector = &metav1.LabelSelector{
MatchLabels: lshr.ExtractLabelSelector(&deployment),
}
deployment.Spec.Template.ObjectMeta.Labels = deployment.Labels
deployment.Spec.Template.Spec.TopologySpreadConstraints = []corev1.TopologySpreadConstraint{
{
MaxSkew: 1,
TopologyKey: "kubernetes.io/hostname",
WhenUnsatisfiable: corev1.ScheduleAnyway,
LabelSelector: deployment.Spec.Selector,
},
}
if deployment.Spec.Replicas == nil {
replicas := int32(1)
deployment.Spec.Replicas = &replicas
}
/* probeHandler := corev1.ProbeHandler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/health",
Port: intstr.FromInt(8088),
},
} */
deployment.Spec.Template.Spec.Containers = []corev1.Container{
{
Image: "registry.libre.sh/imaginary:6cd9edd1d3fb151eb773c14552886e4fc8e50138",
ImagePullPolicy: corev1.PullAlways,
Name: "app",
Ports: []corev1.ContainerPort{
{
ContainerPort: 8088,
Name: "http",
Protocol: corev1.ProtocolTCP,
},
},
Args: []string{"-concurrency", "20", "-enable-url-source"},
Env: []corev1.EnvVar{
{
Name: "PORT",
Value: "8088",
},
{
Name: "IMAGINARY_SECRET",
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{
Name: lshr.GetResourceName(nextcloud, "previews"),
},
Key: lshmeta.SecretPasswordKey,
},
},
},
},
/* ReadinessProbe: &corev1.Probe{
ProbeHandler: probeHandler,
},
LivenessProbe: &corev1.Probe{
ProbeHandler: probeHandler,
},
*/
Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceMemory: resource.MustParse("100Mi"),
},
Limits: corev1.ResourceList{
corev1.ResourceMemory: resource.MustParse("300Mi"),
},
},
},
}
return controllerutil.SetControllerReference(nextcloud, &deployment, r.Scheme())
})
}
func (r *NextcloudReconciler) reconcilePreviewsSecret(ctx context.Context, nextcloud *appsv1alpha1.Nextcloud, resources *nextcloudResources) error {
var secret corev1.Secret
lshr.SetResourceNamespacedName(nextcloud, &secret, "previews")
secret.Namespace = nextcloud.Namespace
return lshr.CreateOrPatch(ctx, r, &secret, func() error {
if secret.Data == nil {
secret.Data = make(map[string][]byte)
}
if len(secret.Data[lshmeta.SecretPasswordKey]) == 0 {
secret.Data[lshmeta.SecretPasswordKey] = []byte(rand.String(32))
}
secret.Data[lshmeta.SecretURLKey] = []byte(fmt.Sprintf("http://%s:8088", lshr.GetResourceName(nextcloud, "previews")))
return controllerutil.SetControllerReference(nextcloud, &secret, r.Scheme())
})
}
func (r *NextcloudReconciler) reconcilePreviewsService(ctx context.Context, nextcloud *lshapps.Nextcloud) error {
var service corev1.Service
lshr.SetResourceNamespacedName(nextcloud, &service, "previews")
return lshr.CreateOrPatch(ctx, r, &service, func() error {
lshr.ApplyLabels(nextcloud, &service, &lshr.LabelOpts{
Component: "previews",
})
service.Spec.Selector = lshr.ExtractLabelSelector(&service)
service.Spec.Ports = []corev1.ServicePort{
{
Name: "http",
TargetPort: intstr.FromString("http"),
Port: 8088,
},
}
return controllerutil.SetControllerReference(nextcloud, &service, r.Scheme())
})
}