Skip to content
Commits on Source (3)
......@@ -27,7 +27,8 @@ run: generate fmt vet manifests
# Install CRDs into a cluster
install: manifests
kustomize build config/crd | kubectl apply -f -
# kustomize build config/crd | kubectl apply -f -
(kustomize build config/crd | kubectl replace -f -) || (kustomize build config/crd | kubectl create -f -)
# Uninstall CRDs from a cluster
uninstall: manifests
......
......@@ -3,5 +3,5 @@ repo: git.indie.host/nextcloud-operator
resources:
- group: apps
kind: Nextcloud
version: v1beta1
version: v1alpha1
version: "2"
......@@ -13,43 +13,43 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package application
package v1alpha1
import (
"github.com/presslabs/controller-util/syncer"
"github.com/presslabs/controller-util/rand"
interfaces "git.indie.host/nextcloud-operator/interfaces"
corev1 "k8s.io/api/core/v1"
)
var (
generatedSalts = map[string]int{
"instanceID": 10,
"adminPassword": 12,
"passwordSalt": 20,
"secret": 20,
func (app *App) SetDefaults() {
if &app.Backend.Port == nil || app.Backend.Port.Port == 0 {
app.Backend.Port.Port = 9000
}
)
func (c *Component) NewSecretSyncer(r interfaces.Reconcile) syncer.Interface {
return syncer.NewObjectSyncer("Secret", c.Owner, &c.Secret, r.GetClient(), r.GetScheme(), c.MutateSecret)
}
if len(app.Backend.Port.Protocol) == 0 {
app.Backend.Port.Protocol = "TCP"
}
if len(app.Backend.Port.Name) == 0 {
app.Backend.Port.Name = "api"
}
func (c *Component) MutateSecret() error {
if len(c.Secret.Data) == 0 {
c.Secret.Data = make(map[string][]byte)
if len(app.Backend.Paths) == 0 {
app.Backend.Paths = []string{"/"}
}
for name, size := range generatedSalts {
if len(c.Secret.Data[name]) == 0 {
random, err := rand.AlphaNumericString(size)
if err != nil {
return err
}
c.Secret.Data[name] = []byte(random)
if app.SecurityContext == nil {
app.SecurityContext = &corev1.PodSecurityContext{
RunAsUser: &wwwDataUserID,
RunAsGroup: &wwwDataUserID,
FSGroup: &wwwDataUserID,
}
}
return nil
if len(app.Image) == 0 {
app.Image = "libresh/nextcloud:18.0.0"
}
if len(app.Settings) == 0 {
app.Settings = []string{"app"}
}
app.InternalWorkload.SetDefaults()
}
......@@ -13,24 +13,33 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package web
package v1alpha1
import (
"github.com/presslabs/controller-util/syncer"
interfaces "git.indie.host/nextcloud-operator/interfaces"
corev1 "k8s.io/api/core/v1"
)
func (c *Component) NewServiceSyncer(r interfaces.Reconcile) syncer.Interface {
return syncer.NewObjectSyncer("Service", c.Owner, &c.Service, r.GetClient(), r.GetScheme(), c.MutateService)
}
func (app *CLI) SetDefaults() {
if app.SecurityContext == nil {
app.SecurityContext = &corev1.PodSecurityContext{
RunAsUser: &wwwDataUserID,
RunAsGroup: &wwwDataUserID,
FSGroup: &wwwDataUserID,
}
}
if len(app.Image) == 0 {
app.Image = "libresh/nextcloud:18.0.0"
}
func (c *Component) MutateService() error {
labels := c.Labels("web")
if len(app.RestartPolicy) == 0 {
app.RestartPolicy = corev1.RestartPolicyOnFailure
}
c.Runtime.MutateService(&c.Service)
app.ObjectMeta.SetComponent("cli")
c.Service.Spec.Selector = labels
// TODO TOFIX
// meta.SetObjectMeta(app, app.ObjectMeta)
return nil
}
......@@ -13,28 +13,33 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package application
package v1alpha1
import (
"github.com/presslabs/controller-util/syncer"
func (app *Web) SetDefaults() {
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
app.ObjectMeta.SetComponent("web")
interfaces "git.indie.host/nextcloud-operator/interfaces"
)
if len(app.Backend.Paths) == 0 {
app.Backend.Paths = []string{"/"}
}
func (c *Component) NewDeploymentSyncer(r interfaces.Reconcile) syncer.Interface {
return syncer.NewObjectSyncer("Deployment", c.Owner, &c.Deployment, r.GetClient(), r.GetScheme(), c.MutateDeployment)
}
func (c *Component) MutateDeployment() error {
c.Settings.MutateDeployment(&c.Deployment)
c.Runtime.MutateDeployment(&c.Deployment)
if &app.Backend.Port == nil || app.Backend.Port.Port == 0 {
app.Backend.Port.Port = 80
}
if len(app.Port.Protocol) == 0 {
app.Backend.Port.Protocol = "TCP"
}
if len(app.Backend.Port.Name) == 0 {
app.Backend.Port.Name = "http"
}
labels := c.Labels("app")
if len(app.Image) == 0 {
app.Image = "libresh/nextcloud:18.0.0"
}
c.Deployment.Spec.Template.ObjectMeta = c.Deployment.ObjectMeta
c.Deployment.Spec.Selector = metav1.SetAsLabelSelector(labels)
if len(app.Settings) == 0 {
app.Settings = []string{"web"}
}
return nil
app.Workload.SetDefaults()
}
......@@ -13,10 +13,10 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
// Package v1beta1 contains API Schema definitions for the apps v1beta1 API group
// Package v1alpha1 contains API Schema definitions for the apps v1alpha1 API group
// +kubebuilder:object:generate=true
// +groupName=apps.libre.sh
package v1beta1
package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
......@@ -25,7 +25,7 @@ import (
var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "apps.libre.sh", Version: "v1beta1"}
GroupVersion = schema.GroupVersion{Group: "apps.libre.sh", Version: "v1alpha1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
......
......@@ -13,111 +13,46 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package v1beta1
package v1alpha1
import (
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.libre.sh/application/components"
"k8s.libre.sh/application/settings"
)
// NextcloudStatus defines the observed state of Nextcloud
type NextcloudStatus struct {
// Version defines the installed version
Version string `json:"version,omitempty"`
Phase Phase `json:"Phase,omitempty"`
Version string `json:"version,omitempty"`
Settings map[string]SettingsStatus `json:"settings,omitempty"`
Phase Phase `json:"phase,omitempty"`
}
// NextcloudSpec defines the desired state of Nextcloud
type NextcloudSpec struct {
// Replicas *int32 `json:"replicas,omitempty"`
// Hosts []Host `json:"hosts,omitempty"`
// Storage storage.StorageSpec `json:"storage,omitempty"`
Version string `json:"version,omitempty"`
App Component `json:"app,omitempty"`
Web Component `json:"web,omitempty"`
CLI Component `json:"cli,omitempty"`
Cron Component `json:"cron,omitempty"`
Database Dependency `json:"database,omitempty"`
SMTP Dependency `json:"smtp,omitempty"`
ObjectStore Dependency `json:"objectStore,omitempty"`
Redis Dependency `json:"redis,omitempty"`
}
type From struct {
// The ConfigMap to select from.
corev1.LocalObjectReference `json:",inline" protobuf:"bytes,1,opt,name=localObjectReference"`
Value string `json:"value,omitempty"`
// The key to select.
Key string `json:"key,omitempty" protobuf:"bytes,2,opt,name=key"`
// An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
// +optional
Prefix string `json:"prefix,omitempty" protobuf:"bytes,1,opt,name=prefix"`
}
//type Foo struct {
// Name string `json:"name,omitempty"`
// Keys []ParametersKey `json:"keys,omitempty"`
//}
//type ParametersKey struct {
// Value string `json:"value,omitempty"`
// Key string `json:"key" protobuf:"bytes,2,opt,name=key"`
// An optional identifier to prepend to each key in the ConfigMap. Must be a C_IDENTIFIER.
// +optional
// Prefix string `json:"prefix,omitempty" protobuf:"bytes,1,opt,name=prefix"`
//}
type Parameters struct {
From []From `json:"from,omitempty"`
EnvVar map[string]string `json:"envVar,omitempty"`
type SettingsStatus struct {
Sources []settings.Source `json:"sources,omitempty"`
}
type Settings struct {
Secrets []From `json:"secrets,omitempty"`
Parameters *Parameters `json:"parameters,omitempty"`
// NextcloudSpec defines the desired state of Nextcloud
type NextcloudSpec struct {
Version string `json:"version,omitempty"`
Settings Settings `json:"settings,omitempty"`
App *App `json:"app,omitempty"`
Web *Web `json:"web,omitempty"`
CLI *CLI `json:"cli,omitempty"`
// Cron Component `json:"cron,omitempty"`
}
type Component struct {
Enabled bool `json:"enabled,omitempty"`
Name string `json:"name,omitempty"`
Runtime Runtime `json:"runtime,omitempty"`
Settings Settings `json:"settings,omitempty"`
type App struct {
*components.InternalWorkload `json:",inline"`
}
type Dependency struct {
Enabled bool `json:"enabled,omitempty"`
Name string `json:"name,omitempty"`
Settings Settings `json:"settings,omitempty"`
type Web struct {
*components.Workload `json:",inline"`
}
// SecretRef represents a reference to a Secret
type SecretRef string
// Host represents a valid hostname
type Host string
type Runtime struct {
Image string `json:"image,omitempty"`
ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
ServiceType corev1.ServiceType `json:"serviceType,omitempty"`
IngressAnnotations map[string]string `json:"ingressAnnotations,omitempty"`
Hosts []Host `json:"hosts,omitempty"`
// Number of desired pods. This is a pointer to distinguish between explicit
// zero and not specified. Defaults to 1.
// +optional
Replicas *int32 `json:"replicas,omitempty" protobuf:"varint,1,opt,name=replicas"`
TLSSecretRef SecretRef `json:"tlsSecretRef,omitempty"`
Ports []corev1.ContainerPort `json:"ports,omitempty"`
Resources corev1.ResourceRequirements `json:"resources,omitempty" protobuf:"bytes,8,opt,name=resources"`
SecurityContext *corev1.PodSecurityContext `json:"securityContext,omitempty"`
ReadinessProbe *corev1.Probe `json:"readinessProbe,omitempty" protobuf:"bytes,11,opt,name=readinessProbe"`
LivenessProbe *corev1.Probe `json:"livenessProbe,omitempty" protobuf:"bytes,10,opt,name=livenessProbe"`
// The deployment strategy to use to replace existing pods with new ones.
// +optional
// +patchStrategy=retainKeys
Strategy appsv1.DeploymentStrategy `json:"strategy,omitempty" patchStrategy:"retainKeys" protobuf:"bytes,4,opt,name=strategy"`
type CLI struct {
*components.CLI `json:",inline"`
}
// Phase is the current status of a App as a whole.
......
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 v1alpha1
import (
"k8s.libre.sh/application"
"k8s.libre.sh/application/components"
"k8s.libre.sh/application/settings"
"k8s.libre.sh/interfaces"
"k8s.libre.sh/meta"
"k8s.libre.sh/objects/job"
)
var (
wwwDataUserID int64 = 33
)
func (o *Nextcloud) GetOwner() interfaces.Object { return o }
func (o *Nextcloud) GetName() string { return o.Name }
func (o *Nextcloud) GetNamespace() string { return o.Namespace }
func (o *Nextcloud) GetInstance() string { return o.Name }
func (o *Nextcloud) SetInstance(s string) {}
func (o *Nextcloud) GetVersion() string { return o.Spec.Version }
func (o *Nextcloud) SetVersion(s string) {}
func (o *Nextcloud) GetComponent() string { return "instance" }
func (o *Nextcloud) SetComponent(s string) {}
func (o *Nextcloud) GetPartOf() string { return "Nextcloud" }
func (o *Nextcloud) SetPartOf(s string) {}
func (o *Nextcloud) GetManagedBy() string { return "Nextcloud-operator" }
func (o *Nextcloud) SetManagedBy(s string) {}
func (o *Nextcloud) GetApplication() string { return "Nextcloud" }
func (o *Nextcloud) SetApplication(s string) {}
func (o *Nextcloud) GetSettings() map[string]settings.Settings {
// TODO TO FIX
setts := map[string]settings.Settings{
"app": settings.NewSettings(&o.Spec.Settings.AppSettings),
"web": settings.NewSettings(&o.Spec.Settings.Web),
}
if len(o.Status.Settings) > 0 {
for k, v := range o.Status.Settings {
setts[k].(*settings.Component).ConfigSpec.Sources = append(setts[k].(*settings.Component).ConfigSpec.Sources, v.Sources...)
}
}
return setts
}
func (app *Nextcloud) GetComponentsSyncOrder() map[int]string {
return map[int]string{
0: "settings",
1: "cli",
2: "app",
3: "web",
}
}
func (app *Nextcloud) GetComponents() map[string]application.Component {
cpts := map[string]application.Component{
"app": app.Spec.App,
"web": app.Spec.Web,
"cli": app.Spec.CLI,
}
return cpts
}
func (app *Nextcloud) Init() {
if app.Spec.App == nil {
app.Spec.App = &App{}
app.Spec.App.InternalWorkload = &components.InternalWorkload{}
}
if app.Spec.Web == nil {
app.Spec.Web = &Web{}
app.Spec.Web.Workload = &components.Workload{}
}
if app.Spec.CLI == nil {
app.Spec.CLI = &CLI{}
app.Spec.CLI.CLI = &components.CLI{}
}
for _, c := range app.GetComponents() {
c.Init()
}
if app.Spec.CLI == nil {
app.Spec.CLI = &CLI{}
app.Spec.CLI.Job = &job.Job{}
}
app.Spec.CLI.Init()
app.Spec.Settings.AppSettings.CreateOptions.Init()
app.Spec.Settings.Web.CreateOptions.Init()
}
func (app *Nextcloud) SetDefaultMeta() {
app.Spec.Web.ObjectMeta.SetComponent("web")
// TODO TO FIX create a func in application package
for _, c := range app.GetComponents() {
meta.SetObjectMetaFromInstance(app, c)
for _, o := range c.GetObjects() {
meta.SetObjectMeta(c, o)
}
}
// TODO TOFIX
meta.SetObjectMeta(app, app.Spec.CLI.ObjectMeta)
app.Spec.CLI.ObjectMeta.SetComponent("cli")
meta.SetObjectMeta(app, app.Spec.Settings.AppSettings.CreateOptions.CommonMeta)
app.Spec.Settings.AppSettings.CreateOptions.CommonMeta.Labels["app.kubernetes.io/component"] = "app"
meta.SetObjectMeta(app, app.Spec.Settings.Web.CreateOptions.CommonMeta)
app.Spec.Settings.Web.CreateOptions.CommonMeta.Labels["app.kubernetes.io/component"] = "web"
}
func (app *Nextcloud) SetDefaults() {
app.Spec.App.SetDefaults()
app.Spec.Web.SetDefaults()
app.Spec.CLI.SetDefaults()
app.Spec.Settings.SetDefaults()
app.Spec.Settings.SetDefaults()
}
package v1alpha1
import (
"k8s.libre.sh/application/settings"
)
type Settings struct {
CreateOptions settings.CreateOptions `json:"createOptions,omitempty"`
Sources []settings.Source `json:"sources,omitempty"`
AppSettings AppSettings `json:"app,omitempty"`
Web WebSettings `json:"web,omitempty"`
}
func (s *Settings) SetDefaults() {
s.AppSettings.SetDefaults()
s.Web.SetDefaults()
}
package v1alpha1
import (
"k8s.libre.sh/application/settings"
"k8s.libre.sh/meta"
"k8s.libre.sh/objects"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type AppSettings struct {
CreateOptions settings.CreateOptions `json:"createOptions,omitempty"`
Sources []settings.Source `json:"sources,omitempty"`
Database Database `json:"database,omitempty"`
SMTP SMTP `json:"smtp,omitempty"`
General General `json:"general,omitempty"`
ObjectStore ObjectStore `json:"objectStore,omitempty"`
Redis Redis `json:"cache,omitempty"`
}
func (s *AppSettings) GetMeta() meta.Instance { return s.CreateOptions.CommonMeta }
func (s *AppSettings) SetDefaults() {
// s.CreateOptions.Init()
// s.CreateOptions.CommonMeta.Labels["app.kubernetes.io/component"] = "app"
s.General.SetDefaults()
s.Database.SetDefaults()
s.SMTP.SetDefaults()
s.ObjectStore.SetDefaults()
s.Redis.SetDefaults()
}
func (s *AppSettings) GetConfig() settings.Config {
params := *s.General.GetParameters()
params = append(params, *s.Database.GetParameters()...)
params = append(params, *s.SMTP.GetParameters()...)
params = append(params, *s.ObjectStore.GetParameters()...)
params = append(params, *s.Redis.GetParameters()...)
settings := &settings.ConfigSpec{
Parameters: &params,
Sources: s.Sources,
}
return settings
}
func (s *AppSettings) GetObjects() map[int]objects.Object {
return nil
}
func (s *AppSettings) Init(c client.Client) error {
return nil
}
func (s *AppSettings) GetCreateOptions() *settings.CreateOptions {
return &s.CreateOptions
}
......@@ -13,23 +13,22 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package application
package v1alpha1
import (
"github.com/presslabs/controller-util/syncer"
interfaces "git.indie.host/nextcloud-operator/interfaces"
"k8s.libre.sh/application/settings/parameters"
)
func (c *Component) NewServiceSyncer(r interfaces.Reconcile) syncer.Interface {
return syncer.NewObjectSyncer("Service", c.Owner, &c.Service, r.GetClient(), r.GetScheme(), c.MutateService)
type Redis struct {
Username parameters.Parameter `json:"username,omitempty" env:"REDIS_USERNAME"`
Password parameters.Parameter `json:"password,omitempty" env:"REDIS_PASSWORD"`
Host parameters.Parameter `json:"host,omitempty" env:"REDIS_HOST"`
Port parameters.Parameter `json:"port,omitempty" env:"REDIS_HOST_PORT"`
}
func (c *Component) MutateService() error {
labels := c.Labels("app")
c.Runtime.MutateService(&c.Service)
c.Service.Spec.Selector = labels
func (d *Redis) SetDefaults() {
}
return nil
func (s *Redis) GetParameters() *parameters.Parameters {
return &parameters.Parameters{}
}
......@@ -13,54 +13,34 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package application
package v1alpha1
import (
"fmt"
import "k8s.libre.sh/application/settings/parameters"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networking "k8s.io/api/networking/v1beta1"
common "git.indie.host/nextcloud-operator/components/common"
interfaces "git.indie.host/nextcloud-operator/interfaces"
)
type Component struct {
Name string
*common.Common
Deployment appsv1.Deployment
Service corev1.Service
Ingress networking.Ingress
Secret corev1.Secret
type Database struct {
Database parameters.Parameter `json:"database,omitempty" env:"DB_NAME"`
Host parameters.Parameter `json:"host,omitempty" env:"DB_HOST"`
Port parameters.Parameter `json:"port,omitempty" env:"DB_PORT"`
Type parameters.Parameter `json:"type,omitempty" env:"DB_TYPE"`
Username parameters.Parameter `json:"username,omitempty" env:"DB_USERNAME"`
Password parameters.Parameter `json:"password,omitempty" env:"DB_PASSWORD"`
}
func CreateAndInit(common *common.Common) *Component {
c := &Component{}
c.Name = "app"
c.Common = common
objects := c.GetObjects()
labels := c.Labels("app")
for _, o := range objects {
o.SetName(c.GetName())
o.SetNamespace(c.Owner.Namespace)
o.SetLabels(labels)
func (s *Database) SetDefaults() {
if len(s.Database.Value) == 0 || len(s.Database.ValueFrom.Ref) == 0 {
s.Database.Value = "nextcloud"
}
return c
}
if len(s.Port.Value) == 0 || len(s.Port.ValueFrom.Ref) == 0 {
s.Port.Value = "5425"
}
func (c *Component) GetName() string {
return fmt.Sprintf("%s-%s", c.Owner.Name, c.Name)
if len(s.Type.Value) == 0 || len(s.Type.ValueFrom.Ref) == 0 {
s.Type.Value = "pgsql"
}
}
func (c *Component) GetObjects() []interfaces.Object {
return []interfaces.Object{
&c.Secret,
&c.Deployment,
&c.Service,
&c.Ingress,
}
func (s *Database) GetParameters() *parameters.Parameters {
params, _ := parameters.Marshal(*s)
return &params
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 v1alpha1
import (
"k8s.libre.sh/application/settings/parameters"
)
type General struct {
AppStore AppStore `json:"appStore,omitempty"`
Locales Locales `json:"locales,omitempty"`
GlobalSecrets `json:",inline"`
GlobalSettings `json:",inline"`
}
func (s *General) SetDefaults() {
s.AppStore.SetDefaults()
s.Locales.SetDefaults()
s.GlobalSecrets.SetDefaults()
s.GlobalSettings.SetDefaults()
}
func (s *General) GetParameters() *parameters.Parameters {
params := append(*s.AppStore.GetParameters(), *s.Locales.GetParameters()...)
params = append(params, *s.GlobalSecrets.GetParameters()...)
params = append(params, *s.GlobalSettings.GetParameters()...)
return &params
}
type GlobalSettings struct {
Domains parameters.Parameter `json:"domains,omitempty" env:"NEXTCLOUD_TRUSTED_DOMAINS"`
OverwriteCLI parameters.Parameter `json:"overwriteCLI,omitempty" env:"OVERWRITE_CLI_URL"`
OverwriteProtocol parameters.Parameter `json:"overwriteProtocol,omitempty" env:"OVERWRITE_PROTOCOL"`
DataDirectory parameters.Parameter `json:"dataDirectory,omitempty" env:"DATA_DIRECTORY"`
Debug parameters.Parameter `json:"debug,omitempty" env:"DEBUG"`
ReadOnly parameters.Parameter `json:"readOnly,omitempty" env:"CONFIG_READONLY"`
UpdateChecker parameters.Parameter `json:"updateChecker,omitempty" env:"UPDATE_CHECKER"`
UpdateURL parameters.Parameter `json:"udpateURL,omitempty" env:"OVERWRITECLI"`
UpdateChannel parameters.Parameter `json:"updateChannel,omitempty" env:"UPDATE_URL"`
UpdateDisable parameters.Parameter `json:"updateDisable,omitempty" env:"UPDATE_CHANNEL"`
BruteForce parameters.Parameter `json:"bruteforce,omitempty" env:"UPDATE_DISABLE_WEB"`
}
func (s *GlobalSettings) GetParameters() *parameters.Parameters {
params, _ := parameters.Marshal(*s)
return &params
}
func (s *GlobalSettings) SetDefaults() {
if len(s.ReadOnly.Value) == 0 || len(s.ReadOnly.ValueFrom.Ref) == 0 {
s.ReadOnly.Value = "true"
}
if len(s.DataDirectory.Value) == 0 || len(s.DataDirectory.ValueFrom.Ref) == 0 {
s.DataDirectory.Value = "/var/www/html/data"
}
if len(s.UpdateChecker.Value) == 0 || len(s.UpdateChecker.ValueFrom.Ref) == 0 {
s.UpdateChecker.Value = "false"
}
if len(s.UpdateDisable.Value) == 0 || len(s.UpdateDisable.ValueFrom.Ref) == 0 {
s.UpdateDisable.Value = "true"
}
if len(s.Domains.Value) == 0 || len(s.Domains.ValueFrom.Ref) == 0 {
s.Domains.Value = "{{ .settings.app.INSTANCE_ID }}"
s.Domains.Generate = parameters.GenerateTemplate
s.Domains.Type = parameters.SecretParameter
}
}
type GlobalSecrets struct {
InstanceID parameters.Parameter `json:"instanceID,omitempty" env:"INSTANCE_ID"`
PasswordSalt parameters.Parameter `json:"passwordSalt,omitempty" env:"PASSWORD_SALT"`
Secret parameters.Parameter `json:"secret,omitempty" env:"SECRET"`
AdminPassword parameters.Parameter `json:"adminPassword,omitempty" env:"ADMIN_PASSWORD"`
AdminUsername parameters.Parameter `json:"adminUsername,omitempty" env:"ADMIN_USERNAME"`
}
func (s *GlobalSecrets) SetDefaults() {
// TODO return warning if value is defined and ignore it. Or use secretParameter type to enforce no values
if len(s.InstanceID.Value) > 0 || len(s.InstanceID.ValueFrom.Ref) == 0 {
s.InstanceID.Generate = parameters.GenerateRand12
}
if len(s.PasswordSalt.Value) == 0 || len(s.PasswordSalt.ValueFrom.Ref) == 0 {
s.PasswordSalt.Generate = parameters.GenerateRand12
}
if len(s.Secret.Value) == 0 || len(s.Secret.ValueFrom.Ref) == 0 {
s.Secret.Generate = parameters.GenerateRand12
}
if len(s.AdminPassword.Value) == 0 || len(s.AdminPassword.ValueFrom.Ref) == 0 {
s.AdminPassword.Generate = parameters.GenerateRand12
}
if len(s.AdminUsername.Value) == 0 || len(s.AdminUsername.ValueFrom.Ref) == 0 {
s.AdminUsername.Value = "admin"
}
}
func (s *GlobalSecrets) GetParameters() *parameters.Parameters {
params, _ := parameters.Marshal(*s)
return &params
}
type AppStore struct {
// StoreEnabled defines if the app store is enabled
StoreEnabled parameters.Parameter `json:"storeEnabled,omitempty" env:"APPS_STORE_ENABLE"`
// Default defines the default app
Default parameters.Parameter `json:"default,omitempty" env:"APPS_DEFAULT"`
// StoreUrl defines the URL for the app store
StoreURL parameters.Parameter `json:"storeURL,omitempty" env:"APPS_STORE_URL"`
}
func (s *AppStore) SetDefaults() {
if len(s.StoreEnabled.Value) == 0 || len(s.StoreEnabled.ValueFrom.Ref) == 0 {
s.StoreEnabled.Value = "false"
}
}
func (s *AppStore) GetParameters() *parameters.Parameters {
params, _ := parameters.Marshal(*s)
return &params
}
type Locales struct {
// Default defines the default language
Default parameters.Parameter `json:"default,omitempty" env:"DEFAULT_LANGUAGE"`
Locale parameters.Parameter `json:"locale,omitempty" env:"DEFAULT_LOCALE"`
ForceLanguage parameters.Parameter `json:"forceLanguage,omitempty" env:"FORCE_LANGUAGE"`
ForceLocale parameters.Parameter `json:"forceLocale,omitempty" env:"DEFAULT_LOCALE"`
}
func (s *Locales) SetDefaults() {}
func (s *Locales) GetParameters() *parameters.Parameters {
params, _ := parameters.Marshal(*s)
return &params
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 v1alpha1
import (
"k8s.libre.sh/application/settings/parameters"
)
type SMTP struct {
Username parameters.Parameter `json:"username,omitempty" env:"SMTP_USERNAME"`
Password parameters.Parameter `json:"password,omitempty" env:"SMTP_PASSWORD"`
FromAdress parameters.Parameter `json:"fromAddress,omitempty" env:"MAIL_FROM_ADDRESS"`
Domain parameters.Parameter `json:"domain,omitempty" env:"MAIL_DOMAIN"`
Secure parameters.Parameter `json:"secure,omitempty" env:"SMTP_SECURE"`
AuthType parameters.Parameter `json:"authType,omitempty" env:"SMTP_AUTHTYPE"`
Debug parameters.Parameter `json:"debug,omitempty" env:"SMTP_DEBUG"`
Host parameters.Parameter `json:"host,omitempty" env:"SMTP_HOST"`
Port parameters.Parameter `json:"port,omitempty" env:"SMTP_PORT"`
TemplateClass parameters.Parameter `json:"templateClass,omitempty" env:"SMTP_TEMPLATE_CLASS"`
PlainTextOnly parameters.Parameter `json:"plainTextOnly,omitempty" env:"SMTP_SEND_PLAINTEXT_ONLY"`
}
func (d *SMTP) SetDefaults() {
}
func (s *SMTP) GetParameters() *parameters.Parameters {
params, _ := parameters.Marshal(*s)
return &params
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 v1alpha1
import "k8s.libre.sh/application/settings/parameters"
type ObjectStore struct {
Bucket parameters.Parameter `json:"bucket,omitempty" env:"OBJECTSTORE_S3_BUCKET"`
Host parameters.Parameter `json:"host,omitempty" env:"OBJECTSTORE_S3_HOST"`
Port parameters.Parameter `json:"port,omitempty" env:"OBJECTSTORE_S3_PORT"`
AutoCreate parameters.Parameter `json:"autocreate,omitempty" env:"OBJECTSTORE_S3_AUTOCREATE"`
SSL parameters.Parameter `json:"ssl,omitempty" env:"OBJECTSTORE_S3_SSL"`
Region parameters.Parameter `json:"region,omitempty" env:"OBJECTSTORE_S3_REGION"`
PathStyle parameters.Parameter `json:"pathStyle,omitempty" env:"OBJECTSTORE_S3_USEPATH_STYLE"`
AccessKeyID parameters.Parameter `json:"accessKeyID,omitempty" env:"OBJECTSTORE_S3_KEY"`
SecretAccessKey parameters.Parameter `json:"secretAccessKey,omitempty" env:"OBJECTSTORE_S3_SECRET"`
}
func (s *ObjectStore) SetDefaults() {
/* if len(d.Bucket) == 0 {
d.Bucket = "nextcloud"
}
if len(d.Port) == 0 {
d.Port = "443"
}
if len(d.Region) == 0 {
d.Region = "default"
} */
}
func (s *ObjectStore) GetParameters() *parameters.Parameters {
params, _ := parameters.Marshal(*s)
return &params
}
/*
Licensed under the GNU AFFERO GENERAL PUBLIC LICENSE, Version 3 (the "License");
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.gnu.org/licenses/agpl-3.0.html
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
......@@ -13,18 +13,17 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package web
package v1alpha1
import (
"bytes"
"html/template"
"github.com/presslabs/controller-util/syncer"
interfaces "git.indie.host/nextcloud-operator/interfaces"
"k8s.libre.sh/application/settings"
"k8s.libre.sh/application/settings/parameters"
"k8s.libre.sh/meta"
"k8s.libre.sh/objects"
"sigs.k8s.io/controller-runtime/pkg/client"
)
const conf = `
const nginxConf = `
user www-data;
events {
worker_connections 768;
......@@ -32,9 +31,9 @@ const conf = `
http {
upstream backend {
server {{ .Name }}-app:9000;
server {{ .components.app.service.meta.name }}:{{ .components.app.service.port.port }};
}
include /etc/nginx/mime.types;
include /etc/nginx/mime.types
default_type application/octet-stream;
server {
......@@ -132,36 +131,50 @@ const conf = `
}
`
func (c *Component) NewConfigMapSyncer(r interfaces.Reconcile) syncer.Interface {
return syncer.NewObjectSyncer("ConfigMap", c.Owner, &c.ConfigMap, r.GetClient(), r.GetScheme(), c.MutateConfigMap)
type WebSettings struct {
CreateOptions settings.CreateOptions `json:"createOptions,omitempty"`
Sources []settings.Source `json:"sources,omitempty"`
ConfTemplate parameters.Parameter `json:"conf,omitempty" env:"nginx-conf"`
}
func (c *Component) MutateConfigMap() error {
data, err := c.GenConfigMapData()
if err != nil {
return err
}
c.ConfigMap.Data = data
func (s *WebSettings) SetDefaults() {
return nil
}
// s.CreateOptions.Init()
// s.CreateOptions.CommonMeta.Labels["app.kubernetes.io/component"] = "web"
// GenAppConfigMapData func generates data for the web configmap that contains the nginx.conf
func (c *Component) GenConfigMapData() (map[string]string, error) {
var cm map[string]string
tmpl, err := template.New("test").Parse(conf)
if err != nil {
return nil, err
}
var tpl bytes.Buffer
err = tmpl.Execute(&tpl, c.Owner)
if err != nil {
return nil, err
if len(s.ConfTemplate.Value) > 0 || len(s.ConfTemplate.ValueFrom.Ref) == 0 {
s.ConfTemplate.Value = nginxConf
s.ConfTemplate.Generate = parameters.GenerateTemplate
s.ConfTemplate.MountType = parameters.MountEnvFile
s.ConfTemplate.Type = parameters.ConfigParameter
s.ConfTemplate.MountType = parameters.MountFile
s.ConfTemplate.MountPath.Path = "/etc/nginx/nginx.conf"
s.ConfTemplate.MountPath.SubPath = "nginx.conf"
}
}
func (s *WebSettings) GetConfig() settings.Config {
params, _ := parameters.Marshal(*s)
cm = map[string]string{
"nginx.conf": tpl.String(),
settings := &settings.ConfigSpec{
Parameters: &params,
Sources: s.Sources,
}
return cm, nil
return settings
}
func (s *WebSettings) GetMeta() meta.Instance { return s.CreateOptions.CommonMeta }
func (s *WebSettings) GetObjects() map[int]objects.Object {
return nil
}
func (s *WebSettings) Init(c client.Client) error {
return nil
}
func (s *WebSettings) GetCreateOptions() *settings.CreateOptions {
return &s.CreateOptions
}
......@@ -17,58 +17,199 @@ limitations under the License.
// Code generated by controller-gen. DO NOT EDIT.
package v1beta1
package v1alpha1
import (
"k8s.io/api/core/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
"k8s.libre.sh/application/components"
"k8s.libre.sh/application/settings"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Component) DeepCopyInto(out *Component) {
func (in *App) DeepCopyInto(out *App) {
*out = *in
in.Runtime.DeepCopyInto(&out.Runtime)
in.Settings.DeepCopyInto(&out.Settings)
if in.InternalWorkload != nil {
in, out := &in.InternalWorkload, &out.InternalWorkload
*out = new(components.InternalWorkload)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Component.
func (in *Component) DeepCopy() *Component {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new App.
func (in *App) DeepCopy() *App {
if in == nil {
return nil
}
out := new(Component)
out := new(App)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Dependency) DeepCopyInto(out *Dependency) {
func (in *AppSettings) DeepCopyInto(out *AppSettings) {
*out = *in
in.Settings.DeepCopyInto(&out.Settings)
in.CreateOptions.DeepCopyInto(&out.CreateOptions)
if in.Sources != nil {
in, out := &in.Sources, &out.Sources
*out = make([]settings.Source, len(*in))
copy(*out, *in)
}
out.Database = in.Database
out.SMTP = in.SMTP
out.General = in.General
out.ObjectStore = in.ObjectStore
out.Redis = in.Redis
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppSettings.
func (in *AppSettings) DeepCopy() *AppSettings {
if in == nil {
return nil
}
out := new(AppSettings)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *AppStore) DeepCopyInto(out *AppStore) {
*out = *in
out.StoreEnabled = in.StoreEnabled
out.Default = in.Default
out.StoreURL = in.StoreURL
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AppStore.
func (in *AppStore) DeepCopy() *AppStore {
if in == nil {
return nil
}
out := new(AppStore)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *CLI) DeepCopyInto(out *CLI) {
*out = *in
if in.CLI != nil {
in, out := &in.CLI, &out.CLI
*out = new(components.CLI)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CLI.
func (in *CLI) DeepCopy() *CLI {
if in == nil {
return nil
}
out := new(CLI)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Database) DeepCopyInto(out *Database) {
*out = *in
out.Database = in.Database
out.Host = in.Host
out.Port = in.Port
out.Type = in.Type
out.Username = in.Username
out.Password = in.Password
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Database.
func (in *Database) DeepCopy() *Database {
if in == nil {
return nil
}
out := new(Database)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *General) DeepCopyInto(out *General) {
*out = *in
out.AppStore = in.AppStore
out.Locales = in.Locales
out.GlobalSecrets = in.GlobalSecrets
out.GlobalSettings = in.GlobalSettings
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new General.
func (in *General) DeepCopy() *General {
if in == nil {
return nil
}
out := new(General)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GlobalSecrets) DeepCopyInto(out *GlobalSecrets) {
*out = *in
out.InstanceID = in.InstanceID
out.PasswordSalt = in.PasswordSalt
out.Secret = in.Secret
out.AdminPassword = in.AdminPassword
out.AdminUsername = in.AdminUsername
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalSecrets.
func (in *GlobalSecrets) DeepCopy() *GlobalSecrets {
if in == nil {
return nil
}
out := new(GlobalSecrets)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *GlobalSettings) DeepCopyInto(out *GlobalSettings) {
*out = *in
out.Domains = in.Domains
out.OverwriteCLI = in.OverwriteCLI
out.OverwriteProtocol = in.OverwriteProtocol
out.DataDirectory = in.DataDirectory
out.Debug = in.Debug
out.ReadOnly = in.ReadOnly
out.UpdateChecker = in.UpdateChecker
out.UpdateURL = in.UpdateURL
out.UpdateChannel = in.UpdateChannel
out.UpdateDisable = in.UpdateDisable
out.BruteForce = in.BruteForce
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Dependency.
func (in *Dependency) DeepCopy() *Dependency {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GlobalSettings.
func (in *GlobalSettings) DeepCopy() *GlobalSettings {
if in == nil {
return nil
}
out := new(Dependency)
out := new(GlobalSettings)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *From) DeepCopyInto(out *From) {
func (in *Locales) DeepCopyInto(out *Locales) {
*out = *in
out.LocalObjectReference = in.LocalObjectReference
out.Default = in.Default
out.Locale = in.Locale
out.ForceLanguage = in.ForceLanguage
out.ForceLocale = in.ForceLocale
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new From.
func (in *From) DeepCopy() *From {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Locales.
func (in *Locales) DeepCopy() *Locales {
if in == nil {
return nil
}
out := new(From)
out := new(Locales)
in.DeepCopyInto(out)
return out
}
......@@ -79,7 +220,7 @@ func (in *Nextcloud) DeepCopyInto(out *Nextcloud) {
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
out.Status = in.Status
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Nextcloud.
......@@ -135,14 +276,22 @@ func (in *NextcloudList) DeepCopyObject() runtime.Object {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NextcloudSpec) DeepCopyInto(out *NextcloudSpec) {
*out = *in
in.App.DeepCopyInto(&out.App)
in.Web.DeepCopyInto(&out.Web)
in.CLI.DeepCopyInto(&out.CLI)
in.Cron.DeepCopyInto(&out.Cron)
in.Database.DeepCopyInto(&out.Database)
in.SMTP.DeepCopyInto(&out.SMTP)
in.ObjectStore.DeepCopyInto(&out.ObjectStore)
in.Redis.DeepCopyInto(&out.Redis)
in.Settings.DeepCopyInto(&out.Settings)
if in.App != nil {
in, out := &in.App, &out.App
*out = new(App)
(*in).DeepCopyInto(*out)
}
if in.Web != nil {
in, out := &in.Web, &out.Web
*out = new(Web)
(*in).DeepCopyInto(*out)
}
if in.CLI != nil {
in, out := &in.CLI, &out.CLI
*out = new(CLI)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NextcloudSpec.
......@@ -158,6 +307,13 @@ func (in *NextcloudSpec) DeepCopy() *NextcloudSpec {
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *NextcloudStatus) DeepCopyInto(out *NextcloudStatus) {
*out = *in
if in.Settings != nil {
in, out := &in.Settings, &out.Settings
*out = make(map[string]SettingsStatus, len(*in))
for key, val := range *in {
(*out)[key] = *val.DeepCopy()
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NextcloudStatus.
......@@ -171,112 +327,155 @@ func (in *NextcloudStatus) DeepCopy() *NextcloudStatus {
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Parameters) DeepCopyInto(out *Parameters) {
func (in *ObjectStore) DeepCopyInto(out *ObjectStore) {
*out = *in
if in.From != nil {
in, out := &in.From, &out.From
*out = make([]From, len(*in))
copy(*out, *in)
}
if in.EnvVar != nil {
in, out := &in.EnvVar, &out.EnvVar
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
}
out.Bucket = in.Bucket
out.Host = in.Host
out.Port = in.Port
out.AutoCreate = in.AutoCreate
out.SSL = in.SSL
out.Region = in.Region
out.PathStyle = in.PathStyle
out.AccessKeyID = in.AccessKeyID
out.SecretAccessKey = in.SecretAccessKey
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Parameters.
func (in *Parameters) DeepCopy() *Parameters {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ObjectStore.
func (in *ObjectStore) DeepCopy() *ObjectStore {
if in == nil {
return nil
}
out := new(Parameters)
out := new(ObjectStore)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Runtime) DeepCopyInto(out *Runtime) {
func (in *Redis) DeepCopyInto(out *Redis) {
*out = *in
if in.ImagePullSecrets != nil {
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
*out = make([]v1.LocalObjectReference, len(*in))
copy(*out, *in)
out.Username = in.Username
out.Password = in.Password
out.Host = in.Host
out.Port = in.Port
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Redis.
func (in *Redis) DeepCopy() *Redis {
if in == nil {
return nil
}
if in.IngressAnnotations != nil {
in, out := &in.IngressAnnotations, &out.IngressAnnotations
*out = make(map[string]string, len(*in))
for key, val := range *in {
(*out)[key] = val
}
out := new(Redis)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SMTP) DeepCopyInto(out *SMTP) {
*out = *in
out.Username = in.Username
out.Password = in.Password
out.FromAdress = in.FromAdress
out.Domain = in.Domain
out.Secure = in.Secure
out.AuthType = in.AuthType
out.Debug = in.Debug
out.Host = in.Host
out.Port = in.Port
out.TemplateClass = in.TemplateClass
out.PlainTextOnly = in.PlainTextOnly
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SMTP.
func (in *SMTP) DeepCopy() *SMTP {
if in == nil {
return nil
}
if in.Hosts != nil {
in, out := &in.Hosts, &out.Hosts
*out = make([]Host, len(*in))
out := new(SMTP)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Settings) DeepCopyInto(out *Settings) {
*out = *in
in.CreateOptions.DeepCopyInto(&out.CreateOptions)
if in.Sources != nil {
in, out := &in.Sources, &out.Sources
*out = make([]settings.Source, len(*in))
copy(*out, *in)
}
if in.Replicas != nil {
in, out := &in.Replicas, &out.Replicas
*out = new(int32)
**out = **in
in.AppSettings.DeepCopyInto(&out.AppSettings)
in.Web.DeepCopyInto(&out.Web)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Settings.
func (in *Settings) DeepCopy() *Settings {
if in == nil {
return nil
}
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
*out = make([]v1.ContainerPort, len(*in))
out := new(Settings)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *SettingsStatus) DeepCopyInto(out *SettingsStatus) {
*out = *in
if in.Sources != nil {
in, out := &in.Sources, &out.Sources
*out = make([]settings.Source, len(*in))
copy(*out, *in)
}
in.Resources.DeepCopyInto(&out.Resources)
if in.SecurityContext != nil {
in, out := &in.SecurityContext, &out.SecurityContext
*out = new(v1.PodSecurityContext)
(*in).DeepCopyInto(*out)
}
if in.ReadinessProbe != nil {
in, out := &in.ReadinessProbe, &out.ReadinessProbe
*out = new(v1.Probe)
(*in).DeepCopyInto(*out)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SettingsStatus.
func (in *SettingsStatus) DeepCopy() *SettingsStatus {
if in == nil {
return nil
}
if in.LivenessProbe != nil {
in, out := &in.LivenessProbe, &out.LivenessProbe
*out = new(v1.Probe)
out := new(SettingsStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Web) DeepCopyInto(out *Web) {
*out = *in
if in.Workload != nil {
in, out := &in.Workload, &out.Workload
*out = new(components.Workload)
(*in).DeepCopyInto(*out)
}
in.Strategy.DeepCopyInto(&out.Strategy)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Runtime.
func (in *Runtime) DeepCopy() *Runtime {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Web.
func (in *Web) DeepCopy() *Web {
if in == nil {
return nil
}
out := new(Runtime)
out := new(Web)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Settings) DeepCopyInto(out *Settings) {
func (in *WebSettings) DeepCopyInto(out *WebSettings) {
*out = *in
if in.Secrets != nil {
in, out := &in.Secrets, &out.Secrets
*out = make([]From, len(*in))
in.CreateOptions.DeepCopyInto(&out.CreateOptions)
if in.Sources != nil {
in, out := &in.Sources, &out.Sources
*out = make([]settings.Source, len(*in))
copy(*out, *in)
}
if in.Parameters != nil {
in, out := &in.Parameters, &out.Parameters
*out = new(Parameters)
(*in).DeepCopyInto(*out)
}
out.ConfTemplate = in.ConfTemplate
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Settings.
func (in *Settings) DeepCopy() *Settings {
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WebSettings.
func (in *WebSettings) DeepCopy() *WebSettings {
if in == nil {
return nil
}
out := new(Settings)
out := new(WebSettings)
in.DeepCopyInto(out)
return out
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 v1beta1
import (
"sort"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networking "k8s.io/api/networking/v1beta1"
interfaces "git.indie.host/nextcloud-operator/interfaces"
)
const (
// InternalHTTPPort represents the internal port used by the runtime container
HTTPPort = 8080
)
var (
wwwDataUserID int64 = 33
)
func (r *Runtime) MutateContainer(obj *corev1.Container) error {
r.SetDefaults()
obj.Name = "test"
obj.Image = r.Image
obj.ImagePullPolicy = r.ImagePullPolicy
obj.Ports = r.Ports
obj.LivenessProbe = r.LivenessProbe
obj.ReadinessProbe = r.ReadinessProbe
return nil
}
func (s *Settings) MutateDeployment(obj *appsv1.Deployment) error {
s.MutatePod(&obj.Spec.Template)
return nil
}
func (r *Runtime) MutateDeployment(obj *appsv1.Deployment) error {
obj.Spec.Replicas = r.Replicas
r.MutatePod(&obj.Spec.Template)
return nil
}
func (s *Settings) MutatePod(obj *corev1.PodTemplateSpec) error {
container := &corev1.Container{}
containers := []corev1.Container{}
container.Name = "test"
s.MutateContainerEnvFrom(container)
containers = append(containers, *container)
if len(obj.Spec.Containers) == 0 {
obj.Spec.Containers = containers
} else {
s.MutateContainerEnvFrom(&obj.Spec.Containers[0])
}
return nil
}
func (r *Runtime) MutatePod(obj *corev1.PodTemplateSpec) error {
container := &corev1.Container{}
containers := []corev1.Container{}
obj.Spec.SecurityContext = r.SecurityContext
r.MutateContainer(container)
containers = append(containers, *container)
if len(obj.Spec.Containers) == 0 {
obj.Spec.Containers = containers
} else {
r.MutateContainer(&obj.Spec.Containers[0])
}
return nil
}
func (f *From) GetLocalObjectReference() corev1.LocalObjectReference {
return f.LocalObjectReference
}
func (f *From) GetValue() string {
return f.Value
}
func (f *From) GetKey() string {
return f.Key
}
func GenEnv(e interfaces.EnvSource, object string) (corev1.EnvFromSource, corev1.EnvVar) {
envFrom := corev1.EnvFromSource{}
envVar := corev1.EnvVar{}
if len(e.GetKey()) == 0 && len(e.GetLocalObjectReference().Name) > 0 && len(e.GetValue()) == 0 {
if object == "configmap" {
ref := &corev1.ConfigMapEnvSource{
LocalObjectReference: e.GetLocalObjectReference(),
}
envFrom.ConfigMapRef = ref
} else {
ref := &corev1.SecretEnvSource{
LocalObjectReference: e.GetLocalObjectReference(),
}
envFrom.SecretRef = ref
}
} else if len(e.GetLocalObjectReference().Name) > 0 && len(e.GetValue()) > 0 {
envVar.Name = e.GetValue()
if object == "configmap" {
valueFrom := &corev1.EnvVarSource{
ConfigMapKeyRef: &corev1.ConfigMapKeySelector{
LocalObjectReference: e.GetLocalObjectReference(),
Key: e.GetKey(),
},
}
envVar.ValueFrom = valueFrom
} else {
valueFrom := &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: e.GetLocalObjectReference(),
Key: e.GetKey(),
},
}
envVar.ValueFrom = valueFrom
}
}
return envFrom, envVar
}
func (s *Settings) MutateContainerEnvFrom(obj *corev1.Container) error {
configMapSources := s.Parameters.From
secretSources := s.Secrets
envVars := []corev1.EnvVar{}
envFroms := []corev1.EnvFromSource{}
for _, source := range configMapSources {
envFrom, envVar := GenEnv(&source, "configmap")
if len(envVar.Name) > 0 {
envVars = append(envVars, envVar)
}
if envFrom.ConfigMapRef != nil {
envFroms = append(envFroms, envFrom)
}
}
if &secretSources != nil {
for _, source := range secretSources {
if &source != nil {
envFrom, envVar := GenEnv(&source, "secret")
if len(envVar.Name) > 0 {
envVars = append(envVars, envVar)
}
if envFrom.SecretRef != nil {
envFroms = append(envFroms, envFrom)
}
}
}
}
for k, v := range s.Parameters.EnvVar {
envVar := corev1.EnvVar{
Name: k,
Value: v,
}
envVars = append(envVars, envVar)
}
// Sort var to avoid update of the object if var are not in the same order?
sort.SliceStable(envVars, func(i, j int) bool {
return envVars[i].Name < envVars[j].Name
})
obj.EnvFrom = envFroms
obj.Env = envVars
return nil
}
func (r *Runtime) MutateService(obj *corev1.Service) error {
ports := []corev1.ServicePort{
{
Port: 9000,
Name: "http",
},
}
obj.Spec.Type = r.ServiceType
obj.Spec.Ports = ports
return nil
}
func (r *Runtime) MutateIngress(obj *networking.Ingress) error {
obj.ObjectMeta.Annotations = r.IngressAnnotations
if len(r.TLSSecretRef) > 0 {
tls := networking.IngressTLS{
SecretName: string(r.TLSSecretRef),
}
for _, d := range r.Hosts {
tls.Hosts = append(tls.Hosts, string(d))
}
obj.Spec.TLS = []networking.IngressTLS{tls}
} else {
obj.Spec.TLS = nil
}
return nil
}
func (r *Runtime) SetDefaults() {
if len(r.Image) == 0 {
r.Image = "indiehosters/nextcloud"
}
if len(r.ServiceType) == 0 {
r.ServiceType = "ClusterIP"
}
if r.Ports == nil {
ports := []corev1.ContainerPort{
{
Name: "http",
ContainerPort: int32(HTTPPort),
Protocol: "TCP",
},
}
r.Ports = ports
}
// if r.Strategy == nil {
// r.Strategy = "recreate"
// }
if r.SecurityContext == nil {
r.SecurityContext = &corev1.PodSecurityContext{
RunAsUser: &wwwDataUserID,
RunAsGroup: &wwwDataUserID,
FSGroup: &wwwDataUserID,
}
}
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 cli
import (
"fmt"
"github.com/presslabs/controller-util/syncer"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
common "git.indie.host/nextcloud-operator/components/common"
interfaces "git.indie.host/nextcloud-operator/interfaces"
)
type Component struct {
Name string
*common.Common
Job batchv1.Job
}
func CreateAndInit(common *common.Common) *Component {
c := &Component{}
c.Name = "cli"
c.Common = common
labels := c.Labels("cli")
objects := c.GetObjects()
for _, o := range objects {
o.SetName(c.GetName())
o.SetNamespace(c.Owner.Namespace)
o.SetLabels(labels)
}
return c
}
func (c *Component) NewJobSyncer(r interfaces.Reconcile) syncer.Interface {
return syncer.NewObjectSyncer("Job", c.Owner, &c.Job, r.GetClient(), r.GetScheme(), c.MutateJob)
}
func (c *Component) MutateJob() error {
c.Settings.MutatePod(&c.Job.Spec.Template)
c.Runtime.MutatePod(&c.Job.Spec.Template)
// _ = mergo.Merge(&component.Job.Spec.Template.ObjectMeta, &component.Job.ObjectMeta)
// component.Job.Spec.Template.ObjectMeta = component.Job.ObjectMeta
c.Job.Spec.Template.Spec.RestartPolicy = corev1.RestartPolicyNever
// args := []string{"/usr/local/bin/php", "/var/www/html/cron.php"}
// component.Job.Spec.JobTemplate.Spec.Template.Spec.Containers[0].Args = args
return nil
}
func (c *Component) GetName() string {
return fmt.Sprintf("%s-%s", c.Owner.Name, c.Name)
}
func (c *Component) GetObjects() []interfaces.Object {
return []interfaces.Object{
&c.Job,
}
}
/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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 common
import (
"github.com/imdario/mergo"
"k8s.io/apimachinery/pkg/labels"
appsv1beta1 "git.indie.host/nextcloud-operator/api/v1beta1"
)
type Common struct {
Owner *appsv1beta1.Nextcloud
Settings *appsv1beta1.Settings
Runtime *appsv1beta1.Runtime
}
func CreateAndInit(app *appsv1beta1.Nextcloud) *Common {
// app.SetDefaults()
runtime := &app.Spec.App.Runtime
settings := &app.Spec.App.Settings
if app.Spec.Database.Enabled {
settings.Secrets = append(settings.Secrets, app.Spec.Database.Settings.Secrets...)
err := mergo.Merge(settings.Parameters, app.Spec.Database.Settings.Parameters)
if err != nil {
// do something
}
}
if app.Spec.Redis.Enabled {
settings.Secrets = append(settings.Secrets, app.Spec.Redis.Settings.Secrets...)
err := mergo.Merge(settings.Parameters, app.Spec.Redis.Settings.Parameters)
if err != nil {
// do something
}
}
if app.Spec.ObjectStore.Enabled {
settings.Secrets = append(settings.Secrets, app.Spec.ObjectStore.Settings.Secrets...)
err := mergo.Merge(settings.Parameters, app.Spec.ObjectStore.Settings.Parameters)
if err != nil {
// do something
}
}
if app.Spec.SMTP.Enabled {
err := mergo.Merge(settings, app.Spec.SMTP.Settings)
if err != nil {
// do something
}
}
return &Common{
Owner: app,
Settings: settings,
Runtime: runtime,
}
}
func (c *Common) Labels(component string) labels.Set {
partOf := "nextcloud"
// if o.ObjectMeta.Labels != nil && len(o.ObjectMeta.Labels["app.kubernetes.io/part-of"]) > 0 {
// partOf = o.ObjectMeta.Labels["app.kubernetes.io/part-of"]
// }
labels := labels.Set{
"app.kubernetes.io/name": "nextcloud",
"app.kubernetes.io/part-of": partOf,
"app.kubernetes.io/instance": c.Owner.ObjectMeta.Name,
// "app.kubernetes.io/version": c.Owner.Spec.AppVersion,
"app.kubernetes.io/component": component,
"app.kubernetes.io/managed-by": "nextcloud-operator.libre.sh",
}
return labels
}
//func (c *Common) SetDefaults() {
//}
//func (c *Common) GetDeployment() obj *appsv1.deployment {
// c.Settings.MutateDeployment(obj)
// return obj
//}
//func (c *Common) GetService() obj *corev1.service {
// return obj
//}
//func (c *Common) GetConfigMap() obj *corev1.ConfigMap {
// return obj
//}
//func (c *Common) GetSecret() obj *corev1.Secret {
//return obj
//}