From fdca498382f050db5dea9a5547e80cc843cb484b Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Wed, 10 Dec 2025 00:09:36 +0100 Subject: [PATCH 01/15] [registry] Add application labels and update filtering mechanism - Add three application metadata labels to HelmRelease: - apps.cozystack.io/application.kind - apps.cozystack.io/application.group - apps.cozystack.io/application.name - Replace shouldIncludeHelmRelease filtering with label-based filtering in Get, List, and Update methods - Always add kind and group label requirements in List for precise filtering - Update CozystackResourceDefinitionController to watch only HelmReleases with cozystack.io/ui=true label - Update LineageControllerWebhook to extract metadata directly from HelmRelease labels instead of using mapping configuration - Add functionality to update HelmRelease chart from CozystackResourceDefinition using label selectors Signed-off-by: Andrei Kvapil --- .../cozystackresource_controller.go | 156 +++++++++++++++ internal/lineagecontrollerwebhook/config.go | 65 ++++-- .../lineagecontrollerwebhook/controller.go | 12 +- packages/apps/tenant/templates/etcd.yaml | 3 + packages/apps/tenant/templates/info.yaml | 3 + packages/apps/tenant/templates/ingress.yaml | 3 + .../apps/tenant/templates/monitoring.yaml | 3 + packages/apps/tenant/templates/seaweedfs.yaml | 3 + packages/core/platform/templates/apps.yaml | 3 + .../system/bootbox/templates/bootbox.yaml | 3 + pkg/registry/apps/application/rest.go | 187 +++++++----------- scripts/migrations/22 | 163 +++++++++++++++ 12 files changed, 460 insertions(+), 144 deletions(-) create mode 100755 scripts/migrations/22 diff --git a/internal/controller/cozystackresource_controller.go b/internal/controller/cozystackresource_controller.go index 46884418..cc237fba 100644 --- a/internal/controller/cozystackresource_controller.go +++ b/internal/controller/cozystackresource_controller.go @@ -5,11 +5,13 @@ import ( "crypto/sha256" "encoding/hex" "encoding/json" + "fmt" "slices" "sync" "time" cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -37,6 +39,25 @@ type CozystackResourceDefinitionReconciler struct { } func (r *CozystackResourceDefinitionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + logger := log.FromContext(ctx) + + // List all CozystackResourceDefinitions + crdList := &cozyv1alpha1.CozystackResourceDefinitionList{} + if err := r.List(ctx, crdList); err != nil { + logger.Error(err, "failed to list CozystackResourceDefinitions") + return ctrl.Result{}, err + } + + // Update HelmReleases for each CRD + for i := range crdList.Items { + crd := &crdList.Items[i] + if err := r.updateHelmReleasesForCRD(ctx, crd); err != nil { + logger.Error(err, "failed to update HelmReleases for CRD", "crd", crd.Name) + // Continue with other CRDs even if one fails + } + } + + // Continue with debounced restart logic return r.debouncedRestart(ctx) } @@ -61,6 +82,29 @@ func (r *CozystackResourceDefinitionReconciler) SetupWithManager(mgr ctrl.Manage }} }), ). + Watches( + &helmv2.HelmRelease{}, + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { + hr, ok := obj.(*helmv2.HelmRelease) + if !ok { + return nil + } + // Only watch HelmReleases with cozystack.io/ui=true label + if hr.Labels == nil || hr.Labels["cozystack.io/ui"] != "true" { + return nil + } + // Trigger reconciliation of all CRDs when a HelmRelease with the label is created/updated + r.mu.Lock() + r.lastEvent = time.Now() + r.mu.Unlock() + return []reconcile.Request{{ + NamespacedName: types.NamespacedName{ + Namespace: "cozy-system", + Name: "cozystack-api", + }, + }} + }), + ). Complete(r) } @@ -185,3 +229,115 @@ func sortCozyRDs(a, b cozyv1alpha1.CozystackResourceDefinition) int { } return 1 } + +// updateHelmReleasesForCRD updates all HelmReleases that match the application labels from CozystackResourceDefinition +func (r *CozystackResourceDefinitionReconciler) updateHelmReleasesForCRD(ctx context.Context, crd *cozyv1alpha1.CozystackResourceDefinition) error { + logger := log.FromContext(ctx) + + // Use application labels to find HelmReleases + // Labels: apps.cozystack.io/application.kind and apps.cozystack.io/application.group + applicationKind := crd.Spec.Application.Kind + + // Validate that applicationKind is non-empty + if applicationKind == "" { + logger.Error(fmt.Errorf("Application.Kind is empty"), "Skipping HelmRelease update: invalid CozystackResourceDefinition", "crd", crd.Name) + return nil + } + + applicationGroup := "apps.cozystack.io" // All applications use this group + + // Build label selector for HelmReleases + // Only reconcile HelmReleases with cozystack.io/ui=true label + labelSelector := client.MatchingLabels{ + "apps.cozystack.io/application.kind": applicationKind, + "apps.cozystack.io/application.group": applicationGroup, + "cozystack.io/ui": "true", + } + + // List all HelmReleases with matching labels + hrList := &helmv2.HelmReleaseList{} + if err := r.List(ctx, hrList, labelSelector); err != nil { + logger.Error(err, "failed to list HelmReleases", "kind", applicationKind, "group", applicationGroup) + return err + } + + logger.V(4).Info("Found HelmReleases to update", "crd", crd.Name, "kind", applicationKind, "count", len(hrList.Items)) + + // Update each HelmRelease + for i := range hrList.Items { + hr := &hrList.Items[i] + if err := r.updateHelmReleaseChart(ctx, hr, crd); err != nil { + logger.Error(err, "failed to update HelmRelease", "name", hr.Name, "namespace", hr.Namespace) + continue + } + } + + return nil +} + +// updateHelmReleaseChart updates the chart in HelmRelease based on CozystackResourceDefinition +func (r *CozystackResourceDefinitionReconciler) updateHelmReleaseChart(ctx context.Context, hr *helmv2.HelmRelease, crd *cozyv1alpha1.CozystackResourceDefinition) error { + logger := log.FromContext(ctx) + hrCopy := hr.DeepCopy() + updated := false + + // Validate Chart configuration exists + if crd.Spec.Release.Chart.Name == "" { + logger.V(4).Info("Skipping HelmRelease chart update: Chart.Name is empty", "crd", crd.Name) + return nil + } + + // Validate SourceRef fields + if crd.Spec.Release.Chart.SourceRef.Kind == "" || + crd.Spec.Release.Chart.SourceRef.Name == "" || + crd.Spec.Release.Chart.SourceRef.Namespace == "" { + logger.Error(fmt.Errorf("invalid SourceRef in CRD"), "Skipping HelmRelease chart update: SourceRef fields are incomplete", + "crd", crd.Name, + "kind", crd.Spec.Release.Chart.SourceRef.Kind, + "name", crd.Spec.Release.Chart.SourceRef.Name, + "namespace", crd.Spec.Release.Chart.SourceRef.Namespace) + return nil + } + + // Get version and reconcileStrategy from CRD or use defaults + version := ">= 0.0.0-0" + reconcileStrategy := "Revision" + // TODO: Add Version and ReconcileStrategy fields to CozystackResourceDefinitionChart if needed + + // Build expected SourceRef + expectedSourceRef := helmv2.CrossNamespaceObjectReference{ + Kind: crd.Spec.Release.Chart.SourceRef.Kind, + Name: crd.Spec.Release.Chart.SourceRef.Name, + Namespace: crd.Spec.Release.Chart.SourceRef.Namespace, + } + + if hrCopy.Spec.Chart == nil { + // Need to create Chart spec + hrCopy.Spec.Chart = &helmv2.HelmChartTemplate{ + Spec: helmv2.HelmChartTemplateSpec{ + Chart: crd.Spec.Release.Chart.Name, + Version: version, + ReconcileStrategy: reconcileStrategy, + SourceRef: expectedSourceRef, + }, + } + updated = true + } else { + // Update existing Chart spec + if hrCopy.Spec.Chart.Spec.Chart != crd.Spec.Release.Chart.Name || + hrCopy.Spec.Chart.Spec.SourceRef != expectedSourceRef { + hrCopy.Spec.Chart.Spec.Chart = crd.Spec.Release.Chart.Name + hrCopy.Spec.Chart.Spec.SourceRef = expectedSourceRef + updated = true + } + } + + if updated { + logger.V(4).Info("Updating HelmRelease chart", "name", hr.Name, "namespace", hr.Namespace) + if err := r.Update(ctx, hrCopy); err != nil { + return fmt.Errorf("failed to update HelmRelease: %w", err) + } + } + + return nil +} diff --git a/internal/lineagecontrollerwebhook/config.go b/internal/lineagecontrollerwebhook/config.go index 4ca45c13..7204ab66 100644 --- a/internal/lineagecontrollerwebhook/config.go +++ b/internal/lineagecontrollerwebhook/config.go @@ -2,49 +2,72 @@ package lineagecontrollerwebhook import ( "fmt" + "strings" cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" helmv2 "github.com/fluxcd/helm-controller/api/v2" ) -type chartRef struct { - repo string - chart string -} - type appRef struct { group string kind string } type runtimeConfig struct { - chartAppMap map[chartRef]*cozyv1alpha1.CozystackResourceDefinition - appCRDMap map[appRef]*cozyv1alpha1.CozystackResourceDefinition + appCRDMap map[appRef]*cozyv1alpha1.CozystackResourceDefinition } func (l *LineageControllerWebhook) initConfig() { l.initOnce.Do(func() { if l.config.Load() == nil { l.config.Store(&runtimeConfig{ - chartAppMap: make(map[chartRef]*cozyv1alpha1.CozystackResourceDefinition), - appCRDMap: make(map[appRef]*cozyv1alpha1.CozystackResourceDefinition), + appCRDMap: make(map[appRef]*cozyv1alpha1.CozystackResourceDefinition), }) } }) } -func (l *LineageControllerWebhook) Map(hr *helmv2.HelmRelease) (string, string, string, error) { - cfg, ok := l.config.Load().(*runtimeConfig) +// getApplicationLabel safely extracts an application label from HelmRelease +func getApplicationLabel(hr *helmv2.HelmRelease, key string) (string, error) { + if hr.Labels == nil { + return "", fmt.Errorf("cannot map helm release %s/%s to dynamic app: labels are nil", hr.Namespace, hr.Name) + } + val, ok := hr.Labels[key] if !ok { - return "", "", "", fmt.Errorf("failed to load chart-app mapping from config") + return "", fmt.Errorf("cannot map helm release %s/%s to dynamic app: missing %s label", hr.Namespace, hr.Name, key) } - if hr.Spec.Chart == nil { - return "", "", "", fmt.Errorf("cannot map helm release %s/%s to dynamic app", hr.Namespace, hr.Name) - } - s := hr.Spec.Chart.Spec - val, ok := cfg.chartAppMap[chartRef{s.SourceRef.Name, s.Chart}] - if !ok { - return "", "", "", fmt.Errorf("cannot map helm release %s/%s to dynamic app", hr.Namespace, hr.Name) - } - return "apps.cozystack.io/v1alpha1", val.Spec.Application.Kind, val.Spec.Release.Prefix, nil + return val, nil +} + +func (l *LineageControllerWebhook) Map(hr *helmv2.HelmRelease) (string, string, string, error) { + // Extract application metadata from labels + appKind, err := getApplicationLabel(hr, "apps.cozystack.io/application.kind") + if err != nil { + return "", "", "", err + } + + appGroup, err := getApplicationLabel(hr, "apps.cozystack.io/application.group") + if err != nil { + return "", "", "", err + } + + appName, err := getApplicationLabel(hr, "apps.cozystack.io/application.name") + if err != nil { + return "", "", "", err + } + + // Construct API version from group + apiVersion := fmt.Sprintf("%s/v1alpha1", appGroup) + + // Extract prefix from HelmRelease name by removing the application name + // HelmRelease name format: + prefix := strings.TrimSuffix(hr.Name, appName) + + // Validate the derived prefix + // This ensures correctness when appName appears multiple times in hr.Name + if prefix+appName != hr.Name { + return "", "", "", fmt.Errorf("cannot derive prefix from helm release %s/%s: name does not end with application name %s", hr.Namespace, hr.Name, appName) + } + + return apiVersion, appKind, prefix, nil } diff --git a/internal/lineagecontrollerwebhook/controller.go b/internal/lineagecontrollerwebhook/controller.go index e7522f62..092d16e7 100644 --- a/internal/lineagecontrollerwebhook/controller.go +++ b/internal/lineagecontrollerwebhook/controller.go @@ -24,25 +24,15 @@ func (c *LineageControllerWebhook) Reconcile(ctx context.Context, req ctrl.Reque return ctrl.Result{}, err } cfg := &runtimeConfig{ - chartAppMap: make(map[chartRef]*cozyv1alpha1.CozystackResourceDefinition), - appCRDMap: make(map[appRef]*cozyv1alpha1.CozystackResourceDefinition), + appCRDMap: make(map[appRef]*cozyv1alpha1.CozystackResourceDefinition), } for _, crd := range crds.Items { - chRef := chartRef{ - crd.Spec.Release.Chart.SourceRef.Name, - crd.Spec.Release.Chart.Name, - } appRef := appRef{ "apps.cozystack.io", crd.Spec.Application.Kind, } newRef := crd - if _, exists := cfg.chartAppMap[chRef]; exists { - l.Info("duplicate chart mapping detected; ignoring subsequent entry", "key", chRef) - } else { - cfg.chartAppMap[chRef] = &newRef - } if _, exists := cfg.appCRDMap[appRef]; exists { l.Info("duplicate app mapping detected; ignoring subsequent entry", "key", appRef) } else { diff --git a/packages/apps/tenant/templates/etcd.yaml b/packages/apps/tenant/templates/etcd.yaml index 9db6ff6c..8cd720cc 100644 --- a/packages/apps/tenant/templates/etcd.yaml +++ b/packages/apps/tenant/templates/etcd.yaml @@ -9,6 +9,9 @@ metadata: internal.cozystack.io/tenantmodule: "true" app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} + apps.cozystack.io/application.kind: Etcd + apps.cozystack.io/application.group: apps.cozystack.io + apps.cozystack.io/application.name: etcd spec: chart: spec: diff --git a/packages/apps/tenant/templates/info.yaml b/packages/apps/tenant/templates/info.yaml index 4b6f2640..4a66e422 100644 --- a/packages/apps/tenant/templates/info.yaml +++ b/packages/apps/tenant/templates/info.yaml @@ -8,6 +8,9 @@ metadata: internal.cozystack.io/tenantmodule: "true" app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} + apps.cozystack.io/application.kind: Info + apps.cozystack.io/application.group: apps.cozystack.io + apps.cozystack.io/application.name: info spec: chart: spec: diff --git a/packages/apps/tenant/templates/ingress.yaml b/packages/apps/tenant/templates/ingress.yaml index b866300f..beb07342 100644 --- a/packages/apps/tenant/templates/ingress.yaml +++ b/packages/apps/tenant/templates/ingress.yaml @@ -9,6 +9,9 @@ metadata: internal.cozystack.io/tenantmodule: "true" app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} + apps.cozystack.io/application.kind: Ingress + apps.cozystack.io/application.group: apps.cozystack.io + apps.cozystack.io/application.name: ingress spec: chart: spec: diff --git a/packages/apps/tenant/templates/monitoring.yaml b/packages/apps/tenant/templates/monitoring.yaml index edcc66d9..4986fc21 100644 --- a/packages/apps/tenant/templates/monitoring.yaml +++ b/packages/apps/tenant/templates/monitoring.yaml @@ -9,6 +9,9 @@ metadata: internal.cozystack.io/tenantmodule: "true" app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} + apps.cozystack.io/application.kind: Monitoring + apps.cozystack.io/application.group: apps.cozystack.io + apps.cozystack.io/application.name: monitoring spec: chart: spec: diff --git a/packages/apps/tenant/templates/seaweedfs.yaml b/packages/apps/tenant/templates/seaweedfs.yaml index 936e294b..9a714b79 100644 --- a/packages/apps/tenant/templates/seaweedfs.yaml +++ b/packages/apps/tenant/templates/seaweedfs.yaml @@ -9,6 +9,9 @@ metadata: internal.cozystack.io/tenantmodule: "true" app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} + apps.cozystack.io/application.kind: SeaweedFS + apps.cozystack.io/application.group: apps.cozystack.io + apps.cozystack.io/application.name: seaweedfs spec: chart: spec: diff --git a/packages/core/platform/templates/apps.yaml b/packages/core/platform/templates/apps.yaml index c7653e03..514dcffb 100644 --- a/packages/core/platform/templates/apps.yaml +++ b/packages/core/platform/templates/apps.yaml @@ -36,6 +36,9 @@ metadata: namespace: tenant-root labels: cozystack.io/ui: "true" + apps.cozystack.io/application.kind: Tenant + apps.cozystack.io/application.group: apps.cozystack.io + apps.cozystack.io/application.name: tenant-root spec: interval: 0s releaseName: tenant-root diff --git a/packages/system/bootbox/templates/bootbox.yaml b/packages/system/bootbox/templates/bootbox.yaml index 496e42e5..45cd07ce 100644 --- a/packages/system/bootbox/templates/bootbox.yaml +++ b/packages/system/bootbox/templates/bootbox.yaml @@ -5,6 +5,9 @@ metadata: helm.sh/resource-policy: keep labels: cozystack.io/ui: "true" + apps.cozystack.io/application.kind: BootBox + apps.cozystack.io/application.group: apps.cozystack.io + apps.cozystack.io/application.name: bootbox name: bootbox namespace: tenant-root spec: diff --git a/pkg/registry/apps/application/rest.go b/pkg/registry/apps/application/rest.go index 704cd709..39c0ddb8 100644 --- a/pkg/registry/apps/application/rest.go +++ b/pkg/registry/apps/application/rest.go @@ -32,6 +32,7 @@ import ( labels "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/selection" "k8s.io/apimachinery/pkg/util/duration" "k8s.io/apimachinery/pkg/watch" "k8s.io/apiserver/pkg/endpoints/request" @@ -66,6 +67,13 @@ const ( AnnotationPrefix = "apps.cozystack.io-" ) +// Application label keys +const ( + ApplicationKindLabel = "apps.cozystack.io/application.kind" + ApplicationGroupLabel = "apps.cozystack.io/application.group" + ApplicationNameLabel = "apps.cozystack.io/application.name" +) + // Define the GroupVersionResource for HelmRelease var helmReleaseGVR = schema.GroupVersionResource{ Group: "helm.toolkit.fluxcd.io", @@ -157,6 +165,13 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation helmRelease.Labels = mergeMaps(r.releaseConfig.Labels, helmRelease.Labels) // Merge user labels with prefix helmRelease.Labels = mergeMaps(helmRelease.Labels, addPrefixedMap(app.Labels, LabelPrefix)) + // Add application metadata labels + if helmRelease.Labels == nil { + helmRelease.Labels = make(map[string]string) + } + helmRelease.Labels[ApplicationKindLabel] = r.kindName + helmRelease.Labels[ApplicationGroupLabel] = r.gvk.Group + helmRelease.Labels[ApplicationNameLabel] = app.Name // Note: Annotations from config are not handled as r.releaseConfig.Annotations is undefined klog.V(6).Infof("Creating HelmRelease %s in namespace %s", helmRelease.Name, app.Namespace) @@ -208,9 +223,10 @@ func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) return nil, err } - // Check if HelmRelease meets the required chartName and sourceRef criteria - if !r.shouldIncludeHelmRelease(helmRelease) { - klog.Errorf("HelmRelease %s does not match the required chartName and sourceRef criteria", helmReleaseName) + // Check if HelmRelease has required labels + if helmRelease.Labels == nil || helmRelease.Labels[ApplicationKindLabel] != r.kindName || + helmRelease.Labels[ApplicationGroupLabel] != r.gvk.Group { + klog.Errorf("HelmRelease %s does not match the required application labels", helmReleaseName) // Return a NotFound error for the Application resource return nil, apierrors.NewNotFound(r.gvr.GroupResource(), name) } @@ -266,6 +282,19 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption } // Process label.selector + // Always add application metadata label requirements + appKindReq, err := labels.NewRequirement(ApplicationKindLabel, selection.Equals, []string{r.kindName}) + if err != nil { + klog.Errorf("Error creating application kind label requirement: %v", err) + return nil, fmt.Errorf("error creating application kind label requirement: %v", err) + } + appGroupReq, err := labels.NewRequirement(ApplicationGroupLabel, selection.Equals, []string{r.gvk.Group}) + if err != nil { + klog.Errorf("Error creating application group label requirement: %v", err) + return nil, fmt.Errorf("error creating application group label requirement: %v", err) + } + labelRequirements := []labels.Requirement{*appKindReq, *appGroupReq} + if options.LabelSelector != nil { ls := options.LabelSelector.String() parsedLabels, err := labels.Parse(ls) @@ -285,9 +314,12 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption } prefixedReqs = append(prefixedReqs, *prefixedReq) } - helmLabelSelector = labels.NewSelector().Add(prefixedReqs...).String() + labelRequirements = append(labelRequirements, prefixedReqs...) } } + helmLabelSelector = labels.NewSelector().Add(labelRequirements...).String() + + klog.V(6).Infof("Using label selector: %s for kind: %s, group: %s", helmLabelSelector, r.kindName, r.gvk.Group) // Set ListOptions for HelmRelease with selector mapping metaOptions := metav1.ListOptions{ @@ -306,18 +338,30 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption return nil, err } + klog.V(6).Infof("Found %d HelmReleases with label selector, filtering by labels...", len(hrList.Items)) + // Initialize Application items array items := make([]appsv1alpha1.Application, 0, len(hrList.Items)) // Iterate over HelmReleases and convert to Applications + // Filter by labels to ensure only relevant HelmReleases are included + // This is a safety check in case label selectors don't work perfectly or HelmReleases were created without labels for i := range hrList.Items { - if !r.shouldIncludeHelmRelease(&hrList.Items[i]) { + hr := &hrList.Items[i] + + // Verify that HelmRelease has the required labels + if hr.Labels == nil || hr.Labels[ApplicationKindLabel] != r.kindName || + hr.Labels[ApplicationGroupLabel] != r.gvk.Group { + klog.V(6).Infof("Skipping HelmRelease %s - missing or incorrect application labels (kind: %s, expected: %s, group: %s, expected: %s)", + hr.GetName(), + getLabelValue(hr.Labels, ApplicationKindLabel), r.kindName, + getLabelValue(hr.Labels, ApplicationGroupLabel), r.gvk.Group) continue } - app, err := r.ConvertHelmReleaseToApplication(&hrList.Items[i]) + app, err := r.ConvertHelmReleaseToApplication(hr) if err != nil { - klog.Errorf("Error converting HelmRelease %s to Application: %v", hrList.Items[i].GetName(), err) + klog.Errorf("Error converting HelmRelease %s to Application: %v", hr.GetName(), err) continue } @@ -436,18 +480,17 @@ func (r *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObje helmRelease.Labels = mergeMaps(r.releaseConfig.Labels, helmRelease.Labels) // Merge user labels with prefix helmRelease.Labels = mergeMaps(helmRelease.Labels, addPrefixedMap(app.Labels, LabelPrefix)) + // Add application metadata labels + if helmRelease.Labels == nil { + helmRelease.Labels = make(map[string]string) + } + helmRelease.Labels[ApplicationKindLabel] = r.kindName + helmRelease.Labels[ApplicationGroupLabel] = r.gvk.Group + helmRelease.Labels[ApplicationNameLabel] = app.Name // Note: Annotations from config are not handled as r.releaseConfig.Annotations is undefined klog.V(6).Infof("Updating HelmRelease %s in namespace %s", helmRelease.Name, helmRelease.Namespace) - // Before updating, ensure the HelmRelease meets the inclusion criteria - // This prevents updating HelmReleases that should not be managed as Applications - if !r.shouldIncludeHelmRelease(helmRelease) { - klog.Errorf("HelmRelease %s does not match the required chartName and sourceRef criteria", helmRelease.Name) - // Return a NotFound error for the Application resource - return nil, false, apierrors.NewNotFound(r.gvr.GroupResource(), name) - } - // Update the HelmRelease in Kubernetes err = r.c.Update(ctx, helmRelease, &client.UpdateOptions{Raw: &metav1.UpdateOptions{}}) if err != nil { @@ -455,13 +498,6 @@ func (r *REST) Update(ctx context.Context, name string, objInfo rest.UpdatedObje return nil, false, fmt.Errorf("failed to update HelmRelease: %v", err) } - // After updating, ensure the updated HelmRelease still meets the inclusion criteria - if !r.shouldIncludeHelmRelease(helmRelease) { - klog.Errorf("Updated HelmRelease %s does not match the required chartName and sourceRef criteria", helmRelease.GetName()) - // Return a NotFound error for the Application resource - return nil, false, apierrors.NewNotFound(r.gvr.GroupResource(), name) - } - // Convert the updated HelmRelease back to Application convertedApp, err := r.ConvertHelmReleaseToApplication(helmRelease) if err != nil { @@ -503,9 +539,10 @@ func (r *REST) Delete(ctx context.Context, name string, deleteValidation rest.Va return nil, false, err } - // Validate that the HelmRelease meets the inclusion criteria - if !r.shouldIncludeHelmRelease(helmRelease) { - klog.Errorf("HelmRelease %s does not match the required chartName and sourceRef criteria", helmReleaseName) + // Validate that the HelmRelease has required labels + if helmRelease.Labels == nil || helmRelease.Labels[ApplicationKindLabel] != r.kindName || + helmRelease.Labels[ApplicationGroupLabel] != r.gvk.Group { + klog.Errorf("HelmRelease %s does not match the required application labels", helmReleaseName) // Return NotFound error for Application resource return nil, false, apierrors.NewNotFound(r.gvr.GroupResource(), name) } @@ -523,7 +560,7 @@ func (r *REST) Delete(ctx context.Context, name string, deleteValidation rest.Va return nil, true, nil } -// Watch sets up a watch on HelmReleases, filters them based on sourceRef and prefix, and converts events to Applications +// Watch sets up a watch on HelmReleases, filters them based on application labels, and converts events to Applications func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptions) (watch.Interface, error) { namespace, err := r.getNamespace(ctx) if err != nil { @@ -639,7 +676,10 @@ func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptio continue } - if !r.shouldIncludeHelmRelease(hr) { + // Verify that HelmRelease has the required labels + if hr.Labels == nil || hr.Labels[ApplicationKindLabel] != r.kindName || + hr.Labels[ApplicationGroupLabel] != r.gvk.Group { + klog.V(6).Infof("Skipping HelmRelease %s in watch - missing or incorrect application labels", hr.GetName()) continue } @@ -694,14 +734,6 @@ func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptio return customW, nil } -// Helper function to get HelmRelease name from object -func helmReleaseName(obj runtime.Object) string { - if app, ok := obj.(*appsv1alpha1.Application); ok { - return app.GetName() - } - return "" -} - // customWatcher wraps the original watcher and filters/converts events type customWatcher struct { resultChan chan watch.Event @@ -725,74 +757,6 @@ func (cw *customWatcher) ResultChan() <-chan watch.Event { return cw.resultChan } -// shouldIncludeHelmRelease determines if a HelmRelease should be included based on filtering criteria -func (r *REST) shouldIncludeHelmRelease(hr *helmv2.HelmRelease) bool { - // Nil check for Chart field - if hr.Spec.Chart == nil { - klog.V(6).Infof("HelmRelease %s has nil spec.chart field", hr.GetName()) - return false - } - - // Filter by Chart Name - chartName := hr.Spec.Chart.Spec.Chart - if chartName == "" { - klog.V(6).Infof("HelmRelease %s missing spec.chart.spec.chart field", hr.GetName()) - return false - } - if chartName != r.releaseConfig.Chart.Name { - klog.V(6).Infof("HelmRelease %s chart name %s does not match expected %s", hr.GetName(), chartName, r.releaseConfig.Chart.Name) - return false - } - - // Filter by SourceRefConfig and Prefix - return r.matchesSourceRefAndPrefix(hr) -} - -// matchesSourceRefAndPrefix checks both SourceRefConfig and Prefix criteria -func (r *REST) matchesSourceRefAndPrefix(hr *helmv2.HelmRelease) bool { - // Nil check for Chart field (defensive) - if hr.Spec.Chart == nil { - klog.V(6).Infof("HelmRelease %s has nil spec.chart field", hr.GetName()) - return false - } - - // Extract SourceRef fields - sourceRef := hr.Spec.Chart.Spec.SourceRef - sourceRefKind := sourceRef.Kind - sourceRefName := sourceRef.Name - sourceRefNamespace := sourceRef.Namespace - - if sourceRefKind == "" { - klog.V(6).Infof("HelmRelease %s missing spec.chart.spec.sourceRef.kind field", hr.GetName()) - return false - } - if sourceRefName == "" { - klog.V(6).Infof("HelmRelease %s missing spec.chart.spec.sourceRef.name field", hr.GetName()) - return false - } - if sourceRefNamespace == "" { - klog.V(6).Infof("HelmRelease %s missing spec.chart.spec.sourceRef.namespace field", hr.GetName()) - return false - } - - // Check if SourceRef matches the configuration - if sourceRefKind != r.releaseConfig.Chart.SourceRef.Kind || - sourceRefName != r.releaseConfig.Chart.SourceRef.Name || - sourceRefNamespace != r.releaseConfig.Chart.SourceRef.Namespace { - klog.V(6).Infof("HelmRelease %s sourceRef does not match expected values", hr.GetName()) - return false - } - - // Additional filtering by Prefix - name := hr.GetName() - if !strings.HasPrefix(name, r.releaseConfig.Prefix) { - klog.V(6).Infof("HelmRelease %s does not have the expected prefix %s", name, r.releaseConfig.Prefix) - return false - } - - return true -} - // getNamespace extracts the namespace from the context func (r *REST) getNamespace(ctx context.Context) (string, error) { namespace, ok := request.NamespaceFrom(ctx) @@ -804,15 +768,6 @@ func (r *REST) getNamespace(ctx context.Context) (string, error) { return namespace, nil } -// buildLabelSelector constructs a label selector string from a map of labels -func buildLabelSelector(labels map[string]string) string { - var selectors []string - for k, v := range labels { - selectors = append(selectors, fmt.Sprintf("%s=%s", k, v)) - } - return strings.Join(selectors, ",") -} - // mergeMaps combines two maps of labels or annotations func mergeMaps(a, b map[string]string) map[string]string { if a == nil && b == nil { @@ -861,6 +816,14 @@ func filterPrefixedMap(original map[string]string, prefix string) map[string]str return processed } +// getLabelValue safely gets a label value, returning empty string if labels is nil or key doesn't exist +func getLabelValue(labels map[string]string, key string) string { + if labels == nil { + return "" + } + return labels[key] +} + // ConvertHelmReleaseToApplication converts a HelmRelease to an Application func (r *REST) ConvertHelmReleaseToApplication(hr *helmv2.HelmRelease) (appsv1alpha1.Application, error) { klog.V(6).Infof("Converting HelmRelease to Application for resource %s", hr.GetName()) diff --git a/scripts/migrations/22 b/scripts/migrations/22 new file mode 100755 index 00000000..192e431c --- /dev/null +++ b/scripts/migrations/22 @@ -0,0 +1,163 @@ +#!/bin/sh +# Migration 22 --> 23 + +set -euo pipefail + +echo "Migrating HelmReleases: adding application labels for tenant-* namespaces" + +# Function to determine application type from HelmRelease name +determine_app_type() { + local name="$1" + local app_kind="" + local app_name="" + + # Try to match by prefix (longest match first) + case "$name" in + virtual-machine-*) + app_kind="VirtualMachine" + app_name="${name#virtual-machine-}" + ;; + vm-instance-*) + app_kind="VMInstance" + app_name="${name#vm-instance-}" + ;; + vm-disk-*) + app_kind="VMDisk" + app_name="${name#vm-disk-}" + ;; + virtualprivatecloud-*) + app_kind="VirtualPrivateCloud" + app_name="${name#virtualprivatecloud-}" + ;; + http-cache-*) + app_kind="HTTPCache" + app_name="${name#http-cache-}" + ;; + tcp-balancer-*) + app_kind="TCPBalancer" + app_name="${name#tcp-balancer-}" + ;; + clickhouse-*) + app_kind="ClickHouse" + app_name="${name#clickhouse-}" + ;; + foundationdb-*) + app_kind="FoundationDB" + app_name="${name#foundationdb-}" + ;; + ferretdb-*) + app_kind="FerretDB" + app_name="${name#ferretdb-}" + ;; + rabbitmq-*) + app_kind="RabbitMQ" + app_name="${name#rabbitmq-}" + ;; + kubernetes-*) + app_kind="Kubernetes" + app_name="${name#kubernetes-}" + ;; + bucket-*) + app_kind="Bucket" + app_name="${name#bucket-}" + ;; + kafka-*) + app_kind="Kafka" + app_name="${name#kafka-}" + ;; + mysql-*) + app_kind="MySQL" + app_name="${name#mysql-}" + ;; + nats-*) + app_kind="NATS" + app_name="${name#nats-}" + ;; + postgres-*) + app_kind="PostgreSQL" + app_name="${name#postgres-}" + ;; + redis-*) + app_kind="Redis" + app_name="${name#redis-}" + ;; + tenant-*) + app_kind="Tenant" + app_name="${name#tenant-}" + ;; + vpn-*) + app_kind="VPN" + app_name="${name#vpn-}" + ;; + bootbox) + app_kind="BootBox" + app_name="bootbox" + ;; + etcd) + app_kind="Etcd" + app_name="etcd" + ;; + info) + app_kind="Info" + app_name="info" + ;; + ingress|ingress-*) + app_kind="Ingress" + if [ "$name" = "ingress" ]; then + app_name="ingress" + else + app_name="${name#ingress-}" + fi + ;; + monitoring) + app_kind="Monitoring" + app_name="monitoring" + ;; + seaweedfs) + app_kind="SeaweedFS" + app_name="seaweedfs" + ;; + *) + # Unknown type + return 1 + ;; + esac + + echo "$app_kind|$app_name" + return 0 +} + +# Process all HelmReleases in tenant-* namespaces with cozystack.io/ui=true label +kubectl get helmreleases --all-namespaces -l cozystack.io/ui=true -o json | \ + jq -r '.items[] | select(.metadata.namespace | startswith("tenant-")) | "\(.metadata.namespace)|\(.metadata.name)"' | \ + while IFS='|' read -r namespace name; do + echo "Processing HelmRelease $namespace/$name" + + # Determine application type + app_type=$(determine_app_type "$name") + status=$? + if [ $status -ne 0 ] || [ -z "$app_type" ]; then + echo "Warning: Could not determine application type for $namespace/$name, skipping" + continue + fi + + app_kind=$(echo "$app_type" | cut -d'|' -f1) + app_name=$(echo "$app_type" | cut -d'|' -f2) + app_group="apps.cozystack.io" + + # Build labels string + labels="apps.cozystack.io/application.kind=$app_kind" + labels="$labels apps.cozystack.io/application.group=$app_group" + labels="$labels apps.cozystack.io/application.name=$app_name" + + # Apply labels using kubectl label --overwrite + kubectl label helmrelease -n "$namespace" "$name" --overwrite $labels + echo "Added application labels to $namespace/$name: $labels" + done + +echo "Migration completed" + +# Stamp version +kubectl create configmap -n cozy-system cozystack-version \ + --from-literal=version=23 --dry-run=client -o yaml | kubectl apply -f- + From 0377bd3d291cb3f3f97273496f5544cc92c187cc Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Thu, 18 Dec 2025 15:31:09 +0100 Subject: [PATCH 02/15] Fix review comments Signed-off-by: Andrei Kvapil --- .../cozystackresource_controller.go | 62 ++++++-------- pkg/apis/apps/v1alpha1/types.go | 7 ++ pkg/registry/apps/application/rest.go | 82 ++++++++++--------- 3 files changed, 76 insertions(+), 75 deletions(-) diff --git a/internal/controller/cozystackresource_controller.go b/internal/controller/cozystackresource_controller.go index cc237fba..21585c6f 100644 --- a/internal/controller/cozystackresource_controller.go +++ b/internal/controller/cozystackresource_controller.go @@ -39,24 +39,10 @@ type CozystackResourceDefinitionReconciler struct { } func (r *CozystackResourceDefinitionReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - logger := log.FromContext(ctx) - - // List all CozystackResourceDefinitions - crdList := &cozyv1alpha1.CozystackResourceDefinitionList{} - if err := r.List(ctx, crdList); err != nil { - logger.Error(err, "failed to list CozystackResourceDefinitions") + if err := r.reconcileCozyRDAndUpdateHelmReleases(ctx); err != nil { return ctrl.Result{}, err } - // Update HelmReleases for each CRD - for i := range crdList.Items { - crd := &crdList.Items[i] - if err := r.updateHelmReleasesForCRD(ctx, crd); err != nil { - logger.Error(err, "failed to update HelmReleases for CRD", "crd", crd.Name) - // Continue with other CRDs even if one fails - } - } - // Continue with debounced restart logic return r.debouncedRestart(ctx) } @@ -82,29 +68,6 @@ func (r *CozystackResourceDefinitionReconciler) SetupWithManager(mgr ctrl.Manage }} }), ). - Watches( - &helmv2.HelmRelease{}, - handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { - hr, ok := obj.(*helmv2.HelmRelease) - if !ok { - return nil - } - // Only watch HelmReleases with cozystack.io/ui=true label - if hr.Labels == nil || hr.Labels["cozystack.io/ui"] != "true" { - return nil - } - // Trigger reconciliation of all CRDs when a HelmRelease with the label is created/updated - r.mu.Lock() - r.lastEvent = time.Now() - r.mu.Unlock() - return []reconcile.Request{{ - NamespacedName: types.NamespacedName{ - Namespace: "cozy-system", - Name: "cozystack-api", - }, - }} - }), - ). Complete(r) } @@ -230,6 +193,29 @@ func sortCozyRDs(a, b cozyv1alpha1.CozystackResourceDefinition) int { return 1 } +// reconcileCozyRDAndUpdateHelmReleases reconciles all CozystackResourceDefinitions and updates HelmReleases from them +func (r *CozystackResourceDefinitionReconciler) reconcileCozyRDAndUpdateHelmReleases(ctx context.Context) error { + logger := log.FromContext(ctx) + + // List all CozystackResourceDefinitions + crdList := &cozyv1alpha1.CozystackResourceDefinitionList{} + if err := r.List(ctx, crdList); err != nil { + logger.Error(err, "failed to list CozystackResourceDefinitions") + return err + } + + // Update HelmReleases for each CRD + for i := range crdList.Items { + crd := &crdList.Items[i] + if err := r.updateHelmReleasesForCRD(ctx, crd); err != nil { + logger.Error(err, "failed to update HelmReleases for CRD", "crd", crd.Name) + // Continue with other CRDs even if one fails + } + } + + return nil +} + // updateHelmReleasesForCRD updates all HelmReleases that match the application labels from CozystackResourceDefinition func (r *CozystackResourceDefinitionReconciler) updateHelmReleasesForCRD(ctx context.Context, crd *cozyv1alpha1.CozystackResourceDefinition) error { logger := log.FromContext(ctx) diff --git a/pkg/apis/apps/v1alpha1/types.go b/pkg/apis/apps/v1alpha1/types.go index 8e756779..0118b0de 100644 --- a/pkg/apis/apps/v1alpha1/types.go +++ b/pkg/apis/apps/v1alpha1/types.go @@ -21,6 +21,13 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// Application label keys used to identify and filter HelmReleases +const ( + ApplicationKindLabel = "apps.cozystack.io/application.kind" + ApplicationGroupLabel = "apps.cozystack.io/application.group" + ApplicationNameLabel = "apps.cozystack.io/application.name" +) + // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // ApplicationList is a list of Application objects. diff --git a/pkg/registry/apps/application/rest.go b/pkg/registry/apps/application/rest.go index 39c0ddb8..78ff8dbc 100644 --- a/pkg/registry/apps/application/rest.go +++ b/pkg/registry/apps/application/rest.go @@ -67,11 +67,11 @@ const ( AnnotationPrefix = "apps.cozystack.io-" ) -// Application label keys +// Application label keys - use constants from API package const ( - ApplicationKindLabel = "apps.cozystack.io/application.kind" - ApplicationGroupLabel = "apps.cozystack.io/application.group" - ApplicationNameLabel = "apps.cozystack.io/application.name" + ApplicationKindLabel = appsv1alpha1.ApplicationKindLabel + ApplicationGroupLabel = appsv1alpha1.ApplicationGroupLabel + ApplicationNameLabel = appsv1alpha1.ApplicationNameLabel ) // Define the GroupVersionResource for HelmRelease @@ -224,8 +224,7 @@ func (r *REST) Get(ctx context.Context, name string, options *metav1.GetOptions) } // Check if HelmRelease has required labels - if helmRelease.Labels == nil || helmRelease.Labels[ApplicationKindLabel] != r.kindName || - helmRelease.Labels[ApplicationGroupLabel] != r.gvk.Group { + if !r.hasRequiredApplicationLabels(helmRelease) { klog.Errorf("HelmRelease %s does not match the required application labels", helmReleaseName) // Return a NotFound error for the Application resource return nil, apierrors.NewNotFound(r.gvr.GroupResource(), name) @@ -338,27 +337,16 @@ func (r *REST) List(ctx context.Context, options *metainternalversion.ListOption return nil, err } - klog.V(6).Infof("Found %d HelmReleases with label selector, filtering by labels...", len(hrList.Items)) + klog.V(6).Infof("Found %d HelmReleases with label selector", len(hrList.Items)) // Initialize Application items array items := make([]appsv1alpha1.Application, 0, len(hrList.Items)) // Iterate over HelmReleases and convert to Applications - // Filter by labels to ensure only relevant HelmReleases are included - // This is a safety check in case label selectors don't work perfectly or HelmReleases were created without labels + // Note: All HelmReleases already match the required labels due to server-side label selector filtering for i := range hrList.Items { hr := &hrList.Items[i] - // Verify that HelmRelease has the required labels - if hr.Labels == nil || hr.Labels[ApplicationKindLabel] != r.kindName || - hr.Labels[ApplicationGroupLabel] != r.gvk.Group { - klog.V(6).Infof("Skipping HelmRelease %s - missing or incorrect application labels (kind: %s, expected: %s, group: %s, expected: %s)", - hr.GetName(), - getLabelValue(hr.Labels, ApplicationKindLabel), r.kindName, - getLabelValue(hr.Labels, ApplicationGroupLabel), r.gvk.Group) - continue - } - app, err := r.ConvertHelmReleaseToApplication(hr) if err != nil { klog.Errorf("Error converting HelmRelease %s to Application: %v", hr.GetName(), err) @@ -540,8 +528,7 @@ func (r *REST) Delete(ctx context.Context, name string, deleteValidation rest.Va } // Validate that the HelmRelease has required labels - if helmRelease.Labels == nil || helmRelease.Labels[ApplicationKindLabel] != r.kindName || - helmRelease.Labels[ApplicationGroupLabel] != r.gvk.Group { + if !r.hasRequiredApplicationLabelsWithName(helmRelease, name) { klog.Errorf("HelmRelease %s does not match the required application labels", helmReleaseName) // Return NotFound error for Application resource return nil, false, apierrors.NewNotFound(r.gvr.GroupResource(), name) @@ -601,6 +588,19 @@ func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptio } // Process label.selector + // Always add application metadata label requirements + appKindReq, err := labels.NewRequirement(ApplicationKindLabel, selection.Equals, []string{r.kindName}) + if err != nil { + klog.Errorf("Error creating application kind label requirement: %v", err) + return nil, fmt.Errorf("error creating application kind label requirement: %v", err) + } + appGroupReq, err := labels.NewRequirement(ApplicationGroupLabel, selection.Equals, []string{r.gvk.Group}) + if err != nil { + klog.Errorf("Error creating application group label requirement: %v", err) + return nil, fmt.Errorf("error creating application group label requirement: %v", err) + } + labelRequirements := []labels.Requirement{*appKindReq, *appGroupReq} + if options.LabelSelector != nil { ls := options.LabelSelector.String() parsedLabels, err := labels.Parse(ls) @@ -620,9 +620,10 @@ func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptio } prefixedReqs = append(prefixedReqs, *prefixedReq) } - helmLabelSelector = labels.NewSelector().Add(prefixedReqs...).String() + labelRequirements = append(labelRequirements, prefixedReqs...) } } + helmLabelSelector = labels.NewSelector().Add(labelRequirements...).String() // Set ListOptions for HelmRelease with selector mapping metaOptions := metav1.ListOptions{ @@ -676,13 +677,7 @@ func (r *REST) Watch(ctx context.Context, options *metainternalversion.ListOptio continue } - // Verify that HelmRelease has the required labels - if hr.Labels == nil || hr.Labels[ApplicationKindLabel] != r.kindName || - hr.Labels[ApplicationGroupLabel] != r.gvk.Group { - klog.V(6).Infof("Skipping HelmRelease %s in watch - missing or incorrect application labels", hr.GetName()) - continue - } - + // Note: All HelmReleases already match the required labels due to server-side label selector filtering // Convert HelmRelease to Application app, err := r.ConvertHelmReleaseToApplication(hr) if err != nil { @@ -768,6 +763,27 @@ func (r *REST) getNamespace(ctx context.Context) (string, error) { return namespace, nil } +// hasRequiredApplicationLabels checks if a HelmRelease has the required application labels +// matching the REST instance's kind and group +func (r *REST) hasRequiredApplicationLabels(hr *helmv2.HelmRelease) bool { + if hr.Labels == nil { + return false + } + return hr.Labels[ApplicationKindLabel] == r.kindName && + hr.Labels[ApplicationGroupLabel] == r.gvk.Group +} + +// hasRequiredApplicationLabelsWithName checks if a HelmRelease has the required application labels +// matching the REST instance's kind, group, and the specified application name +func (r *REST) hasRequiredApplicationLabelsWithName(hr *helmv2.HelmRelease, appName string) bool { + if hr.Labels == nil { + return false + } + return hr.Labels[ApplicationKindLabel] == r.kindName && + hr.Labels[ApplicationGroupLabel] == r.gvk.Group && + hr.Labels[ApplicationNameLabel] == appName +} + // mergeMaps combines two maps of labels or annotations func mergeMaps(a, b map[string]string) map[string]string { if a == nil && b == nil { @@ -816,14 +832,6 @@ func filterPrefixedMap(original map[string]string, prefix string) map[string]str return processed } -// getLabelValue safely gets a label value, returning empty string if labels is nil or key doesn't exist -func getLabelValue(labels map[string]string, key string) string { - if labels == nil { - return "" - } - return labels[key] -} - // ConvertHelmReleaseToApplication converts a HelmRelease to an Application func (r *REST) ConvertHelmReleaseToApplication(hr *helmv2.HelmRelease) (appsv1alpha1.Application, error) { klog.V(6).Infof("Converting HelmRelease to Application for resource %s", hr.GetName()) From e963e480a70fbfddfa15fc01275ebbe3ea80bb0f Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Thu, 18 Dec 2025 19:19:22 +0100 Subject: [PATCH 03/15] [cozystack-operator] Add PackageSet types Signed-off-by: Andrei Kvapil --- api/v1alpha1/packageset_types.go | 89 ++++ api/v1alpha1/packagesetdefinition_types.go | 202 +++++++++ api/v1alpha1/zz_generated.deepcopy.go | 382 ++++++++++++++++++ packages/core/platform/psds/clickhouse.yaml | 52 +++ packages/core/platform/psds/cozystack.yaml | 67 +++ packages/core/platform/psds/ferretdb.yaml | 28 ++ .../platform/psds/foundationdb-operator.yaml | 24 ++ packages/core/platform/psds/foundationdb.yaml | 30 ++ packages/core/platform/psds/http-cache.yaml | 28 ++ .../core/platform/psds/kafka-operator.yaml | 24 ++ packages/core/platform/psds/kafka.yaml | 30 ++ .../core/platform/psds/mariadb-operator.yaml | 26 ++ packages/core/platform/psds/mysql.yaml | 30 ++ packages/core/platform/psds/nats.yaml | 30 ++ packages/core/platform/psds/networking.yaml | 65 +++ packages/core/platform/psds/postgres.yaml | 29 ++ .../core/platform/psds/rabbitmq-operator.yaml | 21 + packages/core/platform/psds/rabbitmq.yaml | 30 ++ .../core/platform/psds/redis-operator.yaml | 21 + packages/core/platform/psds/redis.yaml | 30 ++ packages/core/platform/psds/tcp-balancer.yaml | 29 ++ packages/core/platform/psds/vpn.yaml | 29 ++ packages/packages.yaml | 199 +++++++++ 23 files changed, 1495 insertions(+) create mode 100644 api/v1alpha1/packageset_types.go create mode 100644 api/v1alpha1/packagesetdefinition_types.go create mode 100644 packages/core/platform/psds/clickhouse.yaml create mode 100644 packages/core/platform/psds/cozystack.yaml create mode 100644 packages/core/platform/psds/ferretdb.yaml create mode 100644 packages/core/platform/psds/foundationdb-operator.yaml create mode 100644 packages/core/platform/psds/foundationdb.yaml create mode 100644 packages/core/platform/psds/http-cache.yaml create mode 100644 packages/core/platform/psds/kafka-operator.yaml create mode 100644 packages/core/platform/psds/kafka.yaml create mode 100644 packages/core/platform/psds/mariadb-operator.yaml create mode 100644 packages/core/platform/psds/mysql.yaml create mode 100644 packages/core/platform/psds/nats.yaml create mode 100644 packages/core/platform/psds/networking.yaml create mode 100644 packages/core/platform/psds/postgres.yaml create mode 100644 packages/core/platform/psds/rabbitmq-operator.yaml create mode 100644 packages/core/platform/psds/rabbitmq.yaml create mode 100644 packages/core/platform/psds/redis-operator.yaml create mode 100644 packages/core/platform/psds/redis.yaml create mode 100644 packages/core/platform/psds/tcp-balancer.yaml create mode 100644 packages/core/platform/psds/vpn.yaml create mode 100644 packages/packages.yaml diff --git a/api/v1alpha1/packageset_types.go b/api/v1alpha1/packageset_types.go new file mode 100644 index 00000000..b7529683 --- /dev/null +++ b/api/v1alpha1/packageset_types.go @@ -0,0 +1,89 @@ +/* +Copyright 2025. + +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 ( + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +kubebuilder:object:root=true +// +kubebuilder:resource:scope=Cluster,shortName=ps +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Variant",type="string",JSONPath=".status.variant",description="Selected variant" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status",description="Ready status" +// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].message",description="Ready message" + +// PackageSet is the Schema for the packagesets API +type PackageSet struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PackageSetSpec `json:"spec,omitempty"` + Status PackageSetStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// PackageSetList contains a list of PackageSets +type PackageSetList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PackageSet `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PackageSet{}, &PackageSetList{}) +} + +// PackageSetSpec defines the desired state of PackageSet +type PackageSetSpec struct { + // IgnoreDependencies is a list of package set dependencies to ignore + // Dependencies listed here will not be installed even if they are specified in the PackageSetDefinition + // +optional + IgnoreDependencies []string `json:"ignoreDependencies,omitempty"` + + // Packages is a map of package name to package overrides + // Allows overriding values and enabling/disabling specific packages from the PackageSetDefinition + // +optional + Packages map[string]PackageSetPackageOverride `json:"packages,omitempty"` +} + +// PackageSetPackageOverride defines overrides for a specific package +type PackageSetPackageOverride struct { + // Enabled indicates whether this package should be installed + // If false, the package will be disabled even if it's defined in the PackageSetDefinition + // +optional + Enabled *bool `json:"enabled,omitempty"` + + // Values contains Helm chart values as a JSON object + // These values will be merged with the default values from the PackageSetDefinition + // +optional + Values *apiextensionsv1.JSON `json:"values,omitempty"` +} + +// PackageSetStatus defines the observed state of PackageSet +type PackageSetStatus struct { + // Variant is the selected variant name, or "default" if not specified + // This field is populated by the controller based on spec.packageSetDefinitionRef.variant + // +optional + Variant string `json:"variant,omitempty"` + + // Conditions represents the latest available observations of a PackageSet's state + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` +} diff --git a/api/v1alpha1/packagesetdefinition_types.go b/api/v1alpha1/packagesetdefinition_types.go new file mode 100644 index 00000000..36c1e921 --- /dev/null +++ b/api/v1alpha1/packagesetdefinition_types.go @@ -0,0 +1,202 @@ +/* +Copyright 2025. + +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 ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +kubebuilder:object:root=true +// +kubebuilder:resource:scope=Cluster,shortName=psd +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Variants",type="string",JSONPath=".status.variants",description="Package variants (comma-separated)" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status",description="Ready status" +// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].message",description="Ready message" + +// PackageSetDefinition is the Schema for the packagesetdefinitions API +type PackageSetDefinition struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PackageSetDefinitionSpec `json:"spec,omitempty"` + Status PackageSetDefinitionStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// PackageSetDefinitionList contains a list of PackageSetDefinitions +type PackageSetDefinitionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PackageSetDefinition `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PackageSetDefinition{}, &PackageSetDefinitionList{}) +} + +// PackageSetDefinitionSpec defines the desired state of PackageSetDefinition +type PackageSetDefinitionSpec struct { + // SourceRef is the source reference for the package set charts + // +optional + SourceRef *PackageSetDefinitionSourceRef `json:"sourceRef,omitempty"` + + // Variants is a list of package set variants + // Each variant defines packages, sources, dependencies, and libraries for a specific configuration + // +optional + Variants []PackageSetDefinitionVariant `json:"variants,omitempty"` +} + +// PackageSetDefinitionVariant defines a single variant configuration +type PackageSetDefinitionVariant struct { + // Name is the unique identifier for this variant + // +required + Name string `json:"name"` + + // DependsOn is a list of package set dependencies in the format "packageSetName/target" + // For example: "cozystack-system/network" + // If specified, the dependencies listed in the target's packages will be taken + // from the specified package set and added to all packages in this variant + // +optional + DependsOn []string `json:"dependsOn,omitempty"` + + // Libraries is a list of Helm library charts used by packages in this variant + // +optional + Libraries []PackageSetDefinitionLibrary `json:"libraries,omitempty"` + + // Packages is a list of Helm releases to be installed as part of this variant + // +optional + Packages []PackageSetDefinitionPackage `json:"packages,omitempty"` + + // Sources is a list of application sources for this variant + // +optional + Sources []PackageSetDefinitionApplication `json:"sources,omitempty"` +} + +// PackageSetDefinitionDependencyTarget defines a named group of packages that can be referenced +// by other package sets via dependsOn +type PackageSetDefinitionDependencyTarget struct { + // Name is the unique identifier for this dependency target + // +required + Name string `json:"name"` + + // Packages is a list of package names that belong to this target + // These packages will be added as dependencies when this target is referenced + // +required + Packages []string `json:"packages"` +} + +// PackageSetDefinitionLibrary defines a Helm library chart +type PackageSetDefinitionLibrary struct { + // Name is the optional name for library placed in charts + // +optional + Name string `json:"name,omitempty"` + + // Path is the path to the library chart directory + // +required + Path string `json:"path"` +} + +// PackageSetDefinitionSourceRef defines the source reference for package set charts +type PackageSetDefinitionSourceRef struct { + // Kind of the source reference + // +kubebuilder:validation:Enum=GitRepository;OCIRepository + // +required + Kind string `json:"kind"` + + // Name of the source reference + // +required + Name string `json:"name"` + + // Namespace of the source reference + // +required + Namespace string `json:"namespace"` + + // BasePath is the base path where packages are located in the source. + // For GitRepository, defaults to "packages" if not specified. + // For OCIRepository, defaults to empty string (root) if not specified. + // +optional + Path string `json:"path,omitempty"` +} + +// PackageSetDefinitionPackage defines a single Helm release within a package set +type PackageSetDefinitionPackage struct { + // Name is the unique identifier for this package within the package set + // +required + Name string `json:"name"` + + // ReleaseName is the name of the HelmRelease resource that will be created + // If not specified, defaults to the Name field + // +optional + ReleaseName string `json:"releaseName,omitempty"` + + // Path is the path to the Helm chart directory + // +required + Path string `json:"path"` + + // Namespace is the Kubernetes namespace where the release will be installed + // +required + Namespace string `json:"namespace"` + + // Privileged indicates whether this release requires privileged access + // +optional + Privileged bool `json:"privileged,omitempty"` + + // Disabled indicates whether this release is disabled (should not be installed) + // +optional + Disabled bool `json:"disabled,omitempty"` + + // DependsOn is a list of release names that must be installed before this release + // +optional + DependsOn []string `json:"dependsOn,omitempty"` + + // Libraries is a list of library charts that this package depends on + // +optional + Libraries []PackageSetDefinitionLibrary `json:"libraries,omitempty"` + + // ValuesFiles is a list of values file names to use + // +optional + ValuesFiles []string `json:"valuesFiles,omitempty"` +} + +// PackageSetDefinitionApplication defines a single application release within a package set +type PackageSetDefinitionApplication struct { + // Name is the unique identifier for this application within the package set + // +required + Name string `json:"name"` + + // Path is the path to the Helm chart directory + // +required + Path string `json:"path"` + + // Libraries is a list of library names that this application depends on + // These libraries must be defined at the variant level + // +optional + Libraries []string `json:"libraries,omitempty"` +} + +// PackageSetDefinitionStatus defines the observed state of PackageSetDefinition +type PackageSetDefinitionStatus struct { + // Variants is a comma-separated list of package variant names + // This field is populated by the controller based on spec.packages keys + // +optional + Variants string `json:"variants,omitempty"` + + // Conditions represents the latest available observations of a PackageSetDefinition's state + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty"` +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 42cf4c4a..a49ad31f 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -21,7 +21,9 @@ limitations under the License. package v1alpha1 import ( + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -256,6 +258,386 @@ func (in *CozystackResourceDefinitionSpec) DeepCopy() *CozystackResourceDefiniti return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSet) DeepCopyInto(out *PackageSet) { + *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 PackageSet. +func (in *PackageSet) DeepCopy() *PackageSet { + if in == nil { + return nil + } + out := new(PackageSet) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageSet) 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 *PackageSetDefinition) DeepCopyInto(out *PackageSetDefinition) { + *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 PackageSetDefinition. +func (in *PackageSetDefinition) DeepCopy() *PackageSetDefinition { + if in == nil { + return nil + } + out := new(PackageSetDefinition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageSetDefinition) 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 *PackageSetDefinitionApplication) DeepCopyInto(out *PackageSetDefinitionApplication) { + *out = *in + if in.Libraries != nil { + in, out := &in.Libraries, &out.Libraries + *out = make([]PackageSetDefinitionLibrary, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionApplication. +func (in *PackageSetDefinitionApplication) DeepCopy() *PackageSetDefinitionApplication { + if in == nil { + return nil + } + out := new(PackageSetDefinitionApplication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetDefinitionDependencyTarget) DeepCopyInto(out *PackageSetDefinitionDependencyTarget) { + *out = *in + if in.Packages != nil { + in, out := &in.Packages, &out.Packages + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionDependencyTarget. +func (in *PackageSetDefinitionDependencyTarget) DeepCopy() *PackageSetDefinitionDependencyTarget { + if in == nil { + return nil + } + out := new(PackageSetDefinitionDependencyTarget) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetDefinitionLibrary) DeepCopyInto(out *PackageSetDefinitionLibrary) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionLibrary. +func (in *PackageSetDefinitionLibrary) DeepCopy() *PackageSetDefinitionLibrary { + if in == nil { + return nil + } + out := new(PackageSetDefinitionLibrary) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetDefinitionList) DeepCopyInto(out *PackageSetDefinitionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PackageSetDefinition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionList. +func (in *PackageSetDefinitionList) DeepCopy() *PackageSetDefinitionList { + if in == nil { + return nil + } + out := new(PackageSetDefinitionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageSetDefinitionList) 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 *PackageSetDefinitionPackage) DeepCopyInto(out *PackageSetDefinitionPackage) { + *out = *in + if in.DependsOn != nil { + in, out := &in.DependsOn, &out.DependsOn + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Libraries != nil { + in, out := &in.Libraries, &out.Libraries + *out = make([]PackageSetDefinitionLibrary, len(*in)) + copy(*out, *in) + } + if in.ValuesFiles != nil { + in, out := &in.ValuesFiles, &out.ValuesFiles + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionPackage. +func (in *PackageSetDefinitionPackage) DeepCopy() *PackageSetDefinitionPackage { + if in == nil { + return nil + } + out := new(PackageSetDefinitionPackage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetDefinitionSourceRef) DeepCopyInto(out *PackageSetDefinitionSourceRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionSourceRef. +func (in *PackageSetDefinitionSourceRef) DeepCopy() *PackageSetDefinitionSourceRef { + if in == nil { + return nil + } + out := new(PackageSetDefinitionSourceRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetDefinitionSpec) DeepCopyInto(out *PackageSetDefinitionSpec) { + *out = *in + if in.SourceRef != nil { + in, out := &in.SourceRef, &out.SourceRef + *out = new(PackageSetDefinitionSourceRef) + **out = **in + } + if in.Variants != nil { + in, out := &in.Variants, &out.Variants + *out = make([]PackageSetDefinitionVariant, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionSpec. +func (in *PackageSetDefinitionSpec) DeepCopy() *PackageSetDefinitionSpec { + if in == nil { + return nil + } + out := new(PackageSetDefinitionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetDefinitionStatus) DeepCopyInto(out *PackageSetDefinitionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionStatus. +func (in *PackageSetDefinitionStatus) DeepCopy() *PackageSetDefinitionStatus { + if in == nil { + return nil + } + out := new(PackageSetDefinitionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetDefinitionVariant) DeepCopyInto(out *PackageSetDefinitionVariant) { + *out = *in + if in.DependsOn != nil { + in, out := &in.DependsOn, &out.DependsOn + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Libraries != nil { + in, out := &in.Libraries, &out.Libraries + *out = make([]PackageSetDefinitionLibrary, len(*in)) + copy(*out, *in) + } + if in.Packages != nil { + in, out := &in.Packages, &out.Packages + *out = make([]PackageSetDefinitionPackage, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Applications != nil { + in, out := &in.Applications, &out.Applications + *out = make([]PackageSetDefinitionApplication, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionVariant. +func (in *PackageSetDefinitionVariant) DeepCopy() *PackageSetDefinitionVariant { + if in == nil { + return nil + } + out := new(PackageSetDefinitionVariant) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetList) DeepCopyInto(out *PackageSetList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PackageSet, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetList. +func (in *PackageSetList) DeepCopy() *PackageSetList { + if in == nil { + return nil + } + out := new(PackageSetList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageSetList) 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 *PackageSetPackageOverride) DeepCopyInto(out *PackageSetPackageOverride) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Values != nil { + in, out := &in.Values, &out.Values + *out = new(v1.JSON) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetPackageOverride. +func (in *PackageSetPackageOverride) DeepCopy() *PackageSetPackageOverride { + if in == nil { + return nil + } + out := new(PackageSetPackageOverride) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetSpec) DeepCopyInto(out *PackageSetSpec) { + *out = *in + if in.IgnoreDependencies != nil { + in, out := &in.IgnoreDependencies, &out.IgnoreDependencies + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Packages != nil { + in, out := &in.Packages, &out.Packages + *out = make(map[string]PackageSetPackageOverride, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetSpec. +func (in *PackageSetSpec) DeepCopy() *PackageSetSpec { + if in == nil { + return nil + } + out := new(PackageSetSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSetStatus) DeepCopyInto(out *PackageSetStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetStatus. +func (in *PackageSetStatus) DeepCopy() *PackageSetStatus { + if in == nil { + return nil + } + out := new(PackageSetStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in Selector) DeepCopyInto(out *Selector) { { diff --git a/packages/core/platform/psds/clickhouse.yaml b/packages/core/platform/psds/clickhouse.yaml new file mode 100644 index 00000000..f3506afb --- /dev/null +++ b/packages/core/platform/psds/clickhouse.yaml @@ -0,0 +1,52 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.clickhouse-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + - cozystack.cozystack-core + packages: + - name: clickhouse-operator + path: system/clickhouse-operator + releaseName: clickhouse-operator + namespace: cozy-clickhouse-operator + dependsOn: + - victoria-metrics-operator +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.clickhouse-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.clickhouse-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: clickhouse-application + path: system/clickhouse-application + releaseName: clickhouse-application + namespace: cozy-system + sources: + - name: clickhouse + path: apps/clickhouse + libraries: + - cozy-lib diff --git a/packages/core/platform/psds/cozystack.yaml b/packages/core/platform/psds/cozystack.yaml new file mode 100644 index 00000000..d049842f --- /dev/null +++ b/packages/core/platform/psds/cozystack.yaml @@ -0,0 +1,67 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.cozystack-core +spec: + variants: + - name: default + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: cozystack-controller + releaseName: cozystack-controller + path: system/cozystack-controller + namespace: cozy-system + dependsOn: [] + - name: cozystack-api + releaseName: cozystack-api + path: system/cozystack-api + namespace: cozy-system + dependsOn: [cozystack-controller] + - name: lineage-controller-webhook + releaseName: lineage-controller-webhook + path: system/lineage-controller-webhook + namespace: cozy-system + dependsOn: [cozystack-controller] + - name: dashboard + releaseName: dashboard + path: system/dashboard + namespace: cozy-dashboard + dependsOn: [cozystack-api,cozystack-controller] + - name: cozystack-controller + releaseName: cozystack-controller + path: system/cozystack-controller + namespace: cozy-system + dependsOn: [] + - name: cozystack-api + releaseName: cozystack-api + path: system/cozystack-api + namespace: cozy-system + dependsOn: [cozystack-controller] + - name: lineage-controller-webhook + releaseName: lineage-controller-webhook + path: system/lineage-controller-webhook + namespace: cozy-system + dependsOn: [cozystack-controller] + - name: dashboard + releaseName: dashboard + path: system/dashboard + namespace: cozy-dashboard + dependsOn: [cozystack-api,cozystack-controller,keycloak-configure] + - name: keycloak-configure + releaseName: keycloak-configure + path: system/keycloak-configure + namespace: cozy-keycloak + dependsOn: [keycloak-operator] + - name: keycloak + releaseName: keycloak + path: system/keycloak + namespace: cozy-keycloak + dependsOn: [postgres-operator] + - name: keycloak-operator + releaseName: keycloak-operator + path: system/keycloak-operator + namespace: cozy-keycloak + dependsOn: [keycloak] diff --git a/packages/core/platform/psds/ferretdb.yaml b/packages/core/platform/psds/ferretdb.yaml new file mode 100644 index 00000000..6bd96a77 --- /dev/null +++ b/packages/core/platform/psds/ferretdb.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.ferretdb +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: ferretdb-application + path: system/ferretdb-application + releaseName: ferretdb-application + namespace: cozy-system + sources: + - name: ferretdb + path: apps/ferretdb + libraries: + - cozy-lib diff --git a/packages/core/platform/psds/foundationdb-operator.yaml b/packages/core/platform/psds/foundationdb-operator.yaml new file mode 100644 index 00000000..844b5d20 --- /dev/null +++ b/packages/core/platform/psds/foundationdb-operator.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.foundationdb-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + packages: + - name: foundationdb-operator + path: system/foundationdb-operator + releaseName: foundationdb-operator + namespace: cozy-foundationdb-operator + dependsOn: + - cert-manager + diff --git a/packages/core/platform/psds/foundationdb.yaml b/packages/core/platform/psds/foundationdb.yaml new file mode 100644 index 00000000..d8ac8883 --- /dev/null +++ b/packages/core/platform/psds/foundationdb.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.foundationdb +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.foundationdb-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: foundationdb-application + path: system/foundationdb-application + releaseName: foundationdb-application + namespace: cozy-system + sources: + - name: foundationdb + path: apps/foundationdb + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/http-cache.yaml b/packages/core/platform/psds/http-cache.yaml new file mode 100644 index 00000000..38229093 --- /dev/null +++ b/packages/core/platform/psds/http-cache.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.http-cache-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: http-cache-application + path: system/http-cache-application + releaseName: http-cache + namespace: cozy-system + sources: + - name: http-cache + path: apps/http-cache + libraries: + - cozy-lib diff --git a/packages/core/platform/psds/kafka-operator.yaml b/packages/core/platform/psds/kafka-operator.yaml new file mode 100644 index 00000000..b433a46b --- /dev/null +++ b/packages/core/platform/psds/kafka-operator.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.kafka-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + packages: + - name: kafka-operator + path: system/kafka-operator + releaseName: kafka-operator + namespace: cozy-kafka-operator + dependsOn: + - victoria-metrics-operator + diff --git a/packages/core/platform/psds/kafka.yaml b/packages/core/platform/psds/kafka.yaml new file mode 100644 index 00000000..92d93295 --- /dev/null +++ b/packages/core/platform/psds/kafka.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.kafka +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.kafka-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: kafka-application + path: system/kafka-application + releaseName: kafka-application + namespace: cozy-system + sources: + - name: kafka + path: apps/kafka + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/mariadb-operator.yaml b/packages/core/platform/psds/mariadb-operator.yaml new file mode 100644 index 00000000..d1366cba --- /dev/null +++ b/packages/core/platform/psds/mariadb-operator.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.mariadb-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + - cozystack.cert-manager + packages: + - name: mariadb-operator + path: system/mariadb-operator + releaseName: mariadb-operator + namespace: cozy-mariadb-operator + dependsOn: + - cert-manager + - victoria-metrics-operator + diff --git a/packages/core/platform/psds/mysql.yaml b/packages/core/platform/psds/mysql.yaml new file mode 100644 index 00000000..44c1409f --- /dev/null +++ b/packages/core/platform/psds/mysql.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.mysql +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.mariadb-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: mysql-application + path: system/mysql-application + releaseName: mysql-application + namespace: cozy-system + sources: + - name: mysql + path: apps/mysql + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/nats.yaml b/packages/core/platform/psds/nats.yaml new file mode 100644 index 00000000..746bbf99 --- /dev/null +++ b/packages/core/platform/psds/nats.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.nats +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: nats-application + path: system/nats-application + releaseName: nats-application + namespace: cozy-system + sources: + - name: nats + path: apps/nats + libraries: + - cozy-lib + - name: nats-system + path: system/nats diff --git a/packages/core/platform/psds/networking.yaml b/packages/core/platform/psds/networking.yaml new file mode 100644 index 00000000..57cf3504 --- /dev/null +++ b/packages/core/platform/psds/networking.yaml @@ -0,0 +1,65 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.networking +spec: + variants: + - name: noop + packages: [] + - name: cilium + dependsOn: + - cozystack.cert-manager + packages: + - name: cilium + releaseName: cilium + path: system/cilium + namespace: cozy-cilium + privileged: true + dependsOn: [] + valuesFiles: + - values.yaml + - values-talos.yaml + - name: cilium-networkpolicy + releaseName: cilium-networkpolicy + path: system/cilium-networkpolicy + namespace: cozy-cilium + privileged: true + dependsOn: [cilium] + - name: kubeovn-cilium + dependsOn: + - cozystack.cert-manager + packages: + - name: cilium + releaseName: cilium + path: system/cilium + namespace: cozy-cilium + privileged: true + dependsOn: [] + valuesFiles: + - values.yaml + - values-talos.yaml + - values-kubeovn.yaml + - name: cilium-networkpolicy + releaseName: cilium-networkpolicy + path: system/cilium-networkpolicy + namespace: cozy-cilium + privileged: true + dependsOn: [cilium] + - name: kubeovn + releaseName: kubeovn + path: system/kubeovn + namespace: cozy-kubeovn + privileged: true + dependsOn: [cilium] + - name: kubeovn-plunger + releaseName: kubeovn-plunger + path: system/kubeovn-plunger + namespace: cozy-kubeovn + dependsOn: [cilium,kubeovn] + - name: kubeovn-webhook + releaseName: kubeovn-webhook + path: system/kubeovn-webhook + namespace: cozy-kubeovn + privileged: true + dependsOn: [cilium,kubeovn] diff --git a/packages/core/platform/psds/postgres.yaml b/packages/core/platform/psds/postgres.yaml new file mode 100644 index 00000000..fef3d58e --- /dev/null +++ b/packages/core/platform/psds/postgres.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.postgres +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: postgres-application + path: system/postgres-application + releaseName: postgres-application + namespace: cozy-system + sources: + - name: postgres + path: apps/postgres + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/rabbitmq-operator.yaml b/packages/core/platform/psds/rabbitmq-operator.yaml new file mode 100644 index 00000000..236ae761 --- /dev/null +++ b/packages/core/platform/psds/rabbitmq-operator.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.rabbitmq-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: rabbitmq-operator + path: system/rabbitmq-operator + releaseName: rabbitmq-operator + namespace: cozy-rabbitmq-operator + diff --git a/packages/core/platform/psds/rabbitmq.yaml b/packages/core/platform/psds/rabbitmq.yaml new file mode 100644 index 00000000..39201831 --- /dev/null +++ b/packages/core/platform/psds/rabbitmq.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.rabbitmq +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.rabbitmq-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: rabbitmq-application + path: system/rabbitmq-application + releaseName: rabbitmq-application + namespace: cozy-system + sources: + - name: rabbitmq + path: apps/rabbitmq + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/redis-operator.yaml b/packages/core/platform/psds/redis-operator.yaml new file mode 100644 index 00000000..ee6e349b --- /dev/null +++ b/packages/core/platform/psds/redis-operator.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.redis-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: redis-operator + path: system/redis-operator + releaseName: redis-operator + namespace: cozy-redis-operator + diff --git a/packages/core/platform/psds/redis.yaml b/packages/core/platform/psds/redis.yaml new file mode 100644 index 00000000..1f456bed --- /dev/null +++ b/packages/core/platform/psds/redis.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.redis +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.redis-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: redis-application + path: system/redis-application + releaseName: redis-application + namespace: cozy-system + sources: + - name: redis + path: apps/redis + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/tcp-balancer.yaml b/packages/core/platform/psds/tcp-balancer.yaml new file mode 100644 index 00000000..10ea89ac --- /dev/null +++ b/packages/core/platform/psds/tcp-balancer.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.tcp-balancer-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: tcp-balancer-application + path: system/tcp-balancer-application + releaseName: tcp-balancer + namespace: cozy-system + sources: + - name: tcp-balancer + path: apps/tcp-balancer + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/vpn.yaml b/packages/core/platform/psds/vpn.yaml new file mode 100644 index 00000000..3347a330 --- /dev/null +++ b/packages/core/platform/psds/vpn.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.vpn-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: vpn-application + path: system/vpn-application + releaseName: vpn + namespace: cozy-system + sources: + - name: vpn + path: apps/vpn + libraries: + - cozy-lib + diff --git a/packages/packages.yaml b/packages/packages.yaml new file mode 100644 index 00000000..828af96b --- /dev/null +++ b/packages/packages.yaml @@ -0,0 +1,199 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.clickhouse-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + dependsOn: + - cozystack.networking + - cozystack.monitoring + - cozystack.cozystack-core + packages: + default: + - name: clickhouse-operator + path: system/clickhouse-operator + releaseName: clickhouse-operator + namespace: cozy-clickhouse-operator +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.clickhouse-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + dependsOn: + - cozystack.clickhouse-operator + packages: + default: + - name: clickhouse-application + path: system/clickhouse-application + releaseName: clickhouse-application + namespace: cozy-system + applications: + default: + - name: clickhouse-application + path: apps/clickhouse + libraries: + - path: library/cozy-lib +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.networking +spec: + dependsOn: + - cozystack.cert-manager + packages: + noop: [] + cilium: + - name: cilium + releaseName: cilium + path: system/cilium + namespace: cozy-cilium + privileged: true + dependsOn: [] + valuesFiles: + - values.yaml + - values-talos.yaml + - name: cilium-networkpolicy + releaseName: cilium-networkpolicy + path: system/cilium-networkpolicy + namespace: cozy-cilium + privileged: true + dependsOn: [cilium] + kubeovn-cilium: + - name: cilium + releaseName: cilium + path: system/cilium + namespace: cozy-cilium + privileged: true + dependsOn: [] + valuesFiles: + - values.yaml + - values-talos.yaml + - values-kubeovn.yaml + - name: cilium-networkpolicy + releaseName: cilium-networkpolicy + path: system/cilium-networkpolicy + namespace: cozy-cilium + privileged: true + dependsOn: [cilium] + - name: kubeovn + releaseName: kubeovn + path: system/kubeovn + namespace: cozy-kubeovn + privileged: true + dependsOn: [cilium] + - name: kubeovn-plunger + releaseName: kubeovn-plunger + path: system/kubeovn-plunger + namespace: cozy-kubeovn + dependsOn: [cilium,kubeovn] + - name: kubeovn-webhook + releaseName: kubeovn-webhook + path: system/kubeovn-webhook + namespace: cozy-kubeovn + privileged: true + dependsOn: [cilium,kubeovn] + +# PackageSetDefinition --> ArtifactGenerator --> ExternalArtifact (many) +# PackageSet --> HelmRelease (many) +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSet +metadata: + name: cozystack.networking +spec: + #ignoreDependencies: + #- cozystack.networking + packages: + cilium: + enabled: false + values: + kubeProxyReplacement: strict + k8sServiceHost: api.example.org + k8sServicePort: 6443 + kubeovn: + values: + kube-ovn: + ipv4: + POD_CIDR: "10.244.0.0/16" + POD_GATEWAY: "10.244.0.1" + SVC_CIDR: "10.96.0.0/16" + JOIN_CIDR: "100.64.0.0/16" + +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.cozystack-core +spec: + packages: + default: + - name: cozystack-controller + releaseName: cozystack-controller + path: system/cozystack-controller + namespace: cozy-system + dependsOn: [] + - name: cozystack-api + releaseName: cozystack-api + path: system/cozystack-api + namespace: cozy-system + dependsOn: [cozystack-controller] + - name: lineage-controller-webhook + releaseName: lineage-controller-webhook + path: system/lineage-controller-webhook + namespace: cozy-system + dependsOn: [cozystack-controller] + - name: dashboard + releaseName: dashboard + path: system/dashboard + namespace: cozy-dashboard + dependsOn: [cozystack-api,cozystack-controller] + oidc: + - name: cozystack-controller + releaseName: cozystack-controller + path: system/cozystack-controller + namespace: cozy-system + dependsOn: [] + - name: cozystack-api + releaseName: cozystack-api + path: system/cozystack-api + namespace: cozy-system + dependsOn: [cozystack-controller] + - name: lineage-controller-webhook + releaseName: lineage-controller-webhook + path: system/lineage-controller-webhook + namespace: cozy-system + dependsOn: [cozystack-controller] + - name: dashboard + releaseName: dashboard + path: system/dashboard + namespace: cozy-dashboard + dependsOn: [cozystack-api,cozystack-controller,keycloak-configure] + - name: keycloak-configure + releaseName: keycloak-configure + path: system/keycloak-configure + namespace: cozy-keycloak + dependsOn: [keycloak-operator] + - name: keycloak + releaseName: keycloak + path: system/keycloak + namespace: cozy-keycloak + dependsOn: [postgres-operator] + libraries: + - path: library/cozy-lib + - name: keycloak-operator + releaseName: keycloak-operator + path: system/keycloak-operator + namespace: cozy-keycloak + dependsOn: [keycloak] From 55da82dec2feb485b34fdd672021d2a0921b6457 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Thu, 18 Dec 2025 22:44:00 +0100 Subject: [PATCH 04/15] 1 --- .../platform/psds/bootbox-application.yaml | 29 ++++++++ packages/core/platform/psds/bootbox.yaml | 23 +++++++ packages/core/platform/psds/bucket.yaml | 34 ++++++++++ .../core/platform/psds/capi-operator.yaml | 21 ++++++ .../psds/capi-providers-bootstrap.yaml | 25 +++++++ .../platform/psds/capi-providers-core.yaml | 25 +++++++ .../psds/capi-providers-cpprovider.yaml | 26 ++++++++ .../psds/capi-providers-infraprovider.yaml | 25 +++++++ packages/core/platform/psds/cert-manager.yaml | 33 ++++++++++ .../platform/psds/clickhouse-operator.yaml | 24 +++++++ packages/core/platform/psds/clickhouse.yaml | 24 ------- packages/core/platform/psds/cozy-proxy.yaml | 21 ++++++ packages/core/platform/psds/cozystack.yaml | 7 +- .../core/platform/psds/etcd-application.yaml | 29 ++++++++ .../core/platform/psds/etcd-operator.yaml | 24 +++++++ packages/core/platform/psds/external-dns.yaml | 22 +++++++ .../psds/external-secrets-operator.yaml | 22 +++++++ packages/core/platform/psds/ferretdb.yaml | 2 +- packages/core/platform/psds/foundationdb.yaml | 2 +- packages/core/platform/psds/goldpinger.yaml | 25 +++++++ packages/core/platform/psds/gpu-operator.yaml | 25 +++++++ .../core/platform/psds/grafana-operator.yaml | 20 ++++++ .../core/platform/psds/hetzner-robotlb.yaml | 22 +++++++ packages/core/platform/psds/info.yaml | 29 ++++++++ packages/core/platform/psds/ingress.yaml | 31 +++++++++ packages/core/platform/psds/kafka.yaml | 2 +- packages/core/platform/psds/kamaji.yaml | 20 ++++++ .../core/platform/psds/keycloak-operator.yaml | 23 +++++++ packages/core/platform/psds/kubernetes.yaml | 66 +++++++++++++++++++ packages/core/platform/psds/kubevirt-cdi.yaml | 27 ++++++++ packages/core/platform/psds/kubevirt.yaml | 38 +++++++++++ packages/core/platform/psds/linstor.yaml | 36 ++++++++++ packages/core/platform/psds/metallb.yaml | 21 ++++++ .../core/platform/psds/monitoring-agents.yaml | 26 ++++++++ packages/core/platform/psds/monitoring.yaml | 29 ++++++++ packages/core/platform/psds/multus.yaml | 21 ++++++ packages/core/platform/psds/mysql.yaml | 2 +- packages/core/platform/psds/nats.yaml | 2 +- packages/core/platform/psds/nfs-driver.yaml | 23 +++++++ .../psds/objectstorage-controller.yaml | 21 ++++++ packages/core/platform/psds/postgres.yaml | 2 +- packages/core/platform/psds/rabbitmq.yaml | 2 +- packages/core/platform/psds/redis.yaml | 2 +- packages/core/platform/psds/reloader.yaml | 21 ++++++ packages/core/platform/psds/seaweedfs.yaml | 31 +++++++++ .../platform/psds/snapshot-controller.yaml | 24 +++++++ packages/core/platform/psds/telepresence.yaml | 22 +++++++ packages/core/platform/psds/tenant.yaml | 35 ++++++++++ packages/core/platform/psds/velero.yaml | 26 ++++++++ .../psds/vertical-pod-autoscaler.yaml | 29 ++++++++ .../psds/victoria-metrics-operator.yaml | 21 ++++++ .../core/platform/psds/virtual-machine.yaml | 31 +++++++++ .../platform/psds/virtualprivatecloud.yaml | 30 +++++++++ packages/core/platform/psds/vm-disk.yaml | 30 +++++++++ packages/core/platform/psds/vm-instance.yaml | 30 +++++++++ 55 files changed, 1226 insertions(+), 37 deletions(-) create mode 100644 packages/core/platform/psds/bootbox-application.yaml create mode 100644 packages/core/platform/psds/bootbox.yaml create mode 100644 packages/core/platform/psds/bucket.yaml create mode 100644 packages/core/platform/psds/capi-operator.yaml create mode 100644 packages/core/platform/psds/capi-providers-bootstrap.yaml create mode 100644 packages/core/platform/psds/capi-providers-core.yaml create mode 100644 packages/core/platform/psds/capi-providers-cpprovider.yaml create mode 100644 packages/core/platform/psds/capi-providers-infraprovider.yaml create mode 100644 packages/core/platform/psds/cert-manager.yaml create mode 100644 packages/core/platform/psds/clickhouse-operator.yaml create mode 100644 packages/core/platform/psds/cozy-proxy.yaml create mode 100644 packages/core/platform/psds/etcd-application.yaml create mode 100644 packages/core/platform/psds/etcd-operator.yaml create mode 100644 packages/core/platform/psds/external-dns.yaml create mode 100644 packages/core/platform/psds/external-secrets-operator.yaml create mode 100644 packages/core/platform/psds/goldpinger.yaml create mode 100644 packages/core/platform/psds/gpu-operator.yaml create mode 100644 packages/core/platform/psds/grafana-operator.yaml create mode 100644 packages/core/platform/psds/hetzner-robotlb.yaml create mode 100644 packages/core/platform/psds/info.yaml create mode 100644 packages/core/platform/psds/ingress.yaml create mode 100644 packages/core/platform/psds/kamaji.yaml create mode 100644 packages/core/platform/psds/keycloak-operator.yaml create mode 100644 packages/core/platform/psds/kubernetes.yaml create mode 100644 packages/core/platform/psds/kubevirt-cdi.yaml create mode 100644 packages/core/platform/psds/kubevirt.yaml create mode 100644 packages/core/platform/psds/linstor.yaml create mode 100644 packages/core/platform/psds/metallb.yaml create mode 100644 packages/core/platform/psds/monitoring-agents.yaml create mode 100644 packages/core/platform/psds/monitoring.yaml create mode 100644 packages/core/platform/psds/multus.yaml create mode 100644 packages/core/platform/psds/nfs-driver.yaml create mode 100644 packages/core/platform/psds/objectstorage-controller.yaml create mode 100644 packages/core/platform/psds/reloader.yaml create mode 100644 packages/core/platform/psds/seaweedfs.yaml create mode 100644 packages/core/platform/psds/snapshot-controller.yaml create mode 100644 packages/core/platform/psds/telepresence.yaml create mode 100644 packages/core/platform/psds/tenant.yaml create mode 100644 packages/core/platform/psds/velero.yaml create mode 100644 packages/core/platform/psds/vertical-pod-autoscaler.yaml create mode 100644 packages/core/platform/psds/victoria-metrics-operator.yaml create mode 100644 packages/core/platform/psds/virtual-machine.yaml create mode 100644 packages/core/platform/psds/virtualprivatecloud.yaml create mode 100644 packages/core/platform/psds/vm-disk.yaml create mode 100644 packages/core/platform/psds/vm-instance.yaml diff --git a/packages/core/platform/psds/bootbox-application.yaml b/packages/core/platform/psds/bootbox-application.yaml new file mode 100644 index 00000000..504f1f5d --- /dev/null +++ b/packages/core/platform/psds/bootbox-application.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.bootbox-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: bootbox-application + path: system/bootbox-application + releaseName: bootbox-application + namespace: cozy-system + sources: + - name: bootbox + path: extra/bootbox + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/bootbox.yaml b/packages/core/platform/psds/bootbox.yaml new file mode 100644 index 00000000..8f89c9f6 --- /dev/null +++ b/packages/core/platform/psds/bootbox.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.bootbox +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: bootbox + path: system/bootbox + releaseName: bootbox + namespace: cozy-bootbox + privileged: true + disabled: true + diff --git a/packages/core/platform/psds/bucket.yaml b/packages/core/platform/psds/bucket.yaml new file mode 100644 index 00000000..945d853f --- /dev/null +++ b/packages/core/platform/psds/bucket.yaml @@ -0,0 +1,34 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.bucket-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.objectstorage-controller + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: bucket-application + path: system/bucket-application + releaseName: bucket-application + namespace: cozy-system + sources: + - name: bucket + path: apps/bucket + libraries: + - cozy-lib + - name: bucket-system + path: apps/bucket + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/capi-operator.yaml b/packages/core/platform/psds/capi-operator.yaml new file mode 100644 index 00000000..d2e64d2a --- /dev/null +++ b/packages/core/platform/psds/capi-operator.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.capi-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: capi-operator + path: system/capi-operator + releaseName: capi-operator + namespace: cozy-cluster-api + privileged: true diff --git a/packages/core/platform/psds/capi-providers-bootstrap.yaml b/packages/core/platform/psds/capi-providers-bootstrap.yaml new file mode 100644 index 00000000..3cf1e27c --- /dev/null +++ b/packages/core/platform/psds/capi-providers-bootstrap.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.capi-providers-bootstrap +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.capi-operator + packages: + - name: capi-providers-bootstrap + path: system/capi-providers-bootstrap + releaseName: capi-providers-bootstrap + namespace: cozy-cluster-api + privileged: true + dependsOn: + - capi-operator + diff --git a/packages/core/platform/psds/capi-providers-core.yaml b/packages/core/platform/psds/capi-providers-core.yaml new file mode 100644 index 00000000..ac67b8c2 --- /dev/null +++ b/packages/core/platform/psds/capi-providers-core.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.capi-providers-core +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.capi-operator + packages: + - name: capi-providers-core + path: system/capi-providers-core + releaseName: capi-providers-core + namespace: cozy-cluster-api + privileged: true + dependsOn: + - capi-operator + diff --git a/packages/core/platform/psds/capi-providers-cpprovider.yaml b/packages/core/platform/psds/capi-providers-cpprovider.yaml new file mode 100644 index 00000000..759a9038 --- /dev/null +++ b/packages/core/platform/psds/capi-providers-cpprovider.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.capi-providers-cpprovider +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kamaji + dependsOn: + - cozystack.networking + - cozystack.capi-operator + - cozystack.kamaji + packages: + - name: capi-providers-cpprovider + path: system/capi-providers-cpprovider + releaseName: capi-providers-cpprovider + namespace: cozy-cluster-api + privileged: true + dependsOn: + - capi-operator + diff --git a/packages/core/platform/psds/capi-providers-infraprovider.yaml b/packages/core/platform/psds/capi-providers-infraprovider.yaml new file mode 100644 index 00000000..3abe12bc --- /dev/null +++ b/packages/core/platform/psds/capi-providers-infraprovider.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.capi-providers-infraprovider +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.capi-operator + packages: + - name: capi-providers-infraprovider + path: system/capi-providers-infraprovider + releaseName: capi-providers-infraprovider + namespace: cozy-cluster-api + privileged: true + dependsOn: + - capi-operator + diff --git a/packages/core/platform/psds/cert-manager.yaml b/packages/core/platform/psds/cert-manager.yaml new file mode 100644 index 00000000..42632302 --- /dev/null +++ b/packages/core/platform/psds/cert-manager.yaml @@ -0,0 +1,33 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.cert-manager +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: cert-manager-crds + path: system/cert-manager-crds + releaseName: cert-manager-crds + namespace: cozy-cert-manager + - name: cert-manager + path: system/cert-manager + releaseName: cert-manager + namespace: cozy-cert-manager + dependsOn: + - cert-manager-crds + - name: cert-manager-issuers + path: system/cert-manager-issuers + releaseName: cert-manager-issuers + namespace: cozy-cert-manager + dependsOn: + - cert-manager + diff --git a/packages/core/platform/psds/clickhouse-operator.yaml b/packages/core/platform/psds/clickhouse-operator.yaml new file mode 100644 index 00000000..04b44114 --- /dev/null +++ b/packages/core/platform/psds/clickhouse-operator.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.clickhouse-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + - cozystack.cozystack-core + packages: + - name: clickhouse-operator + path: system/clickhouse-operator + releaseName: clickhouse-operator + namespace: cozy-clickhouse-operator + dependsOn: + - victoria-metrics-operator diff --git a/packages/core/platform/psds/clickhouse.yaml b/packages/core/platform/psds/clickhouse.yaml index f3506afb..0de1610f 100644 --- a/packages/core/platform/psds/clickhouse.yaml +++ b/packages/core/platform/psds/clickhouse.yaml @@ -1,30 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition -metadata: - name: cozystack.clickhouse-operator -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.monitoring - - cozystack.cozystack-core - packages: - - name: clickhouse-operator - path: system/clickhouse-operator - releaseName: clickhouse-operator - namespace: cozy-clickhouse-operator - dependsOn: - - victoria-metrics-operator ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition metadata: name: cozystack.clickhouse-application spec: diff --git a/packages/core/platform/psds/cozy-proxy.yaml b/packages/core/platform/psds/cozy-proxy.yaml new file mode 100644 index 00000000..ee7a8ce8 --- /dev/null +++ b/packages/core/platform/psds/cozy-proxy.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.cozy-proxy +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: cozy-proxy + path: system/cozy-proxy + releaseName: cozystack + namespace: cozy-system + diff --git a/packages/core/platform/psds/cozystack.yaml b/packages/core/platform/psds/cozystack.yaml index d049842f..f3c11048 100644 --- a/packages/core/platform/psds/cozystack.yaml +++ b/packages/core/platform/psds/cozystack.yaml @@ -6,6 +6,8 @@ metadata: spec: variants: - name: default + dependsOn: + - cozystack.keycloak-operator libraries: - name: cozy-lib path: library/cozy-lib @@ -60,8 +62,3 @@ spec: path: system/keycloak namespace: cozy-keycloak dependsOn: [postgres-operator] - - name: keycloak-operator - releaseName: keycloak-operator - path: system/keycloak-operator - namespace: cozy-keycloak - dependsOn: [keycloak] diff --git a/packages/core/platform/psds/etcd-application.yaml b/packages/core/platform/psds/etcd-application.yaml new file mode 100644 index 00000000..93e73926 --- /dev/null +++ b/packages/core/platform/psds/etcd-application.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.etcd-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: etcd-application + path: system/etcd-application + releaseName: etcd-application + namespace: cozy-system + sources: + - name: etcd + path: extra/etcd + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/etcd-operator.yaml b/packages/core/platform/psds/etcd-operator.yaml new file mode 100644 index 00000000..90c9a22a --- /dev/null +++ b/packages/core/platform/psds/etcd-operator.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.etcd-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + packages: + - name: etcd-operator + path: system/etcd-operator + releaseName: etcd-operator + namespace: cozy-etcd-operator + dependsOn: + - cert-manager + diff --git a/packages/core/platform/psds/external-dns.yaml b/packages/core/platform/psds/external-dns.yaml new file mode 100644 index 00000000..30449482 --- /dev/null +++ b/packages/core/platform/psds/external-dns.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.external-dns +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: external-dns + path: system/external-dns + releaseName: external-dns + namespace: cozy-external-dns + disabled: true + diff --git a/packages/core/platform/psds/external-secrets-operator.yaml b/packages/core/platform/psds/external-secrets-operator.yaml new file mode 100644 index 00000000..6f9da422 --- /dev/null +++ b/packages/core/platform/psds/external-secrets-operator.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.external-secrets-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: external-secrets-operator + path: system/external-secrets-operator + releaseName: external-secrets-operator + namespace: cozy-external-secrets-operator + disabled: true + diff --git a/packages/core/platform/psds/ferretdb.yaml b/packages/core/platform/psds/ferretdb.yaml index 6bd96a77..02e95800 100644 --- a/packages/core/platform/psds/ferretdb.yaml +++ b/packages/core/platform/psds/ferretdb.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition metadata: - name: cozystack.ferretdb + name: cozystack.ferretdb-application spec: sourceRef: kind: OCIRepository diff --git a/packages/core/platform/psds/foundationdb.yaml b/packages/core/platform/psds/foundationdb.yaml index d8ac8883..e41e25e4 100644 --- a/packages/core/platform/psds/foundationdb.yaml +++ b/packages/core/platform/psds/foundationdb.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition metadata: - name: cozystack.foundationdb + name: cozystack.foundationdb-application spec: sourceRef: kind: OCIRepository diff --git a/packages/core/platform/psds/goldpinger.yaml b/packages/core/platform/psds/goldpinger.yaml new file mode 100644 index 00000000..0ec1f1f6 --- /dev/null +++ b/packages/core/platform/psds/goldpinger.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.goldpinger +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring-agents + packages: + - name: goldpinger + path: system/goldpinger + releaseName: goldpinger + namespace: cozy-goldpinger + privileged: true + dependsOn: + - monitoring-agents + diff --git a/packages/core/platform/psds/gpu-operator.yaml b/packages/core/platform/psds/gpu-operator.yaml new file mode 100644 index 00000000..54a051ff --- /dev/null +++ b/packages/core/platform/psds/gpu-operator.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.gpu-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: gpu-operator + path: system/gpu-operator + releaseName: gpu-operator + namespace: cozy-gpu-operator + privileged: true + valuesFiles: + - values.yaml + - values-talos.yaml + diff --git a/packages/core/platform/psds/grafana-operator.yaml b/packages/core/platform/psds/grafana-operator.yaml new file mode 100644 index 00000000..2de6ef95 --- /dev/null +++ b/packages/core/platform/psds/grafana-operator.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.grafana-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: grafana-operator + path: system/grafana-operator + releaseName: grafana-operator + namespace: cozy-grafana-operator diff --git a/packages/core/platform/psds/hetzner-robotlb.yaml b/packages/core/platform/psds/hetzner-robotlb.yaml new file mode 100644 index 00000000..1cae55a8 --- /dev/null +++ b/packages/core/platform/psds/hetzner-robotlb.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.hetzner-robotlb +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: hetzner-robotlb + path: system/hetzner-robotlb + releaseName: robotlb + namespace: cozy-hetzner-robotlb + disabled: true + diff --git a/packages/core/platform/psds/info.yaml b/packages/core/platform/psds/info.yaml new file mode 100644 index 00000000..10c8f97d --- /dev/null +++ b/packages/core/platform/psds/info.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.info-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: info-application + path: system/info-application + releaseName: info-application + namespace: cozy-system + sources: + - name: info + path: extra/info + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/ingress.yaml b/packages/core/platform/psds/ingress.yaml new file mode 100644 index 00000000..1ab01efe --- /dev/null +++ b/packages/core/platform/psds/ingress.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.ingress-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: ingress-application + path: system/ingress-application + releaseName: ingress-application + namespace: cozy-system + sources: + - name: ingress + path: extra/ingress + libraries: + - cozy-lib + - name: ingress-system + path: system/ingress-nginx + diff --git a/packages/core/platform/psds/kafka.yaml b/packages/core/platform/psds/kafka.yaml index 92d93295..d7081770 100644 --- a/packages/core/platform/psds/kafka.yaml +++ b/packages/core/platform/psds/kafka.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition metadata: - name: cozystack.kafka + name: cozystack.kafka-application spec: sourceRef: kind: OCIRepository diff --git a/packages/core/platform/psds/kamaji.yaml b/packages/core/platform/psds/kamaji.yaml new file mode 100644 index 00000000..d3538c41 --- /dev/null +++ b/packages/core/platform/psds/kamaji.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.kamaji +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: kamaji + path: system/kamaji + releaseName: kamaji + namespace: cozy-kamaji diff --git a/packages/core/platform/psds/keycloak-operator.yaml b/packages/core/platform/psds/keycloak-operator.yaml new file mode 100644 index 00000000..62a8d31c --- /dev/null +++ b/packages/core/platform/psds/keycloak-operator.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.keycloak-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: keycloak-operator + path: system/keycloak-operator + releaseName: keycloak-operator + namespace: cozy-keycloak + dependsOn: + - keycloak + diff --git a/packages/core/platform/psds/kubernetes.yaml b/packages/core/platform/psds/kubernetes.yaml new file mode 100644 index 00000000..48b7c124 --- /dev/null +++ b/packages/core/platform/psds/kubernetes.yaml @@ -0,0 +1,66 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.kubernetes-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.capi-operator + - cozystack.capi-providers-bootstrap + - cozystack.capi-providers-core + - cozystack.capi-providers-cpprovider + - cozystack.capi-providers-infraprovider + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: kubernetes-application + path: system/kubernetes-application + releaseName: kubernetes-application + namespace: cozy-system + sources: + - name: kubernetes + path: apps/kubernetes + libraries: + - cozy-lib + - name: kubernetes-ingress-nginx + path: system/ingress-nginx + - name: kubernetes-cert-manager-crds + path: system/cert-manager-crds + - name: kubernetes-volumesnapshot-crd + path: system/vsnap-crd + - name: kubernetes-velero + path: system/velero + - name: kubernetes-gateway-api-crds + path: system/gateway-api-crds + - name: kubernetes-victoria-metrics-operator + path: system/victoria-metrics-operator + - name: kubernetes-kubevirt-csi-node + path: system/kubevirt-csi-node + - name: kubernetes-vertical-pod-autoscaler-crds + path: system/vertical-pod-autoscaler-crds + - name: kubernetes-coredns + path: system/coredns + - name: kubernetes-cert-manager + path: system/cert-manager + - name: kubernetes-fluxcd-operator + path: system/fluxcd-operator + - name: kubernetes-fluxcd + path: system/fluxcd + - name: kubernetes-monitoring-agents + path: system/monitoring-agents + - name: kubernetes-cilium + path: system/cilium + - name: kubernetes-gpu-operator + path: system/gpu-operator + - name: kubernetes-vertical-pod-autoscaler + path: system/vertical-pod-autoscaler + diff --git a/packages/core/platform/psds/kubevirt-cdi.yaml b/packages/core/platform/psds/kubevirt-cdi.yaml new file mode 100644 index 00000000..9afb0c73 --- /dev/null +++ b/packages/core/platform/psds/kubevirt-cdi.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.kubevirt-cdi +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: kubevirt-cdi-operator + path: system/kubevirt-cdi-operator + releaseName: kubevirt-cdi-operator + namespace: cozy-kubevirt-cdi + - name: kubevirt-cdi + path: system/kubevirt-cdi + releaseName: kubevirt-cdi + namespace: cozy-kubevirt-cdi + dependsOn: + - kubevirt-cdi-operator + diff --git a/packages/core/platform/psds/kubevirt.yaml b/packages/core/platform/psds/kubevirt.yaml new file mode 100644 index 00000000..b070c5ba --- /dev/null +++ b/packages/core/platform/psds/kubevirt.yaml @@ -0,0 +1,38 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.kubevirt +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + packages: + - name: kubevirt-operator + path: system/kubevirt-operator + releaseName: kubevirt-operator + namespace: cozy-kubevirt + dependsOn: + - victoria-metrics-operator + - name: kubevirt + path: system/kubevirt + releaseName: kubevirt + namespace: cozy-kubevirt + privileged: true + dependsOn: + - kubevirt-operator + - name: kubevirt-instancetypes + path: system/kubevirt-instancetypes + releaseName: kubevirt-instancetypes + namespace: cozy-kubevirt + dependsOn: + - kubevirt-operator + - kubevirt + diff --git a/packages/core/platform/psds/linstor.yaml b/packages/core/platform/psds/linstor.yaml new file mode 100644 index 00000000..b60e03a8 --- /dev/null +++ b/packages/core/platform/psds/linstor.yaml @@ -0,0 +1,36 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.linstor +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + - cozystack.monitoring + - cozystack.reloader + packages: + - name: piraeus-operator + path: system/piraeus-operator + releaseName: piraeus-operator + namespace: cozy-linstor + dependsOn: + - cert-manager + - victoria-metrics-operator + - name: linstor + path: system/linstor + releaseName: linstor + namespace: cozy-linstor + privileged: true + dependsOn: + - piraeus-operator + - cert-manager + - snapshot-controller + diff --git a/packages/core/platform/psds/metallb.yaml b/packages/core/platform/psds/metallb.yaml new file mode 100644 index 00000000..f7f5a240 --- /dev/null +++ b/packages/core/platform/psds/metallb.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.metallb +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: metallb + path: system/metallb + releaseName: metallb + namespace: cozy-metallb + privileged: true diff --git a/packages/core/platform/psds/monitoring-agents.yaml b/packages/core/platform/psds/monitoring-agents.yaml new file mode 100644 index 00000000..d29831b9 --- /dev/null +++ b/packages/core/platform/psds/monitoring-agents.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.monitoring-agents +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + packages: + - name: monitoring-agents + path: system/monitoring-agents + releaseName: monitoring-agents + namespace: cozy-monitoring + privileged: true + dependsOn: + - victoria-metrics-operator + - vertical-pod-autoscaler-crds + diff --git a/packages/core/platform/psds/monitoring.yaml b/packages/core/platform/psds/monitoring.yaml new file mode 100644 index 00000000..a34b9f94 --- /dev/null +++ b/packages/core/platform/psds/monitoring.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.monitoring-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: monitoring-application + path: system/monitoring-application + releaseName: monitoring-application + namespace: cozy-system + sources: + - name: monitoring + path: extra/monitoring + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/multus.yaml b/packages/core/platform/psds/multus.yaml new file mode 100644 index 00000000..cfa17e0c --- /dev/null +++ b/packages/core/platform/psds/multus.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.multus +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: multus + path: system/multus + releaseName: multus + namespace: cozy-multus + privileged: true diff --git a/packages/core/platform/psds/mysql.yaml b/packages/core/platform/psds/mysql.yaml index 44c1409f..2fde3fa7 100644 --- a/packages/core/platform/psds/mysql.yaml +++ b/packages/core/platform/psds/mysql.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition metadata: - name: cozystack.mysql + name: cozystack.mysql-application spec: sourceRef: kind: OCIRepository diff --git a/packages/core/platform/psds/nats.yaml b/packages/core/platform/psds/nats.yaml index 746bbf99..d8e93b25 100644 --- a/packages/core/platform/psds/nats.yaml +++ b/packages/core/platform/psds/nats.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition metadata: - name: cozystack.nats + name: cozystack.nats-application spec: sourceRef: kind: OCIRepository diff --git a/packages/core/platform/psds/nfs-driver.yaml b/packages/core/platform/psds/nfs-driver.yaml new file mode 100644 index 00000000..acc3e943 --- /dev/null +++ b/packages/core/platform/psds/nfs-driver.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.nfs-driver +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: nfs-driver + path: system/nfs-driver + releaseName: nfs-driver + namespace: cozy-nfs-driver + privileged: true + disabled: true + diff --git a/packages/core/platform/psds/objectstorage-controller.yaml b/packages/core/platform/psds/objectstorage-controller.yaml new file mode 100644 index 00000000..b6242c82 --- /dev/null +++ b/packages/core/platform/psds/objectstorage-controller.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.objectstorage-controller +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: objectstorage-controller + path: system/objectstorage-controller + releaseName: objectstorage-controller + namespace: cozy-objectstorage-controller + diff --git a/packages/core/platform/psds/postgres.yaml b/packages/core/platform/psds/postgres.yaml index fef3d58e..2333e417 100644 --- a/packages/core/platform/psds/postgres.yaml +++ b/packages/core/platform/psds/postgres.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition metadata: - name: cozystack.postgres + name: cozystack.postgres-application spec: sourceRef: kind: OCIRepository diff --git a/packages/core/platform/psds/rabbitmq.yaml b/packages/core/platform/psds/rabbitmq.yaml index 39201831..62ba25fa 100644 --- a/packages/core/platform/psds/rabbitmq.yaml +++ b/packages/core/platform/psds/rabbitmq.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition metadata: - name: cozystack.rabbitmq + name: cozystack.rabbitmq-application spec: sourceRef: kind: OCIRepository diff --git a/packages/core/platform/psds/redis.yaml b/packages/core/platform/psds/redis.yaml index 1f456bed..fd0d38cb 100644 --- a/packages/core/platform/psds/redis.yaml +++ b/packages/core/platform/psds/redis.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSetDefinition metadata: - name: cozystack.redis + name: cozystack.redis-application spec: sourceRef: kind: OCIRepository diff --git a/packages/core/platform/psds/reloader.yaml b/packages/core/platform/psds/reloader.yaml new file mode 100644 index 00000000..979e644d --- /dev/null +++ b/packages/core/platform/psds/reloader.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.reloader +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: reloader + path: system/reloader + releaseName: reloader + namespace: cozy-reloader + diff --git a/packages/core/platform/psds/seaweedfs.yaml b/packages/core/platform/psds/seaweedfs.yaml new file mode 100644 index 00000000..2e0b11e3 --- /dev/null +++ b/packages/core/platform/psds/seaweedfs.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.seaweedfs-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: seaweedfs-application + path: system/seaweedfs-application + releaseName: seaweedfs-application + namespace: cozy-system + sources: + - name: seaweedfs + path: extra/seaweedfs + libraries: + - cozy-lib + - name: seaweedfs-system + path: system/seaweedfs + diff --git a/packages/core/platform/psds/snapshot-controller.yaml b/packages/core/platform/psds/snapshot-controller.yaml new file mode 100644 index 00000000..398920a0 --- /dev/null +++ b/packages/core/platform/psds/snapshot-controller.yaml @@ -0,0 +1,24 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.snapshot-controller +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + packages: + - name: snapshot-controller + path: system/snapshot-controller + releaseName: snapshot-controller + namespace: cozy-snapshot-controller + dependsOn: + - cert-manager-issuers + diff --git a/packages/core/platform/psds/telepresence.yaml b/packages/core/platform/psds/telepresence.yaml new file mode 100644 index 00000000..d7904985 --- /dev/null +++ b/packages/core/platform/psds/telepresence.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.telepresence +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + packages: + - name: telepresence + path: system/telepresence + releaseName: traffic-manager + namespace: cozy-telepresence + disabled: true + diff --git a/packages/core/platform/psds/tenant.yaml b/packages/core/platform/psds/tenant.yaml new file mode 100644 index 00000000..953a9a7d --- /dev/null +++ b/packages/core/platform/psds/tenant.yaml @@ -0,0 +1,35 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.tenant-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.ingress-application + - cozystack.seaweedfs-application + - cozystack.info-application + - cozystack.monitoring-application + - cozystack.bootbox-application + - cozystack.etcd-application + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: tenant-application + path: system/tenant-application + releaseName: tenant-application + namespace: cozy-system + sources: + - name: tenant + path: apps/tenant + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/velero.yaml b/packages/core/platform/psds/velero.yaml new file mode 100644 index 00000000..e18e3c70 --- /dev/null +++ b/packages/core/platform/psds/velero.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.velero +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring-agents + packages: + - name: velero + path: system/velero + releaseName: velero + namespace: cozy-velero + privileged: true + disabled: true + dependsOn: + - monitoring-agents + diff --git a/packages/core/platform/psds/vertical-pod-autoscaler.yaml b/packages/core/platform/psds/vertical-pod-autoscaler.yaml new file mode 100644 index 00000000..90c10503 --- /dev/null +++ b/packages/core/platform/psds/vertical-pod-autoscaler.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.vertical-pod-autoscaler +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring-agents + packages: + - name: vertical-pod-autoscaler-crds + path: system/vertical-pod-autoscaler-crds + releaseName: vertical-pod-autoscaler-crds + namespace: cozy-vertical-pod-autoscaler + privileged: true + - name: vertical-pod-autoscaler + path: system/vertical-pod-autoscaler + releaseName: vertical-pod-autoscaler + namespace: cozy-vertical-pod-autoscaler + privileged: true + dependsOn: + - vertical-pod-autoscaler-crds diff --git a/packages/core/platform/psds/victoria-metrics-operator.yaml b/packages/core/platform/psds/victoria-metrics-operator.yaml new file mode 100644 index 00000000..ceb4fb48 --- /dev/null +++ b/packages/core/platform/psds/victoria-metrics-operator.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.victoria-metrics-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + packages: + - name: victoria-metrics-operator + path: system/victoria-metrics-operator + releaseName: victoria-metrics-operator + namespace: cozy-victoria-metrics-operator diff --git a/packages/core/platform/psds/virtual-machine.yaml b/packages/core/platform/psds/virtual-machine.yaml new file mode 100644 index 00000000..99728458 --- /dev/null +++ b/packages/core/platform/psds/virtual-machine.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.virtual-machine-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.kubevirt + - cozystack.kubevirt-cdi + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: virtual-machine-application + path: system/virtual-machine-application + releaseName: virtual-machine-application + namespace: cozy-system + sources: + - name: virtual-machine + path: apps/virtual-machine + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/virtualprivatecloud.yaml b/packages/core/platform/psds/virtualprivatecloud.yaml new file mode 100644 index 00000000..f426f95a --- /dev/null +++ b/packages/core/platform/psds/virtualprivatecloud.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.virtualprivatecloud-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.multus + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: virtualprivatecloud-application + path: system/virtualprivatecloud-application + releaseName: virtualprivatecloud-application + namespace: cozy-system + sources: + - name: virtualprivatecloud + path: apps/vpc + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/vm-disk.yaml b/packages/core/platform/psds/vm-disk.yaml new file mode 100644 index 00000000..c23260a0 --- /dev/null +++ b/packages/core/platform/psds/vm-disk.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.vm-disk-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.kubevirt-cdi + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: vm-disk-application + path: system/vm-disk-application + releaseName: vm-disk-application + namespace: cozy-system + sources: + - name: vm-disk + path: apps/vm-disk + libraries: + - cozy-lib + diff --git a/packages/core/platform/psds/vm-instance.yaml b/packages/core/platform/psds/vm-instance.yaml new file mode 100644 index 00000000..f93058aa --- /dev/null +++ b/packages/core/platform/psds/vm-instance.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSetDefinition +metadata: + name: cozystack.vm-instance-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.kubevirt + libraries: + - name: cozy-lib + path: library/cozy-lib + packages: + - name: vm-instance-application + path: system/vm-instance-application + releaseName: vm-instance-application + namespace: cozy-system + sources: + - name: vm-instance + path: apps/vm-instance + libraries: + - cozy-lib + From dc7dbe22f2ea0fae404675e7454f77363e1ca36d Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Fri, 19 Dec 2025 00:00:07 +0100 Subject: [PATCH 05/15] psds Signed-off-by: Andrei Kvapil --- .../cozystackresourcedefinitions_types.go | 26 +- .../{packageset_types.go => package_types.go} | 60 +- ...nition_types.go => packagesource_types.go} | 136 +-- api/v1alpha1/zz_generated.deepcopy.go | 585 +++++------ packages/core/installer/example/platform.yaml | 27 + .../platform/psds/bootbox-application.yaml | 48 +- packages/core/platform/psds/bootbox.yaml | 25 +- packages/core/platform/psds/bucket.yaml | 52 +- .../core/platform/psds/capi-operator.yaml | 21 +- .../psds/capi-providers-bootstrap.yaml | 28 +- .../platform/psds/capi-providers-core.yaml | 28 +- .../psds/capi-providers-cpprovider.yaml | 30 +- .../psds/capi-providers-infraprovider.yaml | 29 +- packages/core/platform/psds/cert-manager.yaml | 46 +- .../platform/psds/clickhouse-operator.yaml | 27 +- packages/core/platform/psds/clickhouse.yaml | 42 +- packages/core/platform/psds/cozy-proxy.yaml | 20 +- packages/core/platform/psds/cozystack.yaml | 139 +-- .../core/platform/psds/etcd-application.yaml | 41 +- .../core/platform/psds/etcd-operator.yaml | 26 +- packages/core/platform/psds/external-dns.yaml | 22 +- .../psds/external-secrets-operator.yaml | 22 +- packages/core/platform/psds/ferretdb.yaml | 41 +- .../platform/psds/foundationdb-operator.yaml | 26 +- packages/core/platform/psds/foundationdb.yaml | 32 +- packages/core/platform/psds/goldpinger.yaml | 28 +- packages/core/platform/psds/gpu-operator.yaml | 28 +- .../core/platform/psds/grafana-operator.yaml | 19 +- .../core/platform/psds/hetzner-robotlb.yaml | 22 +- packages/core/platform/psds/http-cache.yaml | 35 +- packages/core/platform/psds/info.yaml | 39 +- packages/core/platform/psds/ingress.yaml | 45 +- .../core/platform/psds/kafka-operator.yaml | 26 +- packages/core/platform/psds/kafka.yaml | 42 +- packages/core/platform/psds/kamaji.yaml | 19 +- .../core/platform/psds/keycloak-operator.yaml | 24 +- packages/core/platform/psds/keycloak.yaml | 22 + packages/core/platform/psds/kubernetes.yaml | 56 +- packages/core/platform/psds/kubevirt-cdi.yaml | 33 +- packages/core/platform/psds/kubevirt.yaml | 56 +- packages/core/platform/psds/linstor.yaml | 51 +- .../core/platform/psds/mariadb-operator.yaml | 30 +- packages/core/platform/psds/metallb.yaml | 21 +- .../core/platform/psds/monitoring-agents.yaml | 18 +- packages/core/platform/psds/monitoring.yaml | 50 +- packages/core/platform/psds/multus.yaml | 21 +- packages/core/platform/psds/mysql.yaml | 43 +- packages/core/platform/psds/nats.yaml | 45 +- packages/core/platform/psds/networking.yaml | 130 +-- packages/core/platform/psds/nfs-driver.yaml | 24 +- .../psds/objectstorage-controller.yaml | 20 +- packages/core/platform/psds/postgres.yaml | 51 +- .../core/platform/psds/rabbitmq-operator.yaml | 20 +- packages/core/platform/psds/rabbitmq.yaml | 44 +- .../core/platform/psds/redis-operator.yaml | 20 +- packages/core/platform/psds/redis.yaml | 45 +- packages/core/platform/psds/reloader.yaml | 20 +- packages/core/platform/psds/seaweedfs.yaml | 50 +- .../platform/psds/snapshot-controller.yaml | 26 +- packages/core/platform/psds/tcp-balancer.yaml | 35 +- packages/core/platform/psds/telepresence.yaml | 22 +- packages/core/platform/psds/tenant.yaml | 33 +- packages/core/platform/psds/velero.yaml | 30 +- .../psds/vertical-pod-autoscaler.yaml | 38 +- .../psds/victoria-metrics-operator.yaml | 21 +- .../core/platform/psds/virtual-machine.yaml | 41 +- .../platform/psds/virtualprivatecloud.yaml | 36 +- packages/core/platform/psds/vm-disk.yaml | 36 +- packages/core/platform/psds/vm-instance.yaml | 41 +- packages/core/platform/psds/vpn.yaml | 42 +- packages/packages.yaml | 181 +--- .../crds/cozystack.io_packages.yaml | 156 +++ .../crds/cozystack.io_packagesources.yaml | 958 ++++++++++++++++++ ...stack.io_cozystackresourcedefinitions.yaml | 235 ++--- 74 files changed, 3192 insertions(+), 1515 deletions(-) rename api/v1alpha1/{packageset_types.go => package_types.go} (57%) rename api/v1alpha1/{packagesetdefinition_types.go => packagesource_types.go} (54%) create mode 100644 packages/core/installer/example/platform.yaml create mode 100644 packages/core/platform/psds/keycloak.yaml create mode 100644 packages/system/cozystack-controller/crds/cozystack.io_packages.yaml create mode 100644 packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml diff --git a/api/v1alpha1/cozystackresourcedefinitions_types.go b/api/v1alpha1/cozystackresourcedefinitions_types.go index b2baee85..2f25fb2d 100644 --- a/api/v1alpha1/cozystackresourcedefinitions_types.go +++ b/api/v1alpha1/cozystackresourcedefinitions_types.go @@ -92,7 +92,8 @@ type CozystackResourceDefinitionApplication struct { type CozystackResourceDefinitionRelease struct { // Helm chart configuration - Chart CozystackResourceDefinitionChart `json:"chart"` + // +optional + Chart CozystackResourceDefinitionChart `json:"chart,omitempty"` // Labels for the release Labels map[string]string `json:"labels,omitempty"` // Prefix for the release name @@ -110,17 +111,18 @@ type CozystackResourceDefinitionRelease struct { // - {{ .namespace }}: The namespace of the resource being processed // // Example YAML: -// secrets: -// include: -// - matchExpressions: -// - key: badlabel -// operator: DoesNotExist -// matchLabels: -// goodlabel: goodvalue -// resourceNames: -// - "{{ .name }}-secret" -// - "{{ .kind }}-{{ .name }}-tls" -// - "specificname" +// +// secrets: +// include: +// - matchExpressions: +// - key: badlabel +// operator: DoesNotExist +// matchLabels: +// goodlabel: goodvalue +// resourceNames: +// - "{{ .name }}-secret" +// - "{{ .kind }}-{{ .name }}-tls" +// - "specificname" type CozystackResourceDefinitionResourceSelector struct { metav1.LabelSelector `json:",inline"` // ResourceNames is a list of resource names to match diff --git a/api/v1alpha1/packageset_types.go b/api/v1alpha1/package_types.go similarity index 57% rename from api/v1alpha1/packageset_types.go rename to api/v1alpha1/package_types.go index b7529683..dafb8747 100644 --- a/api/v1alpha1/packageset_types.go +++ b/api/v1alpha1/package_types.go @@ -22,68 +22,68 @@ import ( ) // +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Cluster,shortName=ps +// +kubebuilder:resource:scope=Cluster,shortName={pkg,pkgs} // +kubebuilder:subresource:status -// +kubebuilder:printcolumn:name="Variant",type="string",JSONPath=".status.variant",description="Selected variant" +// +kubebuilder:printcolumn:name="Variant",type="string",JSONPath=".spec.variant",description="Selected variant" // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status",description="Ready status" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].message",description="Ready message" -// PackageSet is the Schema for the packagesets API -type PackageSet struct { +// Package is the Schema for the packages API +type Package struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec PackageSetSpec `json:"spec,omitempty"` - Status PackageSetStatus `json:"status,omitempty"` + Spec PackageSpec `json:"spec,omitempty"` + Status PackageStatus `json:"status,omitempty"` } // +kubebuilder:object:root=true -// PackageSetList contains a list of PackageSets -type PackageSetList struct { +// PackageList contains a list of Packages +type PackageList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []PackageSet `json:"items"` + Items []Package `json:"items"` } func init() { - SchemeBuilder.Register(&PackageSet{}, &PackageSetList{}) + SchemeBuilder.Register(&Package{}, &PackageList{}) } -// PackageSetSpec defines the desired state of PackageSet -type PackageSetSpec struct { - // IgnoreDependencies is a list of package set dependencies to ignore - // Dependencies listed here will not be installed even if they are specified in the PackageSetDefinition +// PackageSpec defines the desired state of Package +type PackageSpec struct { + // Variant is the name of the variant to use from the PackageSource + // If not specified, defaults to "default" + // +optional + Variant string `json:"variant,omitempty"` + + // IgnoreDependencies is a list of package source dependencies to ignore + // Dependencies listed here will not be installed even if they are specified in the PackageSource // +optional IgnoreDependencies []string `json:"ignoreDependencies,omitempty"` - // Packages is a map of package name to package overrides - // Allows overriding values and enabling/disabling specific packages from the PackageSetDefinition + // Components is a map of release name to component overrides + // Allows overriding values and enabling/disabling specific components from the PackageSource // +optional - Packages map[string]PackageSetPackageOverride `json:"packages,omitempty"` + Components map[string]PackageComponent `json:"components,omitempty"` } -// PackageSetPackageOverride defines overrides for a specific package -type PackageSetPackageOverride struct { - // Enabled indicates whether this package should be installed - // If false, the package will be disabled even if it's defined in the PackageSetDefinition +// PackageRelease defines overrides for a specific component +type PackageComponent struct { + // Enabled indicates whether this component should be installed + // If false, the component will be disabled even if it's defined in the PackageSource // +optional Enabled *bool `json:"enabled,omitempty"` // Values contains Helm chart values as a JSON object - // These values will be merged with the default values from the PackageSetDefinition + // These values will be merged with the default values from the PackageSource // +optional Values *apiextensionsv1.JSON `json:"values,omitempty"` } -// PackageSetStatus defines the observed state of PackageSet -type PackageSetStatus struct { - // Variant is the selected variant name, or "default" if not specified - // This field is populated by the controller based on spec.packageSetDefinitionRef.variant - // +optional - Variant string `json:"variant,omitempty"` - - // Conditions represents the latest available observations of a PackageSet's state +// PackageStatus defines the observed state of Package +type PackageStatus struct { + // Conditions represents the latest available observations of a Package's state // +optional Conditions []metav1.Condition `json:"conditions,omitempty"` } diff --git a/api/v1alpha1/packagesetdefinition_types.go b/api/v1alpha1/packagesource_types.go similarity index 54% rename from api/v1alpha1/packagesetdefinition_types.go rename to api/v1alpha1/packagesource_types.go index 36c1e921..b5daa2e1 100644 --- a/api/v1alpha1/packagesetdefinition_types.go +++ b/api/v1alpha1/packagesource_types.go @@ -21,75 +21,73 @@ import ( ) // +kubebuilder:object:root=true -// +kubebuilder:resource:scope=Cluster,shortName=psd +// +kubebuilder:resource:scope=Cluster,shortName={pkgsrc,pkgsrcs} // +kubebuilder:subresource:status // +kubebuilder:printcolumn:name="Variants",type="string",JSONPath=".status.variants",description="Package variants (comma-separated)" // +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status",description="Ready status" // +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].message",description="Ready message" -// PackageSetDefinition is the Schema for the packagesetdefinitions API -type PackageSetDefinition struct { +// PackageSource is the Schema for the packagesources API +type PackageSource struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec PackageSetDefinitionSpec `json:"spec,omitempty"` - Status PackageSetDefinitionStatus `json:"status,omitempty"` + Spec PackageSourceSpec `json:"spec,omitempty"` + Status PackageSourceStatus `json:"status,omitempty"` } // +kubebuilder:object:root=true -// PackageSetDefinitionList contains a list of PackageSetDefinitions -type PackageSetDefinitionList struct { +// PackageSourceList contains a list of PackageSources +type PackageSourceList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []PackageSetDefinition `json:"items"` + Items []PackageSource `json:"items"` } func init() { - SchemeBuilder.Register(&PackageSetDefinition{}, &PackageSetDefinitionList{}) + SchemeBuilder.Register(&PackageSource{}, &PackageSourceList{}) } -// PackageSetDefinitionSpec defines the desired state of PackageSetDefinition -type PackageSetDefinitionSpec struct { - // SourceRef is the source reference for the package set charts +// PackageSourceSpec defines the desired state of PackageSource +type PackageSourceSpec struct { + // SourceRef is the source reference for the package source charts // +optional - SourceRef *PackageSetDefinitionSourceRef `json:"sourceRef,omitempty"` + SourceRef *PackageSourceRef `json:"sourceRef,omitempty"` - // Variants is a list of package set variants - // Each variant defines packages, sources, dependencies, and libraries for a specific configuration + // Variants is a list of package source variants + // Each variant defines components, applications, dependencies, and libraries for a specific configuration // +optional - Variants []PackageSetDefinitionVariant `json:"variants,omitempty"` + Variants []Variant `json:"variants,omitempty"` } -// PackageSetDefinitionVariant defines a single variant configuration -type PackageSetDefinitionVariant struct { +// Variant defines a single variant configuration +type Variant struct { // Name is the unique identifier for this variant // +required Name string `json:"name"` - // DependsOn is a list of package set dependencies in the format "packageSetName/target" - // For example: "cozystack-system/network" - // If specified, the dependencies listed in the target's packages will be taken - // from the specified package set and added to all packages in this variant + // DependsOn is a list of package source dependencies + // For example: "cozystack.networking" // +optional DependsOn []string `json:"dependsOn,omitempty"` - // Libraries is a list of Helm library charts used by packages in this variant + // Libraries is a list of Helm library charts used by components in this variant // +optional - Libraries []PackageSetDefinitionLibrary `json:"libraries,omitempty"` + Libraries []Library `json:"libraries,omitempty"` - // Packages is a list of Helm releases to be installed as part of this variant + // Components is a list of Helm releases to be installed as part of this variant // +optional - Packages []PackageSetDefinitionPackage `json:"packages,omitempty"` + Components []Component `json:"components,omitempty"` - // Sources is a list of application sources for this variant + // Applications is a list of application releases to be installed as part of this variant // +optional - Sources []PackageSetDefinitionApplication `json:"sources,omitempty"` + Applications []Application `json:"applications,omitempty"` } -// PackageSetDefinitionDependencyTarget defines a named group of packages that can be referenced -// by other package sets via dependsOn -type PackageSetDefinitionDependencyTarget struct { +// DependencyTarget defines a named group of packages that can be referenced +// by other package sources via dependsOn +type DependencyTarget struct { // Name is the unique identifier for this dependency target // +required Name string `json:"name"` @@ -100,8 +98,8 @@ type PackageSetDefinitionDependencyTarget struct { Packages []string `json:"packages"` } -// PackageSetDefinitionLibrary defines a Helm library chart -type PackageSetDefinitionLibrary struct { +// Library defines a Helm library chart +type Library struct { // Name is the optional name for library placed in charts // +optional Name string `json:"name,omitempty"` @@ -111,8 +109,8 @@ type PackageSetDefinitionLibrary struct { Path string `json:"path"` } -// PackageSetDefinitionSourceRef defines the source reference for package set charts -type PackageSetDefinitionSourceRef struct { +// PackageSourceRef defines the source reference for package source charts +type PackageSourceRef struct { // Kind of the source reference // +kubebuilder:validation:Enum=GitRepository;OCIRepository // +required @@ -126,56 +124,64 @@ type PackageSetDefinitionSourceRef struct { // +required Namespace string `json:"namespace"` - // BasePath is the base path where packages are located in the source. + // Path is the base path where packages are located in the source. // For GitRepository, defaults to "packages" if not specified. // For OCIRepository, defaults to empty string (root) if not specified. // +optional Path string `json:"path,omitempty"` } -// PackageSetDefinitionPackage defines a single Helm release within a package set -type PackageSetDefinitionPackage struct { - // Name is the unique identifier for this package within the package set - // +required - Name string `json:"name"` - +// ComponentInstall defines installation parameters for a component +type ComponentInstall struct { // ReleaseName is the name of the HelmRelease resource that will be created - // If not specified, defaults to the Name field + // If not specified, defaults to the component Name field // +optional ReleaseName string `json:"releaseName,omitempty"` - // Path is the path to the Helm chart directory - // +required - Path string `json:"path"` - // Namespace is the Kubernetes namespace where the release will be installed - // +required - Namespace string `json:"namespace"` + // +optional + Namespace string `json:"namespace,omitempty"` // Privileged indicates whether this release requires privileged access // +optional Privileged bool `json:"privileged,omitempty"` - // Disabled indicates whether this release is disabled (should not be installed) + // DependsOn is a list of component names that must be installed before this component + // +optional + DependsOn []string `json:"dependsOn,omitempty"` +} + +// Component defines a single Helm release component within a package source +type Component struct { + // Name is the unique identifier for this component within the package source + // +required + Name string `json:"name"` + + // Path is the path to the Helm chart directory + // +required + Path string `json:"path"` + + // Install defines installation parameters for this component + // +optional + Install *ComponentInstall `json:"install,omitempty"` + + // Disabled indicates whether this component is disabled (should not be installed) // +optional Disabled bool `json:"disabled,omitempty"` - // DependsOn is a list of release names that must be installed before this release + // Libraries is a list of library names that this component depends on + // These libraries must be defined at the variant level // +optional - DependsOn []string `json:"dependsOn,omitempty"` - - // Libraries is a list of library charts that this package depends on - // +optional - Libraries []PackageSetDefinitionLibrary `json:"libraries,omitempty"` + Libraries []string `json:"libraries,omitempty"` // ValuesFiles is a list of values file names to use // +optional ValuesFiles []string `json:"valuesFiles,omitempty"` } -// PackageSetDefinitionApplication defines a single application release within a package set -type PackageSetDefinitionApplication struct { - // Name is the unique identifier for this application within the package set +// Application defines a single application release within a package source +type Application struct { + // Name is the unique identifier for this application within the package source // +required Name string `json:"name"` @@ -187,16 +193,20 @@ type PackageSetDefinitionApplication struct { // These libraries must be defined at the variant level // +optional Libraries []string `json:"libraries,omitempty"` + + // Template describes the applications that will be created. + // +required + Template CozystackResourceDefinition `json:"template"` } -// PackageSetDefinitionStatus defines the observed state of PackageSetDefinition -type PackageSetDefinitionStatus struct { +// PackageSourceStatus defines the observed state of PackageSource +type PackageSourceStatus struct { // Variants is a comma-separated list of package variant names - // This field is populated by the controller based on spec.packages keys + // This field is populated by the controller based on spec.variants keys // +optional Variants string `json:"variants,omitempty"` - // Conditions represents the latest available observations of a PackageSetDefinition's state + // Conditions represents the latest available observations of a PackageSource's state // +optional Conditions []metav1.Condition `json:"conditions,omitempty"` } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index a49ad31f..b2ca8ac9 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -27,6 +27,77 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Application) DeepCopyInto(out *Application) { + *out = *in + if in.Libraries != nil { + in, out := &in.Libraries, &out.Libraries + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.Template.DeepCopyInto(&out.Template) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application. +func (in *Application) DeepCopy() *Application { + if in == nil { + return nil + } + out := new(Application) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Component) DeepCopyInto(out *Component) { + *out = *in + if in.Install != nil { + in, out := &in.Install, &out.Install + *out = new(ComponentInstall) + (*in).DeepCopyInto(*out) + } + if in.Libraries != nil { + in, out := &in.Libraries, &out.Libraries + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ValuesFiles != nil { + in, out := &in.ValuesFiles, &out.ValuesFiles + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Component. +func (in *Component) DeepCopy() *Component { + if in == nil { + return nil + } + out := new(Component) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComponentInstall) DeepCopyInto(out *ComponentInstall) { + *out = *in + if in.DependsOn != nil { + in, out := &in.DependsOn, &out.DependsOn + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentInstall. +func (in *ComponentInstall) DeepCopy() *ComponentInstall { + if in == nil { + return nil + } + out := new(ComponentInstall) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CozystackResourceDefinition) DeepCopyInto(out *CozystackResourceDefinition) { *out = *in @@ -259,81 +330,7 @@ func (in *CozystackResourceDefinitionSpec) DeepCopy() *CozystackResourceDefiniti } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSet) DeepCopyInto(out *PackageSet) { - *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 PackageSet. -func (in *PackageSet) DeepCopy() *PackageSet { - if in == nil { - return nil - } - out := new(PackageSet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PackageSet) 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 *PackageSetDefinition) DeepCopyInto(out *PackageSetDefinition) { - *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 PackageSetDefinition. -func (in *PackageSetDefinition) DeepCopy() *PackageSetDefinition { - if in == nil { - return nil - } - out := new(PackageSetDefinition) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PackageSetDefinition) 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 *PackageSetDefinitionApplication) DeepCopyInto(out *PackageSetDefinitionApplication) { - *out = *in - if in.Libraries != nil { - in, out := &in.Libraries, &out.Libraries - *out = make([]PackageSetDefinitionLibrary, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionApplication. -func (in *PackageSetDefinitionApplication) DeepCopy() *PackageSetDefinitionApplication { - if in == nil { - return nil - } - out := new(PackageSetDefinitionApplication) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetDefinitionDependencyTarget) DeepCopyInto(out *PackageSetDefinitionDependencyTarget) { +func (in *DependencyTarget) DeepCopyInto(out *DependencyTarget) { *out = *in if in.Packages != nil { in, out := &in.Packages, &out.Packages @@ -342,57 +339,52 @@ func (in *PackageSetDefinitionDependencyTarget) DeepCopyInto(out *PackageSetDefi } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionDependencyTarget. -func (in *PackageSetDefinitionDependencyTarget) DeepCopy() *PackageSetDefinitionDependencyTarget { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DependencyTarget. +func (in *DependencyTarget) DeepCopy() *DependencyTarget { if in == nil { return nil } - out := new(PackageSetDefinitionDependencyTarget) + out := new(DependencyTarget) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetDefinitionLibrary) DeepCopyInto(out *PackageSetDefinitionLibrary) { +func (in *Library) DeepCopyInto(out *Library) { *out = *in } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionLibrary. -func (in *PackageSetDefinitionLibrary) DeepCopy() *PackageSetDefinitionLibrary { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Library. +func (in *Library) DeepCopy() *Library { if in == nil { return nil } - out := new(PackageSetDefinitionLibrary) + out := new(Library) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetDefinitionList) DeepCopyInto(out *PackageSetDefinitionList) { +func (in *Package) DeepCopyInto(out *Package) { *out = *in out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PackageSetDefinition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } + 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 PackageSetDefinitionList. -func (in *PackageSetDefinitionList) DeepCopy() *PackageSetDefinitionList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Package. +func (in *Package) DeepCopy() *Package { if in == nil { return nil } - out := new(PackageSetDefinitionList) + out := new(Package) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PackageSetDefinitionList) DeepCopyObject() runtime.Object { +func (in *Package) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -400,172 +392,7 @@ func (in *PackageSetDefinitionList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetDefinitionPackage) DeepCopyInto(out *PackageSetDefinitionPackage) { - *out = *in - if in.DependsOn != nil { - in, out := &in.DependsOn, &out.DependsOn - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Libraries != nil { - in, out := &in.Libraries, &out.Libraries - *out = make([]PackageSetDefinitionLibrary, len(*in)) - copy(*out, *in) - } - if in.ValuesFiles != nil { - in, out := &in.ValuesFiles, &out.ValuesFiles - *out = make([]string, len(*in)) - copy(*out, *in) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionPackage. -func (in *PackageSetDefinitionPackage) DeepCopy() *PackageSetDefinitionPackage { - if in == nil { - return nil - } - out := new(PackageSetDefinitionPackage) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetDefinitionSourceRef) DeepCopyInto(out *PackageSetDefinitionSourceRef) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionSourceRef. -func (in *PackageSetDefinitionSourceRef) DeepCopy() *PackageSetDefinitionSourceRef { - if in == nil { - return nil - } - out := new(PackageSetDefinitionSourceRef) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetDefinitionSpec) DeepCopyInto(out *PackageSetDefinitionSpec) { - *out = *in - if in.SourceRef != nil { - in, out := &in.SourceRef, &out.SourceRef - *out = new(PackageSetDefinitionSourceRef) - **out = **in - } - if in.Variants != nil { - in, out := &in.Variants, &out.Variants - *out = make([]PackageSetDefinitionVariant, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionSpec. -func (in *PackageSetDefinitionSpec) DeepCopy() *PackageSetDefinitionSpec { - if in == nil { - return nil - } - out := new(PackageSetDefinitionSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetDefinitionStatus) DeepCopyInto(out *PackageSetDefinitionStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]metav1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionStatus. -func (in *PackageSetDefinitionStatus) DeepCopy() *PackageSetDefinitionStatus { - if in == nil { - return nil - } - out := new(PackageSetDefinitionStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetDefinitionVariant) DeepCopyInto(out *PackageSetDefinitionVariant) { - *out = *in - if in.DependsOn != nil { - in, out := &in.DependsOn, &out.DependsOn - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Libraries != nil { - in, out := &in.Libraries, &out.Libraries - *out = make([]PackageSetDefinitionLibrary, len(*in)) - copy(*out, *in) - } - if in.Packages != nil { - in, out := &in.Packages, &out.Packages - *out = make([]PackageSetDefinitionPackage, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Applications != nil { - in, out := &in.Applications, &out.Applications - *out = make([]PackageSetDefinitionApplication, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetDefinitionVariant. -func (in *PackageSetDefinitionVariant) DeepCopy() *PackageSetDefinitionVariant { - if in == nil { - return nil - } - out := new(PackageSetDefinitionVariant) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetList) DeepCopyInto(out *PackageSetList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]PackageSet, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetList. -func (in *PackageSetList) DeepCopy() *PackageSetList { - if in == nil { - return nil - } - out := new(PackageSetList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PackageSetList) 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 *PackageSetPackageOverride) DeepCopyInto(out *PackageSetPackageOverride) { +func (in *PackageComponent) DeepCopyInto(out *PackageComponent) { *out = *in if in.Enabled != nil { in, out := &in.Enabled, &out.Enabled @@ -579,45 +406,151 @@ func (in *PackageSetPackageOverride) DeepCopyInto(out *PackageSetPackageOverride } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetPackageOverride. -func (in *PackageSetPackageOverride) DeepCopy() *PackageSetPackageOverride { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageComponent. +func (in *PackageComponent) DeepCopy() *PackageComponent { if in == nil { return nil } - out := new(PackageSetPackageOverride) + out := new(PackageComponent) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetSpec) DeepCopyInto(out *PackageSetSpec) { +func (in *PackageList) DeepCopyInto(out *PackageList) { *out = *in - if in.IgnoreDependencies != nil { - in, out := &in.IgnoreDependencies, &out.IgnoreDependencies - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Packages != nil { - in, out := &in.Packages, &out.Packages - *out = make(map[string]PackageSetPackageOverride, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Package, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetSpec. -func (in *PackageSetSpec) DeepCopy() *PackageSetSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageList. +func (in *PackageList) DeepCopy() *PackageList { if in == nil { return nil } - out := new(PackageSetSpec) + out := new(PackageList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageList) 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 *PackageSource) DeepCopyInto(out *PackageSource) { + *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 PackageSource. +func (in *PackageSource) DeepCopy() *PackageSource { + if in == nil { + return nil + } + out := new(PackageSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageSource) 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 *PackageSourceList) DeepCopyInto(out *PackageSourceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PackageSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSourceList. +func (in *PackageSourceList) DeepCopy() *PackageSourceList { + if in == nil { + return nil + } + out := new(PackageSourceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PackageSourceList) 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 *PackageSourceRef) DeepCopyInto(out *PackageSourceRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSourceRef. +func (in *PackageSourceRef) DeepCopy() *PackageSourceRef { + if in == nil { + return nil + } + out := new(PackageSourceRef) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PackageSetStatus) DeepCopyInto(out *PackageSetStatus) { +func (in *PackageSourceSpec) DeepCopyInto(out *PackageSourceSpec) { + *out = *in + if in.SourceRef != nil { + in, out := &in.SourceRef, &out.SourceRef + *out = new(PackageSourceRef) + **out = **in + } + if in.Variants != nil { + in, out := &in.Variants, &out.Variants + *out = make([]Variant, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSourceSpec. +func (in *PackageSourceSpec) DeepCopy() *PackageSourceSpec { + if in == nil { + return nil + } + out := new(PackageSourceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSourceStatus) DeepCopyInto(out *PackageSourceStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions @@ -628,12 +561,61 @@ func (in *PackageSetStatus) DeepCopyInto(out *PackageSetStatus) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSetStatus. -func (in *PackageSetStatus) DeepCopy() *PackageSetStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSourceStatus. +func (in *PackageSourceStatus) DeepCopy() *PackageSourceStatus { if in == nil { return nil } - out := new(PackageSetStatus) + out := new(PackageSourceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageSpec) DeepCopyInto(out *PackageSpec) { + *out = *in + if in.IgnoreDependencies != nil { + in, out := &in.IgnoreDependencies, &out.IgnoreDependencies + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = make(map[string]PackageComponent, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageSpec. +func (in *PackageSpec) DeepCopy() *PackageSpec { + if in == nil { + return nil + } + out := new(PackageSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageStatus) DeepCopyInto(out *PackageStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageStatus. +func (in *PackageStatus) DeepCopy() *PackageStatus { + if in == nil { + return nil + } + out := new(PackageStatus) in.DeepCopyInto(out) return out } @@ -674,6 +656,45 @@ func (in *SourceRef) DeepCopy() *SourceRef { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Variant) DeepCopyInto(out *Variant) { + *out = *in + if in.DependsOn != nil { + in, out := &in.DependsOn, &out.DependsOn + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Libraries != nil { + in, out := &in.Libraries, &out.Libraries + *out = make([]Library, len(*in)) + copy(*out, *in) + } + if in.Components != nil { + in, out := &in.Components, &out.Components + *out = make([]Component, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Applications != nil { + in, out := &in.Applications, &out.Applications + *out = make([]Application, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Variant. +func (in *Variant) DeepCopy() *Variant { + if in == nil { + return nil + } + out := new(Variant) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Workload) DeepCopyInto(out *Workload) { *out = *in diff --git a/packages/core/installer/example/platform.yaml b/packages/core/installer/example/platform.yaml new file mode 100644 index 00000000..da15885d --- /dev/null +++ b/packages/core/installer/example/platform.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.platform +spec: + variant: paas-full + components: + platform: + values: + bundles: + iaas: + enabled: true + paas: + enabled: true + naas: + enabled: true + publishing: + host: "dev5.infra.aenix.org" + apiServerEndpoint: "https://api.dev5.infra.aenix.org" + externalIPs: + - 10.4.0.246 + - 10.4.0.180 + - 10.4.0.46 + authentication: + oidc: + enabled: true diff --git a/packages/core/platform/psds/bootbox-application.yaml b/packages/core/platform/psds/bootbox-application.yaml index 504f1f5d..b7b3b0dc 100644 --- a/packages/core/platform/psds/bootbox-application.yaml +++ b/packages/core/platform/psds/bootbox-application.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.bootbox-application spec: @@ -16,14 +16,48 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: + components: - name: bootbox-application path: system/bootbox-application - releaseName: bootbox-application - namespace: cozy-system - sources: + install: + releaseName: bootbox-application + namespace: cozy-system + applications: - name: bootbox - path: extra/bootbox + path: apps/bootbox libraries: - cozy-lib - + template: + spec: + application: + kind: BootBox + plural: bootboxes + singular: bootbox + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"machines":{"description":"Configuration of physical machine instances.","type":"array","default":[],"items":{"type":"object","required":["arch","hostname","ip","leaseTime","uefi"],"properties":{"arch":{"description":"Architecture.","type":"string"},"hostname":{"description":"Hostname.","type":"string"},"ip":{"description":"IP address configuration.","type":"object","required":["address","gateway","netmask"],"properties":{"address":{"description":"IP address.","type":"string"},"gateway":{"description":"IP gateway.","type":"string"},"netmask":{"description":"Netmask.","type":"string"}}},"leaseTime":{"description":"Lease time.","type":"integer"},"mac":{"description":"MAC addresses.","type":"array","items":{"type":"string"}},"nameServers":{"description":"Name servers.","type":"array","items":{"type":"string"}},"timeServers":{"description":"Time servers.","type":"array","items":{"type":"string"}},"uefi":{"description":"UEFI.","type":"boolean"}}}},"whitelist":{"description":"List of client networks.","type":"array","default":[],"items":{"type":"string"}},"whitelistHTTP":{"description":"Secure HTTP by enabling client networks whitelisting.","type":"boolean","default":true}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + dashboard: + category: Administration + singular: BootBox + plural: BootBox + name: bootbox + description: PXE hardware provisioning + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNzEuNTY5OCA3Ni41MzM2QzcxLjIzNzQgNzYuNTMzNiA3MC45MDM2IDc2LjQ4NDcgNzAuNTgyOSA3Ni4zODkyTDM2LjIwNzkgNjYuMDc2N0MzNC4zODg1IDY1LjUzMTEgMzMuMzU2MiA2My42MTQ0IDMzLjkwMTcgNjEuNzk2NkMzNC40NDg5IDU5Ljk3NTUgMzYuMzY1NyA1OC45NDgzIDM4LjE4MTcgNTkuNDkwNEw3MS41Njk4IDY5LjUwNzZMMTA0Ljk1OCA1OS40OTA0QzEwNi43NzYgNTguOTYgMTA4LjY5MSA1OS45NzcyIDEwOS4yMzggNjEuNzk2NkMxMDkuNzgzIDYzLjYxNDQgMTA4Ljc1MSA2NS41MzExIDEwNi45MzIgNjYuMDc2N0w3Mi41NTY3IDc2LjM4OTJDNzIuMjM2IDc2LjQ4NDcgNzEuOTAyMiA3Ni41MzM2IDcxLjU2OTggNzYuNTMzNloiIGZpbGw9IiMyMzFGMjAiLz4KPHBhdGggZD0iTTc0Ljk3MyA1My4wMjE0Qzc0Ljc2NjggNTQuMzI3NiA3My44MDQzIDU1LjM5MzMgNzIuNTY2OCA1NS43NzE0TDM4LjE5MTggNjYuMDgzOUMzNy44NDggNjYuMTg3IDM3LjUzODcgNjYuMjIxNCAzNy4xOTQ5IDY2LjIyMTRDMzYuMzY5OSA2Ni4yMjE0IDM1LjU3OTMgNjUuOTEyIDM0LjkyNjIgNjUuMzYyTDIxLjE3NjIgNTMuMzMwOEMyMC4yNDggNTIuNTQwMSAxOS44MzU1IDUxLjI2ODMgMjAuMDc2MiA1MC4wNjUxQzIwLjMxNjggNDguODYyIDIxLjE3NjIgNDcuODY1MSAyMi4zNDQ5IDQ3LjQ4N0w1My4yODI0IDM3LjE3NDVDNTQuMzEzNyAzNi44MzA4IDU1LjQ0OCAzNy4wMDI2IDU2LjM0MTggMzcuNjIxNEw3My41MjkzIDQ5LjY1MjZDNzQuNjI5MyA1MC40MDg5IDc1LjE3OTMgNTEuNzE1MSA3NC45NzMgNTMuMDIxNFoiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEyMS45NjQgNTMuMzMwOEwxMDguMjE0IDY1LjM2MkMxMDcuNTYgNjUuOTEyIDEwNi43NyA2Ni4yMjE0IDEwNS45NDUgNjYuMjIxNEMxMDUuNjAxIDY2LjIyMTQgMTA1LjI5MiA2Ni4xODcgMTA0Ljk0OCA2Ni4wODM5TDcwLjU3MyA1NS43NzE0QzY5LjMzNTUgNTUuMzkzMyA2OC4zNzMgNTQuMzI3NiA2OC4xNjY3IDUzLjAyMTRDNjcuOTYwNSA1MS43MTUxIDY4LjUxMDUgNTAuNDA4OSA2OS42MTA1IDQ5LjY1MjZMODYuNzk4IDM3LjYyMTRDODcuNjkxNyAzNy4wMDI2IDg4LjgyNjEgMzYuODMwOCA4OS44NTc0IDM3LjE3NDVMMTIwLjc5NSA0Ny40ODdDMTIxLjk2NCA0Ny44NjUxIDEyMi44MjMgNDguODYyIDEyMy4wNjQgNTAuMDY1MUMxMjMuMzA0IDUxLjI2ODMgMTIyLjg5MiA1Mi41NDAxIDEyMS45NjQgNTMuMzMwOFoiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEwOS4zODIgNjMuNjQyNlYxMDcuNDcxQzEwOS4zODIgMTA4Ljg4IDEwOC41MjIgMTEwLjE1MiAxMDcuMjE2IDExMC42NjhMNzIuODQxMiAxMjQuNDE4QzcyLjQyODcgMTI0LjU4OSA3Mi4wMTYyIDEyNC42NTggNzEuNTY5MyAxMjQuNjU4QzcxLjEyMjUgMTI0LjY1OCA3MC43MSAxMjQuNTg5IDcwLjI5NzUgMTI0LjQxOEwzNS45MjI1IDExMC42NjhDMzQuNjE2MiAxMTAuMTUyIDMzLjc1NjggMTA4Ljg4IDMzLjc1NjggMTA3LjQ3MVY2My42NDI2QzMzLjc1NjggNjEuNzUyIDM1LjMwMzcgNjAuMjA1MSAzNy4xOTQzIDYwLjIwNTFIMTA1Ljk0NEMxMDcuODM1IDYwLjIwNTEgMTA5LjM4MiA2MS43NTIgMTA5LjM4MiA2My42NDI2WiIgZmlsbD0iI0VBQkQ0QyIvPgo8cGF0aCBkPSJNMTA3Ljk5OSA2MS40OTU4QzEwNy45OTkgNjIuOTgxMiAxMDcuMDM3IDY0LjI5NzkgMTA1LjY0MyA2NC43MzY4TDcyLjQ2MTMgNzQuODY1QzcyLjEyOTUgNzQuOTY2MiA3MS44MzA4IDc1IDcxLjQ5OSA3NUM3MS4xNjcyIDc1IDcwLjg2ODYgNzQuOTY2MiA3MC41MzY4IDc0Ljg2NUwzNy4zNTQ5IDY0LjczNjhDMzUuOTYxMyA2NC4yOTc5IDM0Ljk5OSA2Mi45ODEyIDM0Ljk5OSA2MS40OTU4QzM0Ljk5OSA2MC4wMTAzIDM1Ljk2MTMgNTguNjkzNyAzNy4zNTQ5IDU4LjI1NDhMNzAuNTM2OCA0OC4xMjY2QzcxLjE2NzIgNDcuOTU3OCA3MS44MzA4IDQ3Ljk1NzggNzIuNDYxMyA0OC4xMjY2TDEwNS42NDMgNTguMjU0OEMxMDcuMDM3IDU4LjY5MzcgMTA3Ljk5OSA2MC4wMTAzIDEwNy45OTkgNjEuNDk1OFoiIGZpbGw9IiM0QzM4MjUiLz4KPHBhdGggZD0iTTc0LjUxMTggNzdDNzUuMzUgNzcgNzYuMTc5NCA3Ni45NjI4IDc3IDc2LjkxMzNWMjEuMDg2N0M3Ni4xNzY1IDIxLjAzNDcgNzUuMzQ3MSAyMSA3NC41MDU5IDIxQzczLjY2NDcgMjEgNzIuODI5NCAyMS4wMzQ3IDcyIDIxLjA4NjdWNzYuOTEwOEM3Mi44MjY1IDc2Ljk2MjggNzMuNjU4OCA3Ni45OTc1IDc0LjUgNzdINzQuNTExOFoiIGZpbGw9InVybCgjcGFpbnQxX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNDQuMDI4MiAzOC4xMTI5TDQzLjIwNzggMzcuMjk1OUM0Mi4wNzczIDM4LjkxMjEgNDEuMDc0NiA0MC42MTQgNDAuMjA4OCA0Mi4zODYxQzUwLjEwMDEgNTIuNDM1NCA1MS4xNDI0IDU3LjI4MzUgNTEuMTI4OSA1OC45MDc0QzUxLjA5MTkgNjMuMDI2IDQ2LjA1MjIgNjkuNDg0NSA0MC4xNDE2IDc1LjQ2NTdDNDAuOTk5NiA3Ny4yMzc1IDQxLjk5MzMgNzguOTQwNSA0My4xMTM3IDgwLjU1OTJDNDMuNDQ5OSA4MC4yMjMgNDMuNzY5MyA3OS45MTM3IDQ0LjA5NTQgNzkuNTg0MkM1Mi42MjUgNzAuOTk3NSA1Ni43OTQgNjQuMjQ5OCA1Ni44NDQ1IDU4Ljk0NzdDNTYuODk0OSA1My42NDU3IDUyLjcwMjQgNDYuODg3OSA0NC4wMjgyIDM4LjExMjlaIiBmaWxsPSJ1cmwoI3BhaW50Ml9saW5lYXJfOTc5Xzc5MikiLz4KPHBhdGggZD0iTTEwNC42OTUgNzkuNTk3NUwxMDUuNjc2IDgwLjU3MjVDMTA2Ljc5NSA3OC45NDkyIDEwNy43ODcgNzcuMjQxNyAxMDguNjQyIDc1LjQ2NTVDMTAyLjczNSA2OS40NzA5IDk3LjY5NDggNjIuOTk1NSA5Ny42NTQ1IDU4Ljg5MzdDOTcuNjE3NSA1NC44OTI4IDEwMi42MjcgNDguNDIwOCAxMDguNTY4IDQyLjM1OUMxMDcuNzAzIDQwLjU5MTcgMTA2LjcwMyAzOC44OTQ0IDEwNS41NzYgMzcuMjgyMkwxMDQuNzU1IDM4LjA5OTJDOTYuMDgxIDQ2Ljg1NzUgOTEuODg4NSA1My42NzkxIDkxLjkzODkgNTguOTQ0MkM5MS45ODk0IDY0LjIwOTIgOTYuMTU4MyA3MS4wMTA3IDEwNC42OTUgNzkuNTk3NVoiIGZpbGw9InVybCgjcGFpbnQzX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNODcuNDM5NiA1OC45MzQ0Qzg3LjQzOTYgNTEuNTM3OCA5MC43Mzc4IDM5LjIzOTMgOTUuODE3OSAyNy42MTY1Qzk0LjE5NzkgMjYuNTEzOSA5Mi40OTUgMjUuNTM4MiA5MC43MjQ0IDI0LjY5ODJDODUuMTYzNSAzNy4yMjg3IDgxLjcyMDcgNTAuNTU2MSA4MS43MjA3IDU4Ljk0NzhDODEuNzIwNyA2Ny4wNjczIDg1LjQ0OTMgODAuNTQyNSA5MS4xMTEgOTMuMTQwM0M5Mi44NDY4IDkyLjI4NTkgOTQuNTE0NyA5MS4zMDAyIDk2LjEwMDQgOTAuMTkxN0M5MC44NTg5IDc4LjQwMDkgODcuNDM5NiA2Ni4wNzU1IDg3LjQzOTYgNTguOTM0NFoiIGZpbGw9InVybCgjcGFpbnQ0X2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNjcuMDM4NCA1OC45MzUzQzY3LjAzODQgNTAuNDk5OCA2My40NTc4IDM3LjA5ODUgNTcuOTYwOCAyNC43MjI3QzU2LjIxNTggMjUuNTYxMyA1NC41Mzc3IDI2LjUzMjUgNTIuOTQxMiAyNy42Mjc1QzU4LjAzMTQgMzkuMjQzNSA2MS4zMjI4IDUxLjU0NTQgNjEuMzIyOCA1OC45MzUzQzYxLjMyMjggNjYuMDczIDU3LjkwMzYgNzguMzk1IDUyLjY2MjEgOTAuMTcyNEM1NC4yNDgyIDkxLjI4MDIgNTUuOTE2MSA5Mi4yNjU4IDU3LjY1MTQgOTMuMTIxQzYzLjMxOTkgODAuNTI2NiA2Ny4wMzg0IDY3LjA2MTQgNjcuMDM4NCA1OC45MzUzWiIgZmlsbD0idXJsKCNwYWludDVfbGluZWFyXzk3OV83OTIpIi8+CjxwYXRoIGQ9Ik03NC40MjI5IDc0Ljk4N0w2MC42NzI5IDk1LjYxMkM2MC4wMTk3IDk2LjYwODkgNTguOTU0MSA5Ny4xNTg5IDU3LjgxOTcgOTcuMTU4OUM1Ny40MDcyIDk3LjE1ODkgNTYuOTYwNCA5Ny4wOTAxIDU2LjU0NzkgOTYuOTE4M0wyMi4xNzI5IDgzLjE2ODNDMjEuMTQxNiA4Mi43NTU4IDIwLjM4NTQgODEuODk2NCAyMC4xMTA0IDgwLjg2NTFDMTkuODM1NCA3OS43OTk1IDIwLjA3NiA3OC42NjUxIDIwLjc2MzUgNzcuODQwMUwzNC41MTM1IDYwLjY1MjZDMzUuMzcyOSA1OS41NTI2IDMyLjczOTEgNTcuODQwNCAzNC4wNzk3IDU4LjIxODVMNzIuNTY2NiA2OS43OTY0QzczLjU5NzkgNzAuMTA1OCA3NC40MjI5IDcwLjg5NjQgNzQuODAxIDcxLjkyNzZDNzUuMTc5MSA3Mi45NTg5IDc1LjA0MTYgNzQuMDkzMyA3NC40MjI5IDc0Ljk4N1oiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEyMy4wMjkgODAuNjI0MkMxMjIuNzU0IDgxLjY1NTUgMTIxLjk5OCA4Mi41NDkyIDEyMS4wMDEgODIuOTI3NEw4Ni42MjYxIDk2LjkxOEM4Ni4xNzkyIDk3LjA4OTkgODUuNzY2NyA5Ny4xNTg2IDg1LjMxOTkgOTcuMTU4NkM4NC4xODU1IDk3LjE1ODYgODMuMTE5OSA5Ni42MDg2IDgyLjQ2NjcgOTUuNjExN0w2OC43MTY3IDc0Ljk4NjdDNjguMDk4IDc0LjA5MyA2Ny45NjA1IDcyLjk1ODYgNjguMzM4NiA3MS45Mjc0QzY4LjcxNjcgNzAuODk2MSA2OS41NDE3IDcwLjEwNTUgNzAuNTczIDY5Ljc5NjFMMTA4LjQ2OSA1OC40MzMxQzEwOS44MSA1OC4wMjA2IDEwNy43MzIgNTkuNTUyNCAxMDguNjI2IDYwLjYxOEwxMjIuMzc2IDc3LjU5OTJDMTIzLjA2NCA3OC40MjQyIDEyMy4zMDQgNzkuNTU4NiAxMjMuMDI5IDgwLjYyNDJaIiBmaWxsPSIjRkZEQzgzIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfOTc5Xzc5MiIgeDE9IjI0IiB5MT0iMy41IiB4Mj0iMTgxIiB5Mj0iMTQ3IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM0ODAwMDAiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjQUUyMzAwIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQxX2xpbmVhcl85NzlfNzkyIiB4MT0iNzQuNSIgeTE9IjE3LjIzNjkiIHgyPSI3NC41IiB5Mj0iNzkuOTEzMyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDJfbGluZWFyXzk3OV83OTIiIHgxPSI0OC40OTMiIHkxPSIxNS44OTI4IiB4Mj0iNDguNDkzIiB5Mj0iMTAwLjk1NCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDNfbGluZWFyXzk3OV83OTIiIHgxPSIxMDAuMjkiIHkxPSIxNS44OTI2IiB4Mj0iMTAwLjI5IiB5Mj0iMTAwLjk1MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDRfbGluZWFyXzk3OV83OTIiIHgxPSI4OC45MTIyIiB5MT0iMTUuODkyOSIgeDI9Ijg4LjkxMjIiIHkyPSIxMDAuOTU0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkQyMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjA2IiBzdG9wLWNvbG9yPSIjRkZCNTAwIi8+CjxzdG9wIG9mZnNldD0iMC4xNCIgc3RvcC1jb2xvcj0iI0ZGOEMwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMjEiIHN0b3AtY29sb3I9IiNGRjczMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjI2IiBzdG9wLWNvbG9yPSIjRkY2QTAwIi8+CjxzdG9wIG9mZnNldD0iMC4zMyIgc3RvcC1jb2xvcj0iI0ZDNEYwRSIvPgo8c3RvcCBvZmZzZXQ9IjAuNDMiIHN0b3AtY29sb3I9IiNGOTJGMUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUxIiBzdG9wLWNvbG9yPSIjRjgxQjI3Ii8+CjxzdG9wIG9mZnNldD0iMC41NyIgc3RvcC1jb2xvcj0iI0Y3MTQyQiIvPgo8c3RvcCBvZmZzZXQ9IjAuNjgiIHN0b3AtY29sb3I9IiNERjE2MkUiLz4KPHN0b3Agb2Zmc2V0PSIwLjc5IiBzdG9wLWNvbG9yPSIjQUYxQTM4Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzRCMjE0QyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50NV9saW5lYXJfOTc5Xzc5MiIgeDE9IjU5Ljg1NyIgeTE9IjE1Ljg5MzgiIHgyPSI1OS44NTciIHkyPSIxMDAuOTU1IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkQyMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjA2IiBzdG9wLWNvbG9yPSIjRkZCNTAwIi8+CjxzdG9wIG9mZnNldD0iMC4xNCIgc3RvcC1jb2xvcj0iI0ZGOEMwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMjEiIHN0b3AtY29sb3I9IiNGRjczMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjI2IiBzdG9wLWNvbG9yPSIjRkY2QTAwIi8+CjxzdG9wIG9mZnNldD0iMC4zMyIgc3RvcC1jb2xvcj0iI0ZDNEYwRSIvPgo8c3RvcCBvZmZzZXQ9IjAuNDMiIHN0b3AtY29sb3I9IiNGOTJGMUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUxIiBzdG9wLWNvbG9yPSIjRjgxQjI3Ii8+CjxzdG9wIG9mZnNldD0iMC41NyIgc3RvcC1jb2xvcj0iI0Y3MTQyQiIvPgo8c3RvcCBvZmZzZXQ9IjAuNjgiIHN0b3AtY29sb3I9IiNERjE2MkUiLz4KPHN0b3Agb2Zmc2V0PSIwLjc5IiBzdG9wLWNvbG9yPSIjQUYxQTM4Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzRCMjE0QyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "whitelistHTTP"], ["spec", "whitelist"], ["spec", "machines"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - bootbox + ingresses: + exclude: [] + include: + - resourceNames: + - bootbox diff --git a/packages/core/platform/psds/bootbox.yaml b/packages/core/platform/psds/bootbox.yaml index 8f89c9f6..05673c95 100644 --- a/packages/core/platform/psds/bootbox.yaml +++ b/packages/core/platform/psds/bootbox.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.bootbox spec: @@ -10,14 +10,15 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: bootbox - path: system/bootbox - releaseName: bootbox - namespace: cozy-bootbox - privileged: true - disabled: true - + - name: default + dependsOn: + - cozystack.networking + - cozystack.bootbox-application + components: + - name: bootbox + path: system/bootbox + disabled: true + install: + privileged: true + namespace: cozy-bootbox + releaseName: bootbox diff --git a/packages/core/platform/psds/bucket.yaml b/packages/core/platform/psds/bucket.yaml index 945d853f..47b66bf8 100644 --- a/packages/core/platform/psds/bucket.yaml +++ b/packages/core/platform/psds/bucket.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.bucket-application spec: @@ -17,18 +17,46 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: bucket-application - path: system/bucket-application - releaseName: bucket-application - namespace: cozy-system - sources: - - name: bucket - path: apps/bucket - libraries: - - cozy-lib + components: - name: bucket-system path: apps/bucket libraries: - cozy-lib - + applications: + - name: bucket + path: apps/bucket + libraries: + - cozy-lib + template: + spec: + application: + kind: Bucket + plural: buckets + singular: bucket + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{}} + release: + prefix: bucket- + labels: + cozystack.io/ui: "true" + dashboard: + singular: Bucket + plural: Buckets + category: IaaS + weight: 80 + description: S3 compatible storage + tags: + - storage + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzA5MSkiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03MiAzMC4xNjQxTDExNy45ODMgMzYuNzc4OVY0MC42NzM5QzExNy45ODMgNDYuNDY1MyA5Ny4zODYyIDUxLjEzMzIgNzEuOTgyNyA1MS4xMzMyQzQ2LjU3OTIgNTEuMTMzMiAyNiA0Ni40NjUzIDI2IDQwLjY3MzlWMzYuNDQzMUw3MiAzMC4xNjQxWk03MiA1OC4yNjc4QzkxLjIwODQgNTguMjY3OCAxMDcuNjU4IDU1LjU5ODYgMTE0LjU0NyA1MS44MDQ4TDExNi44MDMgNDguMTExTDExNy43MjMgNDQuNzUzVjQ4LjkxNzFMMTAyLjY3OSAxMTEuMDMzQzEwMi42NzkgMTE0Ljg5NSA4OC45NTMzIDExOCA3Mi4wMTcyIDExOEM1NS4wODEyIDExOCA0MS4zNzQzIDExNC44OTUgNDEuMzc0MyAxMTEuMDMzTDI2LjMzIDQ4LjkxNzFWNDQuODM2OUwyOS44MDA3IDUxLjkzODJDMzYuNzA2NSA1NS42NjUzIDUyLjk5OTcgNTguMjY3OCA3MiA1OC4yNjc4WiIgZmlsbD0iIzhDMzEyMyIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTcyLjAwMDMgMjZDOTcuNDAzOCAyNiAxMTggMzAuNjgzOSAxMTggMzYuNDQyQzExOCA0Mi4yIDk3LjM4NjYgNDYuODUwNyA3Mi4wMDAzIDQ2Ljg1MDdDNDYuNjE0MSA0Ni44NTA3IDI2LjAxNzYgNDIuMjM0NSAyNi4wMTc2IDM2LjQ0MkMyNi4wMTc2IDMwLjY0OTQgNDYuNTk2OCAyNiA3Mi4wMDAzIDI2Wk03Mi4wMDAzIDU0LjEwMzdDOTUuNjg1NyA1NC4xMDM3IDExNS4xNzIgNTAuMDU4IDExNy43MDYgNDQuODE5N0wxMDIuNjYyIDEwNi45MzdDMTAyLjY2MiAxMTAuNzk5IDg4LjkzNjQgMTEzLjkwNSA3Mi4wMDAzIDExMy45MDVDNTUuMDY0MyAxMTMuOTA1IDQxLjMzOSAxMTAuODE2IDQxLjMzOSAxMDYuOTU0TDI2LjI5NTkgNDQuODM3QzI4Ljg0NjYgNTAuMDU4IDQ4LjMzMzMgNTQuMTAzNyA3Mi4wMDAzIDU0LjEwMzdaIiBmaWxsPSIjRTA1MjQzIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNjEuMTcyNSA2MC4wMjkzSDgxLjA5MjhWNzkuMTY3Nkg2MS4xNzI1VjYwLjAyOTNaTTQ1LjMzMDEgOTUuMzY4OEM0NS4zMzAxIDkwLjE0MiA0OS43MTA0IDg1LjkzNDIgNTUuMTUxMSA4NS45MzQyQzYwLjU5MTcgODUuOTM0MiA2NC45NzIxIDkwLjE0MiA2NC45NzIxIDk1LjM2ODhDNjQuOTcyMSAxMDAuNTk2IDYwLjU5MTcgMTA0LjgwMyA1NS4xNTExIDEwNC44MDNDNDkuNzEwNCAxMDQuODAzIDQ1LjMzMDEgMTAwLjU5NiA0NS4zMzAxIDk1LjM2ODhaTTk2LjQ0ODcgMTA0LjM2OEg3Ni43NzIyTDg2LjYxMDUgODYuNzczN0w5Ni40NDg3IDEwNC4zNjhaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18zMDkxIiB4MT0iMCIgeTE9IjAiIHgyPSIxNTEiIHkyPSIxODAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0ZGRjBFRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNFQzg4N0QiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`bucket-{{ .name }}`}}" + - "{{`bucket-{{ .name }}-credentials`}}" + ingresses: + exclude: [] + include: + - resourceNames: + - "{{`bucket-{{ .name }}-ui`}}" diff --git a/packages/core/platform/psds/capi-operator.yaml b/packages/core/platform/psds/capi-operator.yaml index d2e64d2a..a4536402 100644 --- a/packages/core/platform/psds/capi-operator.yaml +++ b/packages/core/platform/psds/capi-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.capi-operator spec: @@ -10,12 +10,13 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: capi-operator - path: system/capi-operator - releaseName: capi-operator - namespace: cozy-cluster-api - privileged: true + - name: default + dependsOn: + - cozystack.networking + components: + - name: capi-operator + path: system/capi-operator + install: + privileged: true + namespace: cozy-cluster-api + releaseName: capi-operator diff --git a/packages/core/platform/psds/capi-providers-bootstrap.yaml b/packages/core/platform/psds/capi-providers-bootstrap.yaml index 3cf1e27c..04946a16 100644 --- a/packages/core/platform/psds/capi-providers-bootstrap.yaml +++ b/packages/core/platform/psds/capi-providers-bootstrap.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.capi-providers-bootstrap spec: @@ -10,16 +10,16 @@ spec: namespace: cozy-system path: / variants: - - name: kubevirt - dependsOn: - - cozystack.networking - - cozystack.capi-operator - packages: - - name: capi-providers-bootstrap - path: system/capi-providers-bootstrap - releaseName: capi-providers-bootstrap - namespace: cozy-cluster-api - privileged: true - dependsOn: - - capi-operator - + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.capi-operator + components: + - name: capi-providers-bootstrap + path: system/capi-providers-bootstrap + install: + privileged: true + namespace: cozy-cluster-api + releaseName: capi-providers-bootstrap + dependsOn: + - capi-operator diff --git a/packages/core/platform/psds/capi-providers-core.yaml b/packages/core/platform/psds/capi-providers-core.yaml index ac67b8c2..e3a4e8c3 100644 --- a/packages/core/platform/psds/capi-providers-core.yaml +++ b/packages/core/platform/psds/capi-providers-core.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.capi-providers-core spec: @@ -10,16 +10,16 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.capi-operator - packages: - - name: capi-providers-core - path: system/capi-providers-core - releaseName: capi-providers-core - namespace: cozy-cluster-api - privileged: true - dependsOn: - - capi-operator - + - name: default + dependsOn: + - cozystack.networking + - cozystack.capi-operator + components: + - name: capi-providers-core + path: system/capi-providers-core + install: + privileged: true + namespace: cozy-cluster-api + releaseName: capi-providers-core + dependsOn: + - capi-operator diff --git a/packages/core/platform/psds/capi-providers-cpprovider.yaml b/packages/core/platform/psds/capi-providers-cpprovider.yaml index 759a9038..026494fe 100644 --- a/packages/core/platform/psds/capi-providers-cpprovider.yaml +++ b/packages/core/platform/psds/capi-providers-cpprovider.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.capi-providers-cpprovider spec: @@ -10,17 +10,17 @@ spec: namespace: cozy-system path: / variants: - - name: kamaji - dependsOn: - - cozystack.networking - - cozystack.capi-operator - - cozystack.kamaji - packages: - - name: capi-providers-cpprovider - path: system/capi-providers-cpprovider - releaseName: capi-providers-cpprovider - namespace: cozy-cluster-api - privileged: true - dependsOn: - - capi-operator - + - name: kamaji + dependsOn: + - cozystack.networking + - cozystack.capi-operator + - cozystack.kamaji + components: + - name: capi-providers-cpprovider + path: system/capi-providers-cpprovider + install: + privileged: true + namespace: cozy-cluster-api + releaseName: capi-providers-cpprovider + dependsOn: + - capi-operator diff --git a/packages/core/platform/psds/capi-providers-infraprovider.yaml b/packages/core/platform/psds/capi-providers-infraprovider.yaml index 3abe12bc..22cf0c32 100644 --- a/packages/core/platform/psds/capi-providers-infraprovider.yaml +++ b/packages/core/platform/psds/capi-providers-infraprovider.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.capi-providers-infraprovider spec: @@ -10,16 +10,17 @@ spec: namespace: cozy-system path: / variants: - - name: kubevirt - dependsOn: - - cozystack.networking - - cozystack.capi-operator - packages: - - name: capi-providers-infraprovider - path: system/capi-providers-infraprovider - releaseName: capi-providers-infraprovider - namespace: cozy-cluster-api - privileged: true - dependsOn: - - capi-operator - + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.capi-operator + - cozystack.kubevirt + components: + - name: capi-providers-infraprovider + path: system/capi-providers-infraprovider + install: + privileged: true + namespace: cozy-cluster-api + releaseName: capi-providers-infraprovider + dependsOn: + - capi-operator diff --git a/packages/core/platform/psds/cert-manager.yaml b/packages/core/platform/psds/cert-manager.yaml index 42632302..0907021e 100644 --- a/packages/core/platform/psds/cert-manager.yaml +++ b/packages/core/platform/psds/cert-manager.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.cert-manager spec: @@ -10,24 +10,26 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: cert-manager-crds - path: system/cert-manager-crds - releaseName: cert-manager-crds - namespace: cozy-cert-manager - - name: cert-manager - path: system/cert-manager - releaseName: cert-manager - namespace: cozy-cert-manager - dependsOn: - - cert-manager-crds - - name: cert-manager-issuers - path: system/cert-manager-issuers - releaseName: cert-manager-issuers - namespace: cozy-cert-manager - dependsOn: - - cert-manager - + - name: default + dependsOn: + - cozystack.networking + components: + - name: cert-manager-crds + path: system/cert-manager-crds + install: + namespace: cozy-cert-manager + releaseName: cert-manager-crds + - name: cert-manager + path: system/cert-manager + install: + namespace: cozy-cert-manager + releaseName: cert-manager + dependsOn: + - cert-manager-crds + - name: cert-manager-issuers + path: system/cert-manager-issuers + install: + namespace: cozy-cert-manager + releaseName: cert-manager-issuers + dependsOn: + - cert-manager diff --git a/packages/core/platform/psds/clickhouse-operator.yaml b/packages/core/platform/psds/clickhouse-operator.yaml index 04b44114..881c6639 100644 --- a/packages/core/platform/psds/clickhouse-operator.yaml +++ b/packages/core/platform/psds/clickhouse-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.clickhouse-operator spec: @@ -10,15 +10,16 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.monitoring - - cozystack.cozystack-core - packages: - - name: clickhouse-operator - path: system/clickhouse-operator - releaseName: clickhouse-operator - namespace: cozy-clickhouse-operator - dependsOn: - - victoria-metrics-operator + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + - cozystack.cozystack-core + components: + - name: clickhouse-operator + path: system/clickhouse-operator + install: + namespace: cozy-clickhouse-operator + releaseName: clickhouse-operator + dependsOn: + - victoria-metrics-operator diff --git a/packages/core/platform/psds/clickhouse.yaml b/packages/core/platform/psds/clickhouse.yaml index 0de1610f..25a2eb69 100644 --- a/packages/core/platform/psds/clickhouse.yaml +++ b/packages/core/platform/psds/clickhouse.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.clickhouse-application spec: @@ -16,13 +16,39 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: clickhouse-application - path: system/clickhouse-application - releaseName: clickhouse-application - namespace: cozy-system - sources: + components: [] + applications: - name: clickhouse path: apps/clickhouse libraries: - - cozy-lib + - cozy-lib + template: + spec: + application: + kind: ClickHouse + singular: clickhouse + plural: clickhouses + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["cleanupStrategy","enabled","resticPassword","s3AccessKey","s3Bucket","s3Region","s3SecretKey","schedule"],"properties":{"cleanupStrategy":{"description":"Retention strategy for cleaning up old backups.","type":"string","default":"--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"resticPassword":{"description":"Password for Restic backup encryption.","type":"string","default":""},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3Bucket":{"description":"S3 bucket used for storing backups.","type":"string","default":"s3.example.org/clickhouse-backups"},"s3Region":{"description":"AWS S3 region where backups are stored.","type":"string","default":"us-east-1"},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * *"}}},"clickhouseKeeper":{"description":"ClickHouse Keeper configuration.","type":"object","default":{},"properties":{"enabled":{"description":"Deploy ClickHouse Keeper for cluster coordination.","type":"boolean","default":true},"replicas":{"description":"Number of Keeper replicas.","type":"integer","default":3},"resourcesPreset":{"description":"Default sizing preset.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"logStorageSize":{"description":"Size of Persistent Volume for logs.","default":"2Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"logTTL":{"description":"TTL (expiration time) for `query_log` and `query_thread_log`.","type":"integer","default":15},"replicas":{"description":"Number of ClickHouse replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each ClickHouse replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"shards":{"description":"Number of ClickHouse shards.","type":"integer","default":1},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"},"readonly":{"description":"User is readonly (default: false).","type":"boolean"}}}}}} + release: + prefix: clickhouse- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: ClickHouse + plural: ClickHouse + description: Managed ClickHouse service + tags: [] + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzIwMikiLz4KPHBhdGggZD0iTTIzIDEwNUgzNFYxMTZIMjNWMTA1WiIgZmlsbD0iI0ZGMDAwMCIvPgo8cGF0aCBkPSJNMjMgMjhIMzRWMTA1SDIzVjI4Wk00NSAyOEg1NS45OTk5VjExNkg0NVYyOFpNNjYuOTk5OSAyOEg3Ny45OTk5VjExNkg2Ni45OTk5VjI4Wk04OC45OTk5IDI4SDk5Ljk5OTlWMTE2SDg4Ljk5OTlWMjhaTTExMSA2My43NDk5SDEyMlY4MC4yNDk5SDExMVY2My43NDk5WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMzIwMiIgeDE9Ii0wLjQ5OTk5OCIgeTE9IjEuNSIgeDI9IjE1My41IiB5Mj0iMTYyIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkNDMDAiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkY3QTAwIi8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "shards"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "logStorageSize"], ["spec", "logTTL"], ["spec", "users"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "s3Region"], ["spec", "backup", "s3Bucket"], ["spec", "backup", "schedule"], ["spec", "backup", "cleanupStrategy"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "backup", "resticPassword"], ["spec", "clickhouseKeeper"], ["spec", "clickhouseKeeper", "enabled"], ["spec", "clickhouseKeeper", "size"], ["spec", "clickhouseKeeper", "resourcesPreset"], ["spec", "clickhouseKeeper", "replicas"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`clickhouse-{{ .name }}-credentials`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`chendpoint-clickhouse-{{ .name }}`}}" diff --git a/packages/core/platform/psds/cozy-proxy.yaml b/packages/core/platform/psds/cozy-proxy.yaml index ee7a8ce8..fac0f5fc 100644 --- a/packages/core/platform/psds/cozy-proxy.yaml +++ b/packages/core/platform/psds/cozy-proxy.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.cozy-proxy spec: @@ -10,12 +10,12 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: cozy-proxy - path: system/cozy-proxy - releaseName: cozystack - namespace: cozy-system - + - name: default + dependsOn: + - cozystack.networking + components: + - name: cozy-proxy + path: system/cozy-proxy + install: + namespace: cozy-system + releaseName: cozystack diff --git a/packages/core/platform/psds/cozystack.yaml b/packages/core/platform/psds/cozystack.yaml index f3c11048..65294516 100644 --- a/packages/core/platform/psds/cozystack.yaml +++ b/packages/core/platform/psds/cozystack.yaml @@ -1,64 +1,85 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: - name: cozystack.cozystack-core + name: cozystack.cozystack spec: variants: - - name: default - dependsOn: - - cozystack.keycloak-operator - libraries: - - name: cozy-lib - path: library/cozy-lib - packages: - - name: cozystack-controller - releaseName: cozystack-controller - path: system/cozystack-controller - namespace: cozy-system - dependsOn: [] - - name: cozystack-api - releaseName: cozystack-api - path: system/cozystack-api - namespace: cozy-system - dependsOn: [cozystack-controller] - - name: lineage-controller-webhook - releaseName: lineage-controller-webhook - path: system/lineage-controller-webhook - namespace: cozy-system - dependsOn: [cozystack-controller] - - name: dashboard - releaseName: dashboard - path: system/dashboard - namespace: cozy-dashboard - dependsOn: [cozystack-api,cozystack-controller] - - name: cozystack-controller - releaseName: cozystack-controller - path: system/cozystack-controller - namespace: cozy-system - dependsOn: [] - - name: cozystack-api - releaseName: cozystack-api - path: system/cozystack-api - namespace: cozy-system - dependsOn: [cozystack-controller] - - name: lineage-controller-webhook - releaseName: lineage-controller-webhook - path: system/lineage-controller-webhook - namespace: cozy-system - dependsOn: [cozystack-controller] - - name: dashboard - releaseName: dashboard - path: system/dashboard - namespace: cozy-dashboard - dependsOn: [cozystack-api,cozystack-controller,keycloak-configure] - - name: keycloak-configure - releaseName: keycloak-configure - path: system/keycloak-configure - namespace: cozy-keycloak - dependsOn: [keycloak-operator] - - name: keycloak - releaseName: keycloak - path: system/keycloak - namespace: cozy-keycloak - dependsOn: [postgres-operator] + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: cozystack-controller + path: system/cozystack-controller + install: + namespace: cozy-system + releaseName: cozystack-controller + dependsOn: [] + - name: cozystack-api + path: system/cozystack-api + install: + namespace: cozy-system + releaseName: cozystack-api + dependsOn: + - cozystack-controller + - name: lineage-controller-webhook + path: system/lineage-controller-webhook + install: + namespace: cozy-system + releaseName: lineage-controller-webhook + dependsOn: + - cozystack-controller + - name: dashboard + path: system/dashboard + install: + namespace: cozy-dashboard + releaseName: dashboard + dependsOn: + - cozystack-api + - cozystack-controller + - name: oidc + dependsOn: + - cozystack.networking + - cozystack.keycloak + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: cozystack-controller + path: system/cozystack-controller + install: + namespace: cozy-system + releaseName: cozystack-controller + dependsOn: [] + - name: cozystack-api + path: system/cozystack-api + install: + namespace: cozy-system + releaseName: cozystack-api + dependsOn: + - cozystack-controller + - name: lineage-controller-webhook + path: system/lineage-controller-webhook + install: + namespace: cozy-system + releaseName: lineage-controller-webhook + dependsOn: + - cozystack-controller + - name: dashboard + path: system/dashboard + install: + namespace: cozy-dashboard + releaseName: dashboard + dependsOn: + - cozystack-api + - cozystack-controller + - keycloak-configure + - name: keycloak-configure + path: system/keycloak-configure + install: + namespace: cozy-keycloak + releaseName: keycloak-configure + dependsOn: [] diff --git a/packages/core/platform/psds/etcd-application.yaml b/packages/core/platform/psds/etcd-application.yaml index 93e73926..dbaeb9ab 100644 --- a/packages/core/platform/psds/etcd-application.yaml +++ b/packages/core/platform/psds/etcd-application.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.etcd-application spec: @@ -16,14 +16,39 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: etcd-application - path: system/etcd-application - releaseName: etcd-application - namespace: cozy-system - sources: + components: [] + applications: - name: etcd path: extra/etcd libraries: - cozy-lib - + template: + spec: + application: + kind: Etcd + plural: etcds + singular: etcd + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"replicas":{"description":"Number of etcd replicas.","type":"integer","default":3},"resources":{"description":"Resource configuration for etcd.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","default":"1000m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","default":"512Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"size":{"description":"Persistent Volume size.","default":"4Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + dashboard: + category: Administration + singular: Etcd + plural: Etcd + name: etcd + description: Storage for Kubernetes clusters + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NjMpIi8+CjxwYXRoIGQ9Ik0xMjIuNDQyIDczLjQ3MjlDMTIxLjk1OSA3My41MTM0IDEyMS40NzQgNzMuNTMyMiAxMjAuOTU4IDczLjUzMjJDMTE3Ljk2NSA3My41MzIyIDExNS4wNjEgNzIuODMwNCAxMTIuNDQyIDcxLjU0NTFDMTEzLjMxNCA2Ni41NDIxIDExMy42ODUgNjEuNTAxOSAxMTMuNTg4IDU2LjQ4MDJDMTEwLjc0OCA1Mi4zNzIzIDEwNy41MDIgNDguNDk2NSAxMDMuODM4IDQ0LjkyNTdDMTA1LjQyOCA0MS45NDU0IDEwNy43NzggMzkuMzgxMSAxMTAuNzExIDM3LjU2MjhMMTExLjk3MSAzNi43ODQyTDExMC45ODkgMzUuNjc3NEMxMDUuOTMyIDI5Ljk4MzIgOTkuODk3MSAyNS41ODA5IDkzLjA1NDcgMjIuNTkzN0w5MS42OTAyIDIyTDkxLjM0MzcgMjMuNDQyM0M5MC41Mjc3IDI2LjgwMzYgODguODIyMiAyOS44MzYgODYuNDgwNyAzMi4yNjk1QzgxLjk4MDMgMjkuODc3NCA3Ny4yNzg4IDI3Ljk0NCA3Mi40MzA1IDI2LjQ3OTdDNjcuNTkzNyAyNy45NDA4IDYyLjkwMDUgMjkuODY4NiA1OC40MDIgMzIuMjU3MUM1Ni4wNzAxIDI5LjgyNjggNTQuMzY4OCAyNi44MDE4IDUzLjU1NiAyMy40NTAxTDUzLjIwNzIgMjIuMDA4M0w1MS44NDc3IDIyLjU5OTJDNDUuMDkxNCAyNS41NDMxIDM4Ljg5MDEgMzAuMDY0NyAzMy45MTYyIDM1LjY3NDJMMzIuOTMxOCAzNi43ODMzTDM0LjE5IDM3LjU2MTlDMzcuMTE0MiAzOS4zNzMzIDM5LjQ1NzYgNDEuOTIyNCA0MS4wNDQ0IDQ0Ljg4NjZDMzcuMzkxNyA0OC40NDM1IDM0LjE0OTUgNTIuMzA3IDMxLjMxMTkgNTYuMzk1OUMzMS4yMDE0IDYxLjQxNTQgMzEuNTUzNSA2Ni40OTI0IDMyLjQyOTcgNzEuNTY0NEMyOS44MjMxIDcyLjgzNzggMjYuOTM1OCA3My41MzE4IDIzLjk2MjggNzMuNTMxOEMyMy40NDA5IDczLjUzMTggMjIuOTUyNyA3My41MTI5IDIyLjQ3ODIgNzMuNDczM0wyMSA3My4zNjA2TDIxLjEzODUgNzQuODM2NUMyMS44NjI5IDgyLjMwMzMgMjQuMTgxNCA4OS40MDUzIDI4LjAzMzQgOTUuOTQ3MUwyOC43ODUzIDk3LjIyMzdMMjkuOTE0MiA5Ni4yNjU2QzMyLjUzMDUgOTQuMDQ2NSAzNS42OTE3IDkyLjU3NyAzOS4wNTMgOTEuOTg0N0M0MS4yNjg5IDk2LjUxNTUgNDMuODk1MyAxMDAuNzcyIDQ2Ljg3NDcgMTA0LjcyNUM1MS42Mjg3IDEwNi4zODcgNTYuNTgxOSAxMDcuNjI5IDYxLjY5NzEgMTA4LjM2N0M2Mi4xODc3IDExMS43NSA2MS43OTcgMTE1LjI0OSA2MC40NjI0IDExOC40ODRMNTkuODk5NSAxMTkuODU1TDYxLjM0NjkgMTIwLjE3NEM2NS4wNTI5IDEyMC45ODkgNjguNzkxNyAxMjEuNDA0IDcyLjQ1MjYgMTIxLjQwNEw4My41NTUxIDEyMC4xNzRMODUuMDAzOSAxMTkuODU1TDg0LjQzOTcgMTE4LjQ4MkM4My4xMDg3IDExNS4yNDYgODIuNzE4IDExMS43NDMgODMuMjA4NiAxMDguMzZDODguMzAzNiAxMDcuNjIxIDkzLjIzODQgMTA2LjM4MiA5Ny45NzQ4IDEwNC43MjVDMTAwLjk1NyAxMDAuNzY5IDEwMy41ODYgOTYuNTA5NSAxMDUuODA1IDkxLjk3MjhDMTA5LjE3NyA5Mi41NjE0IDExMi4zNTYgOTQuMDMxNyAxMTQuOTg5IDk2LjI1NzNMMTE2LjExOCA5Ny4yMTQxTDExNi44NjYgOTUuOTQwN0MxMjAuNzI1IDg5LjM5MDUgMTIzLjA0MyA4Mi4yODkxIDEyMy43NTYgNzQuODM0MkwxMjMuODk1IDczLjM2MUwxMjIuNDQyIDczLjQ3MjlaTTg4LjMxOTcgOTEuNTE4MUM4My4wNjczIDkyLjk0NjYgNzcuNzMzIDkzLjY2NzcgNzIuNDMwNSA5My42Njc3QzY3LjExMzcgOTMuNjY3NyA2MS43ODU5IDkyLjk0NyA1Ni41MjkgOTEuNTE4MUM1My42NDQ4IDg3LjAzNjYgNTEuMzY0NSA4Mi4yMzU3IDQ5LjcyMzQgNzcuMTgxMkM0OC4wODkyIDcyLjE1MDIgNDcuMTMyOSA2Ni44Nzk1IDQ2Ljg1NTQgNjEuNDUyMkM1MC4yNTA0IDU3LjI1NDcgNTQuMTExIDUzLjU3NzYgNTguMzc2NyA1MC40ODIzQzYyLjcxMTQgNDcuMzI5NCA2Ny40MjcxIDQ0Ljc2NzkgNzIuNDMwNSA0Mi44NDFDNzcuNDI1NiA0NC43NjgzIDgyLjEzMjYgNDcuMzI2MiA4Ni40NTcyIDUwLjQ2NTdDOTAuNzM5NCA1My41Nzc2IDk0LjYxNzEgNTcuMjgzMiA5OC4wMjg3IDYxLjUwN0M5Ny43Mzc4IDY2LjkwMzQgOTYuNzcgNzIuMTQzOCA5NS4xMzMgNzcuMTY2NUM5My40OTYxIDgyLjIyIDkxLjIwODQgODcuMDM2MSA4OC4zMTk3IDkxLjUxODFaTTc2Ljc2ODQgNjYuMTk3NEM3Ni43Njg0IDY5LjkwODEgNzkuNzc1NCA3Mi45MDk2IDgzLjQ4MSA3Mi45MDk2Qzg3LjE4NTcgNzIuOTA5NiA5MC4xODk1IDY5LjkwODYgOTAuMTg5NSA2Ni4xOTc0QzkwLjE4OTUgNjIuNTAxIDg3LjE4NTcgNTkuNDg4MSA4My40ODEgNTkuNDg4MUM3OS43NzU0IDU5LjQ4ODEgNzYuNzY4NCA2Mi41MDEgNzYuNzY4NCA2Ni4xOTc0Wk02OC4wOTU0IDY2LjE5NzRDNjguMDk1NCA2OS45MDgxIDY1LjA4ODggNzIuOTA5NiA2MS4zODMyIDcyLjkwOTZDNTcuNjc0OSA3Mi45MDk2IDU0LjY3NjYgNjkuOTA4NiA1NC42NzY2IDY2LjE5NzRDNTQuNjc2NiA2Mi41MDI0IDU3LjY3NTMgNTkuNDg5NCA2MS4zODMyIDU5LjQ4OTRDNjUuMDg4OCA1OS40ODk0IDY4LjA5NTQgNjIuNTAyNCA2OC4wOTU0IDY2LjE5NzRaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yOTYzIiB4MT0iNS41IiB5MT0iMTEiIHgyPSIxNDEiIHkyPSIxMjQuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNTNCMkYwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzQxOUVEQSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "size"], ["spec", "storageClass"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resources", "cpu"], ["spec", "resources", "memory"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - etcd diff --git a/packages/core/platform/psds/etcd-operator.yaml b/packages/core/platform/psds/etcd-operator.yaml index 90c9a22a..f9c49d49 100644 --- a/packages/core/platform/psds/etcd-operator.yaml +++ b/packages/core/platform/psds/etcd-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.etcd-operator spec: @@ -10,15 +10,15 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.cert-manager - packages: - - name: etcd-operator - path: system/etcd-operator - releaseName: etcd-operator - namespace: cozy-etcd-operator - dependsOn: - - cert-manager - + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + components: + - name: etcd-operator + path: system/etcd-operator + install: + namespace: cozy-etcd-operator + releaseName: etcd-operator + dependsOn: + - cert-manager diff --git a/packages/core/platform/psds/external-dns.yaml b/packages/core/platform/psds/external-dns.yaml index 30449482..8cee73a1 100644 --- a/packages/core/platform/psds/external-dns.yaml +++ b/packages/core/platform/psds/external-dns.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.external-dns spec: @@ -10,13 +10,13 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: external-dns - path: system/external-dns - releaseName: external-dns - namespace: cozy-external-dns - disabled: true - + - name: default + dependsOn: + - cozystack.networking + components: + - name: external-dns + path: system/external-dns + disabled: true + install: + namespace: cozy-external-dns + releaseName: external-dns diff --git a/packages/core/platform/psds/external-secrets-operator.yaml b/packages/core/platform/psds/external-secrets-operator.yaml index 6f9da422..d626cc93 100644 --- a/packages/core/platform/psds/external-secrets-operator.yaml +++ b/packages/core/platform/psds/external-secrets-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.external-secrets-operator spec: @@ -10,13 +10,13 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: external-secrets-operator - path: system/external-secrets-operator - releaseName: external-secrets-operator - namespace: cozy-external-secrets-operator - disabled: true - + - name: default + dependsOn: + - cozystack.networking + components: + - name: external-secrets-operator + path: system/external-secrets-operator + disabled: true + install: + namespace: cozy-external-secrets-operator + releaseName: external-secrets-operator diff --git a/packages/core/platform/psds/ferretdb.yaml b/packages/core/platform/psds/ferretdb.yaml index 02e95800..538c4a74 100644 --- a/packages/core/platform/psds/ferretdb.yaml +++ b/packages/core/platform/psds/ferretdb.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.ferretdb-application spec: @@ -16,13 +16,40 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: ferretdb-application - path: system/ferretdb-application - releaseName: ferretdb-application - namespace: cozy-system - sources: + components: [] + applications: - name: ferretdb path: apps/ferretdb libraries: - cozy-lib + template: + spec: + application: + kind: FerretDB + plural: ferretdbs + singular: ferretdb + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["destinationPath","enabled","endpointURL","retentionPolicy","s3AccessKey","s3SecretKey","schedule"],"properties":{"destinationPath":{"description":"Path to store the backup (e.g. s3://bucket/path/to/folder/).","type":"string","default":"s3://bucket/path/to/folder/"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"endpointURL":{"description":"S3 endpoint URL for uploads.","type":"string","default":"http://minio-gateway-service:9000"},"retentionPolicy":{"description":"Retention policy.","type":"string","default":"30d"},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * * *"}}},"bootstrap":{"description":"Bootstrap configuration.","type":"object","default":{},"properties":{"enabled":{"description":"Restore database cluster from a backup.","type":"boolean","default":false},"oldName":{"description":"Name of database cluster before deletion.","type":"string","default":""},"recoveryTime":{"description":"Timestamp (RFC3339) for point-in-time recovery; empty means latest.","type":"string","default":""}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"quorum":{"description":"Configuration for quorum-based synchronous replication.","type":"object","default":{},"required":["maxSyncReplicas","minSyncReplicas"],"properties":{"maxSyncReplicas":{"description":"Maximum number of synchronous replicas allowed (must be less than total replicas).","type":"integer","default":0},"minSyncReplicas":{"description":"Minimum number of synchronous replicas required for commit.","type":"integer","default":0}}},"replicas":{"description":"Number of replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each FerretDB replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}}}} + release: + prefix: ferretdb- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: FerretDB + plural: FerretDB + description: Managed FerretDB service + tags: + - database + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NTIpIi8+CjxwYXRoIGQ9Ik02OS41OTIzIDIyLjEzMUM1OC4yNjYyIDIzLjY3ODcgNDYuOTAzNyAzMC44NzE0IDQwLjMzMDIgNDAuNjY3OUMzOS4yNzQgNDIuMjUyMSAzNy40NTMxIDQ1LjU0OCAzNy40NTMxIDQ1Ljg3NTdDMzcuNDUzMSA0NS45MTIyIDM4LjMyNzIgNDUuMzg0MSAzOS4zODMzIDQ0LjY5MjFDNTIuMzg0NyAzNi4xMTU2IDY3Ljg5ODkgMzQuNTMxNCA4MC41MTc4IDQwLjQ4NThDODMuMjY3NCA0MS43Nzg3IDg0Ljk5NzMgNDMuMDM1MSA4Ny40NTU1IDQ1LjQ5MzNDOTEuNTg5IDQ5LjY0NSA5NC42MTE3IDU1LjE5ODggOTYuNzA1OCA2Mi41MDA3Qzk3Ljc5ODMgNjYuMjUxOCA5OC43MDg4IDcxLjM2ODYgOTguOTQ1NSA3NC44NDY1Qzk5LjAwMDEgNzUuNzkzNCA5OS4xNDU4IDc2LjYzMSA5OS4yMzY5IDc2LjY4NTZDOTkuNzQ2NyA3Ni45OTUyIDEwMi4wNDEgNzMuNjYyOSAxMDMuNjYyIDcwLjI3NkMxMDYuMjI5IDY0Ljg4NjEgMTA3LjQzMSA1OS41ODcyIDEwNy40MTMgNTMuNzA1N0MxMDcuMzk1IDQ1LjM4NDEgMTA0LjUxOCAzOC4zOTE3IDk4LjcyNyAzMi41NjQ4QzkzLjU5MiAyNy4zOTM0IDg3LjEwOTUgMjMuODQyNiA4MC4zMTc1IDIyLjQ1ODdDNzguNzMzMyAyMi4xNDkyIDc3LjU2NzkgMjIuMDU4MSA3NC41OTk5IDIyLjAwMzVDNzIuNTQyMiAyMS45ODUzIDcwLjMwMjUgMjIuMDM5OSA2OS41OTIzIDIyLjEzMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00NS41MiA0Ni40NDAyQzQ0LjMzNjQgNDcuMDIyOSA0Mi4zNTE2IDQ4Ljg0MzggNDAuNjAzNSA1MC45Mzc5QzM5LjgyMDUgNTEuODY2NiAzOC42MzY5IDUzLjAxMzcgMzcuNzYyOSA1My42NjkzQzM1LjcyMzQgNTUuMTk4OSAzMi4yNDU1IDU4LjYwNCAzMC40NzkyIDYwLjgwNzNDMjEuMjY1NCA3Mi4yMjQ0IDE4LjY5NzkgODUuMjQ0IDIzLjA4NjMgOTguMzE4MkMyNi42OTE3IDEwOS4wMjUgMzUuMDMxNSAxMTYuMTI3IDQ3Ljg1MDggMTE5LjM1QzUyLjg0MDEgMTIwLjYyNCA2MC4zMjQgMTIxLjMzNSA2My40NTYgMTIwLjg0M0w2NC4yNTcyIDEyMC43MTVMNjMuMDE5IDExOS45ODdDNTYuMTkwNiAxMTYuMDE4IDUxLjQxOTggMTA5LjMxNyA1MC4wOTA1IDEwMS44NjlDNDkuNjg5OSA5OS42MTEgNDkuNjcxNyA5NS42MDUgNTAuMDcyMyA5My40MDE3QzUwLjk2NDUgODguNDQ4OCA1My40NTkyIDgzLjg5NjUgNTYuODQ2MSA4MS4wNTU5QzU4LjQzMDMgNzkuNzI2NiA2MS4xOTgxIDc4LjM2MDkgNjMuNDAxNCA3Ny44MzI5QzY2LjcxNTUgNzcuMDMxNyA2OC43MzY3IDc2LjEyMTIgNzAuODMwNyA3NC40NjQyQzcyLjE3ODIgNzMuNDA4IDczLjM2MTggNzEuODA1NiA3NC4zNDUxIDY5LjcyOThDNzUuMTgyNyA2Ny45NjM1IDc2Ljk2NzIgNjIuMzU1MSA3Ni45NjcyIDYxLjQ2MjhDNzYuOTY3MiA2MC44NDM3IDc2LjMyOTkgNjAuMDA2MSA3NS40MTk1IDU5LjQ0MTZDNzQuOTQ2IDU5LjE1MDIgNzQuMTk5NCA1OC45ODY0IDcyLjI4NzUgNTguNzg2MUM2NC4wNTY5IDU3LjkzMDIgNTkuOTU5OSA1Ni40MzcxIDU1LjAwNyA1Mi41MjIxQzU0LjI5NjggNTEuOTU3NiA1My40NDEgNTEuMzIwMyA1My4wOTUgNTEuMTAxOEM1Mi43NDkgNTAuOTAxNSA1Mi4wNTcxIDUwLjEzNjcgNTEuNTgzNiA0OS40MjY1QzUwLjE0NTEgNDcuMzMyNSA0OC4zNjA2IDQ1Ljk4NSA0Ni45OTQ5IDQ1Ljk2NjhDNDYuNzAzNiA0NS45NjY4IDQ2LjAyOTggNDYuMTg1MyA0NS41MiA0Ni40NDAyWk01NC40NjA3IDU0Ljg3MTFDNTUuMDc5OCA1NS4xODA2IDU1Ljc1MzUgNTUuNTgxMiA1NS45NzIgNTUuNzQ1MUw1Ni4zNzI3IDU2LjA3MjlMNTUuNzM1MyA1OC42MjIyQzU1LjE4OTEgNjAuODQzNyA1NS4wOTggNjEuNDA4MiA1NS4xNTI2IDYyLjk5MjRDNTUuMjA3MyA2NC41NTg0IDU1LjI2MTkgNjQuOTA0MyA1NS42MjYxIDY1LjQxNDJDNTYuMjI3IDY2LjIzMzYgNTcuMjY0OSA2Ni43MjUzIDU4LjQzMDMgNjYuNzI1M0M2MC4wODczIDY2LjcyNTMgNjEuMzgwMiA2NS43Nzg0IDYzLjUyODkgNjIuOTU2QzY0LjE0OCA2Mi4xNTQ4IDY0LjYzOTYgNjEuNzE3NyA2NS4zNjggNjEuMzcxOEM2Ni40OTcgNjAuODA3MyA2Ny4yOTgyIDYwLjc1MjcgNjkuODExIDYwLjk3MTJMNzEuNDg2MyA2MS4xMzVWNjIuMTE4M0M3MS40ODYzIDYzLjY2NjEgNzIuMzA1NyA2NC41NTg0IDczLjk4MDkgNjQuODEzM0w3NC43ODIxIDY0LjkyMjZMNzQuNDkwOCA2NS41OTYzQzczLjIxNjEgNjguNjczNiA2OS45Mzg1IDcyLjE1MTYgNjYuODYxMSA3My42OTk0QzY2LjM2OTUgNzMuOTM2MSA2NS4yNTg3IDc0LjM3MzEgNjQuNDAyOSA3NC42NjQ1QzYzLjAwMDggNzUuMTE5NyA2Mi42MTg0IDc1LjE3NDMgNjAuMjE0OCA3NS4xNzQzQzU3LjgyOTQgNzUuMTc0MyA1Ny40Mjg4IDc1LjExOTcgNTYuMTE3NyA3NC42ODI3QzUyLjE2NjMgNzMuMzcxNiA0OS4yMzQ3IDcwLjQ1ODEgNDcuOTA1NCA2Ni41NDMyQzQ3LjQzMTkgNjUuMTU5MyA0Ny40MTM3IDYxLjEzNSA0Ny44ODcyIDU5LjQ1OThDNDguNTI0NSA1Ny4xNDcyIDQ5LjY1MzUgNTUuMjM1MyA1MC44MzcxIDU0LjQ4ODdDNTEuNjAxOCA1My45OTcgNTMuMDIyMiA1NC4xNjA5IDU0LjQ2MDcgNTQuODcxMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTMuMDIyIDYxLjczNjFDMTEzLjAyMiA2Mi41NTU1IDExMi4xMTEgNjYuMzQzMSAxMTEuMzQ3IDY4LjcxMDJDMTA4LjQ3IDc3LjU3ODEgMTAzLjI2MiA4NS41MzU1IDk2LjQ2OTcgOTEuMzQ0M0M5MS42OTg5IDk1LjQ0MTMgODguMzExOSA5Ny4yNDQgODIuOTQwMiA5OC41NzMzQzc5LjQ4MDUgOTkuNDI5MSA3Ny4yMjI2IDk5LjcwMjMgNzIuODM0MSA5OS44MTE1QzY3LjM1MzIgOTkuOTU3MiA2MS45NDUxIDk5LjQ2NTUgNTcuMTAxNCA5OC40MDk0QzU2LjE3MjcgOTguMjA5MSA1NS4zODk4IDk4LjA4MTYgNTUuMzM1MSA5OC4xMzYzQzU1LjExNjYgOTguMzM2NiA1NS45NTQyIDEwMS4xMjMgNTYuNjgyNiAxMDIuNTk4QzU4LjAxMTkgMTA1LjMyOSA1OS41MjMyIDEwNy4zNjggNjIuMjE4MiAxMTAuMDYzQzY1LjA1ODggMTEyLjkwNCA2Ny4xNzExIDExNC40NyA3MC40NDg3IDExNi4xNjNDNzguNTcgMTIwLjM1MSA4Ny44OTMxIDEyMC45MTYgOTcuNDUzIDExNy43NjZDMTA3LjU0MSAxMTQuNDcgMTE0Ljk1MiAxMDguNTE2IDExOC45NCAxMDAuNTAzQzEyMS41OTggOTUuMTg2NCAxMjIuNjkxIDg5LjUwNTEgMTIyLjI5IDgzLjAyMjdDMTIxLjc5OSA3NS4wMjg4IDExOC44NDkgNjcuMTk4OSAxMTQuNTcgNjIuNTczOEMxMTMuODk2IDYxLjg0NTQgMTEzLjI3NyA2MS4yNjI3IDExMy4xODYgNjEuMjYyN0MxMTMuMDk1IDYxLjI2MjcgMTEzLjAyMiA2MS40ODEyIDExMy4wMjIgNjEuNzM2MVoiIGZpbGw9IndoaXRlIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgzXzI5NTIiIHgxPSI1LjUiIHkxPSIxMSIgeDI9IjE0MSIgeTI9IjEyNC41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM0NUFEQzYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMjE2Nzc4Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "quorum"], ["spec", "quorum", "minSyncReplicas"], ["spec", "quorum", "maxSyncReplicas"], ["spec", "users"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "schedule"], ["spec", "backup", "retentionPolicy"], ["spec", "backup", "endpointURL"], ["spec", "backup", "destinationPath"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "bootstrap"], ["spec", "bootstrap", "enabled"], ["spec", "bootstrap", "recoveryTime"], ["spec", "bootstrap", "oldName"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`ferretdb-{{ .name }}-credentials`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`ferretdb-{{ .name }}`}}" diff --git a/packages/core/platform/psds/foundationdb-operator.yaml b/packages/core/platform/psds/foundationdb-operator.yaml index 844b5d20..2f88dd06 100644 --- a/packages/core/platform/psds/foundationdb-operator.yaml +++ b/packages/core/platform/psds/foundationdb-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.foundationdb-operator spec: @@ -10,15 +10,15 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.cert-manager - packages: - - name: foundationdb-operator - path: system/foundationdb-operator - releaseName: foundationdb-operator - namespace: cozy-foundationdb-operator - dependsOn: - - cert-manager - + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + components: + - name: foundationdb-operator + path: system/foundationdb-operator + install: + namespace: cozy-foundationdb-operator + releaseName: foundationdb-operator + dependsOn: + - cert-manager diff --git a/packages/core/platform/psds/foundationdb.yaml b/packages/core/platform/psds/foundationdb.yaml index e41e25e4..8e6d8e49 100644 --- a/packages/core/platform/psds/foundationdb.yaml +++ b/packages/core/platform/psds/foundationdb.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.foundationdb-application spec: @@ -17,14 +17,30 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: foundationdb-application - path: system/foundationdb-application - releaseName: foundationdb-application - namespace: cozy-system - sources: + components: [] + applications: - name: foundationdb path: apps/foundationdb libraries: - cozy-lib - + template: + spec: + application: + kind: FoundationDB + singular: foundationdb + plural: foundationdbs + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"automaticReplacements":{"description":"Enable automatic pod replacements","type":"boolean","default":true},"backup":{"description":"Backup configuration","type":"object","default":{"enabled":false,"retentionPolicy":"7d","s3":{"bucket":"","credentials":{"accessKeyId":"","secretAccessKey":""},"endpoint":"","region":"us-east-1"}},"required":["enabled","retentionPolicy","s3"],"properties":{"enabled":{"description":"Enable backups","type":"boolean","default":false},"retentionPolicy":{"description":"Retention policy for backups","type":"string","default":"7d"},"s3":{"description":"S3 configuration for backups","type":"object","default":{"bucket":"","credentials":{"accessKeyId":"","secretAccessKey":""},"endpoint":"","region":"us-east-1"},"required":["bucket","credentials","endpoint","region"],"properties":{"bucket":{"description":"S3 bucket name","type":"string"},"credentials":{"description":"S3 credentials","type":"object","default":{"accessKeyId":"","secretAccessKey":""},"required":["accessKeyId","secretAccessKey"],"properties":{"accessKeyId":{"description":"S3 access key ID","type":"string"},"secretAccessKey":{"description":"S3 secret access key","type":"string"}}},"endpoint":{"description":"S3 endpoint URL","type":"string"},"region":{"description":"S3 region","type":"string","default":"us-east-1"}}}}},"cluster":{"description":"Cluster configuration","type":"object","default":{"faultDomain":{"key":"kubernetes.io/hostname","valueFrom":"spec.nodeName"},"processCounts":{"cluster_controller":1,"stateless":-1,"storage":3},"redundancyMode":"double","storageEngine":"ssd-2","version":"7.3.63"},"required":["faultDomain","processCounts","redundancyMode","storageEngine","version"],"properties":{"faultDomain":{"description":"Fault domain configuration","type":"object","default":{"key":"kubernetes.io/hostname","valueFrom":"spec.nodeName"},"required":["key","valueFrom"],"properties":{"key":{"description":"Fault domain key","type":"string","default":"kubernetes.io/hostname"},"valueFrom":{"description":"Fault domain value source","type":"string","default":"spec.nodeName"}}},"processCounts":{"description":"Process counts for different roles","type":"object","default":{"cluster_controller":1,"stateless":-1,"storage":3},"required":["cluster_controller","stateless","storage"],"properties":{"cluster_controller":{"description":"Number of cluster controller processes","type":"integer","default":1},"stateless":{"description":"Number of stateless processes (-1 for automatic)","type":"integer","default":-1},"storage":{"description":"Number of storage processes (determines cluster size)","type":"integer","default":3}}},"redundancyMode":{"description":"Database redundancy mode (single, double, triple, three_datacenter, three_datacenter_fallback)","type":"string","default":"double"},"storageEngine":{"description":"Storage engine (ssd-2, ssd-redwood-v1, ssd-rocksdb-v1, memory)","type":"string","default":"ssd-2"},"version":{"description":"Version of FoundationDB to use","type":"string","default":"7.3.63"}}},"customParameters":{"description":"Custom parameters to pass to FoundationDB","type":"array","default":[],"items":{"type":"string"}},"imageType":{"description":"Container image deployment type","type":"string","default":"unified","enum":["unified","split"]},"monitoring":{"description":"Monitoring configuration","type":"object","default":{"enabled":true},"required":["enabled"],"properties":{"enabled":{"description":"Enable WorkloadMonitor integration","type":"boolean","default":true}}},"resources":{"description":"Explicit CPU and memory configuration for each FoundationDB instance. When left empty, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each instance","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each instance","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted. Allowed values: `small`, `medium`, `large`, `xlarge`, `2xlarge`.","type":"string","default":"medium","enum":["small","medium","large","xlarge","2xlarge"]},"securityContext":{"description":"Security context for containers","type":"object","default":{"runAsGroup":4059,"runAsUser":4059},"required":["runAsGroup","runAsUser"],"properties":{"runAsGroup":{"description":"Group ID to run the container","type":"integer","default":4059},"runAsUser":{"description":"User ID to run the container","type":"integer","default":4059}}},"storage":{"description":"Storage configuration","type":"object","default":{"size":"16Gi","storageClass":""},"required":["size","storageClass"],"properties":{"size":{"description":"Size of persistent volumes for each instance","default":"16Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"Storage class (if not set, uses cluster default)","type":"string"}}}}} + release: + prefix: foundationdb- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: FoundationDB + plural: FoundationDB + description: Managed FoundationDB service + tags: + - database + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF84NThfMzA3MikiLz4KPHBhdGggZD0iTTEzNS43ODQgNzUuNjQ0NkwxMzUuOTM5IDg3Ljc2MzhMODkuNjg0NiA4MS41MzYyTDYyLjA4NjggODQuNTA3OUwzNS4zNDE3IDgxLjQzMjlMOC43NTE2NyA4NC41ODU0TDguNzI1ODMgODEuNTEwNEwzNS4zNjc2IDc3LjU4MjZWNjQuMTcxM0w2Mi4yOTM1IDcwLjczNDhMNjIuMzQ1MiA4MS4yNzc4TDg5LjQ3NzkgNzcuNjg2TDg5LjQwMDQgNjQuMTk3MkwxMzUuNzg0IDc1LjY0NDZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNODkuNDc3OCA4Ni4wMzI1TDEzNS44ODggOTAuODM4OFYxMDIuNzI2SDguNjQ4MjVMOC41MTkwNCA5OS41NzNIMzUuMjY0MUMzNS4yNjQxIDk5LjU3MyAzNS4yNjQxIDkwLjczNTUgMzUuMjY0MSA4Ni4wNTgzQzQ0LjI1NjcgODYuOTM2OSA2Mi4wODY3IDg4LjY5NDEgNjIuMDg2NyA4OC42OTQxVjk5LjI2MjlIODkuNDc3OFY4Ni4wMzI1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTYyLjI5MzQgNjYuODg0Nkw2Mi4yMTU4IDYzLjYyODZDNjIuMjE1OCA2My42Mjg2IDc5LjgxMzMgNTguMzU3MSA4OC45MDkyIDU1LjY2OTdDODguOTA5MiA1MS4zMDI2IDg4LjkwOTIgNDcuMDkwNiA4OC45MDkyIDQyQzEwNC44NzkgNDguNDA4NSAxMjAuMjI4IDU0LjYxMDIgMTM1LjczMyA2MC44Mzc4QzEzNS43MzMgNjQuNzEzOSAxMzUuNzMzIDY4LjQzNSAxMzUuNzMzIDcyLjU2OTVDMTE5Ljg0MSA2OC4yMDI0IDEwNC4yODQgNjMuOTEyOSA4OS4xNjc2IDU5Ljc1MjVDNzkuOTY4NCA2Mi4yMDc0IDYyLjI5MzQgNjYuODg0NiA2Mi4yOTM0IDY2Ljg4NDZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzUuMzk2MiA4MS43MDczTDguODA2MTIgODQuODU5OEw4Ljc4MDI3IDgxLjc4NDhMMzUuNDIyIDc3Ljg1N1Y2NC40NDU3TDYyLjM0OCA3MS4wMDkzTDYyLjM5OTYgODEuNTUyMkw4OS41MzIzIDc3Ljk2MDRMODkuNDU0OCA2NC40NzE2TDEzNS44MzkgNzUuOTE5TDEzNS45OTQgODguMDM4Mkw4OS43MzkxIDgxLjgxMDZMNjIuMTQxMiA4NC43ODIzTDM1LjM5NjIgODEuNzA3M1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik04OS41MzIzIDg2LjMwNjlMMTM1Ljk0MiA5MS4xMTMzVjEwM0g4LjcwMjdMOC41NzM0OSA5OS44NDc0SDM1LjMxODZDMzUuMzE4NiA5OS44NDc0IDM1LjMxODYgOTEuMDA5OSAzNS4zMTg2IDg2LjMzMjhDNDQuMzExMSA4Ny4yMTE0IDYyLjE0MTIgODguOTY4NSA2Mi4xNDEyIDg4Ljk2ODVWOTkuNTM3M0g4OS41MzIzVjg2LjMwNjlaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNjIuMzQ4MyA2Ny4xNTlMNjIuMjcwOCA2My45MDMxQzYyLjI3MDggNjMuOTAzMSA3OS44NjgyIDU4LjYzMTYgODguOTY0MiA1NS45NDQyQzg4Ljk2NDIgNTEuNTc3MSA4OC45NjQyIDQ3LjM2NTEgODguOTY0MiA0Mi4yNzQ0QzEwNC45MzQgNDguNjgyOSAxMjAuMjgzIDU0Ljg4NDcgMTM1Ljc4NyA2MS4xMTIzQzEzNS43ODcgNjQuOTg4NCAxMzUuNzg3IDY4LjcwOTQgMTM1Ljc4NyA3Mi44NDM5QzExOS44OTUgNjguNDc2OSAxMDQuMzM5IDY0LjE4NzMgODkuMjIyNiA2MC4wMjdDODAuMDIzMyA2Mi40ODE4IDYyLjM0ODMgNjcuMTU5IDYyLjM0ODMgNjcuMTU5WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQwX3JhZGlhbF84NThfMzA3MiIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgtMjkuNSAtMTgpIHJvdGF0ZSgzOS42OTYzKSBzY2FsZSgzMDIuMTY4IDI3NS4yNzEpIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0JFRERGRiIvPgo8c3RvcCBvZmZzZXQ9IjAuMjU5NjE1IiBzdG9wLWNvbG9yPSIjOUVDQ0ZEIi8+CjxzdG9wIG9mZnNldD0iMC41OTEzNDYiIHN0b3AtY29sb3I9IiMzRjlBRkIiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMEI3MEUwIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + # keysOrder: [] diff --git a/packages/core/platform/psds/goldpinger.yaml b/packages/core/platform/psds/goldpinger.yaml index 0ec1f1f6..307dac85 100644 --- a/packages/core/platform/psds/goldpinger.yaml +++ b/packages/core/platform/psds/goldpinger.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.goldpinger spec: @@ -10,16 +10,16 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.monitoring-agents - packages: - - name: goldpinger - path: system/goldpinger - releaseName: goldpinger - namespace: cozy-goldpinger - privileged: true - dependsOn: - - monitoring-agents - + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring-agents + components: + - name: goldpinger + path: system/goldpinger + install: + privileged: true + namespace: cozy-goldpinger + releaseName: goldpinger + dependsOn: + - monitoring-agents diff --git a/packages/core/platform/psds/gpu-operator.yaml b/packages/core/platform/psds/gpu-operator.yaml index 54a051ff..e41cc9b2 100644 --- a/packages/core/platform/psds/gpu-operator.yaml +++ b/packages/core/platform/psds/gpu-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.gpu-operator spec: @@ -10,16 +10,16 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: gpu-operator - path: system/gpu-operator - releaseName: gpu-operator - namespace: cozy-gpu-operator - privileged: true - valuesFiles: - - values.yaml - - values-talos.yaml - + - name: default + dependsOn: + - cozystack.networking + components: + - name: gpu-operator + path: system/gpu-operator + valuesFiles: + - values.yaml + - values-talos.yaml + install: + privileged: true + namespace: cozy-gpu-operator + releaseName: gpu-operator diff --git a/packages/core/platform/psds/grafana-operator.yaml b/packages/core/platform/psds/grafana-operator.yaml index 2de6ef95..d46597b7 100644 --- a/packages/core/platform/psds/grafana-operator.yaml +++ b/packages/core/platform/psds/grafana-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.grafana-operator spec: @@ -10,11 +10,12 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: grafana-operator - path: system/grafana-operator - releaseName: grafana-operator - namespace: cozy-grafana-operator + - name: default + dependsOn: + - cozystack.networking + components: + - name: grafana-operator + path: system/grafana-operator + install: + namespace: cozy-grafana-operator + releaseName: grafana-operator diff --git a/packages/core/platform/psds/hetzner-robotlb.yaml b/packages/core/platform/psds/hetzner-robotlb.yaml index 1cae55a8..db24a771 100644 --- a/packages/core/platform/psds/hetzner-robotlb.yaml +++ b/packages/core/platform/psds/hetzner-robotlb.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.hetzner-robotlb spec: @@ -10,13 +10,13 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: hetzner-robotlb - path: system/hetzner-robotlb - releaseName: robotlb - namespace: cozy-hetzner-robotlb - disabled: true - + - name: default + dependsOn: + - cozystack.networking + components: + - name: hetzner-robotlb + path: system/hetzner-robotlb + disabled: true + install: + namespace: cozy-hetzner-robotlb + releaseName: robotlb diff --git a/packages/core/platform/psds/http-cache.yaml b/packages/core/platform/psds/http-cache.yaml index 38229093..49802f98 100644 --- a/packages/core/platform/psds/http-cache.yaml +++ b/packages/core/platform/psds/http-cache.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.http-cache-application spec: @@ -16,13 +16,34 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: http-cache-application - path: system/http-cache-application - releaseName: http-cache - namespace: cozy-system - sources: + components: [] + applications: - name: http-cache path: apps/http-cache libraries: - cozy-lib + template: + spec: + application: + kind: HTTPCache + plural: httpcaches + singular: httpcache + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"endpoints":{"description":"Endpoints configuration, as a list of .","type":"array","default":[],"items":{"type":"string"}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"haproxy":{"description":"HAProxy configuration.","type":"object","default":{},"required":["replicas","resourcesPreset"],"properties":{"replicas":{"description":"Number of HAProxy replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"nginx":{"description":"Nginx configuration.","type":"object","default":{},"required":["replicas","resourcesPreset"],"properties":{"replicas":{"description":"Number of Nginx replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} + release: + prefix: http-cache- + labels: + cozystack.io/ui: "true" + dashboard: + category: NaaS + singular: HTTP Cache + plural: HTTP Cache + description: Layer7 load balancer and caching service + tags: + - cache + - network + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyNSkiLz4KPHBhdGggZD0iTTI2LjAwMjYgMzcuODU4OEMyNi4wMDI2IDYwLjkxOSAyNi4wMDI2IDgzLjk4MTQgMjYuMDAyNiAxMDcuMDQ2QzI1Ljk3MyAxMDguMzIzIDI2LjE5OTYgMTA5LjU5MyAyNi42NjkyIDExMC43ODNDMjcuMTM4NyAxMTEuOTcyIDI3Ljg0MTggMTEzLjA1NiAyOC43Mzc0IDExMy45NzJDMzAuNDUzOSAxMTUuNjU5IDMyLjcgMTE2LjcwOSAzNS4xMDA5IDExNi45NDhDMzcuNTAxOSAxMTcuMTg3IDM5LjkxMjYgMTE2LjYgNDEuOTMxIDExNS4yODRDNDMuMjgyIDExNC4zNzEgNDQuMzg4MSAxMTMuMTQzIDQ1LjE1MjcgMTExLjcwN0M0NS45MTc0IDExMC4yNzEgNDYuMzE3NSAxMDguNjcxIDQ2LjMxODEgMTA3LjA0NkM0Ni4zMTgxIDkwLjM1MjggNDYuMjg2MSA3My42NTk3IDQ2LjMxODEgNTYuOTY2NkM2MS42MTY4IDc1LjE4ODkgNzYuOTQ3NCA5My4zODU2IDkyLjMxIDExMS41NTdDOTQuNDQ0NCAxMTMuNzA4IDk3LjA4NzUgMTE1LjI5MSA5OS45OTcgMTE2LjE2MkMxMDIuOTA2IDExNy4wMzIgMTA1Ljk4OSAxMTcuMTYyIDEwOC45NjIgMTE2LjUzOUMxMTEuMDYxIDExNi4xMjggMTEyLjk3MyAxMTUuMDU3IDExNC40MTUgMTEzLjQ4NUMxMTUuODU3IDExMS45MTMgMTE2Ljc1NCAxMDkuOTIxIDExNi45NzQgMTA3LjgwNEMxMTcuMDA5IDg0LjI2ODEgMTE3LjAwOSA2MC43MzQzIDExNi45NzQgMzcuMjAyNUMxMTYuNzU0IDM0LjY5MDcgMTE1LjU5NSAzMi4zNTIyIDExMy43MjYgMzAuNjQ4NkMxMTEuODU4IDI4Ljk0NSAxMDkuNDE1IDI4IDEwNi44ODEgMjhDMTA0LjM0NiAyOCAxMDEuOTAzIDI4Ljk0NSAxMDAuMDM1IDMwLjY0ODZDOTguMTY2MyAzMi4zNTIyIDk3LjAwNzQgMzQuNjkwNyA5Ni43ODY5IDM3LjIwMjVDOTYuNzg2OSA1NC4xNjMyIDk2LjY4NDQgNzEuMTA0OCA5Ni43ODY5IDg4LjA1OTFDODEuNzYxNiA3MC40MzU4IDY2LjkyMTkgNTIuNjU5NiA1MS45NTQzIDM0Ljk3MjVDNDkuOTgxIDMyLjQ1NTQgNDcuMzY4NSAzMC41MDczIDQ0LjM4NjMgMjkuMzI5MUM0MS40MDQxIDI4LjE1MDkgMzguMTU5OSAyNy43ODUyIDM0Ljk4ODMgMjguMjY5OEMzMi41ODU3IDI4LjUzNTkgMzAuMzU4MyAyOS42NDkzIDI4LjcwOTkgMzEuNDA4NEMyNy4wNjE1IDMzLjE2NzUgMjYuMTAxIDM1LjQ1NTkgMjYuMDAyNiAzNy44NTg4WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODFfMjgyNSIgeDE9IjEwIiB5MT0iMTUuNSIgeDI9IjE0NCIgeTI9IjEzMS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEM1NEEiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDE5NjM5Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "endpoints"], ["spec", "haproxy"], ["spec", "haproxy", "replicas"], ["spec", "haproxy", "resources"], ["spec", "haproxy", "resourcesPreset"], ["spec", "nginx"], ["spec", "nginx", "replicas"], ["spec", "nginx", "resources"], ["spec", "nginx", "resourcesPreset"]] + secrets: + exclude: [] + include: [] diff --git a/packages/core/platform/psds/info.yaml b/packages/core/platform/psds/info.yaml index 10c8f97d..d99d703e 100644 --- a/packages/core/platform/psds/info.yaml +++ b/packages/core/platform/psds/info.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.info-application spec: @@ -16,14 +16,37 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: info-application - path: system/info-application - releaseName: info-application - namespace: cozy-system - sources: + components: [] + applications: - name: info path: extra/info libraries: - cozy-lib - + template: + spec: + application: + kind: Info + plural: infos + singular: info + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + dashboard: + name: info + category: Administration + singular: Info + plural: Info + description: Info + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF8xNDRfMykiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzE0NF8zKSI+CjxwYXRoIGQ9Ik03Ny42NDA3IDk3LjA4NDRMODIuODMzIDk3LjM2MDRWMTA0LjYzN0g2MS4xNzI4Vjk3LjcxOTdMNjQuMTc3MSA5Ny40NDk1QzY1LjgxMDEgOTcuMjY4NCA2Ni44MTA2IDk2LjcxOTMgNjYuODEwNiA5NC41MzQzVjY5LjIzMTRDNjYuODEwNiA2Ny4yMjE3IDY2LjI3MDEgNjYuNTg2NCA2NC41MzY1IDY2LjU4NjRMNjEuMzU2OCA2Ni40MDgxVjU4Ljg1ODRINzcuNjQ2NUw3Ny42NDA3IDk3LjA4NDRaTTcxLjI3MjYgMzkuMzYzQzc1LjI4MDQgMzkuMzYzIDc4LjE4NyA0Mi4zNzMxIDc4LjE4NyA0Ni4xODgzQzc4LjE4NyA1MC4wMTQ5IDc1LjI3MTggNTIuODM4MSA3MS4xNzc4IDUyLjgzODFDNjYuOTk3NSA1Mi44MzgxIDY0LjI2NjMgNTAuMDE0OSA2NC4yNjYzIDQ2LjE4ODNDNjQuMjY2MyA0Mi4zNzMxIDY2Ljk5NzUgMzkuMzYzIDcxLjI3MjYgMzkuMzYzWk03MiAxMThDNDYuNjM2OCAxMTggMjYgOTcuMzYzMiAyNiA3MkMyNiA0Ni42MzY4IDQ2LjYzNjggMjYgNzIgMjZDOTcuMzU3NSAyNiAxMTggNDYuNjM2OCAxMTggNzJDMTE4IDk3LjM2MzIgOTcuMzU3NSAxMTggNzIgMTE4Wk03MiAzNC42MjVDNTEuMzkyIDM0LjYyNSAzNC42MjUgNTEuMzkyIDM0LjYyNSA3MkMzNC42MjUgOTIuNjA4IDUxLjM5MiAxMDkuMzc1IDcyIDEwOS4zNzVDOTIuNjA4IDEwOS4zNzUgMTA5LjM3NSA5Mi42MDggMTA5LjM3NSA3MkMxMDkuMzc1IDUxLjM5MiA5Mi42MDggMzQuNjI1IDcyIDM0LjYyNVoiIGZpbGw9IndoaXRlIi8+CjwvZz4KPGRlZnM+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQwX3JhZGlhbF8xNDRfMyIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgxLjMyMjk4ZS0wNSAtNy41MDAwMSkgcm90YXRlKDQ0LjcxNzgpIHNjYWxlKDIxNS4zMTcgMzEyLjQ1NSkiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDBCNUU3Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwMzk4NCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzE0NF8zIj4KPHJlY3Qgd2lkdGg9IjkyIiBoZWlnaHQ9IjkyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjYgMjYpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`kubeconfig-{{ .namespace }}`}}" + - "{{`{{ .namespace }}`}}" diff --git a/packages/core/platform/psds/ingress.yaml b/packages/core/platform/psds/ingress.yaml index 1ab01efe..51604e6a 100644 --- a/packages/core/platform/psds/ingress.yaml +++ b/packages/core/platform/psds/ingress.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.ingress-application spec: @@ -16,16 +16,41 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: ingress-application - path: system/ingress-application - releaseName: ingress-application - namespace: cozy-system - sources: + components: + - name: ingress-system + path: system/ingress-nginx + applications: - name: ingress path: extra/ingress libraries: - cozy-lib - - name: ingress-system - path: system/ingress-nginx - + template: + spec: + application: + kind: Ingress + plural: ingresses + singular: ingress + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"cloudflareProxy":{"description":"Restoring original visitor IPs when Cloudflare proxied is enabled.","type":"boolean","default":false},"replicas":{"description":"Number of ingress-nginx replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each ingress-nginx replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"List of client networks.","type":"array","default":[],"items":{"type":"string"}}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + dashboard: + category: Administration + singular: Ingress + plural: Ingress + name: ingress + description: NGINX Ingress Controller + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODRfMzIyOSkiLz4KPHBhdGggZD0iTTg2LjkyNzQgMzcuMTA3NEgxN1YxMDcuMDM1SDg2LjkyNzRWMzcuMTA3NFoiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTEyNy42NDMgMjlIMTA3LjQ1NVY0OS4xODgzSDEyNy42NDNWMjlaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik0xMjcuNjQzIDYxLjcyNjZIMTA3LjQ1NVY4MS45MTQ5SDEyNy42NDNWNjEuNzI2NloiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTEyNy42NDMgOTQuNDUyMUgxMDcuNDU1VjExNC42NEgxMjcuNjQzVjk0LjQ1MjFaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik04OC41MTM3IDcyLjA3MTNIMTA2LjI3IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik04Ny41Njc0IDgwLjQyNDhMMTA3LjczIDk1Ljc4MDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTg3LjU2NzQgNjMuNzE4MUwxMDcuNzMgNDguMzYyMyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4NF8zMjI5IiB4MT0iMTAiIHkxPSIxNS41IiB4Mj0iMTQ0IiB5Mj0iMTMxLjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzAwREE1MyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDk2MzkiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "whitelist"], ["spec", "cloudflareProxy"], ["spec", "resources"], ["spec", "resourcesPreset"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - "{{`{{ slice .namespace 7 }}-ingress-controller`}}" diff --git a/packages/core/platform/psds/kafka-operator.yaml b/packages/core/platform/psds/kafka-operator.yaml index b433a46b..c930160b 100644 --- a/packages/core/platform/psds/kafka-operator.yaml +++ b/packages/core/platform/psds/kafka-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.kafka-operator spec: @@ -10,15 +10,15 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.monitoring - packages: - - name: kafka-operator - path: system/kafka-operator - releaseName: kafka-operator - namespace: cozy-kafka-operator - dependsOn: - - victoria-metrics-operator - + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + components: + - name: kafka-operator + path: system/kafka-operator + install: + namespace: cozy-kafka-operator + releaseName: kafka-operator + dependsOn: + - victoria-metrics-operator diff --git a/packages/core/platform/psds/kafka.yaml b/packages/core/platform/psds/kafka.yaml index d7081770..5c69b905 100644 --- a/packages/core/platform/psds/kafka.yaml +++ b/packages/core/platform/psds/kafka.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.kafka-application spec: @@ -17,14 +17,40 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: kafka-application - path: system/kafka-application - releaseName: kafka-application - namespace: cozy-system - sources: + components: [] + applications: - name: kafka path: apps/kafka libraries: - cozy-lib - + template: + spec: + application: + kind: Kafka + plural: kafkas + singular: kafka + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"kafka":{"description":"Kafka configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of Kafka replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size for Kafka.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the Kafka data.","type":"string","default":""}}},"topics":{"description":"Topics configuration.","type":"array","default":[],"items":{"type":"object","required":["config","name","partitions","replicas"],"properties":{"config":{"description":"Topic configuration.","type":"object","x-kubernetes-preserve-unknown-fields":true},"name":{"description":"Topic name.","type":"string"},"partitions":{"description":"Number of partitions.","type":"integer"},"replicas":{"description":"Number of replicas.","type":"integer"}}}},"zookeeper":{"description":"ZooKeeper configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of ZooKeeper replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size for ZooKeeper.","default":"5Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the ZooKeeper data.","type":"string","default":""}}}}} + release: + prefix: kafka- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: Kafka + plural: Kafka + description: Managed Kafka service + tags: + - messaging + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyMCkiLz4KPHBhdGggZD0iTTkxLjAzMDcgNzcuODE4NUM4Ni44NTc3IDc3LjgxODUgODMuMTE2NiA3OS42ODE4IDgwLjU1NDcgODIuNjE1NEw3My45OTAxIDc3LjkzMTVDNzQuNjg2OSA3NS45OTc4IDc1LjA4NyA3My45MjE1IDc1LjA4NyA3MS43NDgyQzc1LjA4NyA2OS42MTI2IDc0LjcwMDggNjcuNTcxMSA3NC4wMjY5IDY1LjY2Nkw4MC41NzY5IDYxLjAzMThDODMuMTM4NSA2My45NTA1IDg2Ljg2OTkgNjUuODAzNyA5MS4wMzA3IDY1LjgwMzdDOTguNzMyOCA2NS44MDM3IDEwNSA1OS40ODg0IDEwNSA1MS43MjQ3QzEwNSA0My45NjEgOTguNzMyOCAzNy42NDU3IDkxLjAzMDcgMzcuNjQ1N0M4My4zMjg1IDM3LjY0NTcgNzcuMDYxNCA0My45NjEgNzcuMDYxNCA1MS43MjQ3Qzc3LjA2MTQgNTMuMTE0MyA3Ny4yNjk3IDU0LjQ1NDMgNzcuNjQzNSA1NS43MjMzTDcxLjA4OTEgNjAuMzU5OEM2OC4zNTEyIDU2LjkzNjUgNjQuNDA5IDU0LjU0NjMgNTkuOTE3NCA1My44MTY2VjQ1Ljg1NTNDNjYuMjQ1MSA0NC41MTU4IDcxLjAxMjggMzguODQ5NSA3MS4wMTI4IDMyLjA3OUM3MS4wMTI4IDI0LjMxNTMgNjQuNzQ1NyAxOCA1Ny4wNDM1IDE4QzQ5LjM0MTQgMTggNDMuMDc0MiAyNC4zMTUzIDQzLjA3NDIgMzIuMDc5QzQzLjA3NDIgMzguNzU4OSA0Ny43MTg0IDQ0LjM1NTIgNTMuOTE5NiA0NS43OTAzVjUzLjg1NTFDNDUuNDU2NyA1NS4zNTIzIDM5IDYyLjc5NjEgMzkgNzEuNzQ4MkMzOSA4MC43NDQgNDUuNTIwNiA4OC4yMTUxIDU0LjA0NDYgODkuNjYxM1Y5OC4xNzcyQzQ3Ljc4MDEgOTkuNTY1IDQzLjA3NDIgMTA1LjE5NiA0My4wNzQyIDExMS45MjFDNDMuMDc0MiAxMTkuNjg1IDQ5LjM0MTQgMTI2IDU3LjA0MzUgMTI2QzY0Ljc0NTcgMTI2IDcxLjAxMjggMTE5LjY4NSA3MS4wMTI4IDExMS45MjFDNzEuMDEyOCAxMDUuMTk2IDY2LjMwNyA5OS41NjUgNjAuMDQyNCA5OC4xNzcyVjg5LjY2MTFDNjQuMzU2OSA4OC45Mjg2IDY4LjI2MDEgODYuNjQwNyA3MS4wMjUyIDgzLjIyMzRMNzcuNjMzNyA4Ny45Mzc2Qzc3LjI2NjkgODkuMTk1MiA3Ny4wNjE0IDkwLjUyMTkgNzcuMDYxNCA5MS44OTc1Qzc3LjA2MTQgOTkuNjYxMiA4My4zMjg1IDEwNS45NzYgOTEuMDMwNyAxMDUuOTc2Qzk4LjczMjggMTA1Ljk3NiAxMDUgOTkuNjYxMiAxMDUgOTEuODk3NUMxMDUgODQuMTMzOCA5OC43MzI4IDc3LjgxODUgOTEuMDMwNyA3Ny44MTg1Wk05MS4wMzA3IDQ0Ljg5ODVDOTQuNzY1NiA0NC44OTg1IDk3LjgwMzQgNDcuOTYxNSA5Ny44MDM0IDUxLjcyNDdDOTcuODAzNCA1NS40ODc5IDk0Ljc2NTYgNTguNTUwNiA5MS4wMzA3IDU4LjU1MDZDODcuMjk1OCA1OC41NTA2IDg0LjI1OCA1NS40ODc5IDg0LjI1OCA1MS43MjQ3Qzg0LjI1OCA0Ny45NjE1IDg3LjI5NTggNDQuODk4NSA5MS4wMzA3IDQ0Ljg5ODVaTTUwLjI3MDUgMzIuMDc5QzUwLjI3MDUgMjguMzE1OCA1My4zMDg2IDI1LjI1MzEgNTcuMDQzNSAyNS4yNTMxQzYwLjc3ODUgMjUuMjUzMSA2My44MTYzIDI4LjMxNTggNjMuODE2MyAzMi4wNzlDNjMuODE2MyAzNS44NDIyIDYwLjc3ODUgMzguOTA0OSA1Ny4wNDM1IDM4LjkwNDlDNTMuMzA4NiAzOC45MDQ5IDUwLjI3MDUgMzUuODQyMiA1MC4yNzA1IDMyLjA3OVpNNjMuODE2MyAxMTEuOTIxQzYzLjgxNjMgMTE1LjY4NCA2MC43Nzg1IDExOC43NDcgNTcuMDQzNSAxMTguNzQ3QzUzLjMwODYgMTE4Ljc0NyA1MC4yNzA1IDExNS42ODQgNTAuMjcwNSAxMTEuOTIxQzUwLjI3MDUgMTA4LjE1OCA1My4zMDg2IDEwNS4wOTUgNTcuMDQzNSAxMDUuMDk1QzYwLjc3ODUgMTA1LjA5NSA2My44MTYzIDEwOC4xNTggNjMuODE2MyAxMTEuOTIxWk01Ny4wNDMgODEuMjY4MUM1MS44MzM5IDgxLjI2ODEgNDcuNTk2MiA3Ni45OTggNDcuNTk2MiA3MS43NDgyQzQ3LjU5NjIgNjYuNDk4MiA1MS44MzM5IDYyLjIyNzMgNTcuMDQzIDYyLjIyNzNDNjIuMjUxOSA2Mi4yMjczIDY2LjQ4OTUgNjYuNDk4MiA2Ni40ODk1IDcxLjc0ODJDNjYuNDg5NSA3Ni45OTggNjIuMjUxOSA4MS4yNjgxIDU3LjA0MyA4MS4yNjgxWk05MS4wMzA3IDk4LjcyMzdDODcuMjk1OCA5OC43MjM3IDg0LjI1OCA5NS42NjA3IDg0LjI1OCA5MS44OTc1Qzg0LjI1OCA4OC4xMzQzIDg3LjI5NTggODUuMDcxNiA5MS4wMzA3IDg1LjA3MTZDOTQuNzY1NiA4NS4wNzE2IDk3LjgwMzQgODguMTM0MyA5Ny44MDM0IDkxLjg5NzVDOTcuODAzNCA5NS42NjA3IDk0Ljc2NTYgOTguNzIzNyA5MS4wMzA3IDk4LjcyMzdaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4MV8yODIwIiB4MT0iMTQwIiB5MT0iMTMwLjUiIHgyPSI0IiB5Mj0iOS40OTk5OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcC8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzQzNDE0MSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "topics"], ["spec", "kafka"], ["spec", "kafka", "replicas"], ["spec", "kafka", "resources"], ["spec", "kafka", "resourcesPreset"], ["spec", "kafka", "size"], ["spec", "kafka", "storageClass"], ["spec", "zookeeper"], ["spec", "zookeeper", "replicas"], ["spec", "zookeeper", "resources"], ["spec", "zookeeper", "resourcesPreset"], ["spec", "zookeeper", "size"], ["spec", "zookeeper", "storageClass"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`kafka-{{ .name }}-clients-ca`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`kafka-{{ .name }}-kafka-bootstrap`}}" diff --git a/packages/core/platform/psds/kamaji.yaml b/packages/core/platform/psds/kamaji.yaml index d3538c41..915c5898 100644 --- a/packages/core/platform/psds/kamaji.yaml +++ b/packages/core/platform/psds/kamaji.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.kamaji spec: @@ -10,11 +10,12 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: kamaji - path: system/kamaji - releaseName: kamaji - namespace: cozy-kamaji + - name: default + dependsOn: + - cozystack.networking + components: + - name: kamaji + path: system/kamaji + install: + namespace: cozy-kamaji + releaseName: kamaji diff --git a/packages/core/platform/psds/keycloak-operator.yaml b/packages/core/platform/psds/keycloak-operator.yaml index 62a8d31c..0c10921f 100644 --- a/packages/core/platform/psds/keycloak-operator.yaml +++ b/packages/core/platform/psds/keycloak-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.keycloak-operator spec: @@ -10,14 +10,14 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: keycloak-operator - path: system/keycloak-operator - releaseName: keycloak-operator - namespace: cozy-keycloak - dependsOn: - - keycloak - + - name: default + dependsOn: + - cozystack.networking + components: + - name: keycloak-operator + path: system/keycloak-operator + install: + namespace: cozy-keycloak + releaseName: keycloak-operator + dependsOn: + - keycloak diff --git a/packages/core/platform/psds/keycloak.yaml b/packages/core/platform/psds/keycloak.yaml new file mode 100644 index 00000000..a9dc64b4 --- /dev/null +++ b/packages/core/platform/psds/keycloak.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.keycloak +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.postgres-operator + components: + - name: keycloak + path: system/keycloak + install: + namespace: cozy-keycloak + releaseName: keycloak diff --git a/packages/core/platform/psds/kubernetes.yaml b/packages/core/platform/psds/kubernetes.yaml index 48b7c124..350f9750 100644 --- a/packages/core/platform/psds/kubernetes.yaml +++ b/packages/core/platform/psds/kubernetes.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.kubernetes-application spec: @@ -21,16 +21,7 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: kubernetes-application - path: system/kubernetes-application - releaseName: kubernetes-application - namespace: cozy-system - sources: - - name: kubernetes - path: apps/kubernetes - libraries: - - cozy-lib + components: - name: kubernetes-ingress-nginx path: system/ingress-nginx - name: kubernetes-cert-manager-crds @@ -63,4 +54,45 @@ spec: path: system/gpu-operator - name: kubernetes-vertical-pod-autoscaler path: system/vertical-pod-autoscaler - + applications: + - name: kubernetes + path: apps/kubernetes + libraries: + - cozy-lib + template: + spec: + application: + kind: Kubernetes + singular: kubernetes + plural: kuberneteses + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"addons":{"description":"Cluster addons configuration.","type":"object","default":{},"required":["certManager","cilium","coredns","fluxcd","gatewayAPI","gpuOperator","ingressNginx","monitoringAgents","velero","verticalPodAutoscaler"],"properties":{"certManager":{"description":"Cert-manager addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable cert-manager.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"cilium":{"description":"Cilium CNI plugin.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"coredns":{"description":"CoreDNS addon.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"fluxcd":{"description":"FluxCD GitOps operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable FluxCD.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"gatewayAPI":{"description":"Gateway API addon.","type":"object","default":{},"required":["enabled"],"properties":{"enabled":{"description":"Enable Gateway API.","type":"boolean","default":false}}},"gpuOperator":{"description":"NVIDIA GPU Operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable GPU Operator.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"ingressNginx":{"description":"Ingress-NGINX controller.","type":"object","default":{},"required":["enabled","exposeMethod","valuesOverride"],"properties":{"enabled":{"description":"Enable the controller (requires nodes labeled `ingress-nginx`).","type":"boolean","default":false},"exposeMethod":{"description":"Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`.","type":"string","default":"Proxied"},"hosts":{"description":"Domains routed to this tenant cluster when `exposeMethod` is `Proxied`.","type":"array","default":[],"items":{"type":"string"}},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"monitoringAgents":{"description":"Monitoring agents.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable monitoring agents.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"velero":{"description":"Velero backup/restore addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable Velero.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"verticalPodAutoscaler":{"description":"Vertical Pod Autoscaler.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}}}},"controlPlane":{"description":"Kubernetes control-plane configuration.","type":"object","default":{},"required":["apiServer","controllerManager","konnectivity","replicas","scheduler"],"properties":{"apiServer":{"description":"API Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for API Server.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"medium","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"controllerManager":{"description":"Controller Manager configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Controller Manager.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"konnectivity":{"description":"Konnectivity configuration.","type":"object","default":{},"required":["server"],"properties":{"server":{"description":"Konnectivity Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Konnectivity.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"replicas":{"description":"Number of control-plane replicas.","type":"integer","default":2},"scheduler":{"description":"Scheduler configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Scheduler.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"host":{"description":"External hostname for Kubernetes cluster. Defaults to `.` if empty.","type":"string","default":""},"nodeGroups":{"description":"Worker nodes configuration map.","type":"object","default":{"md0":{"ephemeralStorage":"20Gi","gpus":[],"instanceType":"u1.medium","maxReplicas":10,"minReplicas":0,"resources":{},"roles":["ingress-nginx"]}},"additionalProperties":{"type":"object","required":["ephemeralStorage","instanceType","maxReplicas","minReplicas","resources"],"properties":{"ephemeralStorage":{"description":"Ephemeral storage size.","default":"20Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"description":"Name of GPU, such as \"nvidia.com/AD102GL_L40S\".","type":"string"}}}},"instanceType":{"description":"Virtual machine instance type.","type":"string","default":"u1.medium"},"maxReplicas":{"description":"Maximum number of replicas.","type":"integer","default":10},"minReplicas":{"description":"Minimum number of replicas.","type":"integer","default":0},"resources":{"description":"CPU and memory resources for each worker node.","type":"object","properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"roles":{"description":"List of node roles.","type":"array","items":{"type":"string"}}}}},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"},"version":{"description":"Kubernetes version (vMAJOR.MINOR). Supported: 1.28–1.33.","type":"string","default":"v1.33","enum":["v1.28","v1.29","v1.30","v1.31","v1.32","v1.33"]}}} + release: + prefix: kubernetes- + labels: + cozystack.io/ui: "true" + dashboard: + category: IaaS + singular: Kubernetes + plural: Kubernetes + weight: 40 + description: Managed Kubernetes service + tags: + - compute + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjg0NSkiLz4KPHBhdGggZD0iTTcxLjk5NjggMTlDNzAuMzAzOSAxOS4wMDAyIDY4LjkzMTIgMjAuNTMyMiA2OC45MzE0IDIyLjQyMjFDNjguOTMxNCAyMi40NTExIDY4LjkzNzMgMjIuNDc4OCA2OC45Mzc5IDIyLjUwNzZDNjguOTM1NCAyMi43NjQ0IDY4LjkyMzEgMjMuMDczNyA2OC45MzE0IDIzLjI5NzNDNjguOTcxNyAyNC4zODczIDY5LjIwODIgMjUuMjIxNiA2OS4zNTA2IDI2LjIyNThDNjkuNjA4NCAyOC4zNzUyIDY5LjgyNDUgMzAuMTU2OSA2OS42OTEyIDMxLjgxM0M2OS41NjE1IDMyLjQzNzUgNjkuMTAzNyAzMy4wMDg2IDY4LjY5NTYgMzMuNDA1Nkw2OC42MjM1IDM0LjcwODZDNjYuNzgzOSAzNC44NjE3IDY0LjkzMTkgMzUuMTQyMSA2My4wODIxIDM1LjU2NDFDNTUuMTIyNiAzNy4zNzk4IDQ4LjI2OTUgNDEuNDk5MSA0My4wNTIgNDcuMDYwOUM0Mi43MTM0IDQ2LjgyODggNDIuMTIxMSA0Ni40MDE5IDQxLjk0NSA0Ni4yNzEyQzQxLjM5NzcgNDYuMzQ1NCA0MC44NDQ1IDQ2LjUxNTEgNDAuMTI0MSA0Ni4wOTM1QzM4Ljc1MjIgNDUuMTY1NyAzNy41MDI4IDQzLjg4NTEgMzUuOTkxIDQyLjM0MjRDMzUuMjk4MiA0MS42MDQ0IDM0Ljc5NjYgNDAuOTAxOCAzMy45NzM1IDQwLjE5MDRDMzMuNzg2NiA0MC4wMjg5IDMzLjUwMTQgMzkuODEwNCAzMy4yOTIzIDM5LjY0NDJDMzIuNjQ4OSAzOS4xMjg4IDMxLjg5IDM4Ljg2IDMxLjE1NyAzOC44MzQ4QzMwLjIxNDcgMzguODAyNCAyOS4zMDc1IDM5LjE3MjUgMjguNzEzOCAzOS45MjA2QzI3LjY1ODQgNDEuMjUwNiAyNy45OTYzIDQzLjI4MzMgMjkuNDY3MSA0NC40NjE0QzI5LjQ4MiA0NC40NzM0IDI5LjQ5NzkgNDQuNDgyNyAyOS41MTI5IDQ0LjQ5NDNDMjkuNzE1IDQ0LjY1ODkgMjkuOTYyNSA0NC44Njk4IDMwLjE0ODMgNDUuMDA3NkMzMS4wMjE3IDQ1LjY1NTUgMzEuODE5NSA0NS45ODcyIDMyLjY4OTcgNDYuNTAxNUMzNC41MjMxIDQ3LjYzOTEgMzYuMDQzIDQ4LjU4MjMgMzcuMjQ4NiA0OS43MTk2QzM3LjcxOTQgNTAuMjIzNyAzNy44MDE2IDUxLjExMjIgMzcuODY0MyA1MS40OTY0TDM4Ljg0NjggNTIuMzc4MkMzMy41ODcyIDYwLjMzMDggMzEuMTUzIDcwLjE1MzkgMzIuNTkxNSA4MC4xNjI3TDMxLjMwNzcgODAuNTM3OEMzMC45NjkzIDgwLjk3NjggMzAuNDkxMiA4MS42Njc2IDI5Ljk5MTEgODEuODczOEMyOC40MTM4IDgyLjM3MjkgMjYuNjM4NyA4Mi41NTYyIDI0LjQ5NTYgODIuNzgxOUMyMy40ODk0IDgyLjg2NiAyMi42MjEzIDgyLjgxNTggMjEuNTU0NiA4My4wMTg4QzIxLjMxOTggODMuMDYzNSAyMC45OTI3IDgzLjE0OTEgMjAuNzM1OCA4My4yMDk3QzIwLjcyNjkgODMuMjExNiAyMC43MTg2IDgzLjIxNDIgMjAuNzA5NiA4My4yMTYyQzIwLjY5NTYgODMuMjE5NSAyMC42NzcyIDgzLjIyNjMgMjAuNjYzOCA4My4yMjk0QzE4Ljg1NyA4My42NjggMTcuNjk2MyA4NS4zMzY1IDE4LjA2OTkgODYuOTgwNUMxOC40NDM3IDg4LjYyNDggMjAuMjA4NiA4OS42MjQ4IDIyLjAyNjIgODkuMjMxMkMyMi4wMzkzIDg5LjIyODIgMjIuMDU4NCA4OS4yMjc3IDIyLjA3MiA4OS4yMjQ2QzIyLjA5MjYgODkuMjE5OSAyMi4xMTA2IDg5LjIwOTkgMjIuMTMxIDg5LjIwNDlDMjIuMzg0NCA4OS4xNDkgMjIuNzAxOSA4OS4wODY4IDIyLjkyMzYgODkuMDI3MkMyMy45NzIzIDg4Ljc0NTEgMjQuNzMxOCA4OC4zMzA2IDI1LjY3NDYgODcuOTY3N0MyNy43MDI5IDg3LjIzNjggMjkuMzgyOCA4Ni42MjYyIDMxLjAxOTUgODYuMzg4M0MzMS43MDMgODYuMzM0NSAzMi40MjMyIDg2LjgxMiAzMi43ODE0IDg3LjAxMzRMMzQuMTE3NyA4Ni43ODMxQzM3LjE5MjYgOTYuMzYxMyA0My42MzY2IDEwNC4xMDMgNTEuNzk2MyAxMDguOTYxTDUxLjIzOTYgMTEwLjMwM0M1MS40NDAzIDExMC44MjQgNTEuNjYxNiAxMTEuNTMgNTEuNTEyMSAxMTIuMDQ1QzUwLjkxNzEgMTEzLjU5NSA0OS44OTggMTE1LjIzMSA0OC43Mzc0IDExNy4wNTVDNDguMTc1NSAxMTcuODk4IDQ3LjYwMDQgMTE4LjU1MiA0Ny4wOTM0IDExOS41MTZDNDYuOTcyIDExOS43NDcgNDYuODE3NSAxMjAuMTAyIDQ2LjcwMDQgMTIwLjM0NkM0NS45MTI1IDEyMi4wMzkgNDYuNDkwNCAxMjMuOTkgNDguMDAzOCAxMjQuNzIyQzQ5LjUyNjggMTI1LjQ1OSA1MS40MTcxIDEyNC42ODIgNTIuMjM1MiAxMjIuOTg1QzUyLjIzNjQgMTIyLjk4MiA1Mi4yNDA2IDEyMi45OCA1Mi4yNDE3IDEyMi45NzhDNTIuMjQyNiAxMjIuOTc2IDUyLjI0MDkgMTIyLjk3MyA1Mi4yNDE3IDEyMi45NzFDNTIuMzU4MiAxMjIuNzMxIDUyLjUyMzMgMTIyLjQxNSA1Mi42MjE2IDEyMi4xODhDNTMuMDU2IDEyMS4xODkgNTMuMjAwNSAxMjAuMzMyIDUzLjUwNTkgMTE5LjM2NUM1NC4zMTcgMTE3LjMxOCA1NC43NjI2IDExNS4xNyA1NS44NzkxIDExMy44MzJDNTYuMTg0OSAxMTMuNDY2IDU2LjY4MzMgMTEzLjMyNSA1Ny4yMDAxIDExMy4xODZMNTcuODk0NCAxMTEuOTIyQzY1LjAwOCAxMTQuNjY1IDcyLjk3MDUgMTE1LjQwMiA4MC45MjQ1IDExMy41ODdDODIuNzM5MSAxMTMuMTczIDg0LjQ5MDggMTEyLjYzNyA4Ni4xODQzIDExMS45OTRDODYuMzc5NCAxMTIuMzQyIDg2Ljc0MiAxMTMuMDExIDg2LjgzOTMgMTEzLjE3OUM4Ny4zNjQ0IDExMy4zNTEgODcuOTM3NyAxMTMuNDM5IDg4LjQwNDcgMTE0LjEzM0M4OS4yNDAxIDExNS41NjcgODkuODExNCAxMTcuMjYzIDkwLjUwNzMgMTE5LjMxMkM5MC44MTI4IDEyMC4yNzkgOTAuOTYzOCAxMjEuMTM2IDkxLjM5ODEgMTIyLjEzNkM5MS40OTcxIDEyMi4zNjMgOTEuNjYxNCAxMjIuNjg0IDkxLjc3OCAxMjIuOTI1QzkyLjU5NDQgMTI0LjYyOCA5NC40OTA3IDEyNS40MDcgOTYuMDE1OSAxMjQuNjY5Qzk3LjUyOTIgMTIzLjkzNyA5OC4xMDc3IDEyMS45ODYgOTcuMzE5NCAxMjAuMjkzQzk3LjIwMjMgMTIwLjA0OSA5Ny4wNDEyIDExOS42OTUgOTYuOTE5OCAxMTkuNDY0Qzk2LjQxMjcgMTE4LjQ5OSA5NS44Mzc3IDExNy44NTIgOTUuMjc1OCAxMTcuMDA5Qzk0LjExNTIgMTE1LjE4NSA5My4xNTI2IDExMy42NyA5Mi41NTc1IDExMi4xMkM5Mi4zMDg3IDExMS4zMiA5Mi41OTk1IDExMC44MjMgOTIuNzkzMyAxMTAuMzAzQzkyLjY3NzIgMTEwLjE3IDkyLjQyODggMTA5LjQxNCA5Mi4yODI0IDEwOS4wNTlDMTAwLjc2MiAxMDQuMDI5IDEwNy4wMTcgOTUuOTk4NSAxMDkuOTU1IDg2LjcyMzlDMTEwLjM1MSA4Ni43ODY1IDExMS4wNDEgODYuOTA5MSAxMTEuMjY1IDg2Ljk1NDJDMTExLjcyNiA4Ni42NDg3IDExMi4xNDkgODYuMjUwMSAxMTIuOTgxIDg2LjMxNTlDMTE0LjYxNyA4Ni41NTM3IDExNi4yOTcgODcuMTY0NSAxMTguMzI2IDg3Ljg5NTNDMTE5LjI2OCA4OC4yNTgxIDEyMC4wMjggODguNjc5MyAxMjEuMDc3IDg4Ljk2MTRDMTIxLjI5OCA4OS4wMjEgMTIxLjYxNiA4OS4wNzY2IDEyMS44NjkgODkuMTMyNUMxMjEuODg5IDg5LjEzNzUgMTIxLjkwOCA4OS4xNDc1IDEyMS45MjggODkuMTUyMkMxMjEuOTQyIDg5LjE1NTMgMTIxLjk2MSA4OS4xNTU4IDEyMS45NzQgODkuMTU4OEMxMjMuNzkyIDg5LjU1MiAxMjUuNTU3IDg4LjU1MjYgMTI1LjkzIDg2LjkwODFDMTI2LjMwMyA4NS4yNjQxIDEyNS4xNDMgODMuNTk1MiAxMjMuMzM2IDgzLjE1N0MxMjMuMDc0IDgzLjA5NyAxMjIuNzAxIDgyLjk5NSAxMjIuNDQ2IDgyLjk0NjVDMTIxLjM3OSA4Mi43NDM1IDEyMC41MTEgODIuNzkzNSAxMTkuNTA1IDgyLjcwOTVDMTE3LjM2MSA4Mi40ODM5IDExNS41ODYgODIuMzAwNCAxMTQuMDA5IDgxLjgwMTRDMTEzLjM2NiA4MS41NTA3IDExMi45MDggODAuNzgxOSAxMTIuNjg2IDgwLjQ2NTVMMTExLjQ0OCA4MC4xMDM1QzExMi4wOSA3NS40MzggMTExLjkxNyA3MC41ODI1IDExMC44MDYgNjUuNzI0M0MxMDkuNjg1IDYwLjgyMDggMTA3LjcwNCA1Ni4zMzYxIDEwNS4wNjIgNTIuMzg0OEMxMDUuMzc5IDUyLjA5NDggMTA1Ljk3OSA1MS41NjEyIDEwNi4xNDkgNTEuNDA0M0MxMDYuMTk5IDUwLjg1MTcgMTA2LjE1NiA1MC4yNzIyIDEwNi43MjUgNDkuNjYwM0MxMDcuOTMxIDQ4LjUyMyAxMDkuNDUxIDQ3LjU3OTkgMTExLjI4NCA0Ni40NDIzQzExMi4xNTQgNDUuOTI3OSAxMTIuOTU5IDQ1LjU5NjQgMTEzLjgzMiA0NC45NDg0QzExNC4wMyA0NC44MDE5IDExNC4yOTkgNDQuNTY5OSAxMTQuNTA3IDQ0LjQwMjJDMTE1Ljk3NyA0My4yMjM3IDExNi4zMTYgNDEuMTkxMSAxMTUuMjYgMzkuODYxNEMxMTQuMjA0IDM4LjUzMTcgMTEyLjE1OSAzOC40MDY1IDExMC42ODggMzkuNTg1QzExMC40NzkgMzkuNzUxNiAxMTAuMTk1IDM5Ljk2ODggMTEwLjAwNyA0MC4xMzEyQzEwOS4xODQgNDAuODQyNiAxMDguNjc2IDQxLjU0NTIgMTA3Ljk4MyA0Mi4yODMyQzEwNi40NzEgNDMuODI1OSAxMDUuMjIyIDQ1LjExMyAxMDMuODUgNDYuMDQwOUMxMDMuMjU1IDQ2LjM4ODUgMTAyLjM4NSA0Ni4yNjgyIDEwMS45OSA0Ni4yNDQ5TDEwMC44MjQgNDcuMDgwNkM5NC4xNzUzIDQwLjA3NjMgODUuMTIzNSAzNS41OTgyIDc1LjM3NjYgMzQuNzI4M0M3NS4zNDk0IDM0LjMxNzkgNzUuMzEzNyAzMy41NzYxIDc1LjMwNDYgMzMuMzUyOUM3NC45MDU2IDMyLjk2OTMgNzQuNDIzNSAzMi42NDE4IDc0LjMwMjQgMzEuODEzQzc0LjE2OTEgMzAuMTU2OSA3NC4zOTE3IDI4LjM3NTIgNzQuNjQ5NiAyNi4yMjU4Qzc0Ljc5MTkgMjUuMjIxNiA3NS4wMjg0IDI0LjM4NzMgNzUuMDY4OCAyMy4yOTczQzc1LjA3OCAyMy4wNDk1IDc1LjA2MzIgMjIuNjkgNzUuMDYyMiAyMi40MjIxQzc1LjA2MiAyMC41MzIyIDczLjY4OTggMTguOTk5OCA3MS45OTY4IDE5Wk02OC4xNTg1IDQyLjg4ODZMNjcuMjQ4IDU5LjA0NDdMNjcuMTgyNSA1OS4wNzc2QzY3LjEyMTQgNjAuNTIyOSA2NS45Mzc1IDYxLjY3NyA2NC40ODM5IDYxLjY3N0M2My44ODg0IDYxLjY3NyA2My4zMzg4IDYxLjQ4NDkgNjIuODkyMiA2MS4xNTcxTDYyLjg2NiA2MS4xNzAzTDQ5LjY4MDcgNTEuNzc5NEM1My43MzMxIDQ3Ljc3NTkgNTguOTE2NCA0NC44MTcyIDY0Ljg5IDQzLjQ1NDZDNjUuOTgxMiA0My4yMDU2IDY3LjA3MTkgNDMuMDIwOSA2OC4xNTg1IDQyLjg4ODZaTTc1Ljg0MTcgNDIuODg4NkM4Mi44MTU5IDQzLjc1MDQgODkuMjY1NyA0Ni45MjMyIDk0LjIwODEgNTEuNzg2TDgxLjEwOCA2MS4xMTc2TDgxLjA2MjEgNjEuMDk3OUM3OS44OTk0IDYxLjk1MTIgNzguMjYxMSA2MS43Mzk0IDc3LjM1NDggNjAuNTk3OEM3Ni45ODM1IDYwLjEzMDEgNzYuNzg4NyA1OS41ODAxIDc2Ljc2NTMgNTkuMDI0OUw3Ni43NTIyIDU5LjAxODRMNzUuODQxNyA0Mi44ODg2Wk00NC44OTkxIDU3LjgxNEw1Ni45MzgyIDY4LjYzM0w1Ni45MjUxIDY4LjY5ODhDNTguMDExNyA2OS42NDc5IDU4LjE3MiA3MS4yOTQ5IDU3LjI2NTcgNzIuNDM2OEM1Ni44OTQ0IDcyLjkwNDUgNTYuMzk3NSA3My4yMTgyIDU1Ljg2MzkgNzMuMzY0N0w1NS44NTA4IDczLjQxNzNMNDAuNDE4OCA3Ny44OTIzQzM5LjYzMzQgNzAuNjc2NSA0MS4zMjYxIDYzLjY2MjEgNDQuODk5MSA1Ny44MTRaTTk5LjAwOTQgNTcuODIwNkMxMDAuNzk4IDYwLjczMzYgMTAyLjE1MyA2My45ODcxIDEwMi45NTkgNjcuNTE0M0MxMDMuNzU2IDcwLjk5OTEgMTAzLjk1NiA3NC40Nzc4IDEwMy42MjcgNzcuODM5N0w4OC4xMTY2IDczLjM1MTVMODguMTAzNSA3My4yODU3Qzg2LjcxNDUgNzIuOTA0MyA4NS44NjA5IDcxLjQ4NDggODYuMTg0MyA3MC4wNjExQzg2LjMxNjggNjkuNDc3OCA4Ni42MjQ5IDY4Ljk4NDQgODcuMDQyMyA2OC42MTk4TDg3LjAzNTggNjguNTg2OUw5OS4wMDk0IDU3LjgyMDZaTTY5LjUyNzQgNjkuNDY4OEg3NC40NTk2TDc3LjUyNTEgNzMuMzE4Nkw3Ni40MjQ3IDc4LjEyMjZMNzEuOTk2OCA4MC4yNjE0TDY3LjU1NTggNzguMTE2MUw2Ni40NTU0IDczLjMxMkw2OS41Mjc0IDY5LjQ2ODhaTTg1LjMzOTMgODIuNjQzN0M4NS41NDg5IDgyLjYzMzEgODUuNzU3NiA4Mi42NTIgODUuOTYxNiA4Mi42ODk4TDg1Ljk4NzggODIuNjU2OUwxMDEuOTUgODUuMzY4MkM5OS42MTQyIDkxLjk2MjQgOTUuMTQ0IDk3LjY3NSA4OS4xNzExIDEwMS40OThMODIuOTc0NyA4Ni40NjA2TDgyLjk5NDQgODYuNDM0M0M4Mi40MjUyIDg1LjEwNTUgODIuOTk0OCA4My41NDcyIDg0LjMwNDQgODIuOTEzNUM4NC42Mzk3IDgyLjc1MTMgODQuOTkgODIuNjYxNCA4NS4zMzkzIDgyLjY0MzdaTTU4LjUyOTggODIuNzA5NUM1OS43NDggODIuNzI2NyA2MC44NDA2IDgzLjU3NjEgNjEuMTIzNyA4NC44MjJDNjEuMjU2MiA4NS40MDUyIDYxLjE5MTcgODUuOTgzMSA2MC45NzMgODYuNDkzNUw2MS4wMTg5IDg2LjU1MjdMNTQuODg4IDEwMS40MzlDNDkuMTU1OSA5Ny43NDMyIDQ0LjU5MDQgOTIuMjA5OSA0Mi4xNDgxIDg1LjQyMDhMNTcuOTczMSA4Mi43MjI3TDU3Ljk5OTMgODIuNzU1NkM1OC4xNzYzIDgyLjcyMjkgNTguMzU1OCA4Mi43MDcxIDU4LjUyOTggODIuNzA5NVpNNzEuODk4NiA4OS4yMzEyQzcyLjMyMjkgODkuMjE1NSA3Mi43NTM0IDg5LjMwMyA3My4xNjI3IDg5LjUwMUM3My42OTkyIDg5Ljc2MDYgNzQuMTEzNiA5MC4xNjkyIDc0LjM3NDUgOTAuNjU5Mkg3NC40MzM0TDgyLjIzNDYgMTA0LjgyMUM4MS4yMjIxIDEwNS4xNjIgODAuMTgxMyAxMDUuNDU0IDc5LjExNjcgMTA1LjY5N0M3My4xNTA1IDEwNy4wNTggNjcuMjAzMiAxMDYuNjQ1IDYxLjgxOCAxMDQuODAyTDY5LjU5OTUgOTAuNjY1OEg2OS42MTI2QzcwLjA3OTUgODkuNzg4OCA3MC45NjUgODkuMjY1NiA3MS44OTg2IDg5LjIzMTJaIiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjI1Ii8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgxXzI4NDUiIHgxPSIxMCIgeTE9IjE1LjUiIHgyPSIxNDQiIHkyPSIxMzEuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNEQ4N0ZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzA1NDdEMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "storageClass"], ["spec", "nodeGroups"], ["spec", "nodeGroups", "md0"], ["spec", "nodeGroups", "md0", "minReplicas"], ["spec", "nodeGroups", "md0", "maxReplicas"], ["spec", "nodeGroups", "md0", "instanceType"], ["spec", "nodeGroups", "md0", "ephemeralStorage"], ["spec", "nodeGroups", "md0", "roles"], ["spec", "nodeGroups", "md0", "resources"], ["spec", "nodeGroups", "md0", "gpus"], ["spec", "version"], ["spec", "host"], ["spec", "addons"], ["spec", "addons", "certManager"], ["spec", "addons", "certManager", "enabled"], ["spec", "addons", "certManager", "valuesOverride"], ["spec", "addons", "cilium"], ["spec", "addons", "cilium", "valuesOverride"], ["spec", "addons", "gatewayAPI"], ["spec", "addons", "gatewayAPI", "enabled"], ["spec", "addons", "ingressNginx"], ["spec", "addons", "ingressNginx", "enabled"], ["spec", "addons", "ingressNginx", "exposeMethod"], ["spec", "addons", "ingressNginx", "hosts"], ["spec", "addons", "ingressNginx", "valuesOverride"], ["spec", "addons", "gpuOperator"], ["spec", "addons", "gpuOperator", "enabled"], ["spec", "addons", "gpuOperator", "valuesOverride"], ["spec", "addons", "fluxcd"], ["spec", "addons", "fluxcd", "enabled"], ["spec", "addons", "fluxcd", "valuesOverride"], ["spec", "addons", "monitoringAgents"], ["spec", "addons", "monitoringAgents", "enabled"], ["spec", "addons", "monitoringAgents", "valuesOverride"], ["spec", "addons", "verticalPodAutoscaler"], ["spec", "addons", "verticalPodAutoscaler", "valuesOverride"], ["spec", "addons", "velero"], ["spec", "addons", "velero", "enabled"], ["spec", "addons", "velero", "valuesOverride"], ["spec", "addons", "coredns"], ["spec", "addons", "coredns", "valuesOverride"], ["spec", "controlPlane"], ["spec", "controlPlane", "replicas"], ["spec", "controlPlane", "apiServer"], ["spec", "controlPlane", "apiServer", "resources"], ["spec", "controlPlane", "apiServer", "resourcesPreset"], ["spec", "controlPlane", "controllerManager"], ["spec", "controlPlane", "controllerManager", "resources"], ["spec", "controlPlane", "controllerManager", "resourcesPreset"], ["spec", "controlPlane", "scheduler"], ["spec", "controlPlane", "scheduler", "resources"], ["spec", "controlPlane", "scheduler", "resourcesPreset"], ["spec", "controlPlane", "konnectivity"], ["spec", "controlPlane", "konnectivity", "server"], ["spec", "controlPlane", "konnectivity", "server", "resources"], ["spec", "controlPlane", "konnectivity", "server", "resourcesPreset"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`kubernetes-{{ .name }}-admin-kubeconfig`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`kubernetes-{{ .name }}`}}" + ingresses: + exclude: [] + include: + - resourceNames: + - "{{`kubernetes-{{ .name }}`}}" diff --git a/packages/core/platform/psds/kubevirt-cdi.yaml b/packages/core/platform/psds/kubevirt-cdi.yaml index 9afb0c73..bd925c0d 100644 --- a/packages/core/platform/psds/kubevirt-cdi.yaml +++ b/packages/core/platform/psds/kubevirt-cdi.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.kubevirt-cdi spec: @@ -10,18 +10,19 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: kubevirt-cdi-operator - path: system/kubevirt-cdi-operator - releaseName: kubevirt-cdi-operator - namespace: cozy-kubevirt-cdi - - name: kubevirt-cdi - path: system/kubevirt-cdi - releaseName: kubevirt-cdi - namespace: cozy-kubevirt-cdi - dependsOn: - - kubevirt-cdi-operator - + - name: default + dependsOn: + - cozystack.networking + components: + - name: kubevirt-cdi-operator + path: system/kubevirt-cdi-operator + install: + namespace: cozy-kubevirt-cdi + releaseName: kubevirt-cdi-operator + - name: kubevirt-cdi + path: system/kubevirt-cdi + install: + namespace: cozy-kubevirt-cdi + releaseName: kubevirt-cdi + dependsOn: + - kubevirt-cdi-operator diff --git a/packages/core/platform/psds/kubevirt.yaml b/packages/core/platform/psds/kubevirt.yaml index b070c5ba..d8ebce0f 100644 --- a/packages/core/platform/psds/kubevirt.yaml +++ b/packages/core/platform/psds/kubevirt.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.kubevirt spec: @@ -10,29 +10,31 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.monitoring - packages: - - name: kubevirt-operator - path: system/kubevirt-operator - releaseName: kubevirt-operator - namespace: cozy-kubevirt - dependsOn: - - victoria-metrics-operator - - name: kubevirt - path: system/kubevirt - releaseName: kubevirt - namespace: cozy-kubevirt - privileged: true - dependsOn: - - kubevirt-operator - - name: kubevirt-instancetypes - path: system/kubevirt-instancetypes - releaseName: kubevirt-instancetypes - namespace: cozy-kubevirt - dependsOn: - - kubevirt-operator - - kubevirt - + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + components: + - name: kubevirt-operator + path: system/kubevirt-operator + install: + namespace: cozy-kubevirt + releaseName: kubevirt-operator + dependsOn: + - victoria-metrics-operator + - name: kubevirt + path: system/kubevirt + install: + privileged: true + namespace: cozy-kubevirt + releaseName: kubevirt + dependsOn: + - kubevirt-operator + - name: kubevirt-instancetypes + path: system/kubevirt-instancetypes + install: + namespace: cozy-kubevirt + releaseName: kubevirt-instancetypes + dependsOn: + - kubevirt-operator + - kubevirt diff --git a/packages/core/platform/psds/linstor.yaml b/packages/core/platform/psds/linstor.yaml index b60e03a8..32288cab 100644 --- a/packages/core/platform/psds/linstor.yaml +++ b/packages/core/platform/psds/linstor.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.linstor spec: @@ -10,27 +10,28 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.cert-manager - - cozystack.monitoring - - cozystack.reloader - packages: - - name: piraeus-operator - path: system/piraeus-operator - releaseName: piraeus-operator - namespace: cozy-linstor - dependsOn: - - cert-manager - - victoria-metrics-operator - - name: linstor - path: system/linstor - releaseName: linstor - namespace: cozy-linstor - privileged: true - dependsOn: - - piraeus-operator - - cert-manager - - snapshot-controller - + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + - cozystack.monitoring + - cozystack.reloader + components: + - name: piraeus-operator + path: system/piraeus-operator + install: + namespace: cozy-linstor + releaseName: piraeus-operator + dependsOn: + - cert-manager + - victoria-metrics-operator + - name: linstor + path: system/linstor + install: + privileged: true + namespace: cozy-linstor + releaseName: linstor + dependsOn: + - piraeus-operator + - cert-manager + - snapshot-controller diff --git a/packages/core/platform/psds/mariadb-operator.yaml b/packages/core/platform/psds/mariadb-operator.yaml index d1366cba..fe509e7c 100644 --- a/packages/core/platform/psds/mariadb-operator.yaml +++ b/packages/core/platform/psds/mariadb-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.mariadb-operator spec: @@ -10,17 +10,17 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.monitoring - - cozystack.cert-manager - packages: - - name: mariadb-operator - path: system/mariadb-operator - releaseName: mariadb-operator - namespace: cozy-mariadb-operator - dependsOn: - - cert-manager - - victoria-metrics-operator - + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + - cozystack.cert-manager + components: + - name: mariadb-operator + path: system/mariadb-operator + install: + namespace: cozy-mariadb-operator + releaseName: mariadb-operator + dependsOn: + - cert-manager + - victoria-metrics-operator diff --git a/packages/core/platform/psds/metallb.yaml b/packages/core/platform/psds/metallb.yaml index f7f5a240..e1a09886 100644 --- a/packages/core/platform/psds/metallb.yaml +++ b/packages/core/platform/psds/metallb.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.metallb spec: @@ -10,12 +10,13 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: metallb - path: system/metallb - releaseName: metallb - namespace: cozy-metallb - privileged: true + - name: default + dependsOn: + - cozystack.networking + components: + - name: metallb + path: system/metallb + install: + privileged: true + namespace: cozy-metallb + releaseName: metallb diff --git a/packages/core/platform/psds/monitoring-agents.yaml b/packages/core/platform/psds/monitoring-agents.yaml index d29831b9..75832fd3 100644 --- a/packages/core/platform/psds/monitoring-agents.yaml +++ b/packages/core/platform/psds/monitoring-agents.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.monitoring-agents spec: @@ -14,13 +14,13 @@ spec: dependsOn: - cozystack.networking - cozystack.monitoring - packages: + - cozystack.goldpinger + - cozystack.victoria-metrics-operator + - cozystack.vertical-pod-autoscaler + components: - name: monitoring-agents path: system/monitoring-agents - releaseName: monitoring-agents - namespace: cozy-monitoring - privileged: true - dependsOn: - - victoria-metrics-operator - - vertical-pod-autoscaler-crds - + install: + releaseName: monitoring-agents + namespace: cozy-monitoring + privileged: true diff --git a/packages/core/platform/psds/monitoring.yaml b/packages/core/platform/psds/monitoring.yaml index a34b9f94..6958bb6a 100644 --- a/packages/core/platform/psds/monitoring.yaml +++ b/packages/core/platform/psds/monitoring.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.monitoring-application spec: @@ -16,14 +16,48 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: monitoring-application - path: system/monitoring-application - releaseName: monitoring-application - namespace: cozy-system - sources: + components: [] + applications: - name: monitoring path: extra/monitoring libraries: - cozy-lib - + template: + spec: + application: + kind: Monitoring + singular: monitoring + plural: monitorings + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"alerta":{"description":"Configuration for the Alerta service.","type":"object","default":{},"properties":{"alerts":{"description":"Alert routing configuration.","type":"object","default":{},"properties":{"slack":{"description":"Configuration for Slack alerts.","type":"object","default":{},"required":["url"],"properties":{"url":{"description":"Configuration uri for Slack alerts.","type":"string","default":""}}},"telegram":{"description":"Configuration for Telegram alerts.","type":"object","default":{},"required":["chatID","token"],"properties":{"chatID":{"description":"Telegram chat ID(s), separated by commas.","type":"string","default":""},"disabledSeverity":{"description":"List of severities without alerts (e.g. \"informational,warning\").","type":"string","default":""},"token":{"description":"Telegram bot token.","type":"string","default":""}}}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"storage":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the database.","type":"string","default":""}}},"grafana":{"description":"Configuration for Grafana.","type":"object","default":{},"properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"size":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}},"host":{"description":"The hostname used to access Grafana externally (defaults to 'grafana' subdomain for the tenant host).","type":"string","default":""},"logsStorages":{"description":"Configuration of logs storage instances.","type":"array","default":[{"name":"generic","retentionPeriod":"1","storage":"10Gi","storageClassName":"replicated"}],"items":{"type":"object","required":["name","retentionPeriod","storage","storageClassName"],"properties":{"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for logs.","type":"string","default":"1"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}},"metricsStorages":{"description":"Configuration of metrics storage instances.","type":"array","default":[{"deduplicationInterval":"15s","name":"shortterm","retentionPeriod":"3d","storage":"10Gi","storageClassName":""},{"deduplicationInterval":"5m","name":"longterm","retentionPeriod":"14d","storage":"10Gi","storageClassName":""}],"items":{"type":"object","required":["deduplicationInterval","name","retentionPeriod","storage"],"properties":{"deduplicationInterval":{"description":"Deduplication interval for metrics.","type":"string"},"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for metrics.","type":"string"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the data.","type":"string"},"vminsert":{"description":"Configuration for vminsert.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmselect":{"description":"Configuration for vmselect.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmstorage":{"description":"Configuration for vmstorage.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}}}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + dashboard: + category: Administration + singular: Monitoring + plural: Monitoring + name: monitoring + description: Monitoring and observability stack + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzI2OCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zMjY4KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMzg0NTRGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNNTQuMTcyMiAzOC43NzU3SDMzLjEwMzJDMzIuMTMwNyAzOC43NzU3IDMxLjQ4MjQgMzguMTI3NCAzMS40ODI0IDM3LjE1NDlDMzEuNDgyNCAzNi4xODI0IDMyLjEzMDcgMzUuNTM0MiAzMy4xMDMyIDM1LjUzNDJINTQuMTcyMkM1NS4xNDQ3IDM1LjUzNDIgNTUuNzkzIDM2LjE4MjQgNTUuNzkzIDM3LjE1NDlDNTUuNzkyOCAzOC4xMjc0IDU1LjE0NDUgMzguNzc1NyA1NC4xNzIyIDM4Ljc3NTdaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik02My44OTYzIDQ1LjI1OTFINDEuMjA2N0M0MC4yMzQyIDQ1LjI1OTEgMzkuNTg1OSA0NC42MTA4IDM5LjU4NTkgNDMuNjM4M0MzOS41ODU5IDQyLjY2NTggNDAuMjM0MiA0Mi4wMTc2IDQxLjIwNjcgNDIuMDE3Nkg2My44OTYzQzY0Ljg2ODggNDIuMDE3NiA2NS41MTcxIDQyLjY2NTggNjUuNTE3MSA0My42MzgzQzY1LjUxNzEgNDQuNjEwOCA2NC44Njg4IDQ1LjI1OTEgNjMuODk2MyA0NS4yNTkxWiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMzQuNzI0IDQ1LjI1OTFIMzMuMTAzMkMzMi4xMzA3IDQ1LjI1OTEgMzEuNDgyNCA0NC42MTA4IDMxLjQ4MjQgNDMuNjM4M0MzMS40ODI0IDQyLjY2NTggMzIuMTMwNyA0Mi4wMTc2IDMzLjEwMzIgNDIuMDE3NkgzNC43MjRDMzUuNjk2NCA0Mi4wMTc2IDM2LjM0NDcgNDIuNjY1OCAzNi4zNDQ3IDQzLjYzODNDMzYuMzQ0NyA0NC42MTA4IDM1LjY5NjMgNDUuMjU5MSAzNC43MjQgNDUuMjU5MVoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgMzguNzc1N0g2MC42NTQ5QzU5LjY4MjQgMzguNzc1NyA1OS4wMzQyIDM4LjEyNzQgNTkuMDM0MiAzNy4xNTQ5QzU5LjAzNDIgMzYuMTgyNCA1OS42ODI0IDM1LjUzNDIgNjAuNjU0OSAzNS41MzQySDYzLjg5NjNDNjQuODY4OCAzNS41MzQyIDY1LjUxNzEgMzYuMTgyNCA2NS41MTcxIDM3LjE1NDlDNjUuNTE3MSAzOC4xMjc0IDY0Ljg2ODggMzguNzc1NyA2My44OTYzIDM4Ljc3NTdaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik00Ny42ODkzIDUxLjc0MTNIMzMuMTAzMkMzMi4xMzA3IDUxLjc0MTMgMzEuNDgyNCA1MS4wOTMxIDMxLjQ4MjQgNTAuMTIwNkMzMS40ODI0IDQ5LjE0ODEgMzIuMTMwNyA0OC41IDMzLjEwMzIgNDguNUg0Ny42ODkzQzQ4LjY2MTggNDguNSA0OS4zMTAxIDQ5LjE0ODMgNDkuMzEwMSA1MC4xMjA4QzQ5LjMxMDEgNTEuMDkzMyA0OC42NjE4IDUxLjc0MTMgNDcuNjg5MyA1MS43NDEzWiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNjMuODk2OCA1MS43NDEzSDU0LjE3MjVDNTMuMiA1MS43NDEzIDUyLjU1MTggNTEuMDkzMSA1Mi41NTE4IDUwLjEyMDZDNTIuNTUxOCA0OS4xNDgxIDUzLjIwMDIgNDguNSA1NC4xNzI3IDQ4LjVINjMuODk2OUM2NC44Njk0IDQ4LjUgNjUuNTE3NyA0OS4xNDgzIDY1LjUxNzcgNTAuMTIwOEM2NS41MTc3IDUxLjA5MzMgNjQuODY5MiA1MS43NDEzIDYzLjg5NjggNTEuNzQxM1oiIGZpbGw9IiNFQ0JBMTYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNTguMjI0SDMzLjEwMzJDMzIuMTMwNyA1OC4yMjQgMzEuNDgyNCA1Ny41NzU3IDMxLjQ4MjQgNTYuNjAzMkMzMS40ODI0IDU1LjYzMDcgMzIuMTMwNyA1NC45ODI0IDMzLjEwMzIgNTQuOTgyNEg1NC4xNzIyQzU1LjE0NDcgNTQuOTgyNCA1NS43OTMgNTUuNjMwNyA1NS43OTMgNTYuNjAzMkM1NS43OTMgNTcuNTc1NyA1NS4xNDQ1IDU4LjIyNCA1NC4xNzIyIDU4LjIyNFoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgNjQuNzA3NEg0MS4yMDY3QzQwLjIzNDIgNjQuNzA3NCAzOS41ODU5IDY0LjA1OTEgMzkuNTg1OSA2My4wODY2QzM5LjU4NTkgNjIuMTE0MSA0MC4yMzQyIDYxLjQ2NTggNDEuMjA2NyA2MS40NjU4SDYzLjg5NjNDNjQuODY4OCA2MS40NjU4IDY1LjUxNzEgNjIuMTE0MSA2NS41MTcxIDYzLjA4NjZDNjUuNTE3MSA2NC4wNTkxIDY0Ljg2ODggNjQuNzA3NCA2My44OTYzIDY0LjcwNzRaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik0zNC43MjQgNjQuNzA3NEgzMy4xMDMyQzMyLjEzMDcgNjQuNzA3NCAzMS40ODI0IDY0LjA1OTEgMzEuNDgyNCA2My4wODY2QzMxLjQ4MjQgNjIuMTE0MSAzMi4xMzA3IDYxLjQ2NTggMzMuMTAzMiA2MS40NjU4SDM0LjcyNEMzNS42OTY0IDYxLjQ2NTggMzYuMzQ0NyA2Mi4xMTQxIDM2LjM0NDcgNjMuMDg2NkMzNi4zNDQ3IDY0LjA1OTEgMzUuNjk2MyA2NC43MDc0IDM0LjcyNCA2NC43MDc0WiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNDcuNjg5MyA3MS4xODk4SDMzLjEwMzJDMzIuMTMwNyA3MS4xODk4IDMxLjQ4MjQgNzAuNTQxNSAzMS40ODI0IDY5LjU2OUMzMS40ODI0IDY4LjU5NjUgMzIuMTMwNyA2Ny45NDgyIDMzLjEwMzIgNjcuOTQ4Mkg0Ny42ODkzQzQ4LjY2MTggNjcuOTQ4MiA0OS4zMTAxIDY4LjU5NjUgNDkuMzEwMSA2OS41NjlDNDkuMzEwMSA3MC41NDE1IDQ4LjY2MTggNzEuMTg5OCA0Ny42ODkzIDcxLjE4OThaIiBmaWxsPSIjNDJCMDVDIi8+CjxwYXRoIGQ9Ik02My44OTY4IDcxLjE4OThINTQuMTcyNUM1My4yIDcxLjE4OTggNTIuNTUxOCA3MC41NDE1IDUyLjU1MTggNjkuNTY5QzUyLjU1MTggNjguNTk2NSA1My4yIDY3Ljk0ODIgNTQuMTcyNSA2Ny45NDgySDYzLjg5NjhDNjQuODY5MiA2Ny45NDgyIDY1LjUxNzUgNjguNTk2NSA2NS41MTc1IDY5LjU2OUM2NS41MTc1IDcwLjU0MTUgNjQuODY5MiA3MS4xODk4IDYzLjg5NjggNzEuMTg5OFoiIGZpbGw9IiM3MzgzQkYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNzcuNjcyMkgzMy4xMDMyQzMyLjEzMDcgNzcuNjcyMiAzMS40ODI0IDc3LjAyMzkgMzEuNDgyNCA3Ni4wNTE0QzMxLjQ4MjQgNzUuMDc4OSAzMi4xMzA3IDc0LjQzMDcgMzMuMTAzMiA3NC40MzA3SDU0LjE3MjJDNTUuMTQ0NyA3NC40MzA3IDU1Ljc5MyA3NS4wNzg5IDU1Ljc5MyA3Ni4wNTE0QzU1Ljc5MjggNzcuMDIzOSA1NS4xNDQ1IDc3LjY3MjIgNTQuMTcyMiA3Ny42NzIyWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNNjMuODk2MyA3Ny42NzIySDYwLjY1NDlDNTkuNjgyNCA3Ny42NzIyIDU5LjAzNDIgNzcuMDIzOSA1OS4wMzQyIDc2LjA1MTRDNTkuMDM0MiA3NS4wNzg5IDU5LjY4MjQgNzQuNDMwNyA2MC42NTQ5IDc0LjQzMDdINjMuODk2M0M2NC44Njg4IDc0LjQzMDcgNjUuNTE3MSA3NS4wNzg5IDY1LjUxNzEgNzYuMDUxNEM2NS41MTcxIDc3LjAyMzkgNjQuODY4OCA3Ny42NzIyIDYzLjg5NjMgNzcuNjcyMloiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTEwMS4xNzIgNzcuNjcyMkg4MC4xMDMyQzc5LjEzMDcgNzcuNjcyMiA3OC40ODI0IDc3LjAyMzkgNzguNDgyNCA3Ni4wNTE0Qzc4LjQ4MjQgNzUuMDc4OSA3OS4xMzA3IDc0LjQzMDcgODAuMTAzMiA3NC40MzA3SDEwMS4xNzJDMTAyLjE0NSA3NC40MzA3IDEwMi43OTMgNzUuMDc4OSAxMDIuNzkzIDc2LjA1MTRDMTAyLjc5MyA3Ny4wMjM5IDEwMi4xNDUgNzcuNjcyMiAxMDEuMTcyIDc3LjY3MjJaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik0xMTAuODk2IDc3LjY3MjJIMTA3LjY1NUMxMDYuNjgyIDc3LjY3MjIgMTA2LjAzNCA3Ny4wMjM5IDEwNi4wMzQgNzYuMDUxNEMxMDYuMDM0IDc1LjA3ODkgMTA2LjY4MiA3NC40MzA3IDEwNy42NTUgNzQuNDMwN0gxMTAuODk2QzExMS44NjkgNzQuNDMwNyAxMTIuNTE3IDc1LjA3ODkgMTEyLjUxNyA3Ni4wNTE0QzExMi41MTcgNzcuMDIzOSAxMTEuODY5IDc3LjY3MjIgMTEwLjg5NiA3Ny42NzIyWiIgZmlsbD0iIzQyQjA1QyIvPgo8cGF0aCBkPSJNNjMuODk2MyA1OC4yMjRINjAuNjU0OUM1OS42ODI0IDU4LjIyNCA1OS4wMzQyIDU3LjU3NTcgNTkuMDM0MiA1Ni42MDMyQzU5LjAzNDIgNTUuNjMwNyA1OS42ODI0IDU0Ljk4MjQgNjAuNjU0OSA1NC45ODI0SDYzLjg5NjNDNjQuODY4OCA1NC45ODI0IDY1LjUxNzEgNTUuNjMwNyA2NS41MTcxIDU2LjYwMzJDNjUuNTE3MSA1Ny41NzU3IDY0Ljg2ODggNTguMjI0IDYzLjg5NjMgNTguMjI0WiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMTEyLjUxNyA1MS43NDExQzExMi41MTcgNjAuNjU0OSAxMDUuMjI0IDY3Ljk0OCA5Ni4zMTA0IDY3Ljk0OEM4Ny4zOTY2IDY3Ljk0OCA4MC4xMDM1IDYwLjY1NDkgODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNDIuODI3MyA4Ny4zOTY2IDM1LjUzNDIgOTYuMzEwNCAzNS41MzQyQzEwNS4yMjQgMzUuNTM0MiAxMTIuNTE3IDQyLjgyNzMgMTEyLjUxNyA1MS43NDExWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNTIuMjI3MyA4MC4xMDM1IDUyLjg3NTUgODAuMTAzNSA1My4zNjE5SDk2LjMxMDRWMzUuNTM0MkM4Ny4zOTY2IDM1LjUzNDIgODAuMTAzNSA0Mi44MjczIDgwLjEwMzUgNTEuNzQxMVoiIGZpbGw9IiM0MkIwNUMiLz4KPC9nPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zMjY4IiB4MT0iMS4yMzIzOWUtMDYiIHkxPSItOS41MDAwMSIgeDI9IjE2OCIgeTI9IjE2MiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjOEZEREZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNzVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zMjY4Ij4KPHJlY3Qgd2lkdGg9Ijk0IiBoZWlnaHQ9Ijk0IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjUgMjUpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "metricsStorages"], ["spec", "logsStorages"], ["spec", "alerta"], ["spec", "alerta", "storage"], ["spec", "alerta", "storageClassName"], ["spec", "alerta", "resources"], ["spec", "alerta", "resources", "limits"], ["spec", "alerta", "resources", "limits", "cpu"], ["spec", "alerta", "resources", "limits", "memory"], ["spec", "alerta", "resources", "requests"], ["spec", "alerta", "resources", "requests", "cpu"], ["spec", "alerta", "resources", "requests", "memory"], ["spec", "alerta", "alerts"], ["spec", "alerta", "alerts", "telegram"], ["spec", "alerta", "alerts", "telegram", "token"], ["spec", "alerta", "alerts", "telegram", "chatID"], ["spec", "alerta", "alerts", "telegram", "disabledSeverity"], ["spec", "alerta", "alerts", "slack"], ["spec", "alerta", "alerts", "slack", "url"], ["spec", "grafana"], ["spec", "grafana", "db"], ["spec", "grafana", "db", "size"], ["spec", "grafana", "resources"], ["spec", "grafana", "resources", "limits"], ["spec", "grafana", "resources", "limits", "cpu"], ["spec", "grafana", "resources", "limits", "memory"], ["spec", "grafana", "resources", "requests"], ["spec", "grafana", "resources", "requests", "cpu"], ["spec", "grafana", "resources", "requests", "memory"]] + secrets: + exclude: [] + include: + - resourceNames: + - grafana-admin-password + services: + exclude: [] + include: + - resourceNames: + - grafana-service + - alerta + ingresses: + exclude: [] + include: + - resourceNames: + - grafana-ingress + - alerta diff --git a/packages/core/platform/psds/multus.yaml b/packages/core/platform/psds/multus.yaml index cfa17e0c..88910e93 100644 --- a/packages/core/platform/psds/multus.yaml +++ b/packages/core/platform/psds/multus.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.multus spec: @@ -10,12 +10,13 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: multus - path: system/multus - releaseName: multus - namespace: cozy-multus - privileged: true + - name: default + dependsOn: + - cozystack.networking + components: + - name: multus + path: system/multus + install: + privileged: true + namespace: cozy-multus + releaseName: multus diff --git a/packages/core/platform/psds/mysql.yaml b/packages/core/platform/psds/mysql.yaml index 2fde3fa7..9a0ff4c7 100644 --- a/packages/core/platform/psds/mysql.yaml +++ b/packages/core/platform/psds/mysql.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.mysql-application spec: @@ -17,14 +17,41 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: mysql-application - path: system/mysql-application - releaseName: mysql-application - namespace: cozy-system - sources: + components: [] + applications: - name: mysql path: apps/mysql libraries: - cozy-lib - + template: + spec: + application: + kind: MySQL + plural: mysqls + singular: mysql + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["cleanupStrategy","enabled","resticPassword","s3AccessKey","s3Bucket","s3Region","s3SecretKey","schedule"],"properties":{"cleanupStrategy":{"description":"Retention strategy for cleaning up old backups.","type":"string","default":"--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"resticPassword":{"description":"Password for Restic backup encryption.","type":"string","default":""},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3Bucket":{"description":"S3 bucket used for storing backups.","type":"string","default":"s3.example.org/mysql-backups"},"s3Region":{"description":"AWS S3 region where backups are stored.","type":"string","default":"us-east-1"},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * *"}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of MariaDB replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each MariaDB replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","required":["maxUserConnections","password"],"properties":{"maxUserConnections":{"description":"Maximum number of connections.","type":"integer"},"password":{"description":"Password for the user.","type":"string"}}}}}} + release: + prefix: mysql- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: MySQL + plural: MySQL + description: Managed MariaDB service + tags: + - database + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5MzApIi8+CjxwYXRoIGQ9Ik0xMzMuMTkxIDI5LjAwMjJDMTMxLjIxMyAyOS4wNjU0IDEzMS44MzkgMjkuNjM1NCAxMjcuNTY0IDMwLjY4NzNDMTIzLjI0OCAzMS43NDk2IDExNy45NzUgMzEuNDIzOSAxMTMuMzI3IDMzLjM3MzNDOTkuNDUxNiAzOS4xOTI0IDk2LjY2NzYgNTkuMDgxMyA4NC4wNTM1IDY2LjIwNTlDNzQuNjI0NyA3MS41MzE4IDY1LjExMiA3MS45NTY1IDU2LjU1OTQgNzQuNjM2NUM1MC45Mzg5IDc2LjM5OSA0NC43OTA2IDgwLjAxMzUgMzkuNjk4MiA4NC40MDE4QzM1Ljc0NTUgODcuODA5MyAzNS42NDIzIDkwLjgwNTQgMzEuNTEyMyA5NS4wNzkxQzI3LjA5NDcgOTkuNjUwNCAxMy45NTUxIDk1LjE1NjQgOCAxMDIuMTUzQzkuOTE4MzUgMTA0LjA5MyAxMC43NTk0IDEwNC42MzYgMTQuNTM5OCAxMDQuMTMzQzEzLjc1NzEgMTA1LjYxNiA5LjE0MzMyIDEwNi44NjYgMTAuMDQ2NSAxMDkuMDQ5QzEwLjk5NjggMTExLjM0NSAyMi4xNTExIDExMi45MDEgMzIuMjkwOCAxMDYuNzhDMzcuMDEzMSAxMDMuOTI5IDQwLjc3NDMgOTkuODE5MyA0OC4xMjg4IDk4LjgzODRDNTcuNjQ1OSA5Ny41Njk5IDY4LjYwOTMgOTkuNjUyIDc5LjYyNjggMTAxLjI0MUM3Ny45OTMyIDEwNi4xMTIgNzQuNzEzMyAxMDkuMzUxIDcyLjA4NiAxMTMuMjMxQzcxLjI3MjQgMTE0LjEwNyA3My43MjAyIDExNC4yMDUgNzYuNTEyNiAxMTMuNjc1QzgxLjUzNTkgMTEyLjQzMyA4NS4xNTYxIDExMS40MzMgODguOTQ3MiAxMDkuMjI3QzkzLjYwNDcgMTA2LjUxNSA5NC4zMTA0IDk5LjU2MzkgMTAwLjAyNSA5OC4wNTk5QzEwMy4yMDkgMTAyLjk1NCAxMTEuODY5IDEwNC4xMSAxMTcuMjQyIDEwMC4xOTVDMTEyLjUyNyA5OC44NjA3IDExMS4yMjQgODguODI0NCAxMTIuODE1IDg0LjQwMThDMTE0LjMyMyA4MC4yMTU2IDExNS44MTMgNzMuNTE5MiAxMTcuMzMxIDY3Ljk4NTVDMTE4Ljk2MSA2Mi4wNDI1IDExOS41NjIgNTQuNTUxOSAxMjEuNTM1IDUxLjUyNDdDMTI0LjUwMyA0Ni45NzAxIDEyNy43ODMgNDUuNDA2IDEzMC42MyA0Mi44Mzc3QzEzMy40NzcgNDAuMjY5NSAxMzYuMDgzIDM3Ljc2OTQgMTM1Ljk5OCAzMS44OTI3QzEzNS45NyAyOS45OTk4IDEzNC45OTIgMjguOTQ0NyAxMzMuMTkxIDI5LjAwMjJaIiBmaWxsPSIjMDQyNDRFIi8+CjxwYXRoIGQ9Ik0xMjguOTUzIDMyLjQ4NDRDMTI5LjQyNyAzNC4xMDA0IDEzMC4xNjggMzQuODQyMSAxMzMuMzc1IDM1LjEzODdDMTMyLjkwNiAzOS4yMDQxIDEzMC4xOTUgNDEuNDI3NiAxMjcuMTU0IDQzLjU2MTFDMTI0LjQ3OSA0NS40Mzc2IDEyMS41NDcgNDcuMjQ0NSAxMTkuNjY0IDUwLjE3NTdDMTE3LjczNCA1My4xNzg1IDExNi41MDkgNjMuNDU1NCAxMTMuNTE3IDczLjYwNDRDMTEwLjkzMSA4Mi4zNzM4IDEwNy4wMjUgOTEuMDQ0NSAxMDAuMjA0IDk0Ljg0MzdDOTkuNDkxOSA5My4wNTAyIDEwMC4yOTUgODkuNzQgOTguODc4IDg4LjY1MkM5Ny45NjExIDkxLjI2NzQgOTYuOTI0MiA5My43NjI3IDk1LjcwOTggOTYuMDgyMUM5MS43MDc3IDEwMy43MzIgODUuNzgyMiAxMDkuNDU5IDc1Ljg4MDEgMTExLjIwOEM4MC41Nzg1IDEwNC44NSA4NS4wNzEgOTguMjg0NCA4NS4xNjgzIDg3LjMyNjJDODEuODYxNyA4OC4wNDE3IDgxLjkzMTkgOTUuODUyMiA3OC41MzQ1IDk3Ljk0MDJDNzYuMzU2MyA5OC4xNzcyIDc0LjE0OTggOTguMTc1OCA3MS45MjkxIDk4LjA0MjRDNjIuODA5MSA5Ny40OTU5IDUzLjQ1MzUgOTQuNzU0OSA0NC45MjE5IDk3LjQ5MjNDMzkuMTEyOCA5OS4zNTY4IDM0LjM2MTkgMTAzLjc1NSAyOS40NDI4IDEwNS44ODhDMjMuNjYxNCAxMDguMzk2IDE5LjI4MzEgMTA5LjQyNyAxMi4wODM2IDEwOC4zOTZDMTEuMTY5NSAxMDcuMTY0IDE3LjM1MjYgMTA1LjU3NSAxNi45ODI5IDEwMi45MDJDMTQuMTY1MyAxMDIuNTkgMTIuNTI5MyAxMDMuMjczIDEwLjA4MDEgMTAyLjE2QzEwLjM1MDUgMTAxLjY2MiAxMC43NDc5IDEwMS4yNDcgMTEuMjQ4MyAxMDAuOTAxQzE1LjczNzMgOTcuNzk0IDI4LjQ4ODIgMTAwLjE2NyAzMS45MDA2IDk2LjgxNjdDMzQuMDA3IDk0Ljc1IDM1LjM4ODkgOTIuNTg2NyAzNi44MTk3IDkwLjQ4MzhDMzguMjA3MiA4OC40NDM0IDM5LjY0MTUgODYuNDU5NyA0MS44MjY4IDg0LjY3MTlDNDIuNjMzNyA4NC4wMTE4IDQzLjUxMSA4My4zNTk2IDQ0LjQ0MjEgODIuNzIzQzQ4LjE2NiA4MC4xNzQzIDUyLjc3MjkgNzcuODYyOCA1Ny4zMDY2IDc2LjI2OTRDNjMuNDgyNiA3NC4wOTg0IDY5Ljc0MSA3My45MTk1IDc2LjMyMzcgNzEuNDA0M0M4MC4zOTA0IDY5Ljg1IDg0LjgxMjcgNjcuOTMwMiA4OC40MTc0IDY1LjI0MzlDODkuMjczMyA2NC42MDUxIDkwLjA4MzEgNjMuOTI0NSA5MC44MzE5IDYzLjE5NDlDMTAxLjEyNSA1My4xNjA4IDEwMy4xNjUgMzUuNDYxIDExOS4yMjQgMzMuODExNkMxMjEuMTY2IDMzLjYxMjEgMTIyLjc1NiAzMy42NzY3IDEyNC4yMDMgMzMuNjMyN0MxMjUuODcxIDMzLjU4MyAxMjcuMzQ3IDMzLjM4OTMgMTI4Ljk1MyAzMi40ODQ0Wk0xMDkuMzc1IDg5LjEzMzlDMTA5LjU2NyA5Mi4yMDEzIDExMS4zNDggOTguMjg3MiAxMTIuOTIgOTkuNzY2M0MxMDkuODQxIDEwMC41MTUgMTA0LjUzNyA5OS4yNzggMTAzLjE3NyA5Ny4xMDYyQzEwMy44NzYgOTMuOTcwNyAxMDcuNTE0IDkxLjEwNDEgMTA5LjM3NSA4OS4xMzM5WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEzMC4xMDkgMzUuOTE4N0MxMjkuNDkgMzcuMjE2OSAxMjguMzA1IDM4Ljg5MDggMTI4LjMwNSA0Mi4xOTU2QzEyOC4zIDQyLjc2MyAxMjcuODc1IDQzLjE1MTcgMTI3Ljg2NyA0Mi4yNzdDMTI3Ljg5OSAzOS4wNDcgMTI4Ljc1NCAzNy42NTA3IDEyOS42NjIgMzUuODE1NUMxMzAuMDg1IDM1LjA2MzYgMTMwLjMzOSAzNS4zNzM4IDEzMC4xMDkgMzUuOTE4N1pNMTI5LjQ4NiAzNS40Mjk3QzEyOC43NTYgMzYuNjY4NCAxMjYuOTk4IDM4LjkyNzggMTI2LjcwNyA0Mi4yMjAzQzEyNi42NTMgNDIuNzg0OCAxMjYuMTk0IDQzLjEzNDMgMTI2LjI2NCA0Mi4yNjE4QzEyNi41ODEgMzkuMDQ3NyAxMjcuOTg2IDM3LjAzNiAxMjkuMDUyIDM1LjI4NzNDMTI5LjUzNiAzNC41NzYxIDEyOS43NjMgMzQuOTA3NCAxMjkuNDg2IDM1LjQyOTdaTTEyOC45MTggMzQuNzgxN0MxMjguMDg2IDM1Ljk1NDMgMTI1LjM4IDM4LjY2NzggMTI0LjgxNCA0MS45MjQ3QzEyNC43MTIgNDIuNDgxOSAxMjQuMjI1IDQyLjc5MjggMTI0LjM2OCA0MS45MjlDMTI0Ljk1NCAzOC43NTIgMTI3LjI4NyAzNi4yNTUgMTI4LjQ5NiAzNC42MDM3QzEyOS4wMzggMzMuOTM0NiAxMjkuMjM3IDM0LjI4NCAxMjguOTE4IDM0Ljc4MTdaTTEyOC40MTEgMzQuMDU4OEwxMjguMTM3IDM0LjM0OTlDMTI2LjkyNyAzNS42NDcyIDEyNC4xMTYgMzguODExNCAxMjMuMTc5IDQxLjcwNzRDMTIyLjk5OSA0Mi4yNDUgMTIyLjQ3NCA0Mi40ODQ4IDEyMi43MzcgNDEuNjQ5M0MxMjMuNzYzIDM4LjU4NjQgMTI2LjU4OSAzNS4yODczIDEyOC4wMTggMzMuODIyN0MxMjguNjUgMzMuMjM2NCAxMjguNzk2IDMzLjYxMDYgMTI4LjQxMSAzNC4wNTg4Wk0xMTMuODg2IDQwLjYxNjJDMTE0LjUxMyAzNy45MjMxIDExNi42MDcgMzYuNjk2IDEyMC4yMjMgMzYuOTk1M0MxMjEuMDk2IDQxLjAxNTEgMTE2LjIxMyA0Mi42MzY2IDExMy44ODYgNDAuNjE2MloiIGZpbGw9IiMwNDI0NEUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMjkzMCIgeDE9IjE0MC41IiB5MT0iMTQxIiB4Mj0iNS45OTk5OSIgeTI9Ii01LjUwMjI4ZS0wNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQzQ5QTZDIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0U3QkY5MyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "s3Region"], ["spec", "backup", "s3Bucket"], ["spec", "backup", "schedule"], ["spec", "backup", "cleanupStrategy"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "backup", "resticPassword"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`mysql-{{ .name }}-credentials`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`mysql-{{ .name }}-primary`}}" + - "{{`mysql-{{ .name }}-secondary`}}" diff --git a/packages/core/platform/psds/nats.yaml b/packages/core/platform/psds/nats.yaml index d8e93b25..ec2a9a97 100644 --- a/packages/core/platform/psds/nats.yaml +++ b/packages/core/platform/psds/nats.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.nats-application spec: @@ -16,15 +16,42 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: nats-application - path: system/nats-application - releaseName: nats-application - namespace: cozy-system - sources: + components: + - name: nats-system + path: system/nats + applications: - name: nats path: apps/nats libraries: - cozy-lib - - name: nats-system - path: system/nats + template: + spec: + application: + kind: NATS + plural: natses + singular: nats + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"config":{"description":"NATS configuration.","type":"object","default":{},"properties":{"merge":{"description":"Additional configuration to merge into NATS config.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true},"resolver":{"description":"Additional resolver configuration to merge into NATS config.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"jetstream":{"description":"Jetstream configuration.","type":"object","default":{},"required":["enabled","size"],"properties":{"enabled":{"description":"Enable or disable Jetstream for persistent messaging in NATS.","type":"boolean","default":true},"size":{"description":"Jetstream persistent storage size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"replicas":{"description":"Number of replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each NATS replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}}}} + release: + prefix: nats- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: NATS + plural: NATS + description: Managed NATS service + tags: + - messaging + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyMSkiLz4KPHJlY3Qgd2lkdGg9IjE0NCIgaGVpZ2h0PSIxNDQiIHJ4PSIyNCIgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMC4zIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTE3LjQ4IDI1SDI3Vjk4Ljk2OTNINjYuMDY4OUw4Ny43MDc1IDExOVY5OC45NjkzSDExNy40OFYyNVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4xMzUyIDcyLjQ1NTJWNDIuNjI1SDEwMi43NzNWODEuMTk5OUg4Ni42NTE5TDU0LjExNCA1MC44NDE0VjgxLjIzMjJINDMuNDQ0M1Y0Mi42MjVINjAuMTI2Mkw5Mi4xMzUyIDcyLjQ1NTJaIiBmaWxsPSJibGFjayIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4MV8yODIxIiB4MT0iMTAiIHkxPSIxNS41IiB4Mj0iMTQ0IiB5Mj0iMTMxLjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzM4NUM5MyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMzMkE1NzQiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "jetstream"], ["spec", "jetstream", "enabled"], ["spec", "jetstream", "size"], ["spec", "config"], ["spec", "config", "merge"], ["spec", "config", "resolver"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`nats-{{ .name }}-credentials`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`nats-{{ .name }}`}}" diff --git a/packages/core/platform/psds/networking.yaml b/packages/core/platform/psds/networking.yaml index 57cf3504..5518de0e 100644 --- a/packages/core/platform/psds/networking.yaml +++ b/packages/core/platform/psds/networking.yaml @@ -1,65 +1,79 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.networking spec: variants: - - name: noop - packages: [] + - name: noop + components: [] + - name: cilium + dependsOn: + - cozystack.cert-manager + components: - name: cilium - dependsOn: - - cozystack.cert-manager - packages: - - name: cilium - releaseName: cilium - path: system/cilium - namespace: cozy-cilium - privileged: true - dependsOn: [] - valuesFiles: - - values.yaml - - values-talos.yaml - - name: cilium-networkpolicy - releaseName: cilium-networkpolicy - path: system/cilium-networkpolicy - namespace: cozy-cilium - privileged: true - dependsOn: [cilium] - - name: kubeovn-cilium - dependsOn: - - cozystack.cert-manager - packages: - - name: cilium - releaseName: cilium - path: system/cilium - namespace: cozy-cilium - privileged: true - dependsOn: [] - valuesFiles: - - values.yaml - - values-talos.yaml - - values-kubeovn.yaml - - name: cilium-networkpolicy - releaseName: cilium-networkpolicy - path: system/cilium-networkpolicy - namespace: cozy-cilium - privileged: true - dependsOn: [cilium] - - name: kubeovn - releaseName: kubeovn - path: system/kubeovn - namespace: cozy-kubeovn - privileged: true - dependsOn: [cilium] - - name: kubeovn-plunger - releaseName: kubeovn-plunger - path: system/kubeovn-plunger - namespace: cozy-kubeovn - dependsOn: [cilium,kubeovn] - - name: kubeovn-webhook - releaseName: kubeovn-webhook - path: system/kubeovn-webhook - namespace: cozy-kubeovn - privileged: true - dependsOn: [cilium,kubeovn] + path: system/cilium + valuesFiles: + - values.yaml + - values-talos.yaml + install: + privileged: true + namespace: cozy-cilium + releaseName: cilium + dependsOn: [] + - name: cilium-networkpolicy + path: system/cilium-networkpolicy + install: + privileged: true + namespace: cozy-cilium + releaseName: cilium-networkpolicy + dependsOn: + - cilium + - name: kubeovn-cilium + dependsOn: + - cozystack.cert-manager + components: + - name: cilium + path: system/cilium + valuesFiles: + - values.yaml + - values-talos.yaml + - values-kubeovn.yaml + install: + privileged: true + namespace: cozy-cilium + releaseName: cilium + dependsOn: [] + - name: cilium-networkpolicy + path: system/cilium-networkpolicy + install: + privileged: true + namespace: cozy-cilium + releaseName: cilium-networkpolicy + dependsOn: + - cilium + - name: kubeovn + path: system/kubeovn + install: + privileged: true + namespace: cozy-kubeovn + releaseName: kubeovn + dependsOn: + - cilium + - name: kubeovn-plunger + path: system/kubeovn-plunger + install: + namespace: cozy-kubeovn + releaseName: kubeovn-plunger + dependsOn: + - cilium + - kubeovn + - name: kubeovn-webhook + path: system/kubeovn-webhook + install: + privileged: true + namespace: cozy-kubeovn + releaseName: kubeovn-webhook + dependsOn: + - cilium + - kubeovn diff --git a/packages/core/platform/psds/nfs-driver.yaml b/packages/core/platform/psds/nfs-driver.yaml index acc3e943..ae07b800 100644 --- a/packages/core/platform/psds/nfs-driver.yaml +++ b/packages/core/platform/psds/nfs-driver.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.nfs-driver spec: @@ -10,14 +10,14 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: nfs-driver - path: system/nfs-driver - releaseName: nfs-driver - namespace: cozy-nfs-driver - privileged: true - disabled: true - + - name: default + dependsOn: + - cozystack.networking + components: + - name: nfs-driver + path: system/nfs-driver + disabled: true + install: + privileged: true + namespace: cozy-nfs-driver + releaseName: nfs-driver diff --git a/packages/core/platform/psds/objectstorage-controller.yaml b/packages/core/platform/psds/objectstorage-controller.yaml index b6242c82..cf89ee46 100644 --- a/packages/core/platform/psds/objectstorage-controller.yaml +++ b/packages/core/platform/psds/objectstorage-controller.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.objectstorage-controller spec: @@ -10,12 +10,12 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: objectstorage-controller - path: system/objectstorage-controller - releaseName: objectstorage-controller - namespace: cozy-objectstorage-controller - + - name: default + dependsOn: + - cozystack.networking + components: + - name: objectstorage-controller + path: system/objectstorage-controller + install: + namespace: cozy-objectstorage-controller + releaseName: objectstorage-controller diff --git a/packages/core/platform/psds/postgres.yaml b/packages/core/platform/psds/postgres.yaml index 2333e417..79ec3a71 100644 --- a/packages/core/platform/psds/postgres.yaml +++ b/packages/core/platform/psds/postgres.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.postgres-application spec: @@ -16,14 +16,51 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: postgres-application - path: system/postgres-application - releaseName: postgres-application - namespace: cozy-system - sources: + components: [] + applications: - name: postgres path: apps/postgres libraries: - cozy-lib + template: + spec: + application: + kind: Postgres + singular: postgres + plural: postgreses + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["enabled"],"properties":{"destinationPath":{"description":"Destination path for backups (e.g. s3://bucket/path/).","type":"string","default":"s3://bucket/path/to/folder/"},"enabled":{"description":"Enable regular backups.","type":"boolean","default":false},"endpointURL":{"description":"S3 endpoint URL for uploads.","type":"string","default":"http://minio-gateway-service:9000"},"retentionPolicy":{"description":"Retention policy (e.g. \"30d\").","type":"string","default":"30d"},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * * *"}}},"bootstrap":{"description":"Bootstrap configuration.","type":"object","default":{},"required":["enabled","oldName"],"properties":{"enabled":{"description":"Whether to restore from a backup.","type":"boolean","default":false},"oldName":{"description":"Previous cluster name before deletion.","type":"string","default":""},"recoveryTime":{"description":"Timestamp (RFC3339) for point-in-time recovery; empty means latest.","type":"string","default":""}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"extensions":{"description":"List of enabled PostgreSQL extensions.","type":"array","items":{"type":"string"}},"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"postgresql":{"description":"PostgreSQL server configuration.","type":"object","default":{},"properties":{"parameters":{"description":"PostgreSQL server parameters.","type":"object","default":{},"properties":{"max_connections":{"description":"Maximum number of concurrent connections to the database server.","type":"integer","default":100}}}}},"quorum":{"description":"Quorum configuration for synchronous replication.","type":"object","default":{},"required":["maxSyncReplicas","minSyncReplicas"],"properties":{"maxSyncReplicas":{"description":"Maximum number of synchronous replicas allowed (must be less than total replicas).","type":"integer","default":0},"minSyncReplicas":{"description":"Minimum number of synchronous replicas required for commit.","type":"integer","default":0}}},"replicas":{"description":"Number of Postgres replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each PostgreSQL replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"},"replication":{"description":"Whether the user has replication privileges.","type":"boolean"}}}}}} + release: + prefix: postgres- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: PostgreSQL + plural: PostgreSQL + description: Managed PostgreSQL service + tags: + - database + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMjg0OSkiLz4KPHBhdGggZD0iTTk0LjQ4MSA5My4zMDQ5Qzk1LjA3MTggODguMzQ3NyA5NC44OTQ4IDg3LjYyMDggOTguNTYxMiA4OC40MjM4TDk5LjQ5MiA4OC41MDYxQzEwMi4zMTEgODguNjM1MyAxMDUuOTk5IDg4LjA0OTUgMTA4LjE2NiA4Ny4wMzU4QzExMi44MyA4NC44NTY0IDExNS41OTUgODEuMjE3NiAxMTAuOTk2IDgyLjE3MzhDMTAwLjUwNiA4NC4zNTMyIDk5Ljc4NDkgODAuNzc1OSA5OS43ODQ5IDgwLjc3NTlDMTEwLjg2MiA2NC4yMjQgMTE1LjQ5MyA0My4yMTI4IDExMS40OTYgMzguMDY5N0MxMDAuNTk0IDI0LjA0MTIgODEuNzIzMSAzMC42NzUgODEuNDA3MyAzMC44NDcyTDgxLjMwNjggMzAuODY1OUM3OS4yMzQgMzAuNDMyOCA3Ni45MTQzIDMwLjE3NCA3NC4zMDg1IDMwLjEzMTZDNjkuNTYxMyAzMC4wNTMgNjUuOTU5MSAzMS4zODQ5IDYzLjIyNjYgMzMuNDcyMUM2My4yMjY2IDMzLjQ3MjEgMjkuNTYyMSAxOS41MDQ3IDMxLjEyODIgNTEuMDM3NUMzMS40NjEzIDU3Ljc0NTQgNDAuNjc1OCAxMDEuNzk1IDUxLjY2NTkgODguNDkwMUM1NS42ODI3IDgzLjYyNDkgNTkuNTY0NiA3OS41MTEzIDU5LjU2NDYgNzkuNTExM0M2MS40OTIyIDgwLjgwMDkgNjMuOCA4MS40NTg4IDY2LjIyMDQgODEuMjIyNUw2Ni40MDc1IDgxLjA2MThDNjYuMzQ4OSA4MS42NjU5IDY2LjM3NDcgODIuMjU2NyA2Ni40ODI0IDgyLjk1NjJDNjMuNjUxNyA4Ni4xNDE5IDY0LjQ4MzUgODYuNzAxMiA1OC44MjMxIDg3Ljg3NDVDNTMuMDk2NSA4OS4wNjMxIDU2LjQ2MDkgOTEuMTc5MyA1OC42NTY5IDkxLjczMjRDNjEuMzE5OSA5Mi40MDMgNjcuNDgwNCA5My4zNTMgNzEuNjQ0IDg3LjQ4NDVMNzEuNDc4MiA4OC4xNTQxQzcyLjU4ODggODkuMDQ4OSA3Mi41MTM3IDk0LjU4NTQgNzIuNjcxMiA5OC41NDExQzcyLjgyODkgMTAyLjQ5NyA3My4wOTE5IDEwNi4xODkgNzMuODkyNiAxMDguMzY1Qzc0LjY5MzMgMTEwLjU0MSA3NS42MzgxIDExNi4xNDcgODMuMDc3MSAxMTQuNTQxQzg5LjI5NDMgMTEzLjIgOTQuMDQ3OCAxMTEuMjY5IDk0LjQ4MSA5My4zMDQ5WiIgZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iNiIvPgo8cGF0aCBkPSJNMTEwLjk5OCA4Mi4xNzI3QzEwMC41MDYgODQuMzUyMSA5OS43ODQ5IDgwLjc3NDggOTkuNzg0OSA4MC43NzQ4QzExMC44NjIgNjQuMjIxOCAxMTUuNDkzIDQzLjIxMDIgMTExLjQ5NyAzOC4wNjc4QzEwMC41OTUgMjQuMDQwMSA4MS43MjMxIDMwLjY3NDMgODEuNDA4MiAzMC44NDY1TDgxLjMwNjggMzAuODY0OEM3OS4yMzQxIDMwLjQzMTUgNzYuOTE0NCAzMC4xNzMzIDc0LjMwNzMgMzAuMTMwNUM2OS41NiAzMC4wNTIxIDY1Ljk1OTEgMzEuMzgzOCA2My4yMjY3IDMzLjQ3MDZDNjMuMjI2NyAzMy40NzA2IDI5LjU2MTUgMTkuNTAzOCAzMS4xMjcyIDUxLjAzNjRDMzEuNDYwMyA1Ny43NDQ3IDQwLjY3NDYgMTAxLjc5NSA1MS42NjUxIDg4LjQ4OTVDNTUuNjgyMSA4My42MjQzIDU5LjU2MzQgNzkuNTEwNiA1OS41NjM0IDc5LjUxMDZDNjEuNDkxMiA4MC44MDAyIDYzLjc5OSA4MS40NTgxIDY2LjIxODQgODEuMjIxOEw2Ni40MDYzIDgxLjA2MTFDNjYuMzQ3OSA4MS42NjUyIDY2LjM3NDYgODIuMjU2IDY2LjQ4MTYgODIuOTU1NUM2My42NTAzIDg2LjE0MTIgNjQuNDgyMiA4Ni43MDA1IDU4LjgyMjMgODcuODczOEM1My4wOTUzIDg5LjA2MjUgNTYuNDU5NyA5MS4xNzg2IDU4LjY1NjMgOTEuNzMxN0M2MS4zMTkzIDkyLjQwMjMgNjcuNDgwMiA5My4zNTI0IDcxLjY0MyA4Ny40ODM4TDcxLjQ3NyA4OC4xNTM0QzcyLjU4NjQgODkuMDQ4MiA3My4zNjU0IDkzLjk3MzkgNzMuMjM0OCA5OC40MzlDNzMuMTA0MiAxMDIuOTA0IDczLjAxNzEgMTA1Ljk3IDczLjg5MTIgMTA4LjM2NEM3NC43NjUzIDExMC43NTkgNzUuNjM2NSAxMTYuMTQ2IDgzLjA3NjkgMTE0LjU0MUM4OS4yOTQxIDExMy4xOTkgOTIuNTE1OSAxMDkuNzIyIDkyLjk2NDEgMTAzLjkyMkM5My4yODIyIDk5Ljc5ODggOTQuMDAxOSAxMDAuNDA4IDk0LjA0NzQgOTYuNzIxOUw5NC42MjQ3IDk0Ljk3NjZDOTUuMjkwNSA4OS4zODcyIDk0LjczMDUgODcuNTg0IDk4LjU2MDggODguNDIyN0w5OS40OTE3IDg4LjUwNUMxMDIuMzExIDg4LjYzNDIgMTA2LjAwMSA4OC4wNDg0IDEwOC4xNjYgODcuMDM0N0MxMTIuODI5IDg0Ljg1NTMgMTE1LjU5NSA4MS4yMTY2IDExMC45OTcgODIuMTcyN0gxMTAuOTk4WiIgZmlsbD0iIzMzNjc5MSIvPgo8cGF0aCBkPSJNNzIuMDkzMyA4NS4zNzdDNzEuODA0NSA5NS43Nzc0IDcyLjE2NTkgMTA2LjI1IDczLjE3NjQgMTA4Ljc5NkM3NC4xODc2IDExMS4zNDEgNzYuMzUxNCAxMTYuMjkyIDgzLjc5MjUgMTE0LjY4NkM5MC4wMDkxIDExMy4zNDQgOTIuMjcxIDExMC43NDcgOTMuMjUyNiAxMDUuMDE0QzkzLjk3NTUgMTAwLjc5NiA5NS4zNjkxIDg5LjA4MSA5NS41NDc5IDg2LjY4MDkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik02My4xNzUgMzMuMjM5M0M2My4xNzUgMzMuMjM5MyAyOS40ODY4IDE5LjM3MzIgMzEuMDUzIDUwLjkwNThDMzEuMzg2IDU3LjYxNDEgNDAuNjAxIDEwMS42NjUgNTEuNTkxMyA4OC4zNTk3QzU1LjYwNzUgODMuNDkzOCA1OS4yMzk3IDc5LjY3NzYgNTkuMjM5NyA3OS42Nzc2IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNODEuMzcxMyAzMC43MDc4QzgwLjIwNTIgMzEuMDc2IDEwMC4xMTEgMjMuMzc5NiAxMTEuNDIzIDM3LjkzNjhDMTE1LjQxOSA0My4wNzk1IDExMC43ODkgNjQuMDkxMSA5OS43MTE1IDgwLjY0NDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik05OS43MTEgODAuNjQ0OEM5OS43MTEgODAuNjQ0OCAxMDAuNDMzIDg0LjIyMyAxMTAuOTI0IDgyLjA0MjJDMTE1LjUyMSA4MS4wODYxIDExMi43NTUgODQuNzI1MiAxMDguMDkzIDg2LjkwNTdDMTA0LjI2NyA4OC42OTQgOTUuNjg4MyA4OS4xNTIzIDk1LjU0ODIgODYuNjgxMkM5NS4xODc2IDgwLjMwNTMgMTAwLjA2MyA4Mi4yNDIzIDk5LjcxMSA4MC42NDQ4Wk05OS43MTEgODAuNjQ0OEM5OS4zOTI5IDc5LjIwNiA5Ny4yMTI4IDc3Ljc5MzkgOTUuNzcwNSA3NC4yNzI1Qzk0LjUxMTQgNzEuMTk5IDc4LjUwMTkgNDcuNjI4OSAxMDAuMjEgNTEuMTI5NEMxMDEuMDA2IDUwLjk2MzcgOTQuNTQ4NSAzMC4zMzQ4IDc0LjIzMjUgMjkuOTk5NEM1My45MjExIDI5LjY2MzkgNTQuNTg3NSA1NS4xNTQ1IDU0LjU4NzUgNTUuMTU0NSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiLz4KPHBhdGggZD0iTTY2LjQwNzcgODIuODI1M0M2My41NzYgODYuMDEwOCA2NC40MDg4IDg2LjU3MDIgNTguNzQ4NSA4Ny43NDM5QzUzLjAyMTQgODguOTMyNyA1Ni4zODYyIDkxLjA0ODUgNTguNTgyMiA5MS42MDEzQzYxLjI0NTIgOTIuMjcyNCA2Ny40MDYxIDkzLjIyMjQgNzEuNTY4OSA4Ny4zNTI0QzcyLjgzNjYgODUuNTY1MSA3MS41NjE0IDgyLjcxMzQgNjkuODIwMSA4MS45ODY0QzY4Ljk3ODcgODEuNjM1NCA2Ny44NTM3IDgxLjE5NTYgNjYuNDA3NyA4Mi44MjUzWiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTY2LjIyMjUgODIuNzY5MUM2NS45MzcyIDgwLjg5NjEgNjYuODMzNiA3OC42Njc0IDY3Ljc5NDMgNzYuMDU5OUM2OS4yMzggNzIuMTQ3NyA3Mi41NjkgNjguMjM0OCA2OS45MDQ0IDU1LjgyNDZDNjcuOTE4MiA0Ni41NzY3IDU0LjU5NjMgNTMuOSA1NC41ODggNTUuMTU0QzU0LjU3OTggNTYuNDA3NSA1NS4xOTA1IDYxLjUwOTkgNTQuMzY1NCA2Ny40NTE1QzUzLjI4ODggNzUuMjA0OCA1OS4yNjQzIDgxLjc2MjEgNjYuMTQ1MSA4MS4wOTEzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNNjMuMDUyOCA1NC45NjY1QzYyLjk5MjggNTUuMzk0OCA2My44MzE0IDU2LjUzNzcgNjQuOTI0OSA1Ni42OTA0QzY2LjAxNjYgNTYuODQzNyA2Ni45NTEgNTUuOTUwNiA2Ny4wMTAyIDU1LjUyMjdDNjcuMDY5NCA1NS4wOTQ1IDY2LjIzMTggNTQuNjIyNyA2NS4xMzc5IDU0LjQ2OTRDNjQuMDQ1NiA1NC4zMTU4IDYzLjExMDggNTQuNTM5MyA2My4wNTMxIDU0Ljk2NjVINjMuMDUyOFoiIGZpbGw9IndoaXRlIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz4KPHBhdGggZD0iTTk2LjMwMzQgNTQuMDkyNEM5Ni4zNjI3IDU0LjUyMDcgOTUuNTI1MSA1NS42NjM1IDk0LjQzMTMgNTUuODE2MkM5My4zMzg5IDU1Ljk2OTYgOTIuNDA0NSA1NS4wNzY1IDkyLjM0NDYgNTQuNjQ4NkM5Mi4yODY4IDU0LjIyMDMgOTMuMTI0NyA1My43NDg2IDk0LjIxNzMgNTMuNTk1M0M5NS4zMSA1My40NDE5IDk2LjI0NDIgNTMuNjY1MiA5Ni4zMDM0IDU0LjA5MjZWNTQuMDkyNFoiIGZpbGw9IndoaXRlIiBzdHJva2U9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMDAuMjEgNTEuMTI4OUMxMDAuMzkgNTQuNDg4MyA5OS40OTIgNTYuNzc2NSA5OS4zNzg3IDYwLjM1MjdDOTkuMjExIDY1LjU1MDggMTAxLjg0IDcxLjUwMDUgOTcuODc4OSA3Ny40NTc1IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yODQ5IiB4MT0iMTQwIiB5MT0iMTMwLjUiIHgyPSI0IiB5Mj0iOS40OTk5OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDAyQzRDIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNDc3QiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + #tabs: + # services: + # labelSelector: + # cnpg.io/cluster: "{reqs[0]['metadata','name']}" + # workloadMonitors: + # labelSelector: + # helm.toolkit.fluxcd.io/name: "{reqs[0]['metadata','name']}" + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "postgresql"], ["spec", "postgresql", "parameters"], ["spec", "postgresql", "parameters", "max_connections"], ["spec", "quorum"], ["spec", "quorum", "minSyncReplicas"], ["spec", "quorum", "maxSyncReplicas"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "retentionPolicy"], ["spec", "backup", "destinationPath"], ["spec", "backup", "endpointURL"], ["spec", "backup", "schedule"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "bootstrap"], ["spec", "bootstrap", "enabled"], ["spec", "bootstrap", "recoveryTime"], ["spec", "bootstrap", "oldName"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`postgres-{{ .name }}-credentials`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`postgres-{{ .name }}-r`}}" + - "{{`postgres-{{ .name }}-ro`}}" + - "{{`postgres-{{ .name }}-rw`}}" + - "{{`postgres-{{ .name }}-external-write`}}" diff --git a/packages/core/platform/psds/rabbitmq-operator.yaml b/packages/core/platform/psds/rabbitmq-operator.yaml index 236ae761..843ceb47 100644 --- a/packages/core/platform/psds/rabbitmq-operator.yaml +++ b/packages/core/platform/psds/rabbitmq-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.rabbitmq-operator spec: @@ -10,12 +10,12 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: rabbitmq-operator - path: system/rabbitmq-operator - releaseName: rabbitmq-operator - namespace: cozy-rabbitmq-operator - + - name: default + dependsOn: + - cozystack.networking + components: + - name: rabbitmq-operator + path: system/rabbitmq-operator + install: + namespace: cozy-rabbitmq-operator + releaseName: rabbitmq-operator diff --git a/packages/core/platform/psds/rabbitmq.yaml b/packages/core/platform/psds/rabbitmq.yaml index 62ba25fa..f0670edd 100644 --- a/packages/core/platform/psds/rabbitmq.yaml +++ b/packages/core/platform/psds/rabbitmq.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.rabbitmq-application spec: @@ -17,14 +17,42 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: rabbitmq-application - path: system/rabbitmq-application - releaseName: rabbitmq-application - namespace: cozy-system - sources: + components: [] + applications: - name: rabbitmq path: apps/rabbitmq libraries: - cozy-lib - + template: + spec: + application: + kind: RabbitMQ + plural: rabbitmqs + singular: rabbitmq + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of RabbitMQ replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration for each RabbitMQ replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}},"vhosts":{"description":"Virtual hosts configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","required":["roles"],"properties":{"roles":{"description":"Virtual host roles list.","type":"object","properties":{"admin":{"description":"List of admin users.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of readonly users.","type":"array","items":{"type":"string"}}}}}}}}} + release: + prefix: rabbitmq- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: RabbitMQ + plural: RabbitMQ + description: Managed RabbitMQ service + tags: + - messaging + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NzIpIi8+CjxwYXRoIGQ9Ik0xMTEuNDExIDYyLjhIODIuNDkzOUM4MS43OTY5IDYyLjc5OTcgODEuMTI4NSA2Mi41MjI4IDgwLjYzNTYgNjIuMDMwMUM4MC4xNDI3IDYxLjUzNzMgNzkuODY1NiA2MC44NjkxIDc5Ljg2NTMgNjAuMTcyMlYzMC4wNDEyQzc5Ljg2NTMgMjcuODEgNzguMDU1NiAyNiA3NS44MjQ5IDI2SDY1LjUwMjFDNjMuMjcgMjYgNjEuNDYxNCAyNy44MSA2MS40NjE0IDMwLjA0MTJWNTkuOTg5OEM2MS40NjE0IDYxLjU0MzUgNjAuMjA1IDYyLjgwNjUgNTguNjUwOCA2Mi44MTMzTDQ5LjE3NDMgNjIuODU4NEM0Ny42MDY5IDYyLjg2NjkgNDYuMzMzNiA2MS41OTU1IDQ2LjMzNjYgNjAuMDI5OEw0Ni4zOTU0IDMwLjA0OEM0Ni40MDA1IDI3LjgxMzQgNDQuNTkwMiAyNiA0Mi4zNTUgMjZIMzIuMDQwN0MyOS44MDgzIDI2IDI4IDI3LjgxIDI4IDMwLjA0MTJWMTE0LjQxMkMyOCAxMTYuMzk0IDI5LjYwNjEgMTE4IDMxLjU4NzEgMTE4SDExMS40MTFDMTEzLjM5NCAxMTggMTE1IDExNi4zOTQgMTE1IDExNC40MTJWNjYuMzg4QzExNSA2NC40MDU4IDExMy4zOTQgNjIuOCAxMTEuNDExIDYyLjhaTTk3Ljg1MDggOTQuNDc3OUM5Ny44NTA4IDk3LjA3NTUgOTUuNzQ0NSA5OS4xODE3IDkzLjE0NjQgOTkuMTgxN0g4NC45ODg0QzgyLjM5IDk5LjE4MTcgODAuMjgzNiA5Ny4wNzU1IDgwLjI4MzYgOTQuNDc3OVY4Ni4zMjE3QzgwLjI4MzYgODMuNzIzOCA4Mi4zOSA4MS42MTc5IDg0Ljk4ODQgODEuNjE3OUg5My4xNDY0Qzk1Ljc0NDUgODEuNjE3OSA5Ny44NTA4IDgzLjcyMzggOTcuODUwOCA4Ni4zMjE3Vjk0LjQ3NzlaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yOTcyIiB4MT0iNSIgeTE9Ii03LjUiIHgyPSIxNDEiIHkyPSIxMjQuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkY4MjJGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGNjYwMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "vhosts"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`rabbitmq-{{ .name }}-default-user`}}" + - matchLabels: + apps.cozystack.io/user-secret: "true" + services: + exclude: [] + include: + - resourceNames: + - "{{`rabbitmq-{{ .name }}`}}" diff --git a/packages/core/platform/psds/redis-operator.yaml b/packages/core/platform/psds/redis-operator.yaml index ee6e349b..9abb3d26 100644 --- a/packages/core/platform/psds/redis-operator.yaml +++ b/packages/core/platform/psds/redis-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.redis-operator spec: @@ -10,12 +10,12 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: redis-operator - path: system/redis-operator - releaseName: redis-operator - namespace: cozy-redis-operator - + - name: default + dependsOn: + - cozystack.networking + components: + - name: redis-operator + path: system/redis-operator + install: + namespace: cozy-redis-operator + releaseName: redis-operator diff --git a/packages/core/platform/psds/redis.yaml b/packages/core/platform/psds/redis.yaml index fd0d38cb..de82f954 100644 --- a/packages/core/platform/psds/redis.yaml +++ b/packages/core/platform/psds/redis.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.redis-application spec: @@ -17,14 +17,43 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: redis-application - path: system/redis-application - releaseName: redis-application - namespace: cozy-system - sources: + components: [] + applications: - name: redis path: apps/redis libraries: - cozy-lib - + template: + spec: + application: + kind: Redis + plural: redises + singular: redis + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"authEnabled":{"description":"Enable password generation.","type":"boolean","default":true},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of Redis replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each Redis replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} + release: + prefix: redis- + labels: + cozystack.io/ui: "true" + dashboard: + category: PaaS + singular: Redis + plural: Redis + description: Managed Redis service + tags: + - cache + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzIxMykiLz4KPHBhdGggZD0iTTEyMC4xNDkgOTUuNTQ5MUMxMTQuNTg2IDk4LjQ0ODUgODUuNzcwOSAxMTAuMjk2IDc5LjYzNjMgMTEzLjQ5NUM3My41MDE2IDExNi42OTMgNzAuMDkzNyAxMTYuNjYyIDY1LjI0NzIgMTE0LjM0NkM2MC40MDEyIDExMi4wMjkgMjkuNzM2NCA5OS42NDIzIDI0LjIxMjUgOTcuMDAxOUMyMS40NTE5IDk1LjY4MjcgMjAgOTQuNTY4NyAyMCA5My41MTY2VjgyLjk4MDlDMjAgODIuOTgwOSA1OS45MjIgNzQuMjkwMSA2Ni4zNjY5IDcxLjk3NzhDNzIuODExNSA2OS42NjU2IDc1LjA0NzYgNjkuNTgyMSA4MC41MzIgNzEuNTkxQzg2LjAxNzMgNzMuNjAwOCAxMTguODEyIDc5LjUxNzYgMTI0LjIzMyA4MS41MDI5TDEyNC4yMyA5MS44ODk2QzEyNC4yMzEgOTIuOTMxMSAxMjIuOTggOTQuMDczNiAxMjAuMTQ5IDk1LjU0OTFaIiBmaWxsPSIjOTEyNjI2Ii8+CjxwYXRoIGQ9Ik0xMjAuMTQ3IDg1LjA3NTJDMTE0LjU4NSA4Ny45NzM0IDg1Ljc3IDk5LjgyMTggNzkuNjM1NCAxMDMuMDJDNzMuNTAxMSAxMDYuMjE5IDcwLjA5MzIgMTA2LjE4NyA2NS4yNDcyIDEwMy44NzFDNjAuNDAwNyAxMDEuNTU1IDI5LjczNzEgODkuMTY2OCAyNC4yMTM2IDg2LjUyOEMxOC42OTAxIDgzLjg4NzYgMTguNTc0NCA4Mi4wNzA0IDI0LjAwMDMgNzkuOTQ1OEMyOS40MjYxIDc3LjgyMDUgNTkuOTIxNSA2NS44NTYxIDY2LjM2NzIgNjMuNTQzOEM3Mi44MTE4IDYxLjIzMjQgNzUuMDQ3NSA2MS4xNDgxIDgwLjUzMTkgNjMuMTU3OEM4Ni4wMTY4IDY1LjE2NjggMTE0LjY2IDc2LjU2NzYgMTIwLjA3OSA3OC41NTI1QzEyNS41MDEgODAuNTM5OSAxMjUuNzA5IDgyLjE3NjMgMTIwLjE0NyA4NS4wNzUyWiIgZmlsbD0iI0M2MzAyQiIvPgo8cGF0aCBkPSJNMTIwLjE0OSA3OC41MDJDMTE0LjU4NiA4MS40MDE4IDg1Ljc3MDkgOTMuMjQ5MyA3OS42MzYzIDk2LjQ0ODhDNzMuNTAxNiA5OS42NDYyIDcwLjA5MzcgOTkuNjE1MiA2NS4yNDcyIDk3LjI5ODVDNjAuNDAwOCA5NC45ODMgMjkuNzM2NCA4Mi41OTUyIDI0LjIxMjUgNzkuOTU0N0MyMS40NTE5IDc4LjYzNTUgMjAgNzcuNTIzMiAyMCA3Ni40NzA3VjY1LjkzMzhDMjAgNjUuOTMzOCA1OS45MjIgNTcuMjQzNCA2Ni4zNjY5IDU0LjkzMTFDNzIuODExNSA1Mi42MTg5IDc1LjA0NzYgNTIuNTM1IDgwLjUzMiA1NC41NDQzQzg2LjAxNzcgNTYuNTUzNiAxMTguODEzIDYyLjQ2OTMgMTI0LjIzMyA2NC40NTVMMTI0LjIzIDc0Ljg0MjhDMTI0LjIzMSA3NS44ODQgMTIyLjk4IDc3LjAyNjQgMTIwLjE0OSA3OC41MDJaIiBmaWxsPSIjOTEyNjI2Ii8+CjxwYXRoIGQ9Ik0xMjAuMTQ3IDY4LjAyODJDMTE0LjU4NSA3MC45MjcxIDg1Ljc3IDgyLjc3NDcgNzkuNjM1NCA4NS45NzM3QzczLjUwMTEgODkuMTcxNiA3MC4wOTMyIDg5LjE0MDIgNjUuMjQ3MiA4Ni44MjM1QzYwLjQwMDcgODQuNTA4NCAyOS43MzcxIDcyLjEyMDEgMjQuMjEzNiA2OS40ODA5QzE4LjY5MDEgNjYuODQxMyAxOC41NzQ0IDY1LjAyMzcgMjQuMDAwMyA2Mi44OTg0QzI5LjQyNjEgNjAuNzc0MiA1OS45MjE5IDQ4LjgwOSA2Ni4zNjcyIDQ2LjQ5NzJDNzIuODExOCA0NC4xODUzIDc1LjA0NzUgNDQuMTAxNCA4MC41MzE5IDQ2LjExMDhDODYuMDE2OCA0OC4xMTk3IDExNC42NiA1OS41MTk3IDEyMC4wNzkgNjEuNTA1NUMxMjUuNTAxIDYzLjQ5MjQgMTI1LjcwOSA2NS4xMjkyIDEyMC4xNDcgNjguMDI4MloiIGZpbGw9IiNDNjMwMkIiLz4KPHBhdGggZD0iTTEyMC4xNDkgNjAuODIyNEMxMTQuNTg2IDYzLjcyMTQgODUuNzcwOSA3NS41Njk4IDc5LjYzNjMgNzguNzY5MkM3My41MDE2IDgxLjk2NzEgNzAuMDkzNyA4MS45MzU3IDY1LjI0NzIgNzkuNjE5QzYwLjQwMDggNzcuMzAzNSAyOS43MzY0IDY0LjkxNTIgMjQuMjEyNSA2Mi4yNzZDMjEuNDUxOSA2MC45NTU2IDIwIDU5Ljg0MjggMjAgNTguNzkxNVY0OC4yNTQyQzIwIDQ4LjI1NDIgNTkuOTIyIDM5LjU2NDIgNjYuMzY2OSAzNy4yNTI0QzcyLjgxMTUgMzQuOTM5NyA3NS4wNDc2IDM0Ljg1NjcgODAuNTMyIDM2Ljg2NTZDODYuMDE3NyAzOC44NzQ5IDExOC44MTMgNDQuNzkwNSAxMjQuMjMzIDQ2Ljc3NjNMMTI0LjIzIDU3LjE2MzdDMTI0LjIzMSA1OC4yMDQgMTIyLjk4IDU5LjM0NjUgMTIwLjE0OSA2MC44MjI0WiIgZmlsbD0iIzkxMjYyNiIvPgo8cGF0aCBkPSJNMTIwLjE0NyA1MC4zNDlDMTE0LjU4NSA1My4yNDc5IDg1Ljc2OTggNjUuMDk2MyA3OS42MzUyIDY4LjI5NDFDNzMuNTAwOSA3MS40OTIgNzAuMDkzIDcxLjQ2MDYgNjUuMjQ2OSA2OS4xNDUxQzYwLjQwMDkgNjYuODI4MyAyOS43MzY5IDU0LjQ0MDkgMjQuMjEzOCA1MS44MDEzQzE4LjY4OTkgNDkuMTYyMSAxOC41NzQ2IDQ3LjM0NDEgMjQgNDUuMjE5MkMyOS40MjU5IDQzLjA5NDYgNTkuOTIxNyAzMS4xMzEgNjYuMzY3IDI4LjgxODRDNzIuODExNiAyNi41MDYxIDc1LjA0NzMgMjYuNDIzIDgwLjUzMTcgMjguNDMyNEM4Ni4wMTY2IDMwLjQ0MTcgMTE0LjY1OSA0MS44NDE4IDEyMC4wNzkgNDMuODI3NUMxMjUuNTAxIDQ1LjgxMjggMTI1LjcwOSA0Ny40NSAxMjAuMTQ3IDUwLjM0OVoiIGZpbGw9IiNDNjMwMkIiLz4KPHBhdGggZD0iTTg0Ljg1NDEgNDAuMDk5NEw3NS44OTI2IDQxLjAyOThMNzMuODg2NSA0NS44NTdMNzAuNjQ2MyA0MC40NzAzTDYwLjI5ODMgMzkuNTQwNEw2OC4wMTk3IDM2Ljc1NThMNjUuNzAzIDMyLjQ4MTRMNzIuOTMyMSAzNS4zMDg4TDc5Ljc0NzEgMzMuMDc3NUw3Ny45MDUyIDM3LjQ5NzJMODQuODU0MSA0MC4wOTk0Wk03My4zNTE1IDYzLjUxODRMNTYuNjI2NiA1Ni41ODE2TDgwLjU5MiA1Mi45MDI5TDczLjM1MTUgNjMuNTE4NFpNNTAuMTYzNyA0Mi43ODI2QzU3LjIzODEgNDIuNzgyNiA2Mi45NzMgNDUuMDA1NyA2Mi45NzMgNDcuNzQ3NUM2Mi45NzMgNTAuNDkwMSA1Ny4yMzgxIDUyLjcxMjggNTAuMTYzNyA1Mi43MTI4QzQzLjA4OTMgNTIuNzEyOCAzNy4zNTQ1IDUwLjQ4OTcgMzcuMzU0NSA0Ny43NDc1QzM3LjM1NDUgNDUuMDA1NyA0My4wODkzIDQyLjc4MjYgNTAuMTYzNyA0Mi43ODI2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTk1LjQ0MzQgNDEuNDE3NEwxMDkuNjI3IDQ3LjAyMjRMOTUuNDU1NiA1Mi42MjJMOTUuNDQzNCA0MS40MTc0WiIgZmlsbD0iIzYyMUIxQyIvPgo8cGF0aCBkPSJNNzkuNzUyOSA0Ny42MjYxTDk1LjQ0NDkgNDEuNDE4OUw5NS40NTcxIDUyLjYyMzZMOTMuOTE4NCA1My4yMjU0TDc5Ljc1MjkgNDcuNjI2MVoiIGZpbGw9IiM5QTI5MjgiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMzIxMyIgeDE9IjE4OSIgeTE9IjIxMC41IiB4Mj0iMCIgeTI9IjAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0E4MDAwMCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkNGQ0YiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "authEnabled"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`redis-{{ .name }}-auth`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`rfs-redis-{{ .name }}`}}" + - "{{`rfrm-redis-{{ .name }}`}}" + - "{{`rfrs-redis-{{ .name }}`}}" + - "{{`redis-{{ .name }}-external-lb`}}" diff --git a/packages/core/platform/psds/reloader.yaml b/packages/core/platform/psds/reloader.yaml index 979e644d..fb3f2e44 100644 --- a/packages/core/platform/psds/reloader.yaml +++ b/packages/core/platform/psds/reloader.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.reloader spec: @@ -10,12 +10,12 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: reloader - path: system/reloader - releaseName: reloader - namespace: cozy-reloader - + - name: default + dependsOn: + - cozystack.networking + components: + - name: reloader + path: system/reloader + install: + namespace: cozy-reloader + releaseName: reloader diff --git a/packages/core/platform/psds/seaweedfs.yaml b/packages/core/platform/psds/seaweedfs.yaml index 2e0b11e3..d37b128f 100644 --- a/packages/core/platform/psds/seaweedfs.yaml +++ b/packages/core/platform/psds/seaweedfs.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.seaweedfs-application spec: @@ -16,16 +16,46 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: seaweedfs-application - path: system/seaweedfs-application - releaseName: seaweedfs-application - namespace: cozy-system - sources: + components: + - name: seaweedfs-system + path: system/seaweedfs + applications: - name: seaweedfs path: extra/seaweedfs libraries: - cozy-lib - - name: seaweedfs-system - path: system/seaweedfs - + template: + spec: + application: + kind: SeaweedFS + singular: seaweedfs + plural: seaweedfses + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of database replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}},"filer":{"description":"Filer service configuration.","type":"object","default":{},"properties":{"grpcHost":{"description":"The hostname used to expose or access the filer service externally.","type":"string","default":""},"grpcPort":{"description":"The port used to access the filer service externally.","type":"integer","default":443},"replicas":{"description":"Number of filer replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"A list of IP addresses or CIDR ranges that are allowed to access the filer service.","type":"array","default":[],"items":{"type":"string"}}}},"host":{"description":"The hostname used to access SeaweedFS externally (defaults to 's3' subdomain for the tenant host).","type":"string","default":""},"master":{"description":"Master service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of master replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"replicationFactor":{"description":"Replication factor: number of replicas for each volume in the SeaweedFS cluster.","type":"integer","default":2},"s3":{"description":"S3 service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of S3 replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"topology":{"description":"The topology of the SeaweedFS cluster.","type":"string","default":"Simple","enum":["Simple","MultiZone","Client"]},"volume":{"description":"Volume service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of volume replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"zones":{"description":"A map of zones for MultiZone topology. Each zone can have its own number of replicas and size.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"replicas":{"description":"Number of replicas in the zone.","type":"integer"},"size":{"description":"Zone storage size.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + dashboard: + category: Administration + singular: SeaweedFS + plural: SeaweedFS + name: seaweedfs + description: Seaweedfs + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTEzOC42ODUgMTIxLjA1N0MxMzguNjg1IDEyNi42NTIgMTM2LjQ2MiAxMzIuMDE3IDEzMi41MDQgMTM1Ljk3M0MxMjguNTQ3IDEzOS45MjkgMTIzLjE3OSAxNDIuMTUxIDExNy41ODIgMTQyLjE1MUMxMTEuOTg1IDE0Mi4xNTEgMTA2LjYxOCAxMzkuOTI5IDEwMi42NiAxMzUuOTczQzk4LjcwMjggMTMyLjAxNyA5Ni40Nzk1IDEyNi42NTIgOTYuNDc5NSAxMjEuMDU3Qzk2LjQ3OTUgMTE4LjI4NyA5Ny4wMjUzIDExNS41NDQgOTguMDg1OCAxMTIuOTg1Qzk5LjE0NjMgMTEwLjQyNSAxMDAuNzAxIDEwOC4xIDEwMi42NiAxMDYuMTQxQzEwNC42MiAxMDQuMTgyIDEwNi45NDYgMTAyLjYyOSAxMDkuNTA3IDEwMS41NjlDMTEyLjA2NyAxMDAuNTA5IDExNC44MTEgOTkuOTYyOSAxMTcuNTgyIDk5Ljk2MjlDMTIwLjM1MyA5OS45NjI5IDEyMy4wOTggMTAwLjUwOSAxMjUuNjU4IDEwMS41NjlDMTI4LjIxOCAxMDIuNjI5IDEzMC41NDQgMTA0LjE4MiAxMzIuNTA0IDEwNi4xNDFDMTM0LjQ2NCAxMDguMSAxMzYuMDE4IDExMC40MjUgMTM3LjA3OSAxMTIuOTg1QzEzOC4xMzkgMTE1LjU0NCAxMzguNjg1IDExOC4yODcgMTM4LjY4NSAxMjEuMDU3WiIgZmlsbD0idXJsKCNwYWludDFfcmFkaWFsXzY3OV8xOTEwKSIvPgo8cGF0aCBkPSJNMTEwLjMzNiAxMjYuMTQ3SDEyMy42OFYxMzYuODIzSDExMC4zMzZWMTI2LjE0N1oiIGZpbGw9IiMwRjVFOUMiLz4KPHBhdGggZD0iTTExOS4yNyAxMTIuMjk0QzExOS4yNyAxMTIuNzE0IDExOS4xNzggMTEzLjEzMSAxMTkgMTEzLjUxOUMxMTguODIxIDExMy45MDggMTE4LjU2IDExNC4yNjEgMTE4LjIzIDExNC41NThDMTE3LjkwMSAxMTQuODU1IDExNy41MDkgMTE1LjA5MSAxMTcuMDc5IDExNS4yNTJDMTE2LjY0OCAxMTUuNDEzIDExNi4xODYgMTE1LjQ5NiAxMTUuNzIgMTE1LjQ5NkMxMTQuNzc4IDExNS40OTYgMTEzLjg3NSAxMTUuMTU4IDExMy4yMSAxMTQuNTU4QzExMi41NDQgMTEzLjk1NyAxMTIuMTcgMTEzLjE0MyAxMTIuMTcgMTEyLjI5NEMxMTIuMTcgMTExLjQ0NSAxMTIuNTQ0IDExMC42MyAxMTMuMjEgMTEwLjAzQzExMy44NzUgMTA5LjQyOSAxMTQuNzc4IDEwOS4wOTIgMTE1LjcyIDEwOS4wOTJDMTE2LjE4NiAxMDkuMDkyIDExNi42NDggMTA5LjE3NSAxMTcuMDc5IDEwOS4zMzZDMTE3LjUwOSAxMDkuNDk2IDExNy45MDEgMTA5LjczMiAxMTguMjMgMTEwLjAzQzExOC41NiAxMTAuMzI3IDExOC44MjEgMTEwLjY4IDExOSAxMTEuMDY4QzExOS4xNzggMTExLjQ1NyAxMTkuMjcgMTExLjg3MyAxMTkuMjcgMTEyLjI5NFoiIGZpbGw9IiM1OTY4NkYiLz4KPHBhdGggZD0iTTEyOC4xMSAxMTQuMTAzQzEyOC4xMSAxMTQuOTUzIDEyNy43MzYgMTE1Ljc2NyAxMjcuMDcgMTE2LjM2OEMxMjYuNDA0IDExNi45NjggMTI1LjUwMSAxMTcuMzA1IDEyNC41NiAxMTcuMzA1QzEyNC4wOTQgMTE3LjMwNSAxMjMuNjMyIDExNy4yMjMgMTIzLjIwMSAxMTcuMDYyQzEyMi43NzEgMTE2LjkwMSAxMjIuMzc5IDExNi42NjUgMTIyLjA1IDExNi4zNjhDMTIxLjcyIDExNi4wNyAxMjEuNDU4IDExNS43MTcgMTIxLjI4IDExNS4zMjlDMTIxLjEwMiAxMTQuOTQgMTIxLjAxIDExNC41MjQgMTIxLjAxIDExNC4xMDNDMTIxLjAxIDExMy42ODMgMTIxLjEwMiAxMTMuMjY2IDEyMS4yOCAxMTIuODc4QzEyMS40NTggMTEyLjQ5IDEyMS43MiAxMTIuMTM3IDEyMi4wNSAxMTEuODM5QzEyMi4zNzkgMTExLjU0MiAxMjIuNzcxIDExMS4zMDYgMTIzLjIwMSAxMTEuMTQ1QzEyMy42MzIgMTEwLjk4NCAxMjQuMDk0IDExMC45MDEgMTI0LjU2IDExMC45MDFDMTI1LjUwMSAxMTAuOTAxIDEyNi40MDQgMTExLjIzOSAxMjcuMDcgMTExLjgzOUMxMjcuNzM2IDExMi40NCAxMjguMTEgMTEzLjI1NCAxMjguMTEgMTE0LjEwM1oiIGZpbGw9IiM1OTY4NkYiLz4KPHBhdGggZD0iTTEyMi4zMzMgMTE4Ljk3NkMxMjIuMzMzIDExOS44MjYgMTIxLjk1OCAxMjAuNjQgMTIxLjI5MyAxMjEuMjQxQzEyMC42MjcgMTIxLjg0MSAxMTkuNzI0IDEyMi4xNzggMTE4Ljc4MiAxMjIuMTc4QzExOC4zMTYgMTIyLjE3OCAxMTcuODU1IDEyMi4wOTYgMTE3LjQyNCAxMjEuOTM1QzExNi45OTMgMTIxLjc3NCAxMTYuNjAyIDEyMS41MzggMTE2LjI3MiAxMjEuMjQxQzExNS45NDMgMTIwLjk0MyAxMTUuNjgxIDEyMC41OSAxMTUuNTAzIDEyMC4yMDJDMTE1LjMyNCAxMTkuODEzIDExNS4yMzIgMTE5LjM5NyAxMTUuMjMyIDExOC45NzZDMTE1LjIzMiAxMTguNTU2IDExNS4zMjQgMTE4LjE0IDExNS41MDMgMTE3Ljc1MUMxMTUuNjgxIDExNy4zNjMgMTE1Ljk0MyAxMTcuMDEgMTE2LjI3MiAxMTYuNzEyQzExNi42MDIgMTE2LjQxNSAxMTYuOTkzIDExNi4xNzkgMTE3LjQyNCAxMTYuMDE4QzExNy44NTUgMTE1Ljg1NyAxMTguMzE2IDExNS43NzQgMTE4Ljc4MiAxMTUuNzc0QzExOS43MjQgMTE1Ljc3NCAxMjAuNjI3IDExNi4xMTIgMTIxLjI5MyAxMTYuNzEyQzEyMS45NTggMTE3LjMxMyAxMjIuMzMzIDExOC4xMjcgMTIyLjMzMyAxMTguOTc2WiIgZmlsbD0iIzU5Njg2RiIvPgo8cGF0aCBkPSJNMTE1LjMwOCAxMjEuOTA1QzExMy43MzUgMTIxLjQyNiAxMTUuNzA3IDEyMC42OCAxMTUuNDI5IDEyMC41NzNDMTE0LjY1MyAxMjAuMjc2IDExNS43MyAxMTkuMzMzIDExNi43NCAxMTguNTM5QzExNy42MjggMTE3Ljg0MSAxMTcuNjU5IDExNy44MzkgMTE3Ljg5MiAxMTguNDY4QzExOC4wMjQgMTE4LjgyMyAxMTguMzcxIDExOS4yMDYgMTE4LjY2NSAxMTkuMzE5QzExOS4yODkgMTE5LjU1OCAxMjAuOTUxIDExOS4yNjkgMTIwLjk1MSAxMTguODM1QzEyMC45NTEgMTE4LjIyMyAxMjEuNDE1IDExOC42OTkgMTIxLjc5NCAxMTkuNTMxQzEyMi40NTcgMTIwLjk4NyAxMjIuNDM3IDEyMi40NzIgMTIxLjQ1IDEyMi40NzJDMTIwLjg1OSAxMjIuNDcyIDEyMC4zMSAxMjIuNjkxIDEyMC4xOSAxMjMuMTQ3QzExNS4wNDYgMTI0LjYgMTE2LjQ3MSAxMjMuMjg0IDExNS4zMDggMTIxLjkwNVpNMTIzLjA5NCAxMTguMDU0QzEyMS42MDkgMTE3LjQ2NiAxMjAuNTQ3IDExNC44MzggMTIwLjU0NyAxMTMuMzA5QzEyMC41NDcgMTExLjMyMyAxMjIuNTQxIDEwOS4wOTUgMTI0LjMxNyAxMDkuMDk1QzEyOC4zMTUgMTA5LjA5NSAxMzAuNjg0IDExMi4yNjEgMTI4LjgzOCAxMTguNDA5QzEyOC4zODUgMTE5LjkxOSAxMjMuOTMzIDExOC4zODcgMTIzLjA5NCAxMTguMDU0Wk0xMjUuODY2IDExNS42NDlDMTI3LjU0NCAxMTQuNDc0IDEyNS44NTcgMTExLjc1NSAxMjMuOTgxIDExMi42MUMxMjIuNDc5IDExMy4yOTQgMTIzLjExOSAxMTYuMTE1IDEyNC43NyAxMTYuMTY0QzEyNC45NjEgMTE2LjE2OSAxMjUuNDU0IDExNS45MzggMTI1Ljg2NiAxMTUuNjQ5Wk0xMjQuMzM5IDExNC41NzlDMTIzLjc3MSAxMTQuMzgxIDEyMy44MDMgMTEzLjI1NiAxMjQuMzgzIDExMy4wMzRDMTI0LjkwMiAxMTIuODM1IDEyNS42MDQgMTEzLjM5OCAxMjUuNjA0IDExNC4wMTRDMTI1LjYwNCAxMTQuNDg5IDEyNC45MzYgMTE0Ljc4NyAxMjQuMzM5IDExNC41NzlaTTExMi4zMTkgMTE2Ljk4QzEwOS45NiAxMTUuNjcgMTEwLjI4NiAxMTEuMDA2IDExMi40MTcgMTA4Ljk2NUMxMTQuMzk2IDEwNy4wNjkgMTE4Ljc3OCAxMDcuMTAzIDExOS43NjQgMTA5LjQ2MkMxMjAuNDE1IDExMS4wMjEgMTIwLjIyOCAxMTIuNiAxMTkuMzk4IDExNC4wNzdDMTE4LjE5NCAxMTYuMjE5IDExNC4yNDIgMTE4LjA0OSAxMTIuMzE5IDExNi45OFpNMTE2LjU2IDExMy41OTNDMTE3LjMyNSAxMTIuOTAxIDExNy4yOTcgMTEyLjA2IDExNi41NzIgMTExLjI1OUMxMTUuNzc3IDExMC4zNzkgMTE0LjY5MiAxMTAuMzQ1IDExNC4wMzUgMTExLjM0N0MxMTMuNTI0IDExMi4xMjcgMTEzLjQzMSAxMTIuNTI4IDExMy45NDMgMTEzLjMwOUMxMTQuNTggMTE0LjI4IDExNS42NyAxMTQuMzk5IDExNi41NiAxMTMuNTkzWk0xMTQuMzc0IDExMi4zNEMxMTQuMTI4IDExMS42OTggMTE0Ljk4NSAxMTAuOTgxIDExNS42OCAxMTEuMjQ3QzExNS45NzQgMTExLjM2IDExNi4xNjQgMTExLjcxOCAxMTYuMTAyIDExMi4wNDRDMTE1Ljk2MSAxMTIuNzg1IDExNC42MzIgMTEzLjAxMiAxMTQuMzc0IDExMi4zNFoiIGZpbGw9IiNEM0Q2REEiLz4KPHBhdGggZD0iTTExOC40NjMgMTIxLjAwOEwxMTcuOTQ1IDEyMC43OEMxMTcuNTEgMTIwLjY4NSAxMTcuMjMxIDEyMS4xMDcgMTE3LjEzNiAxMjEuNTQzTDExNi44ODEgMTIyLjcwOUMxMTYuNzg2IDEyMy4xNDUgMTE3LjA2MSAxMjMuNTcxIDExNy40OTYgMTIzLjY2NkwxMTguNDQ3IDEyMy44NzRDMTE4Ljg4MiAxMjMuOTY5IDExOS4zMTEgMTIzLjY5NCAxMTkuNDA2IDEyMy4yNTlMMTE5LjY4NSAxMjEuNTU2QzExOS43OCAxMjEuMTIgMTE5LjQ3OSAxMjEuMjI4IDExOS4wNDMgMTIxLjEzM0wxMTguNjI4IDEyMS4wNDNDMTE4LjU3MyAxMjEuMzIxIDExOC41MTYgMTIxLjYxMyAxMTguNDcxIDEyMS44MzNDMTE4LjQzOCAxMjEuOTk4IDExOC40MDcgMTIyLjE0OCAxMTguMzc5IDEyMi4yODJDMTE4LjM1MSAxMjIuNDE1IDExOC4zMjcgMTIyLjUzMyAxMTguMzA1IDEyMi42MzVDMTE4LjI4MiAxMjIuNzM4IDExOC4yNjIgMTIyLjgyNSAxMTguMjQ1IDEyMi44OTdDMTE4LjIyOCAxMjIuOTY5IDExOC4yMTQgMTIzLjAyNSAxMTguMjAyIDEyMy4wNjhDMTE4LjE5NiAxMjMuMDg5IDExOC4xOTMgMTIzLjEwNyAxMTguMTg4IDEyMy4xMjFDMTE4LjE4MyAxMjMuMTM1IDExOC4xNzggMTIzLjE0NSAxMTguMTc1IDEyMy4xNTJDMTE4LjE3MyAxMjMuMTU1IDExOC4xNzIgMTIzLjE1NiAxMTguMTcxIDEyMy4xNThDMTE4LjE3IDEyMy4xNTkgMTE4LjE2OCAxMjMuMTYgMTE4LjE2NyAxMjMuMTZMMTE4LjE2NSAxMjMuMTU4QzExOC4xNjQgMTIzLjE1NiAxMTguMTYzIDEyMy4xNTIgMTE4LjE2MyAxMjMuMTQ4QzExOC4xNjIgMTIzLjE0IDExOC4xNjIgMTIzLjEyOSAxMTguMTYzIDEyMy4xMTVDMTE4LjE2MyAxMjMuMSAxMTguMTYzIDEyMy4wODMgMTE4LjE2NSAxMjMuMDYxQzExOC4xNjggMTIzLjAxOCAxMTguMTc1IDEyMi45NjEgMTE4LjE4MyAxMjIuODkxQzExOC4xOTIgMTIyLjgyIDExOC4yMDMgMTIyLjczNiAxMTguMjE2IDEyMi42NEMxMTguMjI5IDEyMi41NDMgMTE4LjI0NiAxMjIuNDMxIDExOC4yNjQgMTIyLjMwOEMxMTguMjgxIDEyMi4xODUgMTE4LjMwMSAxMjIuMDUxIDExOC4zMjMgMTIxLjkwM0MxMTguMzQ2IDEyMS43NTUgMTE4LjM3IDEyMS41OTIgMTE4LjM5NyAxMjEuNDE5QzExOC40MTYgMTIxLjI5OSAxMTguNDQyIDEyMS4xNCAxMTguNDYzIDEyMS4wMDhaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDMuNTgxIDExNi4zNjdDMTAzLjQ3OSAxMTYuMTAzIDEwMy42MjIgMTE1LjY5OSAxMDMuODk4IDExNS40NjlDMTA0LjMwMyAxMTUuMTMzIDEwNC41MDQgMTE1LjE1NSAxMDQuOTMgMTE1LjU4MUMxMDUuMjIgMTE1Ljg3MSAxMDUuMzU1IDExNi4yNzYgMTA1LjIzIDExNi40NzlDMTA0LjkwMiAxMTcuMDA5IDEwMy43OTggMTE2LjkzNCAxMDMuNTgxIDExNi4zNjdaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDYuMDM4IDExMi4yODFDMTA1LjY4IDExMS44NDkgMTA1LjcwMiAxMTEuNjYgMTA2LjE2NSAxMTEuMTk3QzEwNi42ODkgMTEwLjY3NCAxMDYuNzY0IDExMC42NzQgMTA3LjI4NyAxMTEuMTk3QzEwNy43NTEgMTExLjY2IDEwNy43NzMgMTExLjg0OSAxMDcuNDE1IDExMi4yODFDMTA3LjE3NiAxMTIuNTY4IDEwNi44NjYgMTEyLjgwMyAxMDYuNzI2IDExMi44MDNDMTA2LjU4NiAxMTIuODAzIDEwNi4yNzcgMTEyLjU2OCAxMDYuMDM4IDExMi4yODFaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDYuMDM4IDEwNy4yMjRDMTA1LjY4MiAxMDYuNzk1IDEwNS42OTQgMTA2LjYxMiAxMDYuMTA2IDEwNi4yMDFDMTA2LjY1IDEwNS42NTcgMTA3LjczOCAxMDUuODggMTA3LjczOCAxMDYuNTM2QzEwNy43MzggMTA2Ljk3IDEwNy4wNzIgMTA3Ljc0NyAxMDYuNyAxMDcuNzQ3QzEwNi41NzUgMTA3Ljc0NyAxMDYuMjc3IDEwNy41MTIgMTA2LjAzOCAxMDcuMjI0WiIgZmlsbD0iIzk4QzZEOCIvPgo8cGF0aCBkPSJNMTE3Ljk1NSAxMzYuNTQxQzExNC41NzggMTM2LjExMSAxMTAuMDg3IDEzNC44ODEgMTA5LjQxIDEzNC4yNzRDMTA4LjEyMyAxMzMuMTE5IDEwOC45NDIgMTI3Ljg3OSAxMTAuNDY2IDEyNi41NEMxMTEuMzg3IDEyNS43MzEgMTE1LjAzOSAxMjQuNjYzIDExNy4xODIgMTI1LjE2OUMxMTkuNjQyIDEyNS43NDkgMTIzLjkzMiAxMjguNjQ4IDEyNC4yNSAxMjkuNTA4QzEyNC42MjUgMTMwLjUyMiAxMjQuMDQ4IDEzNC41NDEgMTIzLjMyMyAxMzUuNTM2QzEyMi42OTQgMTM2LjM5OSAxMjAuMzI1IDEzNi44NDMgMTE3Ljk1NSAxMzYuNTQxWk0xMjAuNTQgMTM0LjA4NEMxMjEuMjk3IDEzMy4zOTkgMTIxLjM0MiAxMzEuODQyIDEyMC42MjcgMTMxLjEyNkMxMTkuNDkgMTI5Ljk4OSAxMTcuMTEyIDEzMC44NjkgMTE3LjExMiAxMzIuNDI4QzExNy4xMTIgMTM0LjMwNCAxMTkuMTg5IDEzNS4zMDcgMTIwLjU0IDEzNC4wODRaTTExOC41ODIgMTMzLjEyNUMxMTguMzExIDEzMi40MTkgMTE4LjY4IDEzMS42MDggMTE5LjI3MiAxMzEuNjA4QzEyMCAxMzEuNjA4IDEyMC4yMjggMTMyLjE3MyAxMTkuODEyIDEzMi45NDlDMTE5LjM4MSAxMzMuNzU1IDExOC44NTMgMTMzLjgzIDExOC41ODIgMTMzLjEyNVpNMTE2LjQyMiAxMzMuMTQzQzExNy4wOTQgMTMyLjMzMyAxMTYuNzExIDEzMS4xNzYgMTE1LjY4MSAxMzAuOTAyQzExNC41ODEgMTMwLjYxIDExNC4wNTIgMTMxLjE4MyAxMTQuODY5IDEzMS43OEMxMTUuNjgzIDEzMi4zNzUgMTE1LjU1MSAxMzIuNjc5IDExNC41MzMgMTMyLjU1N0MxMTMuMzI3IDEzMi40MTMgMTEyLjgzMyAxMzEuNTY2IDExMy4yNTQgMTMwLjM2MkMxMTMuNjgxIDEyOS4xNDIgMTE1LjE5NyAxMjguODYzIDExNS43NTMgMTI5LjkwMkMxMTYuMTkzIDEzMC43MjUgMTE2LjYyNyAxMzAuNzkzIDExNi45IDEzMC4wODNDMTE3LjIyOSAxMjkuMjI0IDExNS45MTQgMTI4LjIzNyAxMTQuNDQgMTI4LjIzN0MxMTEuOTkzIDEyOC4yMzcgMTEwLjgxNiAxMzEuMDc0IDExMi41NDYgMTMyLjgwM0MxMTMuNSAxMzMuNzU4IDExNS43NDkgMTMzLjk1NSAxMTYuNDIyIDEzMy4xNDNaIiBmaWxsPSIjN0JBOUI5Ii8+CjxwYXRoIGQ9Ik0xMjAuMTE4IDEzOC41OTJDMTE4Ljc1MSAxMzcuMjk3IDEyMS45MTYgMTM2LjA5NiAxMjMuNjA2IDEzOC4yODNDMTI0LjQ2OSAxMzkuMzIyIDEyMi44NTMgMTM5Ljk3NiAxMjAuMTE4IDEzOC41OTJaTTEwNi4xMiAxMzUuNjU4QzEwNC43NTEgMTM0LjI4OSAxMDYuOTYzIDEzMy45MDQgMTA4LjU4MSAxMzUuMjNMMTA5Ljk0MSAxMzUuOTJMMTA4LjA1OSAxMzYuMDYxQzEwNy4yMTUgMTM2LjA2MiAxMDYuMzQzIDEzNS44ODEgMTA2LjEyIDEzNS42NThWMTM1LjY1OFpNMTI1LjM2MyAxMjcuODY2QzEyNS4wODIgMTI3LjQxIDEyOC4zMzMgMTI2LjI2NyAxMjguNjg4IDEyNi40ODZDMTI4Ljg0NiAxMjYuNTg0IDEyOC45NzUgMTI3LjMzNyAxMjguOTc1IDEyOC4xNjFDMTI4Ljk3NSAxMjkuMjM5IDEyOC44NCAxMjkuNjU4IDEyOC40OSAxMjkuNjU4QzEyOC4yMjIgMTI5LjY1OCAxMjUuNDc2IDEyOC4wNDcgMTI1LjM2MyAxMjcuODY2Wk0xMTguNjQxIDEyMS4wOTVDMTE0Ljg3MSAxMjAuNzUzIDExNS4zNzggMTE5LjMyNyAxMTYuMzYxIDExOC40OTlDMTE2LjkyOCAxMTguMDIxIDExNy4zNCAxMTcuNzc5IDExNy45MTMgMTE3LjY2N0MxMTcuOTEzIDExNy42NjcgMTE3Ljg3MiAxMTkuMDQ2IDExOC42NjYgMTE5LjMxOUMxMTkuMjk3IDExOS41MzYgMTIwLjI3OCAxMTkuMDY0IDEyMC40NzEgMTE4LjY3NUMxMjIuMTg4IDExNS4yMDEgMTIxLjQxNSAxMTguNjk5IDEyMS43OTQgMTE5LjUzMkMxMjMuMjM4IDEyNC4wMDcgMTIwLjE4OCAxMjEuNzMgMTE4LjY0MSAxMjEuMDk1Wk0xMDQuOTEyIDEyMS4yM0MxMDQuMjQyIDEyMC40ODcgMTAzLjY5MyAxMTkuNzI5IDEwMy42OTMgMTE5LjU0NEMxMDMuNjkzIDExOS4xMTYgMTA0Ljc0NiAxMTkuMTEyIDEwNS44NjMgMTE5LjUzN0MxMDYuNTkzIDExOS44MTQgMTEwLjM0NyAxMjAuMDA2IDExMC4zNDcgMTIxLjE1M0MxMTAuMzQ3IDEyMS44OTkgMTA4Ljg5IDEyMy43NjIgMTA4LjcyNiAxMjMuNzYyQzEwOC41NjMgMTIzLjc2MiAxMDUuNTgzIDEyMS45NzIgMTA0LjkxMiAxMjEuMjNaIiBmaWxsPSIjQTZCM0MyIi8+CjxwYXRoIGQ9Ik0xMTguNDYzIDEyMS4wMDhDMTE4LjQ0MiAxMjEuMTQgMTE4LjQxNiAxMjEuMjk5IDExOC4zOTcgMTIxLjQxOUMxMTguMzcgMTIxLjU5MiAxMTguMzQ1IDEyMS43NTUgMTE4LjMyMyAxMjEuOTAzQzExOC4zIDEyMi4wNTEgMTE4LjI4MSAxMjIuMTg1IDExOC4yNjMgMTIyLjMwOEMxMTguMjQ1IDEyMi40MzEgMTE4LjIyOSAxMjIuNTQyIDExOC4yMTYgMTIyLjYzOUMxMTguMjAzIDEyMi43MzYgMTE4LjE5MSAxMjIuODIgMTE4LjE4MyAxMjIuODlDMTE4LjE3NSAxMjIuOTYxIDExOC4xNjggMTIzLjAxOCAxMTguMTY1IDEyMy4wNjFDMTE4LjE2MyAxMjMuMDgzIDExOC4xNjQgMTIzLjEgMTE4LjE2MyAxMjMuMTE1QzExOC4xNjIgMTIzLjEyOSAxMTguMTYyIDEyMy4xNCAxMTguMTYzIDEyMy4xNDhDMTE4LjE2MyAxMjMuMTUyIDExOC4xNjQgMTIzLjE1NiAxMTguMTY1IDEyMy4xNThMMTE4LjE2NyAxMjMuMTZDMTE4LjE2OCAxMjMuMTYgMTE4LjE3IDEyMy4xNTkgMTE4LjE3MSAxMjMuMTU4QzExOC4xNzIgMTIzLjE1NyAxMTguMTczIDEyMy4xNTUgMTE4LjE3NSAxMjMuMTUyQzExOC4xNzggMTIzLjE0NSAxMTguMTgyIDEyMy4xMzUgMTE4LjE4NyAxMjMuMTIxQzExOC4xOTIgMTIzLjEwNyAxMTguMTk2IDEyMy4wODkgMTE4LjIwMiAxMjMuMDY3QzExOC4yMTMgMTIzLjAyNSAxMTguMjI4IDEyMi45NjkgMTE4LjI0NSAxMjIuODk3QzExOC4yNjIgMTIyLjgyNSAxMTguMjgyIDEyMi43MzggMTE4LjMwNSAxMjIuNjM1QzExOC4zMjcgMTIyLjUzMyAxMTguMzUxIDEyMi40MTUgMTE4LjM3OSAxMjIuMjgxQzExOC40MDYgMTIyLjE0OCAxMTguNDM4IDEyMS45OTggMTE4LjQ3MSAxMjEuODMzQzExOC41MTYgMTIxLjYxMyAxMTguNTczIDEyMS4zMjEgMTE4LjYyOCAxMjEuMDQzTDExOC40NjMgMTIxLjAwOFoiIGZpbGw9IiM0QzlDQkIiLz4KPHBhdGggZD0iTTMwLjk5ODYgMTQyLjY3M0MyNi40NDg5IDE0MC45MTYgMjEuNDY2NCAxMzYuODA1IDE4Ljc5MjEgMTMyLjYwM0MxNS40MDUzIDEyNy4yODEgMTQuNDA1MiAxMjMuNDE5IDE1LjA2MzYgMTE4LjIwM0MxNS42ODA2IDExMy4zMTUgMTcuMzU1OCAxMTAuNTU3IDIyLjIyMzIgMTA2LjQxM0MyOS4wNDE3IDEwMC42MDggMzQuNDg0NiA5Ny45Nzk5IDQwLjU5NDcgOTcuNTQxNUM0OS44MjEyIDk2Ljg3OTQgNTUuMDk3OCA5OS44MTA5IDU3LjY0NjUgMTA3LjAxNUM1OC41MDQzIDEwOS40MzkgNTguNjg1NiAxMTUuNTcgNTguMDU0NCAxMjAuODA5QzU3LjgzMTEgMTIyLjY2MyA1Ny40Nzg5IDEyNi4wNTUgNTcuMjcxOCAxMjguMzQ4QzU2LjU0NjcgMTM2LjM3NSA1NC40MTQ3IDE0MC40MTcgNDkuNjI1MyAxNDIuODQzQzQ4LjI5NzkgMTQzLjUxNiA0Ny43MTk5IDE0My41NjEgNDAuNjkyNCAxNDMuNTM5QzMzLjUxNTEgMTQzLjUxNiAzMy4wODEgMTQzLjQ3OCAzMC45OTg2IDE0Mi42NzNaTTAuMDc5NTc2NSAxMDQuOTY1QzAuMDgxNTcyMyAxMDMuODUzIDAuMTQ0NDAzIDEwMy40MzggMC4yMTk0MjcgMTA0LjA0NEMwLjI5NDQ1MSAxMDQuNjUgMC4yOTI4OTkgMTA1LjU2IDAuMjE1OTk2IDEwNi4wNjdDMC4xMzkwNzkgMTA2LjU3MyAwLjA3NzY4MzggMTA2LjA3OCAwLjA3OTU3NjUgMTA0Ljk2NVpNMC4wMDE3MzM1MSAxMDIuMjRDMC4wMTc4OTkyIDEwMS44NDggMC4wOTc3ODk3IDEwMS43NjggMC4yMDUzOTggMTAyLjAzN0MwLjMwMjc3MiAxMDIuMjggMC4yOTA3OTcgMTAyLjU3MSAwLjE3ODc4NyAxMDIuNjgzQzAuMDY2Nzc0OCAxMDIuNzk1IC0wLjAxMjkwMjEgMTAyLjU5NiAwLjAwMTczMzUxIDEwMi4yNFpNMC4wMjgzNDQ0IDc1LjEzMjZDMC4wMjgzNDQ0IDc0LjY2OTEgMC4xMDQ4NTcgNzQuNDc5NSAwLjE5ODM2OSA3NC43MTEyQzAuMjkxODg0IDc0Ljk0MyAwLjI5MTg4NCA3NS4zMjIyIDAuMTk4MzY5IDc1LjU1MzlDMC4xMDQ4NTcgNzUuNzg1NyAwLjAyODM0NDQgNzUuNTk2MSAwLjAyODM0NDQgNzUuMTMyNloiIGZpbGw9InVybCgjcGFpbnQyX3JhZGlhbF82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTM1LjMxMzMgMTEyLjU0NEwzNy45IDExMS4wOTFMMzkuMzUxNyAxMjEuNDZMMzkuMjQ4IDEyOC45MjZMMzUuMzcwMyAxMzAuODUxTDMyLjkyMjkgMTI2LjQzN0wzNS4zMTMzIDExMi41NDRaIiBmaWxsPSIjMzA2MEFEIi8+CjxwYXRoIGQ9Ik0zOC43Mjk1IDExNi42OUwzOS4zNTE2IDEyNC41NzFMNDMuMjkxOSAxMjUuOTE5TDQzLjM5NTYgMTA5LjIyNUw0MC4xODEyIDExMC4wNTRMMzguNzI5NSAxMTYuNjlaIiBmaWxsPSIjNjA2MzY4Ii8+CjxwYXRoIGQ9Ik0zNS4zNjk5IDEzMC44NTFDMzMuMDMyNCAxMjkuNzMgMjkuNzMwMSAxMjYuNDA4IDI4LjY2MjEgMTI0LjEwM0MyOC4wMzMyIDEyMi43NDUgMjcuNjM5NyAxMjIuMzEgMjYuODkyMyAxMjIuMTQ2QzI1Ljc4NzkgMTIxLjkwMyAyNS44MDg0IDEyMS45NzEgMjYuMzIxOCAxMjAuMjU4QzI2LjU5MzYgMTE5LjM1IDI2LjkwMzIgMTE4Ljk1NCAyNy4zNDA2IDExOC45NTRDMjcuNjg2MiAxMTguOTU0IDI5LjE1OTcgMTE3Ljg0MSAzMC42MTQ5IDExNi40OEMzMi4wNzAyIDExNS4xMTkgMzMuNzIyNiAxMTMuNjc3IDM0LjI4NjkgMTEzLjI3NUwzNS4zMTI5IDExMi41NDRMMzUuNjc2NyAxMTQuMjQxQzM3LjA0NDMgMTIwLjYxOCAzNy4wMjcgMTI0LjI2NiAzNS42MTk4IDEyNi4yNDNDMzQuNTUyMSAxMjcuNzQ0IDM0Ljg0MTcgMTI4LjM5MyAzNi41NzkxIDEyOC4zOTNDMzcuMzk3IDEyOC4zOTMgMzcuODIyMiAxMjguMTg1IDM4LjEzMDUgMTI3LjYzNEMzOC42NzQ4IDEyNi42NjMgMzguNjMxNSAxMjAuOTY4IDM4LjA0NTQgMTE2LjQyNkMzNy4zNDQ2IDExMC45OTUgMzcuMzEyNyAxMTEuMTY3IDM5LjE1NzggMTEwLjM5OEM0MC4wMzYgMTEwLjAzMSA0MC44MTggMTA5Ljc5NyA0MC44OTU1IDEwOS44NzdDNDAuOTczMSAxMDkuOTU2IDQwLjgxOTEgMTExLjIzNSA0MC41NTM0IDExMi43MThDMzkuNjA2NyAxMTguMDAzIDM5LjkzMTUgMTIzLjIzOCA0MS4yNzUyIDEyNC4zNTNDNDEuNjg1MSAxMjQuNjkzIDQxLjcyMzMgMTIzLjk2OSA0MS41NDUyIDExOS4yMzJDNDEuMzE1NiAxMTMuMTIzIDQxLjUxNzQgMTEwLjkxOSA0Mi40MDc1IDEwOS44MkM0Mi45MTk4IDEwOS4xODggNDMuMjEzIDEwOS4xMTYgNDQuNDk1OSAxMDkuMzFDNDYuOTU2NiAxMDkuNjgyIDQ2Ljk1MDYgMTA5LjY2OCA0Ni4yMDk5IDExMy4yNTRDNDUuODQ5NiAxMTQuOTk5IDQ1LjQ0ODMgMTE3LjIyNCA0NS4zMTggMTE4LjJMNDUuMDgxMiAxMTkuOTczTDQ1Ljk0NDYgMTE5LjY0NUM0Ni40MTk1IDExOS40NjUgNDcuNDQxMyAxMTguOTk0IDQ4LjIxNTMgMTE4LjU5OUw0OS42MjI2IDExNy44ODFMNDkuMzg5MyAxMTguNjdDNDkuMjYxIDExOS4xMDUgNDkuMDY3MiAxMjAuNzAxIDQ4Ljk1ODcgMTIyLjIxOEw0OC43NjE0IDEyNC45NzZMNDcuMTA5NSAxMjQuMzI1QzQ2LjIwMSAxMjMuOTY3IDQ1LjMxMTYgMTIzLjY3NCA0NS4xMzMxIDEyMy42NzRDNDQuOTQxIDEyMy42NzQgNDQuODA4NSAxMjUuNTMyIDQ0LjgwODUgMTI4LjIyNEM0NC44MDg1IDEzMS44OTEgNDQuNzE3MSAxMzIuNzc1IDQ0LjMzODYgMTMyLjc3NUM0MS4wMTk4IDEzMi4yOTUgMzguNzg0MiAxMzIuNDU4IDM1LjM2OTkgMTMwLjg1MVoiIGZpbGw9IiNFRUMyM0IiLz4KPHBhdGggZD0iTTQxLjE2MzkgMTMyLjQxOEM0MS4xNjM5IDEzMi4yODMgNDEuMzQwOCAxMzAuNTE1IDQxLjY2OTIgMTI4LjE0NUM0MS45OTc3IDEyNS43NzUgNDIuMzU3NyAxMjIuOTYxIDQyLjQ2OTIgMTIxLjg5M0M0Mi41ODA4IDEyMC44MjQgNDIuNzk2OSAxMjAuMDI3IDQyLjk0OTUgMTIwLjEyMUM0My42NDQzIDEyMC41NTEgNDQuMjkzOCAxMjkuMzc1IDQ0LjA0NzQgMTMxLjQyQzQzLjg5MDkgMTMyLjcxOSA0My42NTk1IDEzMi43MzcgNDMuMzAxOSAxMzIuNjc3QzQyLjY2MDIgMTMyLjU3IDQxLjkxMDEgMTMyLjUxMyA0MS4xNjM5IDEzMi40MThaTTMyLjU5NjkgMTIyLjczNUMzMS42ODEzIDEyMi41ODMgMzAuODI0MiAxMjEuNDQyIDMwLjgyNDIgMTIwLjM3NEMzMC44MjQyIDExOS40MDcgMzIuMjM4MSAxMTcuOTM3IDMzLjE2ODUgMTE3LjkzN0MzNC42NjY2IDExNy45MzcgMzUuODM5MiAxMjAuNTEzIDM0Ljk0ODQgMTIxLjg0N0MzNC41NTE3IDEyMi40NDEgMzMuNDE0NyAxMjIuODcgMzIuNTk2OSAxMjIuNzM1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExNC4wMjEgMTM3LjQ5OEMxMDcuMzE4IDEzNS43NCAxMDYuMjczIDEzNC4xMDQgMTA2LjYwOSAxMjUuODkxQzEwNi43MTYgMTIzLjI4MSAxMDYuODg1IDEyMC41MzkgMTA2Ljk4NiAxMTkuNzk3QzEwNy41NDUgMTE1LjY2NCAxMDguMzQyIDExMi4xNzMgMTA5LjA4NiAxMTAuNTk5QzEwOS43NDQgMTA5LjIwNiAxMDkuODQyIDEwOC43MTIgMTA5LjUzNSAxMDguMzQyQzEwOC40NSAxMDcuMDM1IDExMC4zNzEgMTA0Ljk5NSAxMTEuOTEgMTA1LjgxOUMxMTIuNDU3IDEwNi4xMTEgMTEyLjkxOCAxMDYuMDc3IDExMy45NDUgMTA1LjY2NUMxMTcuMDYyIDEwNC40MTkgMTIzLjExNyAxMDUuNTcxIDEyNi44MTQgMTA4LjExNUMxMjguMTQ5IDEwOS4wMzMgMTI4LjQ4NSAxMDkuMTM2IDEyOS4wMzggMTA4Ljc5MUMxMzAuNTIzIDEwNy44NjMgMTMyLjQ1MSAxMTAuNTczIDEzMS4yNSAxMTEuOUMxMzAuNzg3IDExMi40MTIgMTMwLjc1NSAxMTIuNzA1IDEzMS4wNjUgMTEzLjU5NkMxMzEuODUgMTE1Ljg0NiAxMzEuNzk0IDExNi4xMDQgMTI4LjAwNiAxMjcuNzE5QzEyNS41OCAxMzUuMTYgMTI0LjU0MyAxMzcuMzY1IDEyMy4yNjQgMTM3LjgxMUMxMjEuNjUzIDEzOC4zNzMgMTE2LjcyMyAxMzguMjA2IDExNC4wMjEgMTM3LjQ5OFpNMTIyLjU0MSAxMzUuMjI5QzEyMy4wMDMgMTM0LjU0MSAxMjMuMzU5IDEzMy4zMTMgMTIzLjUxMyAxMzEuODc4QzEyMy43OTQgMTI5LjI1IDEyMy44MTkgMTI5LjI4MyAxMjAuMzE3IDEyNy42MDFDMTE3LjY4NSAxMjYuMzM4IDExMy44MzMgMTI1Ljk3MiAxMTEuODU1IDEyNi43OThDMTEwLjgyOSAxMjcuMjI3IDExMC41OTUgMTI3LjU1NiAxMTAuMDU5IDEyOS4zMjdDMTA5LjExNiAxMzIuNDQzIDEwOS43MDMgMTM0LjMwOCAxMTEuODMyIDEzNC45NThDMTEzLjEzOSAxMzUuMzU3IDEyMC4wOSAxMzYuNDMgMTIwLjk4IDEzNi4zN0MxMjEuNTA0IDEzNi4zMzUgMTIyLjA4MiAxMzUuOTEyIDEyMi41NDEgMTM1LjIyOVpNMTE5LjQ1MSAxMjIuNDJDMTE5LjYzIDEyMi4wODEgMTE5LjY4NSAxMjEuNTU2IDExOS42ODUgMTIxLjU1NkMxMjAuMTU2IDEyMS42NTQgMTIwLjQ4IDEyMS42ODMgMTIwLjcyNiAxMjEuNzE5QzEyMS4xMDUgMTIxLjc3NCAxMjEuNTY0IDEyMS41ODcgMTIxLjc0NSAxMjEuMzAzQzEyMi4xNDkgMTIwLjY3MSAxMjAuNDc0IDExNy43MDEgMTE5LjU0OCAxMTcuNDA4QzExOC42NjggMTE3LjEyOCAxMTUuOTM1IDExOC44MjcgMTE1LjkzNSAxMTkuNjUzQzExNS45MzUgMTIwLjAyMiAxMTYuNTUzIDEyMC40MTEgMTE2LjgzMSAxMjAuNTE4QzExNi45ODIgMTIwLjU3NiAxMTcuMjUyIDEyMC43MzggMTE3LjU3NiAxMjAuOTM4QzExNy4zOCAxMjEuMzUxIDExNy4zNDYgMTIxLjQ3OCAxMTcuMzEyIDEyMS43MjRDMTE3LjIwNCAxMjIuNDk4IDExNy40MzUgMTIyLjY4NiAxMTguNDE2IDEyMi45MTJDMTE5LjE1MSAxMjIuOTkxIDExOS4yNSAxMjIuODQ1IDExOS40NTEgMTIyLjQyWk0xMjcuMjY1IDExNi44MzZDMTMwLjkzMyAxMTMuNDc1IDEyNy4wNzQgMTA3LjQxIDEyMi43MDUgMTA5LjY3QzEyMS42MjYgMTEwLjIyOCAxMjAuNjU0IDExMi4wMTkgMTIwLjY1NCAxMTMuNDQ5QzEyMC42NTQgMTE1LjY2NCAxMjIuODMxIDExNy45MzcgMTI0Ljk1NyAxMTcuOTQxQzEyNS43MzMgMTE3Ljk0MyAxMjYuNDE0IDExNy42MTcgMTI3LjI2NSAxMTYuODM2Wk0xMTcuMTQxIDExNS42MjJDMTE5LjAzNSAxMTQuNDY4IDExOS44MDQgMTExLjc5NSAxMTguODAyIDEwOS44NTdDMTE4LjA4MiAxMDguNDY0IDExNy4wMDggMTA3LjgzIDExNS4zNjYgMTA3LjgzQzExMS41MDggMTA3LjgzIDEwOS40ODUgMTEzLjIzNCAxMTIuNDY1IDExNS41NzhDMTEzLjU3IDExNi40NDggMTE1Ljc1NCAxMTYuNDY4IDExNy4xNDEgMTE1LjYyMloiIGZpbGw9IiMwOTk2RDEiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMzMuMTc1NyAyNkwzMi4zODEgMjcuMjE5QzMxLjk0NDkgMjcuODg5IDMxLjI4MzYgMjkuMzI0OCAzMC45MDkxIDMwLjQwODhDMzAuNTM0NyAzMS40OTI4IDI5Ljk5MjIgMzIuOTcwMSAyOS43MDQzIDMzLjY5MjhDMjkuNDE2MyAzNC40MTU0IDI5LjE3MzMgMzYuMTE1IDI5LjE2MzggMzcuNDdDMjkuMTQzNiA0MC4zNTMgMjguNzQ5NCA0MS44ODg4IDI3LjYzNjQgNDMuNDIyNUMyNi45MjEyIDQ0LjQwOCAyNi42NzUxIDQ0LjUyMjMgMjUuNDUzMiA0NC40NDFDMjMuODk5NSA0NC4zMzc3IDIyLjgxNTMgNDUuMDgxNSAyMS4yMTcgNDcuMzQ4MUMyMC43MTY1IDQ4LjA1OCAyMC4xMzY3IDQ4LjYzOTMgMTkuOTI4OSA0OC42MzkzQzE5LjcyMTEgNDguNjM5MyAxOS4xODA1IDQ4LjIzMTkgMTguNzI2MiA0Ny43MzUxQzE4LjI3MTkgNDcuMjM4MiAxNy45OTQ0IDQ3LjAxMTUgMTguMTExIDQ3LjIyOThDMTguNDkgNDcuOTM5NiAxNy41OTA0IDUzLjI2MTUgMTYuODM3OCA1NC43NjQyQzE1Ljk2NyA1Ni41MDI4IDE0LjM4NzIgNTcuNzIzMyAxMi41MzU0IDU4LjA4NDNDMTEuMDA1OSA1OC4zODI2IDExLjIyODMgNTguMDkgOC43MTc5NSA2My4wOTQ2QzYuNjYzMzQgNjcuMTkwNyA1Ljk2OTM1IDY3LjgyNjQgMi42NTUzMyA2OC42NTQyQzEuNDk3MTcgNjguOTQzNCAwLjQ1ODc1OSA2OS43MTQyIDAgNzAuNTI4N1Y3Mi44MjYzQzAuMzU2MTkzIDcyLjc0NzMgMC44Mjg3MjggNzIuNjIwMyAxLjYxNDk5IDcyLjM4NzNDMi45OTQ4NiA3MS45NzgyIDQuODIzNDggNzEuNDgwNiA1LjY3ODEgNzEuMjgwNkM3LjcyOTM0IDcwLjgwMDYgOS4zOTM1MSA2OS4yMTk1IDkuOTIyNzkgNjcuMjQ2N0MxMC4yNDI0IDY2LjA1NTQgMTAuNzAzMyA2NS40MjQxIDExLjk5OTIgNjQuNDA1OEMxMy4yODQgNjMuMzk2MiAxMy43NTY1IDYyLjc1NDYgMTQuMDY3MSA2MS41OTY5QzE0LjM3MzkgNjAuNDUzMiAxNC43MDExIDYwLjAwNCAxNS40NDA3IDU5LjcwNjNDMTcuMDE1MyA1OS4wNzI0IDIwLjY0NDQgNTUuODY1NSAyMS4yMzYzIDU0LjU4NThDMjEuNTM3MyA1My45MzQ5IDIyLjExOTggNTIuNTM5OSAyMi41Mjg3IDUxLjQ4NjJDMjMuMjYzNCA0OS41OTMyIDI1LjAxOTUgNDcuMzI2MSAyNS43NTAxIDQ3LjMyNjFDMjUuOTU3NCA0Ny4zMjYxIDI3LjEwOSA0Ni43MjQ4IDI4LjMwOTMgNDUuOTkwOEMzMS4yMzc2IDQ0LjIwMDMgMzEuNTk5MSA0My40MTM2IDMxLjU5OTEgMzguODYxNEMzMS41OTkxIDM1LjY4MTQgMzEuNjg3IDM1LjE1NTcgMzIuMzQ2OCAzNC4zNjg0QzMzLjAwMzcgMzMuNTg0NyAzMy4wOTk3IDMzLjAyNDkgMzMuMTM1MSAyOS43MzkxTDMzLjE3NTcgMjZaTTI0LjMzMzggNjMuNTk1OEMyNC4yMDM3IDYzLjYxMzUgMjQuMDczOCA2My42NjE4IDIzLjkyNTggNjMuNzM2MkMyMi45Mzk3IDY0LjIzMTUgMjIuNjEzNiA2NC45MTAyIDIxLjU5NzMgNjguNTg2QzIxLjAxNzkgNzAuNjgxNSAyMC40MjEyIDcyLjA4MTkgMTkuODc5OCA3Mi42MTc4QzE5LjQyMzUgNzMuMDY5NSAxOC45MzgzIDczLjg4MjMgMTguODAxIDc0LjQyNDJDMTguMTgxIDc2Ljg3MTUgMTYuNzQ1NCA3OC42MDczIDE0LjQ0OTUgNzkuNjg3MUMxMi40NTU1IDgwLjYyNDkgMTAuNjQwNyA4Mi4xMTc5IDkuMTExMDIgODQuMDc5OEM4LjMyMTA5IDg1LjA5MjkgNy40ODc1MiA4Ni4wMjkgNy4yNTY3OCA4Ni4xNjA5QzYuNzYxNjQgODYuNDQ0IDUuNzA4OTkgODguODk0MSA0LjYwNzg1IDkyLjMyOEMzLjcxMDkyIDk1LjEyNSAxLjcxMDY1IDk3LjQ2ODIgMC40Nzg1MTQgOTcuMTY1OEMwLjI1NDkzMSA5Ny4xMTA5IDAuMTA2OTExIDk3LjExMzcgMCA5Ny4yOTAxVjEwNC40OTJDMC41NTY0MTEgMTAzLjY2NCAxLjIzNDIgMTAyLjYyOSAyLjU2MzQ3IDEwMC41NEM0LjM0NTExIDk3LjczOTcgNi40NjM4NSA5NC40ODY3IDcuMjcxNzMgOTMuMzEyNEM4LjA3OTYgOTIuMTM4MSA5LjM1Njg3IDkwLjE0ODggMTAuMTA4NiA4OC44OTE2QzExLjIzNDIgODcuMDA5MiAxMi4xMDE2IDg2LjEyNDMgMTUuMDI4NCA4My44ODMzTDE4LjU4MzEgODEuMTYyN0wyMC40MDUzIDc1Ljk4ODFDMjMuMTg5NSA2OC4wODE3IDIzLjk1ODUgNjcuMTk5NyAyNy43NjI0IDY3LjU1MTVDMjkuNDYwNSA2Ny43MDg1IDMwLjYzMzQgNjcuNjE5NiAzMi4wNzM0IDY3LjIyNjdDMzQuMTgyNiA2Ni42NTEyIDM0LjQ3OTkgNjYuMTg3MiAzMy4zNTUxIDY1LjIzMThDMzIuNjU1NCA2NC42Mzc2IDMxLjMxNTMgNjQuNjQgMjguMjM4OCA2NS4yNDE4QzI3LjMzOTcgNjUuNDE3NyAyNi45MzQzIDY1LjI3NTcgMjUuODkzMiA2NC40MTc4QzI1LjEwNTEgNjMuNzY4NCAyNC43MjQxIDYzLjU0MjYgMjQuMzMzOCA2My41OTU4Wk0zMS43MTY2IDgzLjI1OThDMzEuNjYwNSA4My4yNzQ5IDMxLjU5MjEgODMuMzEyNiAzMS41MTE1IDgzLjM3MjFDMzEuMjcwOSA4My41NSAzMC42NTM2IDgzLjc5IDMwLjEzNzkgODMuOTA1NEMyOS4zODc2IDg0LjA3MzQgMjkuMDQ5OCA4NC40OTMyIDI4LjQ0ODIgODYuMDA0NUMyOC4wMzQ3IDg3LjA0MzIgMjcuNDkxNSA4OC4xMTUzIDI3LjI0MTIgODguMzg2M0MyNi45OTA5IDg4LjY1NzMgMjYuNDc1IDg5LjU1MSAyNi4wOTQxIDkwLjM3MzJDMjQuOTQyMiA5Mi44NTkyIDIzLjUyODIgOTQuMDYxOCAxOS45MDExIDk1LjY0MjFDMTYuNjEwNyA5Ny4wNzU2IDE2LjU2NyA5Ny4xMDg2IDE1LjY2NzEgOTguOTgwMkMxNS4xMDI3IDEwMC4xNTQgMTQuNjc5MiAxMDEuNzU3IDE0LjU0OTkgMTAzLjIwNUMxNC4yNzMxIDEwNi4zMDIgMTMuNTk2MiAxMDcuMDMxIDkuNTIxMTggMTA4LjYxNkM1LjkxNDk3IDExMC4wMTkgMy41NzcwMiAxMTEuNzQ1IDMuNDE1ODMgMTEzLjEyM0MzLjI0MDQxIDExNC42MjMgMi41OTgxMyAxMTUuMDg0IDAuOTI5MjYgMTE0LjkwN0MwLjUzOTUyOSAxMTQuODY2IDAuMjQ0MzMyIDExNC44NTEgMCAxMTQuODgxVjEyMUMxLjAyNjU4IDExOS42NTggMi43MTkyMiAxMTguMzYxIDYuMjI0OTcgMTE2LjIwNkMxMC4zNjA0IDExMy42NjUgMTIuNzA2NSAxMTEuNTc1IDEzLjU3NzkgMTA5LjY1NEMxMy45MjYgMTA4Ljg4NyAxNC42NTQ3IDEwNy4zOTMgMTUuMTk3MSAxMDYuMzM0QzE1LjczOTUgMTA1LjI3NSAxNi4yODQ1IDEwMy45MDEgMTYuNDA4NCAxMDMuMjgxQzE2LjczMjQgMTAxLjY2IDE4LjMwMzIgMTAwLjM0OSAyMC42NjU5IDk5LjcyNkMyNS4xNzcgOTguNTM3MiAyNS43NDYxIDk4LjAxNjMgMjYuMzUyNSA5NC41MzU0QzI2Ljg1NjEgOTEuNjQ1MiAyOC42MTIgODguMDY2MSAzMC41MjY3IDg2LjAyNDZDMzEuMzA5NSA4NS4xOSAzMS45NDk1IDg0LjE4IDMxLjk0OTUgODMuNzc5MUMzMS45NDk1IDgzLjM3NjYgMzEuODg0OSA4My4yMTQ2IDMxLjcxNjYgODMuMjU5OFoiIGZpbGw9IiMzNTkxMzYiLz4KPHBhdGggZD0iTTguMDgxNzcgNzQuNDA4M0M2LjAzNDE5IDczLjg3MDUgNS44OTQ0MyA3My43MzAyIDYuMDQyNzEgNzIuMzYxNUM2LjEzMDI1IDcxLjU1MzMgNi4yNDAxNyA3MC44NTc1IDYuMjg2OTYgNzAuODE1NEM2LjMzMzc2IDcwLjc3MzMgNy43MDQ0MyA3MS4wNjg3IDkuMzMyOTIgNzEuNDcxOUMxMS45NzY4IDcyLjEyNjQgMTIuNDg2NiA3Mi4xMjM4IDE0LjA5NDcgNzEuNDQ3NEMxNi40MDQxIDcwLjQ3NiAxNy4yMzgzIDY4Ljc3NTMgMTYuNDAyMiA2Ni43NDMxQzE1Ljk0MjQgNjUuNjI1NyAxNC45MjA0IDY0LjgyODEgMTIuMjM4NCA2My40OTRDNy42NDE3IDYxLjIwNzUgNi41MzA2MiA1OS45OTkgNi4yNzQ2NSA1Ny4wMDc2QzUuODkzMzcgNTIuNTUxOSA4Ljg0Njg5IDQ5Ljk4MzYgMTQuMzUyMiA0OS45ODM2QzE1Ljk3MzMgNDkuOTgzNiAxNy44NDg3IDUwLjE5MzcgMTguNTE5NiA1MC40NTA1QzE5LjYzNjggNTAuODc4MSAxOS42OTM3IDUxLjAzOTkgMTkuMTk0NSA1Mi4zNzEyQzE4LjcxODIgNTMuNjQxNiAxOC41MDI3IDUzLjc2ODggMTcuNDg2MSA1My4zNzk2QzE1LjUxOTkgNTIuNjI3IDEyLjE5NDggNTIuODU1NCAxMS4wMDU4IDUzLjgyNDdDOS43OTA1OCA1NC44MTUzIDkuNTU3MzYgNTYuOTI1MiAxMC41MzI0IDU4LjEwNzlDMTAuODcyNyA1OC41MjA3IDEyLjkwODcgNTkuNzc5IDE1LjA1NjkgNjAuOTA0MUMxOC40NjI4IDYyLjY4ODEgMTkuMDgyIDYzLjIyMTQgMTkuODk1MSA2NS4wNzE5QzIxLjExNTIgNjcuODQ4NyAyMC42Nzg4IDcwLjM0MzcgMTguNjA3OCA3Mi40MzIzQzE2LjE2MDcgNzQuOTAwMiAxMi41NDEzIDc1LjU3OTYgOC4wODE3NyA3NC40MDgzWk0yOC45MzI4IDc0LjM4MjNDMjUuMjM2NSA3Mi45OTU4IDIzLjcxMzggNzAuNTQwNSAyMy43MTM4IDY1Ljk2NjdDMjMuNzEzOCA2Mi41MDM0IDI0LjU1ODggNjAuNDY5NyAyNi44MzMzIDU4LjQ1OTNDMjguMzk2NCA1Ny4wNzc2IDI4Ljk4NjcgNTYuODY4NiAzMS4zMjY4IDU2Ljg2ODZDMzIuODE2OCA1Ni44Njg2IDM0LjY4MjEgNTcuMjEyOSAzNS41MDA1IDU3LjYzODlDMzcuMzE2OSA1OC41ODQ2IDM4LjgzMTkgNjEuNzQyNiAzOC44NDY2IDY0LjYxNDNMMzguODU3MyA2Ni43MDQ0SDMyLjk0MjNIMjcuMDI3M0wyNy4zNDIgNjguMDU2OUMyNy41MTUgNjguODAwNyAyOC4zMzU0IDcwLjAzOTEgMjkuMTY1IDcwLjgwOUMzMC41NzczIDcyLjExOTYgMzAuODk0OSA3Mi4xOTc5IDM0LjE1NDcgNzIuMDM4NUMzNy4zOTM4IDcxLjg4MDEgMzcuNjQ2MyA3MS45NDA5IDM3Ljc4NCA3Mi45MTIyQzM3Ljk2MjYgNzQuMTcyNSAzNy4xODgyIDc0LjUyMzYgMzMuNTI0MiA3NC44NDM0QzMxLjgwODUgNzQuOTkzMiAzMC4xMDU2IDc0LjgyMjIgMjguOTMyOCA3NC4zODIzWk0zNS4wODgxIDYyLjUyNDJDMzQuOTU1OCA2MC42NzMgMzMuMzY0NCA1OS4zMjc2IDMxLjMwNzIgNTkuMzI3NkMyOS43MDg2IDU5LjMyNzYgMjguNzI4MSA2MC4wOTA5IDI3LjY2MiA2Mi4xNjU1QzI2Ljc0NTcgNjMuOTQ4NiAyNy40MTIgNjQuMjk2NSAzMS40NDg4IDY0LjE0MjVMMzUuMTkzNiA2My45OTk2TDM1LjA4ODEgNjIuNTI0MlpNNDQuMzkxNCA3NC4zNzA4QzQyLjU3MTEgNzMuNTQ2OCA0MS43MDU5IDcyLjEyODYgNDEuNjQyMSA2OS44NjQ3QzQxLjU0MTYgNjYuMjk0NCA0NC4xMTEgNjQuMTQ2OCA0OS4yNTc2IDYzLjQ5OTRDNTEuODQxNCA2My4xNzQ0IDUyLjA0OTUgNjMuMDU3NyA1MS43NTkzIDYyLjA5NjlDNTAuOTY1IDU5LjQ2NjYgNDguMjQyMyA1OC41NjQ0IDQ0LjkyNzYgNTkuODMzMUM0My40MzAzIDYwLjQwNjMgNDMuNDg2OCA2MC40MzEzIDQzLjA1MTQgNTkuMDAzMkM0Mi43ODAxIDU4LjExMzUgNDIuOTk4MiA1Ny44NTExIDQ0LjM5NSA1Ny4zODdDNDYuOTM2NCA1Ni41NDI3IDUxLjM3NDUgNTYuNjM0MiA1Mi43Nzc5IDU3LjU2QzU0LjkzOTIgNTguOTg1NyA1NS4zNzUxIDYwLjYwMTkgNTUuNTQ4NyA2Ny44MzI4TDU1LjcxMDYgNzQuNTc0NUw1NC4xMjMgNzQuNTc0QzUzLjAzNzcgNzQuNTczMyA1Mi41MzUzIDc0LjMzOTYgNTIuNTM1MyA3My44MzU0QzUyLjUzNTMgNzIuOTA2NiA1Mi4wNTI4IDcyLjkwMjQgNTAuNzUyIDczLjgxOTZDNDkuMjAxMyA3NC45MTMgNDYuMTY5NyA3NS4xNzU3IDQ0LjM5MTQgNzQuMzcwOFpNNTAuOTQ3NyA3MC44MTc1QzUxLjcwOTkgNjkuOTczNSA1Mi4wNDY4IDY4Ljk4NiA1Mi4wNDY4IDY3LjU5NjZWNjUuNTkyOUw0OS44MTgyIDY1Ljg0NThDNDUuNzE5IDY2LjMxMSA0My44NzQ5IDY5LjUxMTggNDYuNTA1OCA3MS41OTUzQzQ4LjAzNzEgNzIuODA3OSA0OS4zNTk0IDcyLjU3NjMgNTAuOTQ3NyA3MC44MTc1Wk05Mi4wMDIgNzQuNTc4OEM4OC40MDI0IDczLjQ4NjQgODYuMjQxOSA3MC4yNDY2IDg2LjI0MTkgNjUuOTQxQzg2LjI0MTkgNjAuNDA0MiA4OS41MjExIDU2LjgzMjUgOTQuNjQxIDU2Ljc5MjVDOTguNjk4OSA1Ni43NjA5IDEwMS4yNjMgNTkuNDY3OSAxMDEuNTAzIDY0LjAzNjZMMTAxLjYzIDY2LjQ1ODVMOTYuMjU2MiA2Ni41ODg1QzkzLjMwMDcgNjYuNjYgOTAuNjE1OCA2Ni44MTYgOTAuMjg5NyA2Ni45MzUxQzg5LjM4MTggNjcuMjY2OCA5MC40Nzg4IDY5Ljk0NyA5Mi4wMzA2IDcxLjE4ODZDOTMuMTU5OSA3Mi4wOTIxIDkzLjc3MSA3Mi4xOTEyIDk2LjgxNzggNzEuOTY1QzEwMC4xOTMgNzEuNzE0NCAxMDAuMzE4IDcxLjc0NDkgMTAwLjUzMSA3Mi44Njg0QzEwMC43MyA3My45MTMzIDEwMC41MDkgNzQuMDgzNSA5OC4zNTc5IDc0LjU0OEM5NS42MTAzIDc1LjE0MTIgOTMuODgyOSA3NS4xNDk2IDkyLjAwMiA3NC41Nzg4Wk05Ny45NjU5IDYzLjA4MjNDOTcuOTY1OSA2MS4xMjMxIDk2LjE4NTggNTkuMzI3NiA5NC4yNDM0IDU5LjMyNzZDOTIuMjQ5NCA1OS4zMjc2IDkwLjE0OTkgNjEuMjU2MiA5MC4xNDk5IDYzLjA4NzhDOTAuMTQ5OSA2NC4yMDcgOTAuMjc5NyA2NC4yNDU1IDk0LjA1NzkgNjQuMjQ1NUM5Ny44NDE0IDY0LjI0NTUgOTcuOTY1OSA2NC4yMDg0IDk3Ljk2NTkgNjMuMDgyM1pNMTEwLjA0MiA3NC40N0MxMDYuMTQ5IDczLjQzIDEwMy45MyA2OS40MDI5IDEwNC41NCA2NC40ODYyQzEwNS4xNjYgNTkuNDQ0MiAxMDcuOTUxIDU2Ljg3MzYgMTEyLjc5MiA1Ni44NzA1QzExNS4zNzQgNTYuODY5IDExNS44MDUgNTcuMDI0OSAxMTcuMjYgNTguNDlDMTE4Ljg3OCA2MC4xMTg1IDExOS45NDEgNjIuODM0MyAxMTkuOTQ2IDY1LjM1MkwxMTkuOTQ5IDY2LjcwNDRIMTE0LjA4N0MxMDguNDg4IDY2LjcwNDQgMTA4LjIyNSA2Ni43NTAxIDEwOC4yMjUgNjcuNzIwM0MxMDguMjI1IDcwLjcxMjIgMTEwLjk1MiA3Mi4zNDQyIDExNS4zNTcgNzEuOTg4MkMxMTguMTM2IDcxLjc2MzcgMTE4LjQyMyA3MS44MzE1IDExOC42NjcgNzIuNzY3NEMxMTguOTk4IDc0LjA0NDMgMTE4Ljk2OCA3NC4wNzIgMTE2LjY5IDc0LjYwNDNDMTE0LjM2NyA3NS4xNDcgMTEyLjQzIDc1LjEwNzggMTEwLjA0MiA3NC40N1pNMTE2LjExOSA2Mi43NzAxQzExNS44NjQgNjAuODc4NyAxMTQuMTU5IDU5LjMyNzYgMTEyLjMzNSA1OS4zMjc2QzExMC41NjYgNTkuMzI3NiAxMDguMjI0IDYxLjYwMTQgMTA4LjIyNCA2My4zMTk1QzEwOC4yMjQgNjQuMjEyOCAxMDguNTI3IDY0LjI3NDYgMTEyLjI1NSA2NC4xNDI0QzExNi4yNDEgNjQuMDAxMSAxMTYuMjgzIDYzLjk4NjIgMTE2LjExOSA2Mi43NzAxWk0xMjYuODk0IDc0LjI0N0MxMjQuODI2IDczLjIyMDggMTIzLjUzMiA3MS4zNTg5IDEyMi44OTQgNjguNDg4OUMxMjEuOTc1IDY0LjM2MDUgMTIzLjA3NCA2MC40OTE0IDEyNS44MyA1OC4xNTY3QzEyNy44MjcgNTYuNDY1NyAxMzEuODM4IDU2LjMzMDUgMTMzLjgwNSA1Ny44ODc5TDEzNS4wOTIgNTguOTA3MlY1My45NTM2VjQ5SDEzNy4wNDZIMTM5VjYxLjc4NjVWNzQuNTczMUgxMzcuMjlDMTM1Ljc2MiA3NC41NzMxIDEzNS41OCA3NC40MzMxIDEzNS41OCA3My4yNTc5VjcxLjk0MjdMMTM0LjQ4MSA3Mi45NzkyQzEzMi4yMzMgNzUuMDk5OCAxMjkuNTI1IDc1LjU1MjMgMTI2Ljg5NCA3NC4yNDdaTTEzMy42NjQgNzAuNjc2NkMxMzQuOTc2IDY5LjM1NTcgMTM1LjA5MiA2OC45NTM3IDEzNS4wOTIgNjUuNzIwOUMxMzUuMDkyIDYyLjQ1NzIgMTM0Ljk4NSA2Mi4wOTQ1IDEzMy42MDcgNjAuNzA3NkMxMzIuMzY1IDU5LjQ1NzUgMTMxLjg2NSA1OS4yNjIyIDEzMC41NTQgNTkuNTE1NEMxMjYuMTQ0IDYwLjM2NzIgMTI0LjgzNSA2OC4xNDIzIDEyOC41OTggNzEuMTIyOUMxMzAuMzQ4IDcyLjUwODEgMTMxLjk4OCA3Mi4zNjM1IDEzMy42NjQgNzAuNjc2NlpNNjEuNDEwNyA2Ni4wNTg0QzYwLjAyMiA2MS4zNzU0IDU4Ljg4NTkgNTcuMzkxOSA1OC44ODU5IDU3LjIwNjJDNTguODg1OSA1Ny4wMjA2IDU5LjcyNzQgNTYuODY4NiA2MC43NTU5IDU2Ljg2ODZINjIuNjI1OUw2NC4yNTUxIDYzLjg3NjZDNjUuMTUxMiA2Ny43MzEgNjUuOTU2IDcwLjY2MzMgNjYuMDQzNyA3MC4zOTI5QzY2LjEzMTMgNzAuMTIyNCA2Ny4wNTU3IDY3LjAyNDEgNjguMDk3OCA2My41MDc4TDY5Ljk5MjYgNTcuMTE0NUg3MS41OTY5SDczLjIwMTJMNzQuODg2NSA2My4yNjE5Qzc1LjgxMzQgNjYuNjQzIDc2LjY4MzIgNjkuNzQxMiA3Ni44MTk0IDcwLjE0N0M3Ni45NTU3IDcwLjU1MjcgNzcuODQxOSA2Ny43MzEgNzguNzg5IDYzLjg3NjZMODAuNTEwOSA1Ni44Njg2SDgyLjQ1MTdDODMuOTUxNyA1Ni44Njg2IDg0LjMzMDMgNTcuMDMxNiA4NC4xMTkgNTcuNTg2QzgzLjk2ODYgNTcuOTgwNiA4Mi42OTU2IDYxLjk2NDEgODEuMjkwMiA2Ni40MzgyTDc4LjczNDkgNzQuNTczMUg3Ni45NjM1SDc1LjE5MjFMNzMuNTgxMiA2OC43OTQ1QzcyLjY5NTIgNjUuNjE2MyA3MS44NTg1IDYyLjY4NDEgNzEuNzIxNyA2Mi4yNzgzQzcxLjQ0NjUgNjEuNDYxNiA3MS41OTExIDYxLjA3MzMgNjkuMTExNCA2OS4yODYzTDY3LjUxNTIgNzQuNTczMUg2NS43MjU0SDYzLjkzNTZMNjEuNDEwNyA2Ni4wNTg0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTE5Ljk3NDYgMTE5LjI3NEMxOS4wMTU4IDExOC4xMTkgMjAuMzM4MSAxMTYuMTY2IDIxLjU2MDQgMTE2LjkzMkMyMi43NjMyIDExNy42ODYgMjIuMzMwNSAxMTkuNzYxIDIwLjk3MDQgMTE5Ljc2MUMyMC42NDUgMTE5Ljc2MSAyMC4xOTY5IDExOS41NDIgMTkuOTc0NiAxMTkuMjc0WiIgZmlsbD0idXJsKCNwYWludDNfcmFkaWFsXzY3OV8xOTEwKSIvPgo8cGF0aCBkPSJNMjMuODM2IDExMi42M0MyMi4xMTUyIDExMS42ODkgMjEuODAyOSAxMDkuNzk3IDIzLjE0NjUgMTA4LjQ1M0MyNC4wODU3IDEwNy41MTQgMjUuMjEgMTA3LjM5NCAyNi4yNTA3IDEwOC4xMjNDMjcuODU3MSAxMDkuMjQ5IDI3LjQ2NTUgMTEyLjAxMyAyNS42MDc5IDExMi42NkMyNS42MDc5IDExMi42NiAyNC40NzQ1IDExMi45NzMgMjMuODM2IDExMi42M1oiIGZpbGw9InVybCgjcGFpbnQ0X3JhZGlhbF82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTMzLjc4NTUgMTIwLjAzNkMzMy43ODU1IDEyMC4xODggMzMuNzU1NyAxMjAuMzM4IDMzLjY5NzYgMTIwLjQ3OUMzMy42Mzk1IDEyMC42MTkgMzMuNTU0NCAxMjAuNzQ2IDMzLjQ0NzEgMTIwLjg1M0MzMy4zMzk4IDEyMC45NjEgMzMuMjEyNCAxMjEuMDQ2IDMzLjA3MjMgMTIxLjEwNEMzMi45MzIxIDEyMS4xNjIgMzIuNzgxOCAxMjEuMTkyIDMyLjYzMDEgMTIxLjE5MkMzMi40NzgzIDEyMS4xOTIgMzIuMzI4MSAxMjEuMTYyIDMyLjE4NzkgMTIxLjEwNEMzMi4wNDc3IDEyMS4wNDYgMzEuOTIwMyAxMjAuOTYxIDMxLjgxMyAxMjAuODUzQzMxLjcwNTcgMTIwLjc0NiAzMS42MjA2IDEyMC42MTkgMzEuNTYyNiAxMjAuNDc5QzMxLjUwNDUgMTIwLjMzOCAzMS40NzQ2IDEyMC4xODggMzEuNDc0NiAxMjAuMDM2QzMxLjQ3NDYgMTE5LjczIDMxLjU5NjMgMTE5LjQzNiAzMS44MTMgMTE5LjIxOUMzMi4wMjk3IDExOS4wMDMgMzIuMzIzNiAxMTguODgxIDMyLjYzMDEgMTE4Ljg4MUMzMi45MzY1IDExOC44ODEgMzMuMjMwNCAxMTkuMDAzIDMzLjQ0NzEgMTE5LjIxOUMzMy42NjM4IDExOS40MzYgMzMuNzg1NSAxMTkuNzMgMzMuNzg1NSAxMjAuMDM2WiIgZmlsbD0iYmxhY2siLz4KPHBhdGggZD0iTTEyMC43MjEgMTE4LjI3NkMxMjAuNzIxIDExOC42MjMgMTIwLjU2NSAxMTguOTU2IDEyMC4yODcgMTE5LjIwMUMxMjAuMDA5IDExOS40NDYgMTE5LjYzMiAxMTkuNTg0IDExOS4yMzkgMTE5LjU4NEMxMTguODQ2IDExOS41ODQgMTE4LjQ2OSAxMTkuNDQ2IDExOC4xOTEgMTE5LjIwMUMxMTcuOTEzIDExOC45NTYgMTE3Ljc1NyAxMTguNjIzIDExNy43NTcgMTE4LjI3NkMxMTcuNzU3IDExOC4xMDUgMTE3Ljc5NSAxMTcuOTM1IDExNy44NyAxMTcuNzc2QzExNy45NDQgMTE3LjYxNyAxMTguMDUzIDExNy40NzMgMTE4LjE5MSAxMTcuMzUyQzExOC4zMjkgMTE3LjIzIDExOC40OTIgMTE3LjEzNCAxMTguNjcyIDExNy4wNjhDMTE4Ljg1MSAxMTcuMDAzIDExOS4wNDQgMTE2Ljk2OSAxMTkuMjM5IDExNi45NjlDMTE5LjQzMyAxMTYuOTY5IDExOS42MjYgMTE3LjAwMyAxMTkuODA2IDExNy4wNjhDMTE5Ljk4NiAxMTcuMTM0IDEyMC4xNDkgMTE3LjIzIDEyMC4yODcgMTE3LjM1MkMxMjAuNDI0IDExNy40NzMgMTIwLjUzMyAxMTcuNjE3IDEyMC42MDggMTE3Ljc3NkMxMjAuNjgyIDExNy45MzUgMTIwLjcyMSAxMTguMTA1IDEyMC43MjEgMTE4LjI3NloiIGZpbGw9IiM1OTY4NkYiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82NzlfMTkxMCIgeDE9IjExIiB5MT0iLTQuNzc3NjhlLTA3IiB4Mj0iMTY0LjUiIHkyPSIxNTAuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNjRCN0ZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNURBRCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50MV9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTI0LjkwNCAxMjguNjM2KSByb3RhdGUoLTAuMDQ4NTUyKSBzY2FsZSgzNi4yODAyIDMxLjQwMzIpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzExNzdDRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM3RUM3RkYiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50Ml9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzkuMzUxMiAxMjEuNDYpIHJvdGF0ZSgtMC4wNTczKSBzY2FsZSg1MC4yMjc2IDUxLjMwOTEpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzExNzdDRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM3RUM3RkYiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50M19yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjAuOTU0OCAxMTguMjYpIHNjYWxlKDEuMzA5MjkgMS41MDEyNykiPgo8c3RvcCBzdG9wLWNvbG9yPSIjODhBM0QwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzVEODNCRiIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50NF9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQuNzg0MyAxMTAuMjIxKSBzY2FsZSgyLjQ3Mjc3IDIuNTY5NTQpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzg4QTNEMCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM1RDgzQkYiLz4KPC9yYWRpYWxHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "topology"], ["spec", "replicationFactor"], ["spec", "db"], ["spec", "db", "replicas"], ["spec", "db", "size"], ["spec", "db", "storageClass"], ["spec", "db", "resources"], ["spec", "db", "resourcesPreset"], ["spec", "master"], ["spec", "master", "replicas"], ["spec", "master", "resources"], ["spec", "master", "resourcesPreset"], ["spec", "filer"], ["spec", "filer", "replicas"], ["spec", "filer", "resources"], ["spec", "filer", "resourcesPreset"], ["spec", "filer", "grpcHost"], ["spec", "filer", "grpcPort"], ["spec", "filer", "whitelist"], ["spec", "volume"], ["spec", "volume", "replicas"], ["spec", "volume", "size"], ["spec", "volume", "storageClass"], ["spec", "volume", "resources"], ["spec", "volume", "resourcesPreset"], ["spec", "volume", "zones"], ["spec", "s3"], ["spec", "s3", "replicas"], ["spec", "s3", "resources"], ["spec", "s3", "resourcesPreset"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - "{{`seaweedfs-{{ .name }}-s3`}}" + ingresses: + exclude: [] + include: + - resourceNames: + - "{{`ingress-seaweedfs-{{ .name }}-s3`}}" diff --git a/packages/core/platform/psds/snapshot-controller.yaml b/packages/core/platform/psds/snapshot-controller.yaml index 398920a0..11add6c8 100644 --- a/packages/core/platform/psds/snapshot-controller.yaml +++ b/packages/core/platform/psds/snapshot-controller.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.snapshot-controller spec: @@ -10,15 +10,15 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.cert-manager - packages: - - name: snapshot-controller - path: system/snapshot-controller - releaseName: snapshot-controller - namespace: cozy-snapshot-controller - dependsOn: - - cert-manager-issuers - + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + components: + - name: snapshot-controller + path: system/snapshot-controller + install: + namespace: cozy-snapshot-controller + releaseName: snapshot-controller + dependsOn: + - cert-manager-issuers diff --git a/packages/core/platform/psds/tcp-balancer.yaml b/packages/core/platform/psds/tcp-balancer.yaml index 10ea89ac..34fc4ed7 100644 --- a/packages/core/platform/psds/tcp-balancer.yaml +++ b/packages/core/platform/psds/tcp-balancer.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.tcp-balancer-application spec: @@ -16,14 +16,33 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: tcp-balancer-application - path: system/tcp-balancer-application - releaseName: tcp-balancer - namespace: cozy-system - sources: + components: [] + applications: - name: tcp-balancer path: apps/tcp-balancer libraries: - cozy-lib - + template: + spec: + application: + kind: TCPBalancer + plural: tcpbalancers + singular: tcpbalancer + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"httpAndHttps":{"description":"HTTP and HTTPS configuration.","type":"object","default":{},"required":["mode","targetPorts"],"properties":{"endpoints":{"description":"Endpoint addresses list.","type":"array","default":[],"items":{"type":"string"}},"mode":{"description":"Mode for balancer.","type":"string","default":"tcp","enum":["tcp","tcp-with-proxy"]},"targetPorts":{"description":"Target ports configuration.","type":"object","default":{},"required":["http","https"],"properties":{"http":{"description":"HTTP port number.","type":"integer","default":80},"https":{"description":"HTTPS port number.","type":"integer","default":443}}}}},"replicas":{"description":"Number of HAProxy replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each TCP Balancer replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"List of allowed client networks.","type":"array","default":[],"items":{"type":"string"}},"whitelistHTTP":{"description":"Secure HTTP by whitelisting client networks (default: false).","type":"boolean","default":false}}} + release: + prefix: tcp-balancer- + labels: + cozystack.io/ui: "true" + dashboard: + category: NaaS + singular: TCP Balancer + plural: TCP Balancer + description: Layer4 load balancer service + tags: + - network + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMjk4NSkiLz4KPHBhdGggZD0iTTcyLjE2NDUgNTkuNDI0M0w2Mi41IDQ4LjQ5OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjI2IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTQxLjY4NTUgNTEuMDIxNUw0OS4yNDcgNjIuMDY5MyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTcyLjE2NDYgNTkuNDQxNEw4MS43MjYzIDQ4LjM5MzZNODMuNzE3MSA3MS42Mjk0TDk1LjA2NCA2Mi4wNjc4TTgzLjcxNzEgNzEuNjEwOEw5NS4wNjQgODEuNTkzTTgxLjgyOTEgOTQuMjAxN0w3Mi4xNjQ2IDgzLjQ4MTFNNjIuNTAwMSA5NC4yMDE3TDcyLjE2NDYgODMuNDkwNE00OS4yNTU5IDgxLjE3MjRMNjAuMTgyMSA3MS42MTA4TTYwLjE5MTUgNzEuNjEwOEw0OS4yNjUyIDYyLjA0OTFMNzIuMTY0NiA1OS40MjI3TDk1LjA2NCA2Mi4wNDkxIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMjYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNODEuNzE2OCA0OC4zOTM2TDgzLjcxNyA3MS42MTA4TDgxLjgyOSA5NC4xOTI0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMjYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDY0IDgxLjU5MjVMNzIuMTY0NiA4My40ODA1TTQ5LjI1NTkgODEuMTcxOUw3Mi4xNTUzIDgzLjQ5OTIiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4yNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik02Mi41MDEyIDk0LjIwMTRMNjAuMTczOCA3MS42MTk4TTYyLjUwMTIgNDguNDk2MUw2MC4xNzM4IDcxLjYxMDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4yNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0zOC43NSA2NC45OTQ4TDQ5LjI1NTcgNjIuMDUwNk01MS40NjE1IDQwLjYxODdMNjIuNTA5MyA0OC40OTc5TTYyLjQ5MDYgNDguNDk3OUw2NS4wMTQyIDM1LjY4MzZMODEuNzE2OCA0OC4zOTUxIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNzkuMjAzMSAzNS42ODM2TDgxLjcyNjcgNDguMzk1MU05Mi43NTU4IDQwLjYxODdMODEuNzA4IDQ4LjM5NTFNMTAyLjYyNiA1MS4wMjE1TDgxLjcxNzQgNDguMzk1MU0xMDIuNjI2IDUxLjAwMjhMOTUuMDY0NSA2Mi4wNTA2TDEwNS43NzYgNjQuOTk0OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTk1LjA2MzkgNjIuMDUwNkwxMDUuNTcgNzguMDE0OE03OS4yMDI1IDM1LjY4MzZMNjIuNSA0OC40OTc5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDYzNyA2Mi4wNTExTDkyLjczNjMgNDAuNjE5MU05NS4wNjM3IDgxLjU5NTFMMTA1LjU2OSA3OC4wMTUzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDY1IDgxLjU5NDlMMTA1Ljc3NiA2NC45OTUxTTk1LjA2NSA4MS41OTQ5TDEwMi42MjYgOTEuNzgyOE05NS4wNjUgODEuNTk0OUw5Mi43Mzc3IDEwMi4xODZNODEuODMwMSA5NC4yMDM1TDkyLjc1NjQgMTAyLjE4NiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTgxLjgyOSA5NC4yMDNMMTAyLjYyNSA5MS43ODIyTTgxLjgyOSA5NC4yMDNMNzkuMzI0MSAxMDcuMTExTTgxLjgyOSA5NC4yMDNMNjUuMDE0MyAxMDcuMTAxTTYyLjUgOTQuMjAzTDY1LjAyMzYgMTA3LjEzOSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTYyLjUwMTIgOTQuMjAzMUw3OS4zMjUzIDEwNy4xMTFNNTEuNDYyOCAxMDIuMTg1TDYyLjUxMDUgOTQuMjAzMUw0MS42NzY4IDkxLjg4NTFMNDkuMjU2OSA4MS4xNzM4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNTEuNDYxOCAxMDIuMTg1TDQ5LjI1NiA4MS4xNzMxTDM4LjY0NzUgNzcuOTExMUw0OS4yNTYgNjIuMDQ5OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTQ5LjI1NTcgODEuMTc0NUwzOC43NSA2NC45OTUzTTUxLjQ2MTUgNDAuNjE5MUw0OS4yNTU3IDYyLjA1MTEiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik00MS42ODU1IDUxLjAyMTdMNjIuNDgxOSA0OC40OTgiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik00My4zNzYgMzYuODMzOEw1MS40NjA5IDQwLjYxOTJMNTAuODM0NiAzMS43OTU5TDY1LjAxMzYgMzUuNjg0MSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik01OC45Mjg5IDI4LjIyNDRMNjUuMDEzNiAzNS42ODMxTDY3LjUzNzMgMjYuNzM4M0w3OS4yMDE5IDM1LjY4MzFNNTEuNDYwOSA0MC42MTgxTDU4LjkxOTYgMjguMjI0NCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik03Ni41NjY3IDI2LjQ0MDRMNzkuMjAyNSAzNS42ODQzTDg1LjI5NjYgMjguMjI1Nk02NS4wMDQ5IDM1LjY4NDNMNzYuNTU3NCAyNi40NDA0TTkyLjc1NTIgNDAuNjE5NEw4NS4yNzc5IDI4LjIyNTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTIuNzU0OSA0MC42MTkyTDkzLjQ5MzIgMzEuNzk1OU05Mi43NTQ5IDQwLjYxOTJMMTAxLjAzNiAzNi40MTMyTTkyLjc1NDkgNDAuNjE5MkwxMDcuMTQ5IDQyLjgyNU03OS4yMDIxIDM1LjY4NDFMOTMuNDgzOSAzMS43OTU5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTEwMi42MjUgNTEuMDIxNEwxMDcuMTM5IDQyLjgyNDRNMTAyLjYyNSA1MS4wMjE0TDEwMS4wNDUgMzYuNDIxOU0xMDIuNjI1IDUxLjAyMTRMMTEyLjA4MyA1MC4yODNNMTAyLjYyNSA1MS4wMjE0TDExNS41NiA1OC4zNzczIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTEwNS43NzQgNjQuOTk0OUwxMTIuMDgzIDUwLjI4MzJNMTA1Ljc3NCA2NC45OTQ5TDExNS41NDEgNTguMzc3NE0xMDUuNzc0IDY0Ljk5NDlMMTE2LjcgNjcuMjAwN0wxMDUuNTY4IDc4LjAxNDkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMTE3LjAxOSA3NS45MTIxTDEwNS41NjkgNzguMDE1MUwxMTUuMzM3IDg0LjUyOTdMMTAyLjYyNSA5MS43ODI3TTEwNS43NzUgNjQuOTk1MUwxMTcuMDE5IDc1LjkyMTQiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMTAyLjYyNSA5MS43ODMzTDExMS45NzEgOTIuNzI3M00xMDUuNTc4IDc4LjAxNTZMMTExLjk3MSA5Mi43MThNMTA3LjA1NSAxMDAuMDY0TDEwMi42NDMgOTEuNzgzM0wxMDAuOTYxIDEwNi4yOCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0xMDAuOTQzIDEwNi4yNzlMOTIuNzQ1OCAxMDIuMTg1TTkyLjc1NTEgMTAyLjE4NUw5My4zODEzIDExMS4zNDVNOTIuNzU1MSAxMDIuMTg1TDEwNy4wMzcgMTAwLjA4Mk05Mi43NTUxIDEwMi4xODVMODUuMjg3MSAxMTQuNzk0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTc5LjMyMzIgMTA3LjEwM0w4NS4yNzcgMTE0Ljc2N003OS4zMjMyIDEwNy4xMDNMOTMuMzk5MyAxMTEuMzA5TTc5LjMyMzIgMTA3LjEwM0w3Ni41NjU5IDExNi41NjFNNzkuMzIzMiAxMDcuMTAzTDY3LjU1NTcgMTE2LjU2MSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik02NS4wMTM2IDEwNy4xMDJMNjcuNTM3MyAxMTYuNTYxTTY1LjAxMzYgMTA3LjEwMkw3Ni41NTY4IDExNi41NjFNNjUuMDEzNiAxMDcuMTAyTDU5LjAyMjQgMTE0Ljc2Nk01MS40NjA5IDEwMi4xODZMNTkuMDIyNCAxMTQuNzk0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTY1LjAxMzkgMTA3LjEwMUw1MC43MzIyIDExMS41MTNNNTAuNzIyOCAxMTEuNTMyTDUxLjQ2MTIgMTAyLjE4NUw0My4yNjQyIDEwNi42OTlMNDEuNjg0NiA5MS44ODQ4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTUxLjQ2MSAxMDIuMTg2TDM3LjA2NzEgMTAwLjE5NU00MS42ODQ0IDkxLjg4NkwzNy4wNTc4IDEwMC4xNjdNNDEuNjg0NCA5MS44ODZMMzIuMjI1NSA5Mi44MzAxTTQxLjY4NDQgOTEuODg2TDI4LjY3MzggODQuNjQyM0wzOC42NDY3IDc3LjkxMjdMMjcuMjk5OCA3NS45MjE5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTM4LjY0NjcgNzcuOTEyM0wzMi4yNTM2IDkyLjgyOTZNMzguNzQ5NSA2NC45OTUxTDI3LjI5OTggNzUuOTIxNCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0zOC42NDY3IDc3LjkxMjJMMjcuMjk5OCA2Ny4yMDA5TTM4Ljc1ODkgNjQuOTk1MUwyOC45ODIyIDU4LjQ4MDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMjcuMjk5OCA2Ny4yMDA3TDM4Ljc0OTUgNjQuOTk0OUwzMi4yNDQyIDUwLjI4MzIiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNDEuNjgzNiA1MS4wMjE3TDMyLjIyNDcgNTAuMjgzM000MS42ODM2IDUxLjAyMTdMMjguOTgxNCA1OC40ODA0TTQxLjY4MzYgNTEuMDIxN0wzNy4xNzg1IDQzLjI0NTNNNDEuNjgzNiA1MS4wMjE3TDQzLjM2NiAzNi44NDI4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTUxLjQ2MSA0MC42MTkxTDM3LjE2OTkgNDMuMjQ1NiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik01NC41NjQ1IDc3LjA3MDJMNTQuNjM5MiA2Ni4wMjI0TDY1LjY4NyA2Ni4wOTcxTDY1LjYxMjMgNzcuMTQ0OUw1NC41NjQ1IDc3LjA3MDJaTTY2LjUxODkgNjQuOTEwMUw2Ni41OTM3IDUzLjg2MjNMNzcuNjQxNSA1My45MzcxTDc3LjU2NjcgNjQuOTg0OUw2Ni41MTg5IDY0LjkxMDFaTTY2LjUxODkgODkuMTI3NEw2Ni41OTM3IDc4LjA3OTZMNzcuNjQxNSA3OC4xNTQ0TDc3LjU2NjcgODkuMjAyMkw2Ni41MTg5IDg5LjEyNzRaTTc4LjU3NjEgNzYuOTY3M0w3OC42NTA5IDY1LjkxOTVMODkuNjk4NyA2NS45OTQzTDg5LjYyMzkgNzcuMDQyMUw3OC41NzYxIDc2Ljk2NzNaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNzcuOTQwNiA1Mi4yMzY2TDc3Ljk5NjYgNDQuNTcyM0w4NS42OTgzIDQ0LjYyODNMODUuNjQyMiA1Mi4yOTI2TDc3Ljk0MDYgNTIuMjM2NlpNNTguNjg2NCA1Mi4yMzY2TDU4Ljc0MjQgNDQuNTcyM0w2Ni40NDQxIDQ0LjYyODNMNjYuMzg4IDUyLjI5MjZMNTguNjg2NCA1Mi4yMzY2Wk00NS4zNTggNjUuODkyMUw0NS40MTQxIDU4LjIyNzhMNTMuMTE1NyA1OC4yODM5TDUzLjA1OTcgNjUuOTQ4Mkw0NS4zNTggNjUuODkyMVpNNDUuMzQ4NiA4NS4xNjVMNDUuNDMyOCA3Ny41MDA3TDUzLjEzNDQgNzcuNTg0OEw1My4wNTAzIDg1LjI0OTFMNDUuMzQ4NiA4NS4xNjVaTTkxLjI2OSA4NS4wMTU0TDkxLjMyNSA3Ny4zNTExTDk5LjAyNjcgNzcuNDA3Mkw5OC45NzA2IDg1LjA3MTVMOTEuMjY5IDg1LjAxNTRaTTkxLjQxODUgNjUuOTQ4Mkw5MS41MDI2IDU4LjI4MzlMOTkuMjA0MyA1OC4zNjhMOTkuMTIwMiA2Ni4wMzIzTDkxLjQxODUgNjUuOTQ4MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0zOS4xMTQzIDUzLjUyNjNMMzkuMTUxNyA0OC40NzkxTDQ0LjE4MDIgNDguNTE2NUw0NC4xNDI4IDUzLjU2MzdMMzkuMTE0MyA1My41MjYzWk00OC45NTYzIDQzLjI2MzdMNDguOTkzNyAzOC4yMTY0TDU0LjAyMjMgMzguMjUzOEw1My45ODQ5IDQzLjMwMUw0OC45NTYzIDQzLjI2MzdaTTYyLjQ5OTcgMzguMTg4NEw2Mi41MzcxIDMzLjE0MTJMNjcuNTY1NiAzMy4xNzg2TDY3LjUyODIgMzguMjI1OEw2Mi40OTk3IDM4LjE4ODRaTTM2LjE1MTQgNjcuNDkwM0wzNi4xODg4IDYyLjQ0MzFMNDEuMTg5MiA2Mi40ODA1TDQxLjE1MTkgNjcuNTI3N0wzNi4xNTE0IDY3LjQ5MDNaTTEwMC4wODMgNDguNTUzOUwxMDUuMTMgNDguNTE2NUwxMDUuMTY3IDUzLjU0NUwxMDAuMTIgNTMuNTgyNEwxMDAuMDgzIDQ4LjU1MzlaTTkwLjI0MDcgMzguMTEzNkw5NS4yODc5IDM4LjA3NjJMOTUuMzI1MyA0My4xMDQ4TDkwLjI3ODEgNDMuMTQyMUw5MC4yNDA3IDM4LjExMzZaTTc2LjY1MDYgMzMuMTY5Mkw4MS42OTc4IDMzLjEzMThMODEuNzM1MiAzOC4xNjA0TDc2LjY4OCAzOC4xOTc3TDc2LjY1MDYgMzMuMTY5MlpNMTAzLjAxOCA2Mi40OTkyTDEwOC4wNjUgNjIuNDYxOEwxMDguMTAyIDY3LjQ5MDNMMTAzLjA1NSA2Ny41Mjc3TDEwMy4wMTggNjIuNDk5MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik01OC41ODMgOTguMjQwNUw1OC42MzkxIDkwLjU3NjJMNjYuMzQwOCA5MC42MzIzTDY2LjI4NDcgOTguMjk2NUw1OC41ODMgOTguMjQwNVpNNzcuODM3MiA5OC4yNDA1TDc3Ljg5MzMgOTAuNTc2Mkw4NS41OTUgOTAuNjMyM0w4NS41Mzg5IDk4LjI5NjVMNzcuODM3MiA5OC4yNDA1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEwMC4wNDUgOTQuMzYxOUwxMDAuMDgyIDg5LjMxNDdMMTA1LjExMSA4OS4zNTIxTDEwNS4wNzQgOTQuMzk5M0wxMDAuMDQ1IDk0LjM2MTlaTTkwLjMxNTIgMTA0LjcyN0w5MC4zNTI2IDk5LjY4MDJMOTUuMzgxMSA5OS43MTc2TDk1LjM0MzcgMTA0Ljc2NUw5MC4zMTUyIDEwNC43MjdaTTc2Ljc3MTggMTA5LjdMNzYuODA5MiAxMDQuNjUzTDgxLjgzNzcgMTA0LjY5TDgxLjgwMDQgMTA5LjczN0w3Ni43NzE4IDEwOS43Wk0xMDMuMDA4IDgwLjM5NzlMMTAzLjA0NSA3NS4zNTA3TDEwOC4wNzQgNzUuMzg4MUwxMDguMDM3IDgwLjQzNTNMMTAzLjAwOCA4MC4zOTc5Wk0zOS4xMjMzIDg5LjMxNDdMNDQuMTcwNiA4OS4yNzczTDQ0LjIwNzkgOTQuMzA1OEwzOS4xNjA3IDk0LjM0MzJMMzkuMTIzMyA4OS4zMTQ3Wk00OC45NjU0IDk5LjY0MjhMNTQuMDEyNiA5OS42MDU0TDU0LjA1IDEwNC42MzRMNDkuMDAyOCAxMDQuNjcxTDQ4Ljk2NTQgOTkuNjQyOFpNNjIuNDQzMyAxMDQuNTk3TDY3LjQ5MDYgMTA0LjU1OUw2Ny41Mjc5IDEwOS41ODhMNjIuNDgwNyAxMDkuNjI1TDYyLjQ0MzMgMTA0LjU5N1pNMzYuMTg4NSA3NS4zNjk0TDQxLjIzNTcgNzUuMzMyTDQxLjI3MzEgODAuMzYwNkwzNi4yMjU5IDgwLjM5NzlMMzYuMTg4NSA3NS4zNjk0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExMC42MjUgNTEuNjM4NEwxMTAuNjQ0IDQ4LjkwOTJMMTEzLjQyOSA0OC45Mjc5TDExMy40MSA1MS42NTcxTDExMC42MjUgNTEuNjM4NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTQuMjI0IDU5Ljg5MTNMMTE0LjI0MiA1Ny4xNjIxTDExNy4wMjggNTcuMTgwOEwxMTcuMDA5IDU5LjkxTDExNC4yMjQgNTkuODkxM1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMDUuNzY3IDQ0LjMzNzZMMTA1Ljc4NSA0MS42MDg0TDEwOC41NzEgNDEuNjI3MUwxMDguNTUyIDQ0LjM1NjNMMTA1Ljc2NyA0NC4zMzc2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTQxLjk3MzYgMzguMDk0NUw0MS45OTIzIDM1LjM2NTJMNDQuNzc3NiAzNS4zODM5TDQ0Ljc1ODkgMzguMTEzMkw0MS45NzM2IDM4LjA5NDVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMjYgNjguNTU1NEwyNi4wMTg3IDY1LjgyNjJMMjguODA0IDY1Ljg0NDlMMjguNzg1MyA2OC41NzQxTDI2IDY4LjU1NTRaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOTkuNjI0IDM4LjA5NDVMOTkuNjQyNyAzNS4zNjUyTDEwMi40MjggMzUuMzgzOUwxMDIuNDA5IDM4LjExMzJMOTkuNjI0IDM4LjA5NDVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMjcuNTg5OCA1OS44ODE2TDI3LjYwODUgNTcuMTUyM0wzMC4zOTM5IDU3LjE3MUwzMC4zNzUyIDU5LjkwMDNMMjcuNTg5OCA1OS44ODE2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTU3LjYyOTkgMjkuNjM1NUw1Ny42NDg2IDI2LjkwNjJMNjAuNDMzOSAyNi45MjQ5TDYwLjQxNTIgMjkuNjU0Mkw1Ny42Mjk5IDI5LjYzNTVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzAuOTcyNyA1MS42Mzg0TDMwLjk5MTMgNDguOTA5MkwzMy43NzY3IDQ4LjkyNzlMMzMuNzU4IDUxLjY1NzFMMzAuOTcyNyA1MS42Mzg0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTM1Ljk0NTMgNDQuMjM2MUwzNS45NjQgNDEuNTA2OEwzOC43NDkzIDQxLjUyNTVMMzguNzMwNiA0NC4yNTQ4TDM1Ljk0NTMgNDQuMjM2MVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00OS40MjI5IDMwLjQyMDRMNTIuMTUyMSAzMC40MDE3TDUyLjE3MDggMzMuMTg3TDQ5LjQ0MTUgMzMuMjA1N0w0OS40MjI5IDMwLjQyMDRaTTY2LjMwMyAyNS4wNDZMNjkuMDMyMiAyNS4wMjczTDY5LjA1MDkgMjcuODEyN0w2Ni4zMjE3IDI3LjgzMTRMNjYuMzAzIDI1LjA0NloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4yMjI3IDMzLjIyNDRMOTIuMjQxNCAzMC40OTUxTDk1LjAyNjcgMzAuNTEzOEw5NS4wMDggMzMuMjQzTDkyLjIyMjcgMzMuMjI0NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTUuNTk4IDY4LjQ1MjlMMTE1LjYxNiA2NS43MjM2TDExOC40MDIgNjUuNzQyM0wxMTguMzgzIDY4LjQ3MTZMMTE1LjU5OCA2OC40NTI5WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTc1LjE5MTQgMjcuNzI5Mkw3NS4yMTAxIDI1TDc3Ljk5NTQgMjUuMDE4N0w3Ny45NzY3IDI3Ljc0NzlMNzUuMTkxNCAyNy43MjkyWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTgzLjg2NjIgMjkuNTIzMkw4My44ODQ5IDI2Ljc5MzlMODYuNjcwMiAyNi44MTI2TDg2LjY1MTUgMjkuNTQxOUw4My44NjYyIDI5LjUyMzJaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOTkuNjI0IDEwNy43TDk5LjY0MjcgMTA0Ljk3MUwxMDIuNDI4IDEwNC45ODlMMTAyLjQwOSAxMDcuNzE5TDk5LjYyNCAxMDcuN1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTUuNTk4IDc3LjIzOUwxMTUuNjE2IDc0LjUwOThMMTE4LjQwMiA3NC41Mjg1TDExOC4zODMgNzcuMjU3N0wxMTUuNTk4IDc3LjIzOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00MS45NzM2IDEwNy43TDQxLjk5MjMgMTA0Ljk3MUw0NC43Nzc2IDEwNC45ODlMNDQuNzU4OSAxMDcuNzE5TDQxLjk3MzYgMTA3LjdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMTE0LjIyNCA4Ni4wMzI5TDExNC4yNDIgODMuMzAzN0wxMTcuMDI4IDgzLjMyMjRMMTE3LjAwOSA4Ni4wNTE2TDExNC4yMjQgODYuMDMyOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik04My44NjYyIDExNi4yN0w4My44ODQ5IDExMy41NDFMODYuNjcwMiAxMTMuNTZMODYuNjUxNSAxMTYuMjg5TDgzLjg2NjIgMTE2LjI3WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExMC42MjUgOTQuMjY4M0wxMTAuNjQ0IDkxLjUzOTFMMTEzLjQyOSA5MS41NTc4TDExMy40MSA5NC4yODdMMTEwLjYyNSA5NC4yNjgzWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEwNS43NjcgMTAxLjY3MkwxMDUuNzg1IDk4Ljk0MjRMMTA4LjU3MSA5OC45NjExTDEwOC41NTIgMTAxLjY5TDEwNS43NjcgMTAxLjY3MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4xMDk0IDExMC4wNjVMOTQuODM4NiAxMTAuMDQ2TDk0Ljg1NzMgMTEyLjgzMUw5Mi4xMjggMTEyLjg1TDkyLjEwOTQgMTEwLjA2NVpNNzUuMzMyIDExNS4yMTVMNzguMDYxMyAxMTUuMTk2TDc4LjA4IDExNy45ODFMNzUuMzUwNyAxMThMNzUuMzMyIDExNS4yMTVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNDkuNDc4NSAxMTIuODg2TDQ5LjQ5NzIgMTEwLjE1N0w1Mi4yODI1IDExMC4xNzZMNTIuMjYzOCAxMTIuOTA1TDQ5LjQ3ODUgMTEyLjg4NloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0zMC44NTk0IDk0LjE2NThMMzAuODc4MSA5MS40MzY1TDMzLjY2MzQgOTEuNDU1MkwzMy42NDQ3IDk0LjE4NDVMMzAuODU5NCA5NC4xNjU4WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTI3LjU4MDEgODYuMDE0NEwyNy41OTg4IDgzLjI4NTJMMzAuMzg0MSA4My4zMDM5TDMwLjM2NTQgODYuMDMzMUwyNy41ODAxIDg2LjAxNDRaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzUuODMyIDEwMS42NzJMMzUuODUwNyA5OC45NDI0TDM4LjYzNiA5OC45NjExTDM4LjYxNzMgMTAxLjY5TDM1LjgzMiAxMDEuNjcyWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTI2IDc3LjIzOUwyNi4wMTg3IDc0LjUwOThMMjguODA0IDc0LjUyODVMMjguNzg1MyA3Ny4yNTc3TDI2IDc3LjIzOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik02Ni40MDUzIDExNy45NjJMNjYuNDI0IDExNS4yMzJMNjkuMjA5MyAxMTUuMjUxTDY5LjE5MDYgMTE3Ljk4TDY2LjQwNTMgMTE3Ljk2MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik01Ny41MTc2IDExNi4xNjhMNTcuNTM2MyAxMTMuNDM4TDYwLjMyMTYgMTEzLjQ1N0w2MC4zMDI5IDExNi4xODZMNTcuNTE3NiAxMTYuMTY4WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMjk4NSIgeDE9IjEwIiB5MT0iMTUuNSIgeDI9IjE0NCIgeTI9IjEzMS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEE4REEiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ5NSIgc3RvcC1jb2xvcj0iIzM1NzlCQyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyODZFQTUiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "external"], ["spec", "httpAndHttps"], ["spec", "httpAndHttps", "mode"], ["spec", "httpAndHttps", "targetPorts"], ["spec", "httpAndHttps", "targetPorts", "http"], ["spec", "httpAndHttps", "targetPorts", "https"], ["spec", "httpAndHttps", "endpoints"], ["spec", "whitelistHTTP"], ["spec", "whitelist"]] + secrets: + exclude: [] + include: [] diff --git a/packages/core/platform/psds/telepresence.yaml b/packages/core/platform/psds/telepresence.yaml index d7904985..55f62a03 100644 --- a/packages/core/platform/psds/telepresence.yaml +++ b/packages/core/platform/psds/telepresence.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.telepresence spec: @@ -10,13 +10,13 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - packages: - - name: telepresence - path: system/telepresence - releaseName: traffic-manager - namespace: cozy-telepresence - disabled: true - + - name: default + dependsOn: + - cozystack.networking + components: + - name: telepresence + path: system/telepresence + disabled: true + install: + namespace: cozy-telepresence + releaseName: traffic-manager diff --git a/packages/core/platform/psds/tenant.yaml b/packages/core/platform/psds/tenant.yaml index 953a9a7d..fc0c77a2 100644 --- a/packages/core/platform/psds/tenant.yaml +++ b/packages/core/platform/psds/tenant.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.tenant-application spec: @@ -22,14 +22,31 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: tenant-application - path: system/tenant-application - releaseName: tenant-application - namespace: cozy-system - sources: + components: [] + applications: - name: tenant path: apps/tenant libraries: - cozy-lib - + template: + spec: + application: + kind: Tenant + singular: tenant + plural: tenants + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"etcd":{"description":"Deploy own Etcd cluster.","type":"boolean","default":false},"host":{"description":"The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host).","type":"string","default":""},"ingress":{"description":"Deploy own Ingress Controller.","type":"boolean","default":false},"isolated":{"description":"Enforce tenant namespace with network policies (default: true).","type":"boolean","default":true},"monitoring":{"description":"Deploy own Monitoring Stack.","type":"boolean","default":false},"resourceQuotas":{"description":"Define resource quotas for the tenant.","type":"object","default":{},"additionalProperties":{"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}},"seaweedfs":{"description":"Deploy own SeaweedFS.","type":"boolean","default":false}}} + release: + prefix: tenant- + labels: + cozystack.io/ui: "true" + dashboard: + category: Administration + singular: Tenant + plural: Tenants + description: Separated tenant namespace + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQwMykiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDAzKSI+CjxwYXRoIGQ9Ik03MiAyOUM2Ni4zOTI2IDI5IDYxLjAxNDggMzEuMjM4OCA1Ny4wNDk3IDM1LjIyNEM1My4wODQ3IDM5LjIwOTEgNTAuODU3MSA0NC42MTQxIDUwLjg1NzEgNTAuMjVDNTAuODU3MSA1NS44ODU5IDUzLjA4NDcgNjEuMjkwOSA1Ny4wNDk3IDY1LjI3NkM2MS4wMTQ4IDY5LjI2MTIgNjYuMzkyNiA3MS41IDcyIDcxLjVDNzcuNjA3NCA3MS41IDgyLjk4NTIgNjkuMjYxMiA4Ni45NTAzIDY1LjI3NkM5MC45MTUzIDYxLjI5MDkgOTMuMTQyOSA1NS44ODU5IDkzLjE0MjkgNTAuMjVDOTMuMTQyOSA0NC42MTQxIDkwLjkxNTMgMzkuMjA5MSA4Ni45NTAzIDM1LjIyNEM4Mi45ODUyIDMxLjIzODggNzcuNjA3NCAyOSA3MiAyOVpNNjAuOTgyNiA4My4zMDM3QzYwLjQ1NCA4Mi41ODk4IDU5LjU5NTEgODIuMTkxNCA1OC43MTk2IDgyLjI3NDRDNDUuMzg5NyA4My43MzU0IDM1IDk1LjEwNzQgMzUgMTA4LjkwM0MzNSAxMTEuNzI2IDM3LjI3OTUgMTE0IDQwLjA3MSAxMTRIMTAzLjkyOUMxMDYuNzM3IDExNCAxMDkgMTExLjcwOSAxMDkgMTA4LjkwM0MxMDkgOTUuMTA3NCA5OC42MTAzIDgzLjc1MiA4NS4yNjM4IDgyLjI5MUM4NC4zODg0IDgyLjE5MTQgODMuNTI5NSA4Mi42MDY0IDgzLjAwMDkgODMuMzIwM0w3NC4wOTc4IDk1LjI0MDJDNzMuMDQwNiA5Ni42NTE0IDcwLjkyNjMgOTYuNjUxNCA2OS44NjkyIDk1LjI0MDJMNjAuOTY2MSA4My4zMjAzTDYwLjk4MjYgODMuMzAzN1oiIGZpbGw9ImJsYWNrIi8+CjwvZz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODdfMzQwMyIgeDE9IjcyIiB5MT0iMTQ0IiB4Mj0iLTEuMjgxN2UtMDUiIHkyPSI0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNDMEQ2RkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjMiIHN0b3AtY29sb3I9IiNDNERBRkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjY1IiBzdG9wLWNvbG9yPSIjRDNFOUZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0U5RkZGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zNDAzIj4KPHJlY3Qgd2lkdGg9Ijc0IiBoZWlnaHQ9Ijg1IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzUgMjkpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "etcd"], ["spec", "monitoring"], ["spec", "ingress"], ["spec", "seaweedfs"], ["spec", "isolated"], ["spec", "resourceQuotas"]] + secrets: + exclude: [] + include: [] diff --git a/packages/core/platform/psds/velero.yaml b/packages/core/platform/psds/velero.yaml index e18e3c70..37392e36 100644 --- a/packages/core/platform/psds/velero.yaml +++ b/packages/core/platform/psds/velero.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.velero spec: @@ -10,17 +10,17 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.monitoring-agents - packages: - - name: velero - path: system/velero - releaseName: velero - namespace: cozy-velero - privileged: true - disabled: true - dependsOn: - - monitoring-agents - + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring-agents + components: + - name: velero + path: system/velero + disabled: true + install: + privileged: true + namespace: cozy-velero + releaseName: velero + dependsOn: + - monitoring-agents diff --git a/packages/core/platform/psds/vertical-pod-autoscaler.yaml b/packages/core/platform/psds/vertical-pod-autoscaler.yaml index 90c10503..f90de53d 100644 --- a/packages/core/platform/psds/vertical-pod-autoscaler.yaml +++ b/packages/core/platform/psds/vertical-pod-autoscaler.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.vertical-pod-autoscaler spec: @@ -10,20 +10,22 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.monitoring-agents - packages: - - name: vertical-pod-autoscaler-crds - path: system/vertical-pod-autoscaler-crds - releaseName: vertical-pod-autoscaler-crds - namespace: cozy-vertical-pod-autoscaler - privileged: true - - name: vertical-pod-autoscaler - path: system/vertical-pod-autoscaler - releaseName: vertical-pod-autoscaler - namespace: cozy-vertical-pod-autoscaler - privileged: true - dependsOn: - - vertical-pod-autoscaler-crds + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring-agents + components: + - name: vertical-pod-autoscaler-crds + path: system/vertical-pod-autoscaler-crds + install: + privileged: true + namespace: cozy-vertical-pod-autoscaler + releaseName: vertical-pod-autoscaler-crds + - name: vertical-pod-autoscaler + path: system/vertical-pod-autoscaler + install: + privileged: true + namespace: cozy-vertical-pod-autoscaler + releaseName: vertical-pod-autoscaler + dependsOn: + - vertical-pod-autoscaler-crds diff --git a/packages/core/platform/psds/victoria-metrics-operator.yaml b/packages/core/platform/psds/victoria-metrics-operator.yaml index ceb4fb48..a5b47683 100644 --- a/packages/core/platform/psds/victoria-metrics-operator.yaml +++ b/packages/core/platform/psds/victoria-metrics-operator.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.victoria-metrics-operator spec: @@ -10,12 +10,13 @@ spec: namespace: cozy-system path: / variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.cert-manager - packages: - - name: victoria-metrics-operator - path: system/victoria-metrics-operator - releaseName: victoria-metrics-operator - namespace: cozy-victoria-metrics-operator + - name: default + dependsOn: + - cozystack.networking + - cozystack.cert-manager + components: + - name: victoria-metrics-operator + path: system/victoria-metrics-operator + install: + namespace: cozy-victoria-metrics-operator + releaseName: victoria-metrics-operator diff --git a/packages/core/platform/psds/virtual-machine.yaml b/packages/core/platform/psds/virtual-machine.yaml index 99728458..6629311f 100644 --- a/packages/core/platform/psds/virtual-machine.yaml +++ b/packages/core/platform/psds/virtual-machine.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.virtual-machine-application spec: @@ -18,14 +18,39 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: virtual-machine-application - path: system/virtual-machine-application - releaseName: virtual-machine-application - namespace: cozy-system - sources: + components: [] + applications: - name: virtual-machine path: apps/virtual-machine libraries: - cozy-lib - + template: + spec: + application: + kind: VirtualMachine + plural: virtualmachines + singular: virtualmachine + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Whether the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"subnets":{"description":"Additional subnets","type":"array","default":[],"items":{"type":"object","properties":{"name":{"description":"Subnet name","type":"string"}}}},"systemDisk":{"description":"System disk configuration.","type":"object","default":{},"required":["image","storage"],"properties":{"image":{"description":"The base image for the virtual machine.","type":"string","default":"ubuntu","enum":["ubuntu","cirros","alpine","fedora","talos"]},"storage":{"description":"The size of the disk allocated for the virtual machine.","type":"string","default":"5Gi"},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}}} + release: + prefix: virtual-machine- + labels: + cozystack.io/ui: "true" + dashboard: + category: IaaS + singular: Virtual Machine + plural: Virtual Machines + description: Virtual Machine (simple) + weight: 10 + tags: + - compute + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQ1NCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDU0KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMDBCM0ZGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi41Mjc1IDUzLjgzNjdDNzIuNDQzMSA1My44MzUxIDcyLjM2MDUgNTMuODEyMiA3Mi4yODczIDUzLjc3MDFMNTYuNDY5OSA0NC43OTM0QzU2LjM5ODMgNDQuNzUxOSA1Ni4zMzg4IDQ0LjY5MjMgNTYuMjk3MyA0NC42MjA3QzU2LjI1NTkgNDQuNTQ5IDU2LjIzMzggNDQuNDY3OCA1Ni4yMzM0IDQ0LjM4NUM1Ni4yMzM0IDQ0LjIxNjkgNTYuMzI1OCA0NC4wNjE3IDU2LjQ2OTkgNDMuOTc4NUw3Mi4xOTEyIDM1LjA2MDlDNzIuMjYzNyAzNS4wMjEgNzIuMzQ1IDM1IDcyLjQyNzcgMzVDNzIuNTEwNSAzNSA3Mi41OTE4IDM1LjAyMSA3Mi42NjQzIDM1LjA2MDlMODguNDg3MiA0NC4wMzk1Qzg4LjU1OTEgNDQuMDgwMSA4OC42MTg4IDQ0LjEzOTIgODguNjYgNDQuMjEwN0M4OC43MDEzIDQ0LjI4MjIgODguNzIyNyA0NC4zNjM1IDg4LjcyMTkgNDQuNDQ2Qzg4LjcyMjUgNDQuNTI4NSA4OC43MDEgNDQuNjA5NyA4OC42NTk4IDQ0LjY4MTJDODguNjE4NSA0NC43NTI2IDg4LjU1ODkgNDQuODExOCA4OC40ODcyIDQ0Ljg1MjVMNzIuNzcxNCA1My43NjgzQzcyLjY5NzIgNTMuODExNCA3Mi42MTMzIDUzLjgzNDkgNzIuNTI3NSA1My44MzY3IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjciIGQ9Ik03MC4yNTUzIDc1LjY1MTdDNzAuMTcxIDc1LjY1MzUgNzAuMDg3OCA3NS42MzE3IDcwLjAxNTEgNzUuNTg4OEw1NC4yNDU4IDY2LjY0MTdDNTQuMTcxNSA2Ni42MDI0IDU0LjEwOTUgNjYuNTQzNiA1NC4wNjYxIDY2LjQ3MTZDNTQuMDIyOCA2Ni4zOTk3IDU0IDY2LjMxNzMgNTQgNjYuMjMzM1Y0OC4yNzhDNTQgNDguMTA4IDU0LjA5MjQgNDcuOTU0NiA1NC4yNDM5IDQ3Ljg2OTZDNTQuMzE3MiA0Ny44MjcxIDU0LjQwMDQgNDcuODA0NyA1NC40ODUxIDQ3LjgwNDdDNTQuNTY5NyA0Ny44MDQ3IDU0LjY1MjkgNDcuODI3MSA1NC43MjYyIDQ3Ljg2OTZMNzAuNDkzNyA1Ni44MTMxQzcwLjU2NDIgNTYuODU2NSA3MC42MjI1IDU2LjkxNyA3MC42NjMyIDU2Ljk4OTFDNzAuNzAzOSA1Ny4wNjEyIDcwLjcyNTcgNTcuMTQyNCA3MC43MjY1IDU3LjIyNTFWNzUuMTgwNUM3MC43MjU5IDc1LjI2MjggNzAuNzA0MiA3NS4zNDM2IDcwLjY2MzUgNzUuNDE1MUM3MC42MjI3IDc1LjQ4NjYgNzAuNTY0MiA3NS41NDY0IDcwLjQ5MzcgNzUuNTg4OEM3MC40MjA2IDc1LjYyOTEgNzAuMzM4NyA3NS42NTA3IDcwLjI1NTMgNzUuNjUxNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC40IiBkPSJNNzQuNzE5OCA3NS42NTExQzc0LjYzMzMgNzUuNjUxMiA3NC41NDgyIDc1LjYyOTYgNzQuNDcyMiA3NS41ODgzQzc0LjQwMTYgNzUuNTQ2MSA3NC4zNDMyIDc1LjQ4NjIgNzQuMzAyNyA3NS40MTQ3Qzc0LjI2MjMgNzUuMzQzMSA3NC4yNDExIDc1LjI2MjIgNzQuMjQxMiA3NS4xOFY1Ny4zMzczQzc0LjI0MTIgNTcuMTcxIDc0LjMzMzYgNTcuMDE1OCA3NC40NzIyIDU2LjkyOUw5MC4yMzk3IDQ3Ljk4NTVDOTAuMzExOSA0Ny45NDM4IDkwLjM5MzggNDcuOTIxOSA5MC40NzcxIDQ3LjkyMTlDOTAuNTYwNSA0Ny45MjE5IDkwLjY0MjQgNDcuOTQzOCA5MC43MTQ2IDQ3Ljk4NTVDOTAuNzg3NiA0OC4wMjU1IDkwLjg0ODUgNDguMDg0MiA5MC44OTExIDQ4LjE1NTdDOTAuOTMzNyA0OC4yMjcyIDkwLjk1NjMgNDguMzA4OCA5MC45NTY2IDQ4LjM5MlY2Ni4yMzI4QzkwLjk1NyA2Ni4zMTY0IDkwLjkzNDcgNjYuMzk4NSA5MC44OTIxIDY2LjQ3MDRDOTAuODQ5NSA2Ni41NDI0IDkwLjc4ODEgNjYuNjAxNCA5MC43MTQ2IDY2LjY0MTFMNzQuOTUyNiA3NS41ODgzQzc0Ljg4MjUgNzUuNjMwNyA3NC44MDE4IDc1LjY1MjUgNzQuNzE5OCA3NS42NTExIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zNDU0IiB4MT0iMTYxIiB5MT0iMTgwIiB4Mj0iMy41OTI4NGUtMDciIHkyPSI0Ljk5OTk4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTk1NjU2Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNjg3XzM0NTQiPgo8cmVjdCB3aWR0aD0iOTQiIGhlaWdodD0iOTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSAyNSkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "systemDisk"], ["spec", "systemDisk", "image"], ["spec", "systemDisk", "storage"], ["spec", "systemDisk", "storageClass"], ["spec", "subnets"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - "{{`virtual-machine-{{ .name }}`}}" diff --git a/packages/core/platform/psds/virtualprivatecloud.yaml b/packages/core/platform/psds/virtualprivatecloud.yaml index f426f95a..e32dfd14 100644 --- a/packages/core/platform/psds/virtualprivatecloud.yaml +++ b/packages/core/platform/psds/virtualprivatecloud.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.virtualprivatecloud-application spec: @@ -17,14 +17,34 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: virtualprivatecloud-application - path: system/virtualprivatecloud-application - releaseName: virtualprivatecloud-application - namespace: cozy-system - sources: + components: [] + applications: - name: virtualprivatecloud path: apps/vpc libraries: - cozy-lib - + template: + spec: + application: + kind: VirtualPrivateCloud + plural: virtualprivateclouds + singular: virtualprivatecloud + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"subnets":{"description":"Subnets of a VPC","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"cidr":{"description":"IP address range","type":"string"}}}}}} + release: + prefix: "virtualprivatecloud-" + labels: + cozystack.io/ui: "true" + dashboard: + category: IaaS + singular: VPC + plural: VPCs + description: "Isolated networks" + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8xMDI1XzMpIi8+CjxwYXRoIGQ9Ik0xMDkuNiA4Ni4xSDExNC4zQzExNi44ODUgODYuMSAxMTkgODguMjE1IDExOSA5MC44NDdWMTA0Ljg1M0MxMTkgMTA3LjQ4NSAxMTYuODg1IDEwOS42IDExNC4zIDEwOS42SDk1LjVDOTIuOTE1IDEwOS42IDkwLjggMTA3LjQ4NSA5MC44IDEwNC44NTNWOTAuODQ3QzkwLjggODguMjE1IDkyLjkxNSA4Ni4xIDk1LjUgODYuMUgxMDAuMlY3Ni43SDc2LjdWODYuMUg4MS40QzgzLjk4NSA4Ni4xIDg2LjEgODguMjE1IDg2LjEgOTAuODQ3VjEwNC44NTNDODYuMSAxMDcuNDg1IDgzLjk4NSAxMDkuNiA4MS40IDEwOS42SDYyLjZDNjAuMDE1IDEwOS42IDU3LjkgMTA3LjQ4NSA1Ny45IDEwNC44NTNWOTAuODQ3QzU3LjkgODguMjE1IDYwLjAxNSA4Ni4xIDYyLjYgODYuMUg2Ny4zVjc2LjdINDMuOFY4Ni4xSDQ4LjVDNTEuMDg1IDg2LjEgNTMuMiA4OC4yMTUgNTMuMiA5MC44NDdWMTA0Ljg1M0M1My4yIDEwNy40ODUgNTEuMDg1IDEwOS42IDQ4LjUgMTA5LjZIMjkuN0MyNy4xMTUgMTA5LjYgMjUgMTA3LjQ4NSAyNSAxMDQuODUzVjkwLjg0N0MyNSA4OC4yMTUgMjcuMTE1IDg2LjEgMjkuNyA4Ni4xSDM0LjRWNzYuN0MzNC40IDcxLjUzIDM4LjYzIDY3LjMgNDMuOCA2Ny4zSDY3LjNWNTcuOUg2Mi42QzYwLjAxNSA1Ny45IDU3LjkgNTUuNzg1IDU3LjkgNTMuMTUzVjM5LjE0N0M1Ny45IDM2LjUxNSA2MC4wMTUgMzQuNCA2Mi42IDM0LjRIODEuNEM4My45ODUgMzQuNCA4Ni4xIDM2LjUxNSA4Ni4xIDM5LjE0N1Y1My4xNTNDODYuMSA1NS43ODUgODMuOTg1IDU3LjkgODEuNCA1Ny45SDc2LjdWNjcuM0gxMDAuMkMxMDUuMzcgNjcuMyAxMDkuNiA3MS41MyAxMDkuNiA3Ni43Vjg2LjFaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzEwMjVfMyIgeDE9IjE0Mi41IiB5MT0iMTQzIiB4Mj0iMy45OTk5OSIgeTI9IjkuNDk5OTkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzAwMDgyRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyRTMwNjciLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "subnets"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: [] diff --git a/packages/core/platform/psds/vm-disk.yaml b/packages/core/platform/psds/vm-disk.yaml index c23260a0..01797d29 100644 --- a/packages/core/platform/psds/vm-disk.yaml +++ b/packages/core/platform/psds/vm-disk.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.vm-disk-application spec: @@ -17,14 +17,34 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: vm-disk-application - path: system/vm-disk-application - releaseName: vm-disk-application - namespace: cozy-system - sources: + components: [] + applications: - name: vm-disk path: apps/vm-disk libraries: - cozy-lib - + template: + spec: + application: + kind: VMDisk + singular: vmdisk + plural: vmdisks + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"optical":{"description":"Defines if disk should be considered optical.","type":"boolean","default":false},"source":{"description":"The source image location used to create a disk.","type":"object","default":{},"properties":{"http":{"description":"Download image from an HTTP source.","type":"object","required":["url"],"properties":{"url":{"description":"URL to download the image.","type":"string"}}},"image":{"description":"Use image by name.","type":"object","required":["name"],"properties":{"name":{"description":"Name of the image to use (uploaded as \"golden image\" or from the list: `ubuntu`, `fedora`, `cirros`, `alpine`, `talos`).","type":"string"}}},"upload":{"description":"Upload local image."}}},"storage":{"description":"The size of the disk allocated for the virtual machine.","default":"5Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}} + release: + prefix: vm-disk- + labels: + cozystack.io/ui: "true" + dashboard: + category: IaaS + singular: VM Disk + plural: VM Disks + description: Virtual Machine disk + weight: 51 + tags: + - storage + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8zMzBfNDg5NjMpIi8+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2lfMzMwXzQ4OTYzKSI+CjxwYXRoIGQ9Ik03Mi4wMDAxIDI2LjYzNjdDNDYuODc3MiAyNi42MzY3IDI2LjUxMTIgNDcuMDAyNyAyNi41MTEyIDcyLjEyNTZDMjYuNTExMiA5Ny4yNDg0IDQ2Ljg3NzIgMTE3LjYxNCA3Mi4wMDAxIDExNy42MTRDOTcuMTIyOSAxMTcuNjE0IDExNy40ODkgOTcuMjQ4MiAxMTcuNDg5IDcyLjEyNTRDMTE3LjQ4OSA0Ny4wMDI1IDk3LjEyMjkgMjYuNjM2NyA3Mi4wMDAxIDI2LjYzNjdaTTcyLjAwMDEgODEuNjIxMkM2Ni43NTU3IDgxLjYyMTIgNjIuNTA0NCA3Ny4zNjk5IDYyLjUwNDQgNzIuMTI1NkM2Mi41MDQ0IDY2Ljg4MTIgNjYuNzU1NyA2Mi42Mjk5IDcyLjAwMDEgNjIuNjI5OUM3Ny4yNDQ0IDYyLjYyOTkgODEuNDk1NyA2Ni44ODEyIDgxLjQ5NTcgNzIuMTI1NkM4MS40OTU3IDc3LjM2OTkgNzcuMjQ0NCA4MS42MjEyIDcyLjAwMDEgODEuNjIxMloiIGZpbGw9IiNCQUQ5RkYiLz4KPC9nPgo8cGF0aCBkPSJNNTIuMDA3NSA2NS43MjA5TDMyLjI5NzYgNTkuMDQ5OEMzNi4yODQyIDQ3LjI3MTEgNDUuMzI4NSAzNy42MzE1IDU2LjQ5MSAzMy4yNjRMNjQuMDcyOCA1Mi42NDE5QzU4LjY0MiA1NC43NjY3IDU0LjAxOSA1OS43NzgzIDUyLjAwNzUgNjUuNzIwOVpNOTEuOTkyNiA3OC41M0wxMTEuNzAzIDg1LjIwMTFDMTA3LjcxNiA5Ni45Nzk5IDk4LjY3MTggMTA2LjYxOSA4Ny41MDkzIDExMC45ODdMNzkuOTI3NSA5MS42MDlDODUuMzU4MSA4OS40ODQyIDg5Ljk4MTMgODQuNDcyNiA5MS45OTI2IDc4LjUzWiIgZmlsbD0iI0VERjZGRiIvPgo8cGF0aCBkPSJNNTUuOTMyNCA1OC43MDI4QzU3LjY1MTQgNTYuNjE0IDU5LjcxOTQgNTQuODYzMiA2MS45ODk0IDUzLjYxODNDNjMuMTQ5IDUyLjk4MjQgNjQuMjYzMyA1My4xMjk2IDYzLjc4MTQgNTEuODk3OUw1Ny4yMDk1IDM1LjEwMDlDNTYuMjkwOSAzMi43NTI5IDU1LjI4MTQgMzMuNzI4NSA1My45MDYgMzQuMzg2OEM0OC45NzM0IDM2Ljc0NzYgNDQuNTM0OSA0MC4xNTkgNDAuODYwMSA0NC4zMTU0TDU1LjkzMjQgNTguNzAyOFpNODguMDY3NiA4NS41NDgxQzg1LjgzNTIgODguMjYwNSA4My4wMTQ4IDkwLjQwMjkgNzkuOTI2OSA5MS42MDhMODcuNTA4OSAxMTAuOTg2QzkzLjQ3ODUgMTA4LjY1NCA5OC44MzM2IDEwNC44MDYgMTAzLjE0IDk5LjkzNTVMODguMDY3NiA4NS41NDgxWiIgZmlsbD0iI0NERTNGRiIvPgo8cGF0aCBkPSJNNzIgODkuNDM4OEM2Mi40NTM0IDg5LjQzODggNTQuNjg2NSA4MS42NzIxIDU0LjY4NjUgNzIuMTI1NEM1NC42ODY1IDYyLjU3ODYgNjIuNDUzNCA1NC44MTE5IDcyIDU0LjgxMTlDODEuNTQ2OCA1NC44MTE5IDg5LjMxMzQgNjIuNTc4OCA4OS4zMTM0IDcyLjEyNTRDODkuMzEzNCA4MS42NzIgODEuNTQ2OCA4OS40Mzg4IDcyIDg5LjQzODhaTTcyIDU5LjExMDVDNjQuODIzNCA1OS4xMTA1IDU4Ljk4NDkgNjQuOTQ5IDU4Ljk4NDkgNzIuMTI1NkM1OC45ODQ5IDc5LjMwMjIgNjQuODIzNCA4NS4xNDA2IDcyIDg1LjE0MDZDNzkuMTc2NiA4NS4xNDA2IDg1LjAxNSA3OS4zMDIyIDg1LjAxNSA3Mi4xMjU2Qzg1LjAxNSA2NC45NDkgNzkuMTc2NiA1OS4xMTA1IDcyIDU5LjExMDVaIiBmaWxsPSIjMDBCNEZGIi8+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2lfMzMwXzQ4OTYzIiB4PSIyNi41MTEyIiB5PSIyNi42MzY3IiB3aWR0aD0iOTIuOTc3OCIgaGVpZ2h0PSI5Mi45Nzc1IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+CjxmZUNvbG9yTWF0cml4IGluPSJTb3VyY2VBbHBoYSIgdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIiByZXN1bHQ9ImhhcmRBbHBoYSIvPgo8ZmVPZmZzZXQgZHg9IjIiIGR5PSIyIi8+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIuNSIvPgo8ZmVDb21wb3NpdGUgaW4yPSJoYXJkQWxwaGEiIG9wZXJhdG9yPSJhcml0aG1ldGljIiBrMj0iLTEiIGszPSIxIi8+CjxmZUNvbG9yTWF0cml4IHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDEgMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwLjIxIDAiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbjI9InNoYXBlIiByZXN1bHQ9ImVmZmVjdDFfaW5uZXJTaGFkb3dfMzMwXzQ4OTYzIi8+CjwvZmlsdGVyPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMzMwXzQ4OTYzIiB4MT0iLTE1LjUiIHkxPSItMTIiIHgyPSIyMTYuNSIgeTI9IjE4NS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM2NUNDRkYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDQ0Mzc0Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "source"], ["spec", "optical"], ["spec", "storage"], ["spec", "storageClass"]] + secrets: + exclude: [] + include: [] diff --git a/packages/core/platform/psds/vm-instance.yaml b/packages/core/platform/psds/vm-instance.yaml index f93058aa..aed6caa6 100644 --- a/packages/core/platform/psds/vm-instance.yaml +++ b/packages/core/platform/psds/vm-instance.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.vm-instance-application spec: @@ -17,14 +17,39 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: vm-instance-application - path: system/vm-instance-application - releaseName: vm-instance-application - namespace: cozy-system - sources: + components: [] + applications: - name: vm-instance path: apps/vm-instance libraries: - cozy-lib - + template: + spec: + application: + kind: VMInstance + singular: vminstance + plural: vminstances + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"disks":{"description":"List of disks to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"bus":{"description":"Disk bus type (e.g. \"sata\").","type":"string"},"name":{"description":"Disk name.","type":"string"}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Determines if the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"subnets":{"description":"Additional subnets","type":"array","default":[],"items":{"type":"object","properties":{"name":{"description":"Subnet name","type":"string"}}}}}} + release: + prefix: vm-instance- + labels: + cozystack.io/ui: "true" + dashboard: + category: IaaS + singular: VM Instance + plural: VM Instances + description: Virtual machine instance + weight: 50 + tags: + - compute + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQ1NCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDU0KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMDBCM0ZGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi41Mjc1IDUzLjgzNjdDNzIuNDQzMSA1My44MzUxIDcyLjM2MDUgNTMuODEyMiA3Mi4yODczIDUzLjc3MDFMNTYuNDY5OSA0NC43OTM0QzU2LjM5ODMgNDQuNzUxOSA1Ni4zMzg4IDQ0LjY5MjMgNTYuMjk3MyA0NC42MjA3QzU2LjI1NTkgNDQuNTQ5IDU2LjIzMzggNDQuNDY3OCA1Ni4yMzM0IDQ0LjM4NUM1Ni4yMzM0IDQ0LjIxNjkgNTYuMzI1OCA0NC4wNjE3IDU2LjQ2OTkgNDMuOTc4NUw3Mi4xOTEyIDM1LjA2MDlDNzIuMjYzNyAzNS4wMjEgNzIuMzQ1IDM1IDcyLjQyNzcgMzVDNzIuNTEwNSAzNSA3Mi41OTE4IDM1LjAyMSA3Mi42NjQzIDM1LjA2MDlMODguNDg3MiA0NC4wMzk1Qzg4LjU1OTEgNDQuMDgwMSA4OC42MTg4IDQ0LjEzOTIgODguNjYgNDQuMjEwN0M4OC43MDEzIDQ0LjI4MjIgODguNzIyNyA0NC4zNjM1IDg4LjcyMTkgNDQuNDQ2Qzg4LjcyMjUgNDQuNTI4NSA4OC43MDEgNDQuNjA5NyA4OC42NTk4IDQ0LjY4MTJDODguNjE4NSA0NC43NTI2IDg4LjU1ODkgNDQuODExOCA4OC40ODcyIDQ0Ljg1MjVMNzIuNzcxNCA1My43NjgzQzcyLjY5NzIgNTMuODExNCA3Mi42MTMzIDUzLjgzNDkgNzIuNTI3NSA1My44MzY3IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjciIGQ9Ik03MC4yNTUzIDc1LjY1MTdDNzAuMTcxIDc1LjY1MzUgNzAuMDg3OCA3NS42MzE3IDcwLjAxNTEgNzUuNTg4OEw1NC4yNDU4IDY2LjY0MTdDNTQuMTcxNSA2Ni42MDI0IDU0LjEwOTUgNjYuNTQzNiA1NC4wNjYxIDY2LjQ3MTZDNTQuMDIyOCA2Ni4zOTk3IDU0IDY2LjMxNzMgNTQgNjYuMjMzM1Y0OC4yNzhDNTQgNDguMTA4IDU0LjA5MjQgNDcuOTU0NiA1NC4yNDM5IDQ3Ljg2OTZDNTQuMzE3MiA0Ny44MjcxIDU0LjQwMDQgNDcuODA0NyA1NC40ODUxIDQ3LjgwNDdDNTQuNTY5NyA0Ny44MDQ3IDU0LjY1MjkgNDcuODI3MSA1NC43MjYyIDQ3Ljg2OTZMNzAuNDkzNyA1Ni44MTMxQzcwLjU2NDIgNTYuODU2NSA3MC42MjI1IDU2LjkxNyA3MC42NjMyIDU2Ljk4OTFDNzAuNzAzOSA1Ny4wNjEyIDcwLjcyNTcgNTcuMTQyNCA3MC43MjY1IDU3LjIyNTFWNzUuMTgwNUM3MC43MjU5IDc1LjI2MjggNzAuNzA0MiA3NS4zNDM2IDcwLjY2MzUgNzUuNDE1MUM3MC42MjI3IDc1LjQ4NjYgNzAuNTY0MiA3NS41NDY0IDcwLjQ5MzcgNzUuNTg4OEM3MC40MjA2IDc1LjYyOTEgNzAuMzM4NyA3NS42NTA3IDcwLjI1NTMgNzUuNjUxNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC40IiBkPSJNNzQuNzE5OCA3NS42NTExQzc0LjYzMzMgNzUuNjUxMiA3NC41NDgyIDc1LjYyOTYgNzQuNDcyMiA3NS41ODgzQzc0LjQwMTYgNzUuNTQ2MSA3NC4zNDMyIDc1LjQ4NjIgNzQuMzAyNyA3NS40MTQ3Qzc0LjI2MjMgNzUuMzQzMSA3NC4yNDExIDc1LjI2MjIgNzQuMjQxMiA3NS4xOFY1Ny4zMzczQzc0LjI0MTIgNTcuMTcxIDc0LjMzMzYgNTcuMDE1OCA3NC40NzIyIDU2LjkyOUw5MC4yMzk3IDQ3Ljk4NTVDOTAuMzExOSA0Ny45NDM4IDkwLjM5MzggNDcuOTIxOSA5MC40NzcxIDQ3LjkyMTlDOTAuNTYwNSA0Ny45MjE5IDkwLjY0MjQgNDcuOTQzOCA5MC43MTQ2IDQ3Ljk4NTVDOTAuNzg3NiA0OC4wMjU1IDkwLjg0ODUgNDguMDg0MiA5MC44OTExIDQ4LjE1NTdDOTAuOTMzNyA0OC4yMjcyIDkwLjk1NjMgNDguMzA4OCA5MC45NTY2IDQ4LjM5MlY2Ni4yMzI4QzkwLjk1NyA2Ni4zMTY0IDkwLjkzNDcgNjYuMzk4NSA5MC44OTIxIDY2LjQ3MDRDOTAuODQ5NSA2Ni41NDI0IDkwLjc4ODEgNjYuNjAxNCA5MC43MTQ2IDY2LjY0MTFMNzQuOTUyNiA3NS41ODgzQzc0Ljg4MjUgNzUuNjMwNyA3NC44MDE4IDc1LjY1MjUgNzQuNzE5OCA3NS42NTExIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zNDU0IiB4MT0iMTYxIiB5MT0iMTgwIiB4Mj0iMy41OTI4NGUtMDciIHkyPSI0Ljk5OTk4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTk1NjU2Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNjg3XzM0NTQiPgo8cmVjdCB3aWR0aD0iOTQiIGhlaWdodD0iOTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSAyNSkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "disks"], ["spec", "subnets"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - matchLabels: + apps.cozystack.io/user-service: "true" diff --git a/packages/core/platform/psds/vpn.yaml b/packages/core/platform/psds/vpn.yaml index 3347a330..788562c2 100644 --- a/packages/core/platform/psds/vpn.yaml +++ b/packages/core/platform/psds/vpn.yaml @@ -1,6 +1,6 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition +kind: PackageSource metadata: name: cozystack.vpn-application spec: @@ -16,14 +16,40 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - packages: - - name: vpn-application - path: system/vpn-application - releaseName: vpn - namespace: cozy-system - sources: + components: [] + applications: - name: vpn path: apps/vpn libraries: - cozy-lib - + template: + spec: + application: + kind: VPN + plural: vpns + singular: vpn + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalIPs":{"description":"List of externalIPs for service. Optional. If not specified, will use LoadBalancer service by default.","type":"array","default":[],"items":{"type":"string"}},"host":{"description":"Host used to substitute into generated URLs.","type":"string","default":""},"replicas":{"description":"Number of VPN server replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each VPN server replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user (autogenerated if not provided).","type":"string"}}}}}} + release: + prefix: vpn- + labels: + cozystack.io/ui: "true" + dashboard: + category: NaaS + singular: VPN + plural: VPN + description: Managed VPN service + tags: + - network + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xNDMuOTkyIDMwLjM2OTdDMTQzLjk5MiAyOS4yNTU2IDE0My45OTIgMjguMTUxNyAxNDMuOTkyIDI3LjA0NzdDMTQzLjk0NSAyNC42Mjg3IDE0My43MTcgMjIuMjE2NiAxNDMuMzA5IDE5LjgzMTZDMTQyLjkxMiAxNy40NDczIDE0Mi4xNTcgMTUuMTM2NSAxNDEuMDcyIDEyLjk3NjlDMTM5Ljk3IDEwLjgxOCAxMzguNTM0IDguODQ2NjUgMTM2LjgxNyA3LjEzNTc3TDEzMC45OTcgMi44OTA0NEMxMjguODM3IDEuODAyODkgMTI2LjUyNyAxLjA0MTg5IDEyNC4xNDQgMC42MzIyODNDMTIxLjc1NiAwLjIzNDgwOCAxMTkuMzQgMC4wMjM0MTEzIDExNi45MTkgMEMxMTUuODE1IDAgMjguMTQ2MSAwIDI3LjAzMjMgMEMyNC42MDQ3IDAuMDI0MjIxMSAyMi4xODI2IDAuMjM1NjA5IDE5Ljc4NzYgMC42MzIyODNDMTcuNDEyOCAxLjAzODUxIDE1LjExMjYgMS43OTk3NCAxMi45NjQzIDIuODkwNDRDMTAuODEzIDMuOTk1MTkgOC44NDYyNSA1LjQyNzM2IDcuMTM0MzYgNy4xMzU3N0M1LjQxNzY4IDguODQ0NCAzLjk4NDggMTAuODE2MyAyLjg4OTg3IDEyLjk3NjlDMS44MDA4NiAxNS4xMzYgMS4wNDMxMyAxNy40NDY4IDAuNjQyMTkzIDE5LjgzMTZDMC4yNDM0OTcgMjIuMjE2OSAwLjAyODc5OTggMjQuNjI5NCAwIDI3LjA0NzdDMCAyOC4xNTE3IDAgMTE1LjgzOCAwIDExNi45NTJDMC4wMjYxNzU1IDExOS4zODQgMC4yNDA4ODQgMTIxLjgxIDAuNjQyMTkzIDEyNC4yMDlDMS4wNDA0NCAxMjYuNTk0IDEuNzk4MjkgMTI4LjkwNSAyLjg4OTg3IDEzMS4wNjNDMy45ODUxNSAxMzMuMjE4IDUuNDE4MSAxMzUuMTgzIDcuMTM0MzYgMTM2Ljg4NEM4Ljg0MDk1IDEzOC41OTkgMTAuODA4NyAxNDAuMDMyIDEyLjk2NDMgMTQxLjEzQzE1LjExNDcgMTQyLjIwOSAxNy40MTQ2IDE0Mi45NiAxOS43ODc2IDE0My4zNThDMjIuMTczMSAxNDMuNzUxIDI0LjU4NDcgMTQzLjk2NiAyNy4wMDIyIDE0NEMyOC4xMTYgMTQ0IDExNS43ODUgMTQ0IDExNi44ODkgMTQ0QzExOS4zMDMgMTQzLjk2NyAxMjEuNzEyIDE0My43NTIgMTI0LjA5NCAxNDMuMzU4QzEyNi40ODUgMTQyLjk0NiAxMjguODAxIDE0Mi4xODIgMTMwLjk2NyAxNDEuMDg5QzEzMy4xMjEgMTM5Ljk5NCAxMzUuMDg2IDEzOC41NjEgMTM2Ljc4NyAxMzYuODQ0QzEzOC41MDMgMTM1LjE0IDEzOS45MzkgMTMzLjE3NiAxNDEuMDQyIDEzMS4wMjNDMTQyLjEzNyAxMjguODc5IDE0Mi45MDEgMTI2LjU4MSAxNDMuMzA5IDEyNC4yMDlDMTQzLjcxIDEyMS44MjMgMTQzLjkzMiAxMTkuNDExIDE0My45NzIgMTE2Ljk5MkMxNDMuOTkyIDExNS44MzggMTQ0LjAxMiAzMS42NzQ0IDE0My45OTIgMzAuMzY5N1oiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgxOCkiLz4KPHBhdGggZD0iTTExNS45NTUgNjcuNDIzMUMxMTQuOTQxIDU3LjgyMzQgMTEwLjcwMSA0OC44NTE4IDEwMy45MjggNDEuOTc1MkM5Ny4xNTQ5IDM1LjA5ODYgODguMjQ5NSAzMC43MjM5IDc4LjY2OCAyOS41NjY0VjQ2Ljc3ODZDODQuNDg4NyA0Ny45MTI3IDg5LjczMzggNTEuMDM2MiA5My41MDQ5IDU1LjYxMzdDOTcuMjc2IDYwLjE5MTIgOTkuMzM4MSA2NS45Mzc5IDk5LjMzODEgNzEuODY5MkM5OS4zMzgxIDc3LjgwMDQgOTcuMjc2IDgzLjU0NzEgOTMuNTA0OSA4OC4xMjQ2Qzg5LjczMzggOTIuNzAyMiA4NC40ODg3IDk1LjgyNTYgNzguNjY4IDk2Ljk1OThWMTE0LjIyMkM4OS43ODAxIDExMi44NzcgOTkuOTE3OCAxMDcuMjE1IDEwNi44OTQgOTguNDYwMUMxMTMuODY5IDg5LjcwNDggMTE3LjEyNCA3OC41NTczIDExNS45NTUgNjcuNDIzMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0yOC4wMTU1IDc2LjM2NTRDMjkuMDMxMSA4NS45NjQ0IDMzLjI3MTggOTQuOTM1MSA0MC4wNDQ3IDEwMS44MTFDNDYuODE3NSAxMDguNjg4IDU1LjcyMiAxMTMuMDYzIDY1LjMwMjggMTE0LjIyMlYyOS41NjY0QzU0LjE5MDcgMzAuOTExOSA0NC4wNTMgMzYuNTczMSAzNy4wNzcyIDQ1LjMyODRDMzAuMTAxMyA1NC4wODM3IDI2Ljg0NjcgNjUuMjMxMiAyOC4wMTU1IDc2LjM2NTRaIiBmaWxsPSIjNUJCMTkzIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgxXzI4MTgiIHgxPSIxMzIuNSIgeTE9IjEzMi41IiB4Mj0iLTI0IiB5Mj0iLTE5IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMxODM3MjkiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNDU5RDc1Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "external"], ["spec", "host"], ["spec", "users"], ["spec", "externalIPs"]] + secrets: + exclude: [] + include: + - resourceNames: + - "{{`vpn-{{ .name }}-urls`}}" + services: + exclude: [] + include: + - resourceNames: + - "{{`vpn-{{ .name }}-vpn`}}" diff --git a/packages/packages.yaml b/packages/packages.yaml index 828af96b..3405c21d 100644 --- a/packages/packages.yaml +++ b/packages/packages.yaml @@ -1,121 +1,13 @@ --- apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition -metadata: - name: cozystack.clickhouse-operator -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - dependsOn: - - cozystack.networking - - cozystack.monitoring - - cozystack.cozystack-core - packages: - default: - - name: clickhouse-operator - path: system/clickhouse-operator - releaseName: clickhouse-operator - namespace: cozy-clickhouse-operator ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition -metadata: - name: cozystack.clickhouse-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - dependsOn: - - cozystack.clickhouse-operator - packages: - default: - - name: clickhouse-application - path: system/clickhouse-application - releaseName: clickhouse-application - namespace: cozy-system - applications: - default: - - name: clickhouse-application - path: apps/clickhouse - libraries: - - path: library/cozy-lib ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition -metadata: - name: cozystack.networking -spec: - dependsOn: - - cozystack.cert-manager - packages: - noop: [] - cilium: - - name: cilium - releaseName: cilium - path: system/cilium - namespace: cozy-cilium - privileged: true - dependsOn: [] - valuesFiles: - - values.yaml - - values-talos.yaml - - name: cilium-networkpolicy - releaseName: cilium-networkpolicy - path: system/cilium-networkpolicy - namespace: cozy-cilium - privileged: true - dependsOn: [cilium] - kubeovn-cilium: - - name: cilium - releaseName: cilium - path: system/cilium - namespace: cozy-cilium - privileged: true - dependsOn: [] - valuesFiles: - - values.yaml - - values-talos.yaml - - values-kubeovn.yaml - - name: cilium-networkpolicy - releaseName: cilium-networkpolicy - path: system/cilium-networkpolicy - namespace: cozy-cilium - privileged: true - dependsOn: [cilium] - - name: kubeovn - releaseName: kubeovn - path: system/kubeovn - namespace: cozy-kubeovn - privileged: true - dependsOn: [cilium] - - name: kubeovn-plunger - releaseName: kubeovn-plunger - path: system/kubeovn-plunger - namespace: cozy-kubeovn - dependsOn: [cilium,kubeovn] - - name: kubeovn-webhook - releaseName: kubeovn-webhook - path: system/kubeovn-webhook - namespace: cozy-kubeovn - privileged: true - dependsOn: [cilium,kubeovn] - -# PackageSetDefinition --> ArtifactGenerator --> ExternalArtifact (many) -# PackageSet --> HelmRelease (many) ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSet +kind: Package metadata: name: cozystack.networking spec: + variant: cilium-kubeovn #ignoreDependencies: #- cozystack.networking - packages: + components: cilium: enabled: false values: @@ -130,70 +22,3 @@ spec: POD_GATEWAY: "10.244.0.1" SVC_CIDR: "10.96.0.0/16" JOIN_CIDR: "100.64.0.0/16" - ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSetDefinition -metadata: - name: cozystack.cozystack-core -spec: - packages: - default: - - name: cozystack-controller - releaseName: cozystack-controller - path: system/cozystack-controller - namespace: cozy-system - dependsOn: [] - - name: cozystack-api - releaseName: cozystack-api - path: system/cozystack-api - namespace: cozy-system - dependsOn: [cozystack-controller] - - name: lineage-controller-webhook - releaseName: lineage-controller-webhook - path: system/lineage-controller-webhook - namespace: cozy-system - dependsOn: [cozystack-controller] - - name: dashboard - releaseName: dashboard - path: system/dashboard - namespace: cozy-dashboard - dependsOn: [cozystack-api,cozystack-controller] - oidc: - - name: cozystack-controller - releaseName: cozystack-controller - path: system/cozystack-controller - namespace: cozy-system - dependsOn: [] - - name: cozystack-api - releaseName: cozystack-api - path: system/cozystack-api - namespace: cozy-system - dependsOn: [cozystack-controller] - - name: lineage-controller-webhook - releaseName: lineage-controller-webhook - path: system/lineage-controller-webhook - namespace: cozy-system - dependsOn: [cozystack-controller] - - name: dashboard - releaseName: dashboard - path: system/dashboard - namespace: cozy-dashboard - dependsOn: [cozystack-api,cozystack-controller,keycloak-configure] - - name: keycloak-configure - releaseName: keycloak-configure - path: system/keycloak-configure - namespace: cozy-keycloak - dependsOn: [keycloak-operator] - - name: keycloak - releaseName: keycloak - path: system/keycloak - namespace: cozy-keycloak - dependsOn: [postgres-operator] - libraries: - - path: library/cozy-lib - - name: keycloak-operator - releaseName: keycloak-operator - path: system/keycloak-operator - namespace: cozy-keycloak - dependsOn: [keycloak] diff --git a/packages/system/cozystack-controller/crds/cozystack.io_packages.yaml b/packages/system/cozystack-controller/crds/cozystack.io_packages.yaml new file mode 100644 index 00000000..04d19b72 --- /dev/null +++ b/packages/system/cozystack-controller/crds/cozystack.io_packages.yaml @@ -0,0 +1,156 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: packages.cozystack.io +spec: + group: cozystack.io + names: + kind: Package + listKind: PackageList + plural: packages + shortNames: + - pkg + - pkgs + singular: package + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Selected variant + jsonPath: .spec.variant + name: Variant + type: string + - description: Ready status + jsonPath: .status.conditions[?(@.type=='Ready')].status + name: Ready + type: string + - description: Ready message + jsonPath: .status.conditions[?(@.type=='Ready')].message + name: Status + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Package is the Schema for the packages API + 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: PackageSpec defines the desired state of Package + properties: + components: + additionalProperties: + description: PackageRelease defines overrides for a specific component + properties: + enabled: + description: |- + Enabled indicates whether this component should be installed + If false, the component will be disabled even if it's defined in the PackageSource + type: boolean + values: + description: |- + Values contains Helm chart values as a JSON object + These values will be merged with the default values from the PackageSource + x-kubernetes-preserve-unknown-fields: true + type: object + description: |- + Components is a map of release name to component overrides + Allows overriding values and enabling/disabling specific components from the PackageSource + type: object + ignoreDependencies: + description: |- + IgnoreDependencies is a list of package source dependencies to ignore + Dependencies listed here will not be installed even if they are specified in the PackageSource + items: + type: string + type: array + variant: + description: |- + Variant is the name of the variant to use from the PackageSource + If not specified, defaults to "default" + type: string + type: object + status: + description: PackageStatus defines the observed state of Package + properties: + conditions: + description: Conditions represents the latest available observations + of a Package's state + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + 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 in CamelCase or in foo.example.com/CamelCase. + 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 + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml b/packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml new file mode 100644 index 00000000..2596175a --- /dev/null +++ b/packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml @@ -0,0 +1,958 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.4 + name: packagesources.cozystack.io +spec: + group: cozystack.io + names: + kind: PackageSource + listKind: PackageSourceList + plural: packagesources + shortNames: + - pkgsrc + - pkgsrcs + singular: packagesource + scope: Cluster + versions: + - additionalPrinterColumns: + - description: Package variants (comma-separated) + jsonPath: .status.variants + name: Variants + type: string + - description: Ready status + jsonPath: .status.conditions[?(@.type=='Ready')].status + name: Ready + type: string + - description: Ready message + jsonPath: .status.conditions[?(@.type=='Ready')].message + name: Status + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PackageSource is the Schema for the packagesources API + 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: PackageSourceSpec defines the desired state of PackageSource + properties: + sourceRef: + description: SourceRef is the source reference for the package source + charts + properties: + kind: + description: Kind of the source reference + enum: + - GitRepository + - OCIRepository + type: string + name: + description: Name of the source reference + type: string + namespace: + description: Namespace of the source reference + type: string + path: + description: |- + Path is the base path where packages are located in the source. + For GitRepository, defaults to "packages" if not specified. + For OCIRepository, defaults to empty string (root) if not specified. + type: string + required: + - kind + - name + - namespace + type: object + variants: + description: |- + Variants is a list of package source variants + Each variant defines components, applications, dependencies, and libraries for a specific configuration + items: + description: Variant defines a single variant configuration + properties: + applications: + description: Applications is a list of application releases + to be installed as part of this variant + items: + description: Application defines a single application release + within a package source + properties: + libraries: + description: |- + Libraries is a list of library names that this application depends on + These libraries must be defined at the variant level + items: + type: string + type: array + name: + description: Name is the unique identifier for this application + within the package source + type: string + path: + description: Path is the path to the Helm chart directory + type: string + template: + description: Template describes the applications that + will be created. + 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: + properties: + application: + description: Application configuration + properties: + kind: + description: Kind of the application, used + for UI and API + type: string + openAPISchema: + description: OpenAPI schema for the application, + used for API validation + type: string + plural: + description: Plural name of the application, + used for UI and API + type: string + singular: + description: Singular name of the application, + used for UI and API + type: string + required: + - kind + - openAPISchema + - plural + - singular + type: object + dashboard: + description: Dashboard configuration for this + resource + properties: + category: + description: Category used to group resources + in the UI (e.g., "Storage", "Networking") + type: string + description: + description: Short description shown in catalogs + or headers (e.g., "S3 compatible storage") + type: string + icon: + description: Icon encoded as a string (e.g., + inline SVG, base64, or data URI) + type: string + keysOrder: + description: Order of keys in the YAML view + items: + items: + type: string + type: array + type: array + module: + description: Whether this resource is a module + (tenant module) + type: boolean + name: + description: Hard-coded name used in the UI + (e.g., "bucket") + type: string + plural: + description: Plural human-readable name (e.g., + "Buckets") + type: string + singular: + description: Human-readable name shown in + the UI (e.g., "Bucket") + type: string + singularResource: + description: Whether this resource is singular + (not a collection) in the UI + type: boolean + tabs: + description: Which tabs to show for this resource + items: + description: DashboardTab enumerates allowed + UI tabs. + enum: + - workloads + - ingresses + - services + - secrets + - yaml + type: string + type: array + tags: + description: Free-form tags for search and + filtering + items: + type: string + type: array + weight: + description: Order weight for sorting resources + in the UI (lower first) + type: integer + required: + - category + - plural + - singular + type: object + ingresses: + description: Ingress selectors + properties: + exclude: + description: |- + Exclude contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, it is + hidden from the user, regardless of the matches in the include array. + items: + description: "CozystackResourceDefinitionResourceSelector + extends metav1.LabelSelector with resourceNames + support.\nA resource matches this selector + only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions + and matchLabels)\n- AND has a name that + matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field + supports Go templates with the following + variables available:\n- {{ .name }}: The + name of the managing application (from + apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the + managing application (from apps.cozystack.io/application.kind)\n- + {{ .namespace }}: The namespace of the + resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t + \ include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: + DoesNotExist\n\t matchLabels:\n\t goodlabel: + goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind + }}-{{ .name }}-tls\"\n\t - \"specificname\"" + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + include: + description: |- + Include contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, and + matches none of the selectors in the exclude array that resource is marked + as a tenant resource and is visible to users. + items: + description: "CozystackResourceDefinitionResourceSelector + extends metav1.LabelSelector with resourceNames + support.\nA resource matches this selector + only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions + and matchLabels)\n- AND has a name that + matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field + supports Go templates with the following + variables available:\n- {{ .name }}: The + name of the managing application (from + apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the + managing application (from apps.cozystack.io/application.kind)\n- + {{ .namespace }}: The namespace of the + resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t + \ include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: + DoesNotExist\n\t matchLabels:\n\t goodlabel: + goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind + }}-{{ .name }}-tls\"\n\t - \"specificname\"" + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + type: object + release: + description: Release configuration + properties: + chart: + description: Helm chart configuration + properties: + name: + description: Name of the Helm chart + type: string + sourceRef: + description: Source reference for the + Helm chart + properties: + kind: + default: HelmRepository + description: Kind of the source reference + type: string + name: + description: Name of the source reference + type: string + namespace: + default: cozy-public + description: Namespace of the source + reference + type: string + required: + - kind + - name + - namespace + type: object + required: + - name + - sourceRef + type: object + labels: + additionalProperties: + type: string + description: Labels for the release + type: object + prefix: + description: Prefix for the release name + type: string + required: + - prefix + type: object + secrets: + description: Secret selectors + properties: + exclude: + description: |- + Exclude contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, it is + hidden from the user, regardless of the matches in the include array. + items: + description: "CozystackResourceDefinitionResourceSelector + extends metav1.LabelSelector with resourceNames + support.\nA resource matches this selector + only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions + and matchLabels)\n- AND has a name that + matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field + supports Go templates with the following + variables available:\n- {{ .name }}: The + name of the managing application (from + apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the + managing application (from apps.cozystack.io/application.kind)\n- + {{ .namespace }}: The namespace of the + resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t + \ include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: + DoesNotExist\n\t matchLabels:\n\t goodlabel: + goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind + }}-{{ .name }}-tls\"\n\t - \"specificname\"" + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + include: + description: |- + Include contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, and + matches none of the selectors in the exclude array that resource is marked + as a tenant resource and is visible to users. + items: + description: "CozystackResourceDefinitionResourceSelector + extends metav1.LabelSelector with resourceNames + support.\nA resource matches this selector + only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions + and matchLabels)\n- AND has a name that + matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field + supports Go templates with the following + variables available:\n- {{ .name }}: The + name of the managing application (from + apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the + managing application (from apps.cozystack.io/application.kind)\n- + {{ .namespace }}: The namespace of the + resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t + \ include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: + DoesNotExist\n\t matchLabels:\n\t goodlabel: + goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind + }}-{{ .name }}-tls\"\n\t - \"specificname\"" + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + type: object + services: + description: Service selectors + properties: + exclude: + description: |- + Exclude contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, it is + hidden from the user, regardless of the matches in the include array. + items: + description: "CozystackResourceDefinitionResourceSelector + extends metav1.LabelSelector with resourceNames + support.\nA resource matches this selector + only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions + and matchLabels)\n- AND has a name that + matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field + supports Go templates with the following + variables available:\n- {{ .name }}: The + name of the managing application (from + apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the + managing application (from apps.cozystack.io/application.kind)\n- + {{ .namespace }}: The namespace of the + resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t + \ include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: + DoesNotExist\n\t matchLabels:\n\t goodlabel: + goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind + }}-{{ .name }}-tls\"\n\t - \"specificname\"" + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + include: + description: |- + Include contains an array of resource selectors that target resources. + If a resource matches the selector in any of the elements in the array, and + matches none of the selectors in the exclude array that resource is marked + as a tenant resource and is visible to users. + items: + description: "CozystackResourceDefinitionResourceSelector + extends metav1.LabelSelector with resourceNames + support.\nA resource matches this selector + only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions + and matchLabels)\n- AND has a name that + matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field + supports Go templates with the following + variables available:\n- {{ .name }}: The + name of the managing application (from + apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the + managing application (from apps.cozystack.io/application.kind)\n- + {{ .namespace }}: The namespace of the + resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t + \ include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: + DoesNotExist\n\t matchLabels:\n\t goodlabel: + goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind + }}-{{ .name }}-tls\"\n\t - \"specificname\"" + properties: + matchExpressions: + description: matchExpressions is a list + of label selector requirements. The + requirements are ANDed. + items: + description: |- + A label selector requirement is a selector that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label + key that the selector applies + to. + type: string + operator: + description: |- + operator represents a key's relationship to a set of values. + Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: |- + values is an array of string values. If the operator is In or NotIn, + the values array must be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + matchLabels: + additionalProperties: + type: string + description: |- + matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, whose key field is "key", the + operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + resourceNames: + description: |- + ResourceNames is a list of resource names to match + If specified, the resource must have one of these exact names to match the selector + items: + type: string + type: array + type: object + x-kubernetes-map-type: atomic + type: array + type: object + required: + - application + - release + type: object + type: object + required: + - name + - path + - template + type: object + type: array + components: + description: Components is a list of Helm releases to be installed + as part of this variant + items: + description: Component defines a single Helm release component + within a package source + properties: + disabled: + description: Disabled indicates whether this component + is disabled (should not be installed) + type: boolean + install: + description: Install defines installation parameters for + this component + properties: + dependsOn: + description: DependsOn is a list of component names + that must be installed before this component + items: + type: string + type: array + namespace: + description: Namespace is the Kubernetes namespace + where the release will be installed + type: string + privileged: + description: Privileged indicates whether this release + requires privileged access + type: boolean + releaseName: + description: |- + ReleaseName is the name of the HelmRelease resource that will be created + If not specified, defaults to the component Name field + type: string + type: object + libraries: + description: |- + Libraries is a list of library names that this component depends on + These libraries must be defined at the variant level + items: + type: string + type: array + name: + description: Name is the unique identifier for this component + within the package source + type: string + path: + description: Path is the path to the Helm chart directory + type: string + valuesFiles: + description: ValuesFiles is a list of values file names + to use + items: + type: string + type: array + required: + - name + - path + type: object + type: array + dependsOn: + description: |- + DependsOn is a list of package source dependencies + For example: "cozystack.networking" + items: + type: string + type: array + libraries: + description: Libraries is a list of Helm library charts used + by components in this variant + items: + description: Library defines a Helm library chart + properties: + name: + description: Name is the optional name for library placed + in charts + type: string + path: + description: Path is the path to the library chart directory + type: string + required: + - path + type: object + type: array + name: + description: Name is the unique identifier for this variant + type: string + required: + - name + type: object + type: array + type: object + status: + description: PackageSourceStatus defines the observed state of PackageSource + properties: + conditions: + description: Conditions represents the latest available observations + of a PackageSource's state + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + 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. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + 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 in CamelCase or in foo.example.com/CamelCase. + 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 + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + variants: + description: |- + Variants is a comma-separated list of package variant names + This field is populated by the controller based on spec.variants keys + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml b/packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml index 685d4ac5..c62a5ce3 100644 --- a/packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml +++ b/packages/system/cozystack-resource-definition-crd/definition/cozystack.io_cozystackresourcedefinitions.yaml @@ -135,29 +135,22 @@ spec: If a resource matches the selector in any of the elements in the array, it is hidden from the user, regardless of the matches in the include array. items: - description: |- - CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. - A resource matches this selector only if it satisfies ALL criteria: - - Label selector conditions (matchExpressions and matchLabels) - - AND has a name that matches one of the names in resourceNames (if specified) - - The resourceNames field supports Go templates with the following variables available: - - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) - - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) - - {{ .namespace }}: The namespace of the resource being processed - - Example YAML: - secrets: - include: - - matchExpressions: - - key: badlabel - operator: DoesNotExist - matchLabels: - goodlabel: goodvalue - resourceNames: - - "{{ .name }}-secret" - - "{{ .kind }}-{{ .name }}-tls" - - "specificname" + description: "CozystackResourceDefinitionResourceSelector extends + metav1.LabelSelector with resourceNames support.\nA resource + matches this selector only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions and matchLabels)\n- + AND has a name that matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field supports Go templates + with the following variables available:\n- {{ .name }}: The + name of the managing application (from apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the managing application + (from apps.cozystack.io/application.kind)\n- {{ .namespace + }}: The namespace of the resource being processed\n\nExample + YAML:\n\n\tsecrets:\n\t include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: DoesNotExist\n\t matchLabels:\n\t + \ goodlabel: goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind }}-{{ .name }}-tls\"\n\t + \ - \"specificname\"" properties: matchExpressions: description: matchExpressions is a list of label selector @@ -217,29 +210,22 @@ spec: matches none of the selectors in the exclude array that resource is marked as a tenant resource and is visible to users. items: - description: |- - CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. - A resource matches this selector only if it satisfies ALL criteria: - - Label selector conditions (matchExpressions and matchLabels) - - AND has a name that matches one of the names in resourceNames (if specified) - - The resourceNames field supports Go templates with the following variables available: - - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) - - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) - - {{ .namespace }}: The namespace of the resource being processed - - Example YAML: - secrets: - include: - - matchExpressions: - - key: badlabel - operator: DoesNotExist - matchLabels: - goodlabel: goodvalue - resourceNames: - - "{{ .name }}-secret" - - "{{ .kind }}-{{ .name }}-tls" - - "specificname" + description: "CozystackResourceDefinitionResourceSelector extends + metav1.LabelSelector with resourceNames support.\nA resource + matches this selector only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions and matchLabels)\n- + AND has a name that matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field supports Go templates + with the following variables available:\n- {{ .name }}: The + name of the managing application (from apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the managing application + (from apps.cozystack.io/application.kind)\n- {{ .namespace + }}: The namespace of the resource being processed\n\nExample + YAML:\n\n\tsecrets:\n\t include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: DoesNotExist\n\t matchLabels:\n\t + \ goodlabel: goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind }}-{{ .name }}-tls\"\n\t + \ - \"specificname\"" properties: matchExpressions: description: matchExpressions is a list of label selector @@ -334,7 +320,6 @@ spec: description: Prefix for the release name type: string required: - - chart - prefix type: object secrets: @@ -346,29 +331,22 @@ spec: If a resource matches the selector in any of the elements in the array, it is hidden from the user, regardless of the matches in the include array. items: - description: |- - CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. - A resource matches this selector only if it satisfies ALL criteria: - - Label selector conditions (matchExpressions and matchLabels) - - AND has a name that matches one of the names in resourceNames (if specified) - - The resourceNames field supports Go templates with the following variables available: - - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) - - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) - - {{ .namespace }}: The namespace of the resource being processed - - Example YAML: - secrets: - include: - - matchExpressions: - - key: badlabel - operator: DoesNotExist - matchLabels: - goodlabel: goodvalue - resourceNames: - - "{{ .name }}-secret" - - "{{ .kind }}-{{ .name }}-tls" - - "specificname" + description: "CozystackResourceDefinitionResourceSelector extends + metav1.LabelSelector with resourceNames support.\nA resource + matches this selector only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions and matchLabels)\n- + AND has a name that matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field supports Go templates + with the following variables available:\n- {{ .name }}: The + name of the managing application (from apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the managing application + (from apps.cozystack.io/application.kind)\n- {{ .namespace + }}: The namespace of the resource being processed\n\nExample + YAML:\n\n\tsecrets:\n\t include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: DoesNotExist\n\t matchLabels:\n\t + \ goodlabel: goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind }}-{{ .name }}-tls\"\n\t + \ - \"specificname\"" properties: matchExpressions: description: matchExpressions is a list of label selector @@ -428,29 +406,22 @@ spec: matches none of the selectors in the exclude array that resource is marked as a tenant resource and is visible to users. items: - description: |- - CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. - A resource matches this selector only if it satisfies ALL criteria: - - Label selector conditions (matchExpressions and matchLabels) - - AND has a name that matches one of the names in resourceNames (if specified) - - The resourceNames field supports Go templates with the following variables available: - - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) - - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) - - {{ .namespace }}: The namespace of the resource being processed - - Example YAML: - secrets: - include: - - matchExpressions: - - key: badlabel - operator: DoesNotExist - matchLabels: - goodlabel: goodvalue - resourceNames: - - "{{ .name }}-secret" - - "{{ .kind }}-{{ .name }}-tls" - - "specificname" + description: "CozystackResourceDefinitionResourceSelector extends + metav1.LabelSelector with resourceNames support.\nA resource + matches this selector only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions and matchLabels)\n- + AND has a name that matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field supports Go templates + with the following variables available:\n- {{ .name }}: The + name of the managing application (from apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the managing application + (from apps.cozystack.io/application.kind)\n- {{ .namespace + }}: The namespace of the resource being processed\n\nExample + YAML:\n\n\tsecrets:\n\t include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: DoesNotExist\n\t matchLabels:\n\t + \ goodlabel: goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind }}-{{ .name }}-tls\"\n\t + \ - \"specificname\"" properties: matchExpressions: description: matchExpressions is a list of label selector @@ -513,29 +484,22 @@ spec: If a resource matches the selector in any of the elements in the array, it is hidden from the user, regardless of the matches in the include array. items: - description: |- - CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. - A resource matches this selector only if it satisfies ALL criteria: - - Label selector conditions (matchExpressions and matchLabels) - - AND has a name that matches one of the names in resourceNames (if specified) - - The resourceNames field supports Go templates with the following variables available: - - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) - - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) - - {{ .namespace }}: The namespace of the resource being processed - - Example YAML: - secrets: - include: - - matchExpressions: - - key: badlabel - operator: DoesNotExist - matchLabels: - goodlabel: goodvalue - resourceNames: - - "{{ .name }}-secret" - - "{{ .kind }}-{{ .name }}-tls" - - "specificname" + description: "CozystackResourceDefinitionResourceSelector extends + metav1.LabelSelector with resourceNames support.\nA resource + matches this selector only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions and matchLabels)\n- + AND has a name that matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field supports Go templates + with the following variables available:\n- {{ .name }}: The + name of the managing application (from apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the managing application + (from apps.cozystack.io/application.kind)\n- {{ .namespace + }}: The namespace of the resource being processed\n\nExample + YAML:\n\n\tsecrets:\n\t include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: DoesNotExist\n\t matchLabels:\n\t + \ goodlabel: goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind }}-{{ .name }}-tls\"\n\t + \ - \"specificname\"" properties: matchExpressions: description: matchExpressions is a list of label selector @@ -595,29 +559,22 @@ spec: matches none of the selectors in the exclude array that resource is marked as a tenant resource and is visible to users. items: - description: |- - CozystackResourceDefinitionResourceSelector extends metav1.LabelSelector with resourceNames support. - A resource matches this selector only if it satisfies ALL criteria: - - Label selector conditions (matchExpressions and matchLabels) - - AND has a name that matches one of the names in resourceNames (if specified) - - The resourceNames field supports Go templates with the following variables available: - - {{ .name }}: The name of the managing application (from apps.cozystack.io/application.name) - - {{ .kind }}: The lowercased kind of the managing application (from apps.cozystack.io/application.kind) - - {{ .namespace }}: The namespace of the resource being processed - - Example YAML: - secrets: - include: - - matchExpressions: - - key: badlabel - operator: DoesNotExist - matchLabels: - goodlabel: goodvalue - resourceNames: - - "{{ .name }}-secret" - - "{{ .kind }}-{{ .name }}-tls" - - "specificname" + description: "CozystackResourceDefinitionResourceSelector extends + metav1.LabelSelector with resourceNames support.\nA resource + matches this selector only if it satisfies ALL criteria:\n- + Label selector conditions (matchExpressions and matchLabels)\n- + AND has a name that matches one of the names in resourceNames + (if specified)\n\nThe resourceNames field supports Go templates + with the following variables available:\n- {{ .name }}: The + name of the managing application (from apps.cozystack.io/application.name)\n- + {{ .kind }}: The lowercased kind of the managing application + (from apps.cozystack.io/application.kind)\n- {{ .namespace + }}: The namespace of the resource being processed\n\nExample + YAML:\n\n\tsecrets:\n\t include:\n\t - matchExpressions:\n\t + \ - key: badlabel\n\t operator: DoesNotExist\n\t matchLabels:\n\t + \ goodlabel: goodvalue\n\t resourceNames:\n\t - + \"{{ .name }}-secret\"\n\t - \"{{ .kind }}-{{ .name }}-tls\"\n\t + \ - \"specificname\"" properties: matchExpressions: description: matchExpressions is a list of label selector From 025607531293034b79a532b039325b714d4c12dc Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Fri, 19 Dec 2025 01:56:24 +0100 Subject: [PATCH 06/15] add operator manifests --- packages/core/installer/Makefile | 20 ++++- .../templates/cozystack-operator.yaml | 76 +++++++++++++++++++ packages/core/installer/values.yaml | 4 + 3 files changed, 98 insertions(+), 2 deletions(-) create mode 100644 packages/core/installer/templates/cozystack-operator.yaml diff --git a/packages/core/installer/Makefile b/packages/core/installer/Makefile index a51e7b61..8039d698 100644 --- a/packages/core/installer/Makefile +++ b/packages/core/installer/Makefile @@ -20,9 +20,9 @@ diff: update: hack/gen-profiles.sh -image: pre-checks image-matchbox image-cozystack image-talos +image: pre-checks image-matchbox image-cozystack image-talos image-packages -image-cozystack: +image-cozystack: update-version docker buildx build -f images/cozystack/Dockerfile ../../.. \ --tag $(REGISTRY)/installer:$(call settag,$(TAG)) \ --cache-from type=registry,ref=$(REGISTRY)/installer:latest \ @@ -58,3 +58,19 @@ talos-initramfs talos-kernel talos-installer talos-iso talos-nocloud talos-metal cat images/talos/profiles/$(subst talos-,,$@).yaml | \ docker run --rm -i -v /dev:/dev --privileged "ghcr.io/siderolabs/imager:$(TALOS_VERSION)" --tar-to-stdout - | \ tar -C ../../../_out/assets -xzf- + +update-version: + TAG="$(call settag,$(TAG))" \ + yq -i '.cozystackOperator.cozystackVersion = strenv(TAG)' values.yaml + +image-packages: update-version + mkdir -p ../../../_out/assets images + flux push artifact \ + oci://$(REGISTRY)/platform-packages:$(call settag,$(TAG)) \ + --path=../../../packages \ + --source=https://github.com/cozystack/cozystack \ + --revision="$$(git describe --tags):$$(git rev-parse HEAD)" \ + 2>&1 | tee images/cozystack-packages.log + export REPO="oci://$(REGISTRY)/platform-packages"; \ + export DIGEST=$$(awk -F@ '/artifact successfully pushed/ {print $$2}' images/cozystack-packages.log; rm -f images/cozystack-packages.log); \ + test -n "$$DIGEST" && yq -i '.cozystackOperator.platformSource = (strenv(REPO) + "@" + strenv(DIGEST))' values.yaml diff --git a/packages/core/installer/templates/cozystack-operator.yaml b/packages/core/installer/templates/cozystack-operator.yaml new file mode 100644 index 00000000..3e8c6eee --- /dev/null +++ b/packages/core/installer/templates/cozystack-operator.yaml @@ -0,0 +1,76 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: cozy-system + labels: + cozystack.io/system: "true" + pod-security.kubernetes.io/enforce: privileged +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cozystack + namespace: cozy-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: cozystack +subjects: +- kind: ServiceAccount + name: cozystack + namespace: cozy-system +roleRef: + kind: ClusterRole + name: cluster-admin + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cozystack-operator + namespace: cozy-system +spec: + replicas: 1 + selector: + matchLabels: + app: cozystack-operator + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + template: + metadata: + labels: + app: cozystack-operator + spec: + serviceAccountName: cozystack + containers: + - name: cozystack-operator + image: "{{ .Values.cozystackOperator.image }}" + args: + - --leader-elect=true + - --install-flux=true + - --metrics-bind-address=0 + - --health-probe-bind-address= + - --cozystack-version={{ .Values.cozystackOperator.cozystackVersion }} + {{- if .Values.cozystackOperator.disableTelemetry }} + - --disable-telemetry + {{- end }} + - --platform-name="cozystack-platform" + - --platform-source="{{ .Values.cozystackOperator.platformSource }}" + env: + - name: KUBERNETES_SERVICE_HOST + value: localhost + - name: KUBERNETES_SERVICE_PORT + value: "7445" + hostNetwork: true + tolerations: + - key: "node.kubernetes.io/not-ready" + operator: "Exists" + effect: "NoSchedule" + - key: "node.cilium.io/agent-not-ready" + operator: "Exists" + effect: "NoSchedule" diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index dbb7b846..a5ec3df7 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,2 +1,6 @@ cozystack: image: ghcr.io/cozystack/cozystack/installer:v0.38.2@sha256:9ff92b655de6f9bea3cba4cd42dcffabd9aace6966dcfb1cc02dda2420ea4a15 +cozystackOperator: + image: ghcr.io/cozystack/cozystack/cozystack-operator:latest@sha256:446b4afe9ed160a850cc9b61dd6f34b2ae36d69d4cd974d6d35a25180bd73879 + platformSource: 'oci://ghcr.io/cozystack/cozystack/platform-packages@sha256:3edff5f9feb4bd66e4b46df9e07e5db3eb6ead051edac74cbda3b222eb940a70' + cozystackVersion: latest From 71a6dde579ad19d393a0c0408245c079d4d6ca5f Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Fri, 19 Dec 2025 02:20:07 +0100 Subject: [PATCH 07/15] Update go modules Signed-off-by: Andrei Kvapil --- go.mod | 145 ++++++++------- go.sum | 345 ++++++++++++++++++----------------- pkg/cmd/server/start.go | 65 +------ pkg/cmd/server/start_test.go | 52 +----- 4 files changed, 260 insertions(+), 347 deletions(-) diff --git a/go.mod b/go.mod index 6ae20909..ca558579 100644 --- a/go.mod +++ b/go.mod @@ -2,38 +2,39 @@ module github.com/cozystack/cozystack -go 1.23.0 +go 1.25.0 require ( - github.com/fluxcd/helm-controller/api v1.1.0 - github.com/go-logr/logr v1.4.2 + github.com/fluxcd/helm-controller/api v1.4.3 + github.com/fluxcd/source-controller/api v1.6.2 + github.com/fluxcd/source-watcher/api/v2 v2.0.2 + github.com/go-logr/logr v1.4.3 github.com/go-logr/zapr v1.3.0 github.com/google/gofuzz v1.2.0 - github.com/onsi/ginkgo/v2 v2.19.0 - github.com/onsi/gomega v1.33.1 - github.com/prometheus/client_golang v1.19.1 + github.com/onsi/ginkgo/v2 v2.23.3 + github.com/onsi/gomega v1.37.0 + github.com/prometheus/client_golang v1.22.0 github.com/robfig/cron/v3 v3.0.1 - github.com/spf13/cobra v1.8.1 - github.com/stretchr/testify v1.9.0 + github.com/spf13/cobra v1.9.1 go.uber.org/zap v1.27.0 gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.31.2 - k8s.io/apiextensions-apiserver v0.31.2 - k8s.io/apimachinery v0.31.2 - k8s.io/apiserver v0.31.2 - k8s.io/client-go v0.31.2 - k8s.io/component-base v0.31.2 + k8s.io/api v0.34.1 + k8s.io/apiextensions-apiserver v0.34.1 + k8s.io/apimachinery v0.34.1 + k8s.io/apiserver v0.34.1 + k8s.io/client-go v0.34.1 + k8s.io/component-base v0.34.1 k8s.io/klog/v2 v2.130.1 - k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 - k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 - sigs.k8s.io/controller-runtime v0.19.0 - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 + k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b + k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d + sigs.k8s.io/controller-runtime v0.22.2 + sigs.k8s.io/structured-merge-diff/v4 v4.7.0 ) require ( + cel.dev/expr v0.24.0 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/antlr4-go/antlr/v4 v4.13.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect @@ -41,85 +42,91 @@ require ( github.com/coreos/go-semver v0.3.1 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/evanphx/json-patch v4.12.0+incompatible // indirect - github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.11 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect - github.com/fluxcd/pkg/apis/kustomize v1.6.1 // indirect - github.com/fluxcd/pkg/apis/meta v1.6.1 // indirect - github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/fluxcd/pkg/apis/acl v0.9.0 // indirect + github.com/fluxcd/pkg/apis/kustomize v1.13.0 // indirect + github.com/fluxcd/pkg/apis/meta v1.22.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/google/cel-go v0.21.0 // indirect - github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect - github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/google/btree v1.1.3 // indirect + github.com/google/cel-go v0.26.0 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.0 // indirect + github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect - github.com/imdario/mergo v0.3.6 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/moby/spdystream v0.4.0 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/moby/spdystream v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/pflag v1.0.7 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/x448/float16 v0.8.4 // indirect - go.etcd.io/etcd/api/v3 v3.5.16 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect - go.etcd.io/etcd/client/v3 v3.5.16 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect - go.opentelemetry.io/otel/sdk v1.28.0 // indirect - go.opentelemetry.io/otel/trace v1.28.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.etcd.io/etcd/api/v3 v3.6.4 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.6.4 // indirect + go.etcd.io/etcd/client/v3 v3.6.4 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect + go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.31.0 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.42.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect - golang.org/x/net v0.33.0 // indirect - golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/term v0.27.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.7.0 // indirect - golang.org/x/tools v0.26.0 // indirect + golang.org/x/net v0.45.0 // indirect + golang.org/x/oauth2 v0.29.0 // indirect + golang.org/x/sync v0.17.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/term v0.35.0 // indirect + golang.org/x/text v0.29.0 // indirect + golang.org/x/time v0.11.0 // indirect + golang.org/x/tools v0.37.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/grpc v1.65.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/grpc v1.72.1 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/kms v0.31.2 // indirect - sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect - sigs.k8s.io/yaml v1.4.0 // indirect + k8s.io/kms v0.34.1 // indirect + sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect ) // See: issues.k8s.io/135537 -replace k8s.io/apimachinery => github.com/cozystack/apimachinery v0.0.0-20251201201312-18e522a87614 +replace k8s.io/apimachinery => github.com/cozystack/apimachinery v0.0.0-20251219010959-1f91eabae46c diff --git a/go.sum b/go.sum index 88c81e7b..9eec9d5c 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI= github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= @@ -18,47 +18,50 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cozystack/apimachinery v0.0.0-20251201201312-18e522a87614 h1:jH9elECUvhiIs3IMv3oS5k1JgCLVsSK6oU4dmq5gyW8= -github.com/cozystack/apimachinery v0.0.0-20251201201312-18e522a87614/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cozystack/apimachinery v0.0.0-20251219010959-1f91eabae46c h1:C2wIfH/OzhU9XOK/e6Ik9cg7nZ1z6fN4lf6a3yFdik8= +github.com/cozystack/apimachinery v0.0.0-20251219010959-1f91eabae46c/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= -github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU= +github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fluxcd/helm-controller/api v1.1.0 h1:NS5Wm3U6Kv4w7Cw2sDOV++vf2ecGfFV00x1+2Y3QcOY= -github.com/fluxcd/helm-controller/api v1.1.0/go.mod h1:BgHMgMY6CWynzl4KIbHpd6Wpn3FN9BqgkwmvoKCp6iE= -github.com/fluxcd/pkg/apis/kustomize v1.6.1 h1:22FJc69Mq4i8aCxnKPlddHhSMyI4UPkQkqiAdWFcqe0= -github.com/fluxcd/pkg/apis/kustomize v1.6.1/go.mod h1:5dvQ4IZwz0hMGmuj8tTWGtarsuxW0rWsxJOwC6i+0V8= -github.com/fluxcd/pkg/apis/meta v1.6.1 h1:maLhcRJ3P/70ArLCY/LF/YovkxXbX+6sTWZwZQBeNq0= -github.com/fluxcd/pkg/apis/meta v1.6.1/go.mod h1:YndB/gxgGZmKfqpAfFxyCDNFJFP0ikpeJzs66jwq280= -github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= -github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fluxcd/helm-controller/api v1.4.3 h1:CdZwjL1liXmYCWyk2jscmFEB59tICIlnWB9PfDDW5q4= +github.com/fluxcd/helm-controller/api v1.4.3/go.mod h1:0XrBhKEaqvxyDj/FziG1Q8Fmx2UATdaqLgYqmZh6wW4= +github.com/fluxcd/pkg/apis/acl v0.9.0 h1:wBpgsKT+jcyZEcM//OmZr9RiF8klL3ebrDp2u2ThsnA= +github.com/fluxcd/pkg/apis/acl v0.9.0/go.mod h1:TttNS+gocsGLwnvmgVi3/Yscwqrjc17+vhgYfqkfrV4= +github.com/fluxcd/pkg/apis/kustomize v1.13.0 h1:GGf0UBVRIku+gebY944icVeEIhyg1P/KE3IrhOyJJnE= +github.com/fluxcd/pkg/apis/kustomize v1.13.0/go.mod h1:TLKVqbtnzkhDuhWnAsN35977HvRfIjs+lgMuNro/LEc= +github.com/fluxcd/pkg/apis/meta v1.22.0 h1:EHWQH5ZWml7i8eZ/AMjm1jxid3j/PQ31p+hIwCt6crM= +github.com/fluxcd/pkg/apis/meta v1.22.0/go.mod h1:Kc1+bWe5p0doROzuV9XiTfV/oL3ddsemYXt8ZYWdVVg= +github.com/fluxcd/source-controller/api v1.6.2 h1:UmodAeqLIeF29HdTqf2GiacZyO+hJydJlepDaYsMvhc= +github.com/fluxcd/source-controller/api v1.6.2/go.mod h1:ZJcAi0nemsnBxjVgmJl0WQzNvB0rMETxQMTdoFosmMw= +github.com/fluxcd/source-watcher/api/v2 v2.0.2 h1:fWSxsDqYN7My2AEpQwbP7O6Qjix8nGBX+UE/qWHtZfM= +github.com/fluxcd/source-watcher/api/v2 v2.0.2/go.mod h1:Hs6ueayPt23jlkIr/d1pGPZ+OHiibQwWjxvU6xqljzg= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= @@ -66,164 +69,171 @@ github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/cel-go v0.21.0 h1:cl6uW/gxN+Hy50tNYvI691+sXxioCnstFzLp2WO4GCI= -github.com/google/cel-go v0.21.0/go.mod h1:rHUlWCcBKgyEk+eV03RPdZUekPp6YcJwV0FxuUksYxc= -github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= -github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= +github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= +github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= -github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= -github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 h1:+9834+KizmvFV7pXQGSXQTsaWhq2GjuNUt0aUU0YBYw= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= -github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= -github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= +github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/moby/spdystream v0.4.0 h1:Vy79D6mHeJJjiPdFEL2yku1kl0chZpJfZcPpb16BRl8= -github.com/moby/spdystream v0.4.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= -github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= -github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= -github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0= +github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM= +github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y= +github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q= +github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M= +github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.3.0 h1:g0eASXYtp+yvN9fK8sH94oCIk0fau9uV1/ZdJ0AVEzs= github.com/stoewer/go-strcase v1.3.0/go.mod h1:fAH5hQ5pehh+j3nZfvwdk2RgEgQjAoM8wodgtPmh1xo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= -github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75 h1:6fotK7otjonDflCTK0BCfls4SPy3NcCVb5dqqmbRknE= github.com/tmc/grpc-websocket-proxy v0.0.0-20220101234140-673ab2c3ae75/go.mod h1:KO6IkyS8Y3j8OdNO85qEYBsRPuteD+YciPomcXdrMnk= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510 h1:S2dVYn90KE98chqDkyE9Z4N61UnQd+KOfgp5Iu53llk= +github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI= -go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE= -go.etcd.io/etcd/api/v3 v3.5.16 h1:WvmyJVbjWqK4R1E+B12RRHz3bRGy9XVfh++MgbN+6n0= -go.etcd.io/etcd/api/v3 v3.5.16/go.mod h1:1P4SlIP/VwkDmGo3OlOD7faPeP8KDIFhqvciH5EfN28= -go.etcd.io/etcd/client/pkg/v3 v3.5.16 h1:ZgY48uH6UvB+/7R9Yf4x574uCO3jIx0TRDyetSfId3Q= -go.etcd.io/etcd/client/pkg/v3 v3.5.16/go.mod h1:V8acl8pcEK0Y2g19YlOV9m9ssUe6MgiDSobSoaBAM0E= -go.etcd.io/etcd/client/v2 v2.305.13 h1:RWfV1SX5jTU0lbCvpVQe3iPQeAHETWdOTb6pxhd77C8= -go.etcd.io/etcd/client/v2 v2.305.13/go.mod h1:iQnL7fepbiomdXMb3om1rHq96htNNGv2sJkEcZGDRRg= -go.etcd.io/etcd/client/v3 v3.5.16 h1:sSmVYOAHeC9doqi0gv7v86oY/BTld0SEFGaxsU9eRhE= -go.etcd.io/etcd/client/v3 v3.5.16/go.mod h1:X+rExSGkyqxvu276cr2OwPLBaeqFu1cIl4vmRjAD/50= -go.etcd.io/etcd/pkg/v3 v3.5.13 h1:st9bDWNsKkBNpP4PR1MvM/9NqUPfvYZx/YXegsYEH8M= -go.etcd.io/etcd/pkg/v3 v3.5.13/go.mod h1:N+4PLrp7agI/Viy+dUYpX7iRtSPvKq+w8Y14d1vX+m0= -go.etcd.io/etcd/raft/v3 v3.5.13 h1:7r/NKAOups1YnKcfro2RvGGo2PTuizF/xh26Z2CTAzA= -go.etcd.io/etcd/raft/v3 v3.5.13/go.mod h1:uUFibGLn2Ksm2URMxN1fICGhk8Wu96EfDQyuLhAcAmw= -go.etcd.io/etcd/server/v3 v3.5.13 h1:V6KG+yMfMSqWt+lGnhFpP5z5dRUj1BDRJ5k1fQ9DFok= -go.etcd.io/etcd/server/v3 v3.5.13/go.mod h1:K/8nbsGupHqmr5MkgaZpLlH1QdX1pcNQLAkODy44XcQ= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 h1:9G6E0TXzGFVfTnawRzrPl83iHOAV7L8NJiR8RSGYV1g= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= -go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= -go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0 h1:qFffATk0X+HD+f1Z8lswGiOQYKHRlzfmdJm0wEaVrFA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.27.0/go.mod h1:MOiCmryaYtc+V0Ei+Tx9o5S1ZjA7kzLucuVuyzBZloQ= -go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= -go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= -go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= -go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= -go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.etcd.io/bbolt v1.4.2 h1:IrUHp260R8c+zYx/Tm8QZr04CX+qWS5PGfPdevhdm1I= +go.etcd.io/bbolt v1.4.2/go.mod h1:Is8rSHO/b4f3XigBC0lL0+4FwAQv3HXEEIgFMuKHceM= +go.etcd.io/etcd/api/v3 v3.6.4 h1:7F6N7toCKcV72QmoUKa23yYLiiljMrT4xCeBL9BmXdo= +go.etcd.io/etcd/api/v3 v3.6.4/go.mod h1:eFhhvfR8Px1P6SEuLT600v+vrhdDTdcfMzmnxVXXSbk= +go.etcd.io/etcd/client/pkg/v3 v3.6.4 h1:9HBYrjppeOfFjBjaMTRxT3R7xT0GLK8EJMVC4xg6ok0= +go.etcd.io/etcd/client/pkg/v3 v3.6.4/go.mod h1:sbdzr2cl3HzVmxNw//PH7aLGVtY4QySjQFuaCgcRFAI= +go.etcd.io/etcd/client/v3 v3.6.4 h1:YOMrCfMhRzY8NgtzUsHl8hC2EBSnuqbR3dh84Uryl7A= +go.etcd.io/etcd/client/v3 v3.6.4/go.mod h1:jaNNHCyg2FdALyKWnd7hxZXZxZANb0+KGY+YQaEMISo= +go.etcd.io/etcd/pkg/v3 v3.6.4 h1:fy8bmXIec1Q35/jRZ0KOes8vuFxbvdN0aAFqmEfJZWA= +go.etcd.io/etcd/pkg/v3 v3.6.4/go.mod h1:kKcYWP8gHuBRcteyv6MXWSN0+bVMnfgqiHueIZnKMtE= +go.etcd.io/etcd/server/v3 v3.6.4 h1:LsCA7CzjVt+8WGrdsnh6RhC0XqCsLkBly3ve5rTxMAU= +go.etcd.io/etcd/server/v3 v3.6.4/go.mod h1:aYCL/h43yiONOv0QIR82kH/2xZ7m+IWYjzRmyQfnCAg= +go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ= +go.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 h1:x7wzEgXfnzJcHDwStJT+mxOz4etr2EcexjqhBvmoakw= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0/go.mod h1:rg+RlpR5dKwaS95IyyZqj5Wd4E13lk/msnTS0Xl9lJM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= +go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= +go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI= +golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -232,50 +242,48 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= -golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.45.0 h1:RLBg5JKixCy82FtLJpeNlVM0nrSqpCRYzVU1n8kj0tM= +golang.org/x/net v0.45.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY= +golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= +golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= +golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= -golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ= +golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.7.0 h1:ntUhktv3OPE6TgYxXWv9vKvUSJyIFJlyohwbkEwPrKQ= -golang.org/x/time v0.7.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk= +golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY= -google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA= +google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -285,37 +293,42 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.31.2 h1:3wLBbL5Uom/8Zy98GRPXpJ254nEFpl+hwndmk9RwmL0= -k8s.io/api v0.31.2/go.mod h1:bWmGvrGPssSK1ljmLzd3pwCQ9MgoTsRCuK35u6SygUk= -k8s.io/apiextensions-apiserver v0.31.2 h1:W8EwUb8+WXBLu56ser5IudT2cOho0gAKeTOnywBLxd0= -k8s.io/apiextensions-apiserver v0.31.2/go.mod h1:i+Geh+nGCJEGiCGR3MlBDkS7koHIIKWVfWeRFiOsUcM= -k8s.io/apiserver v0.31.2 h1:VUzOEUGRCDi6kX1OyQ801m4A7AUPglpsmGvdsekmcI4= -k8s.io/apiserver v0.31.2/go.mod h1:o3nKZR7lPlJqkU5I3Ove+Zx3JuoFjQobGX1Gctw6XuE= -k8s.io/client-go v0.31.2 h1:Y2F4dxU5d3AQj+ybwSMqQnpZH9F30//1ObxOKlTI9yc= -k8s.io/client-go v0.31.2/go.mod h1:NPa74jSVR/+eez2dFsEIHNa+3o09vtNaWwWwb1qSxSs= -k8s.io/component-base v0.31.2 h1:Z1J1LIaC0AV+nzcPRFqfK09af6bZ4D1nAOpWsy9owlA= -k8s.io/component-base v0.31.2/go.mod h1:9PeyyFN/drHjtJZMCTkSpQJS3U9OXORnHQqMLDz0sUQ= +k8s.io/api v0.34.1 h1:jC+153630BMdlFukegoEL8E/yT7aLyQkIVuwhmwDgJM= +k8s.io/api v0.34.1/go.mod h1:SB80FxFtXn5/gwzCoN6QCtPD7Vbu5w2n1S0J5gFfTYk= +k8s.io/apiextensions-apiserver v0.34.1 h1:NNPBva8FNAPt1iSVwIE0FsdrVriRXMsaWFMqJbII2CI= +k8s.io/apiextensions-apiserver v0.34.1/go.mod h1:hP9Rld3zF5Ay2Of3BeEpLAToP+l4s5UlxiHfqRaRcMc= +k8s.io/apiserver v0.34.1 h1:U3JBGdgANK3dfFcyknWde1G6X1F4bg7PXuvlqt8lITA= +k8s.io/apiserver v0.34.1/go.mod h1:eOOc9nrVqlBI1AFCvVzsob0OxtPZUCPiUJL45JOTBG0= +k8s.io/client-go v0.34.1 h1:ZUPJKgXsnKwVwmKKdPfw4tB58+7/Ik3CrjOEhsiZ7mY= +k8s.io/client-go v0.34.1/go.mod h1:kA8v0FP+tk6sZA0yKLRG67LWjqufAoSHA2xVGKw9Of8= +k8s.io/component-base v0.34.1 h1:v7xFgG+ONhytZNFpIz5/kecwD+sUhVE6HU7qQUiRM4A= +k8s.io/component-base v0.34.1/go.mod h1:mknCpLlTSKHzAQJJnnHVKqjxR7gBeHRv0rPXA7gdtQ0= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kms v0.31.2 h1:pyx7l2qVOkClzFMIWMVF/FxsSkgd+OIGH7DecpbscJI= -k8s.io/kms v0.31.2/go.mod h1:OZKwl1fan3n3N5FFxnW5C4V3ygrah/3YXeJWS3O6+94= -k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2 h1:GKE9U8BH16uynoxQii0auTjmmmuZ3O0LFMN6S0lPPhI= -k8s.io/kube-openapi v0.0.0-20240827152857-f7e401e7b4c2/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A= -k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 h1:CPT0ExVicCzcpeN4baWEV2ko2Z/AsiZgEdwgcfwLgMo= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= -sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q= -sigs.k8s.io/controller-runtime v0.19.0/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= -sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +k8s.io/kms v0.34.1 h1:iCFOvewDPzWM9fMTfyIPO+4MeuZ0tcZbugxLNSHFG4w= +k8s.io/kms v0.34.1/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= +k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d h1:wAhiDyZ4Tdtt7e46e9M5ZSAJ/MnPGPs+Ki1gHw4w1R0= +k8s.io/utils v0.0.0-20250820121507-0af2bda4dd1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 h1:jpcvIRr3GLoUoEKRkHKSmGjxb6lWwrBlJsXc+eUYQHM= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw= +sigs.k8s.io/controller-runtime v0.22.2 h1:cK2l8BGWsSWkXz09tcS4rJh95iOLney5eawcK5A33r4= +sigs.k8s.io/controller-runtime v0.22.2/go.mod h1:+QX1XUpTXN4mLoblf4tqr5CQcyHPAki2HLXqQMY6vh8= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.7.0 h1:qPeWmscJcXP0snki5IYF79Z8xrl8ETFxgMd7wez1XkI= +sigs.k8s.io/structured-merge-diff/v4 v4.7.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/pkg/cmd/server/start.go b/pkg/cmd/server/start.go index 3427e61d..d9566498 100644 --- a/pkg/cmd/server/start.go +++ b/pkg/cmd/server/start.go @@ -35,15 +35,9 @@ import ( "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/runtime" utilerrors "k8s.io/apimachinery/pkg/util/errors" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apimachinery/pkg/util/version" "k8s.io/apiserver/pkg/endpoints/openapi" genericapiserver "k8s.io/apiserver/pkg/server" genericoptions "k8s.io/apiserver/pkg/server/options" - utilfeature "k8s.io/apiserver/pkg/util/feature" - utilversionpkg "k8s.io/apiserver/pkg/util/version" - "k8s.io/component-base/featuregate" - baseversion "k8s.io/component-base/version" netutils "k8s.io/utils/net" "sigs.k8s.io/controller-runtime/pkg/client" k8sconfig "sigs.k8s.io/controller-runtime/pkg/client/config" @@ -87,7 +81,7 @@ func NewCommandStartCozyServer(ctx context.Context, defaults *CozyServerOptions) Short: "Launch an Cozystack API server", Long: "Launch an Cozystack API server", PersistentPreRunE: func(*cobra.Command, []string) error { - return utilversionpkg.DefaultComponentGlobalsRegistry.Set() + return nil }, RunE: func(c *cobra.Command, args []string) error { if err := o.Complete(); err != nil { @@ -107,38 +101,8 @@ func NewCommandStartCozyServer(ctx context.Context, defaults *CozyServerOptions) flags := cmd.Flags() o.RecommendedOptions.AddFlags(flags) - // The following lines demonstrate how to configure version compatibility and feature gates - // for the "Cozy" component according to KEP-4330. - - // Create a default version object for the "Cozy" component. - defaultCozyVersion := "1.1" - // Register the "Cozy" component in the global component registry, - // associating it with its effective version and feature gate configuration. - _, appsFeatureGate := utilversionpkg.DefaultComponentGlobalsRegistry.ComponentGlobalsOrRegister( - apiserver.CozyComponentName, utilversionpkg.NewEffectiveVersion(defaultCozyVersion), - featuregate.NewVersionedFeatureGate(version.MustParse(defaultCozyVersion)), - ) - - // Add feature gate specifications for the "Cozy" component. - utilruntime.Must(appsFeatureGate.AddVersioned(map[featuregate.Feature]featuregate.VersionedSpecs{ - // Example of adding feature gates: - // "FeatureName": {{"v1", true}, {"v2", false}}, - })) - - // Register the standard kube component if it is not already registered in the global registry. - _, _ = utilversionpkg.DefaultComponentGlobalsRegistry.ComponentGlobalsOrRegister( - utilversionpkg.DefaultKubeComponent, - utilversionpkg.NewEffectiveVersion(baseversion.DefaultKubeBinaryVersion), - utilfeature.DefaultMutableFeatureGate, - ) - - // Set the version emulation mapping from the "Cozy" component to the kube component. - utilruntime.Must(utilversionpkg.DefaultComponentGlobalsRegistry.SetEmulationVersionMapping( - apiserver.CozyComponentName, utilversionpkg.DefaultKubeComponent, CozyVersionToKubeVersion, - )) - - // Add flags from the global component registry. - utilversionpkg.DefaultComponentGlobalsRegistry.AddFlags(flags) + // Note: KEP-4330 component versioning functionality (k8s.io/apiserver/pkg/util/version) + // is not available in Kubernetes v0.34.1. The component versioning code has been removed. return cmd } @@ -225,7 +189,6 @@ func (o *CozyServerOptions) Complete() error { func (o CozyServerOptions) Validate(args []string) error { var allErrors []error allErrors = append(allErrors, o.RecommendedOptions.Validate()...) - allErrors = append(allErrors, utilversionpkg.DefaultComponentGlobalsRegistry.Validate()...) return utilerrors.NewAggregate(allErrors) } @@ -281,13 +244,6 @@ func (o *CozyServerOptions) Config() (*apiserver.Config, error) { serverConfig.OpenAPIV3Config.PostProcessSpec = buildPostProcessV3(kindSchemas) - serverConfig.FeatureGate = utilversionpkg.DefaultComponentGlobalsRegistry.FeatureGateFor( - utilversionpkg.DefaultKubeComponent, - ) - serverConfig.EffectiveVersion = utilversionpkg.DefaultComponentGlobalsRegistry.EffectiveVersionFor( - apiserver.CozyComponentName, - ) - if err := o.RecommendedOptions.ApplyTo(serverConfig); err != nil { return nil, err } @@ -318,18 +274,3 @@ func (o CozyServerOptions) RunCozyServer(ctx context.Context) error { return server.GenericAPIServer.PrepareRun().RunWithContext(ctx) } - -// CozyVersionToKubeVersion defines the version mapping between the Cozy component and kube -func CozyVersionToKubeVersion(ver *version.Version) *version.Version { - if ver.Major() != 1 { - return nil - } - kubeVer := utilversionpkg.DefaultKubeEffectiveVersion().BinaryVersion() - // "1.2" corresponds to kubeVer - offset := int(ver.Minor()) - 2 - mappedVer := kubeVer.OffsetMinor(offset) - if mappedVer.GreaterThan(kubeVer) { - return kubeVer - } - return mappedVer -} diff --git a/pkg/cmd/server/start_test.go b/pkg/cmd/server/start_test.go index da96ed31..df7c3547 100644 --- a/pkg/cmd/server/start_test.go +++ b/pkg/cmd/server/start_test.go @@ -16,53 +16,5 @@ limitations under the License. package server -import ( - "testing" - - "k8s.io/apimachinery/pkg/util/version" - utilversion "k8s.io/apiserver/pkg/util/version" - - "github.com/stretchr/testify/assert" -) - -func TestCozyEmulationVersionToKubeEmulationVersion(t *testing.T) { - defaultKubeEffectiveVersion := utilversion.DefaultKubeEffectiveVersion() - - testCases := []struct { - desc string - appsEmulationVer *version.Version - expectedKubeEmulationVer *version.Version - }{ - { - desc: "same version as than kube binary", - appsEmulationVer: version.MajorMinor(1, 2), - expectedKubeEmulationVer: defaultKubeEffectiveVersion.BinaryVersion(), - }, - { - desc: "1 version lower than kube binary", - appsEmulationVer: version.MajorMinor(1, 1), - expectedKubeEmulationVer: defaultKubeEffectiveVersion.BinaryVersion().OffsetMinor(-1), - }, - { - desc: "2 versions lower than kube binary", - appsEmulationVer: version.MajorMinor(1, 0), - expectedKubeEmulationVer: defaultKubeEffectiveVersion.BinaryVersion().OffsetMinor(-2), - }, - { - desc: "capped at kube binary", - appsEmulationVer: version.MajorMinor(1, 3), - expectedKubeEmulationVer: defaultKubeEffectiveVersion.BinaryVersion(), - }, - { - desc: "no mapping", - appsEmulationVer: version.MajorMinor(2, 10), - }, - } - - for _, tc := range testCases { - t.Run(tc.desc, func(t *testing.T) { - mappedKubeEmulationVer := CozyVersionToKubeVersion(tc.appsEmulationVer) - assert.True(t, mappedKubeEmulationVer.EqualTo(tc.expectedKubeEmulationVer)) - }) - } -} +// Note: Tests for KEP-4330 component versioning functionality have been removed +// as the functionality is not available in Kubernetes v0.34.1. From 38995ae1ab2ce126d2386dea3e0aa596ab18d95d Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Fri, 19 Dec 2025 03:07:30 +0100 Subject: [PATCH 08/15] Introduce cozystack-operator Signed-off-by: Andrei Kvapil --- cmd/cozystack-operator/main.go | 462 ++++++++++++++++++ internal/fluxinstall/install.go | 352 +++++++++++++ internal/fluxinstall/manifests.embed.go | 51 ++ .../fluxinstall/manifests}/fluxcd.yaml | 6 - packages/core/flux-aio/Makefile | 12 +- packages/core/flux-aio/manifests | 1 + packages/core/flux-aio/templates/_helpers.tpl | 13 - packages/core/installer/1.yaml | 1 + packages/core/installer/Makefile | 25 +- .../images/cozystack-operator/Dockerfile | 23 + .../Dockerfile.dockerignore | 12 + .../installer/images/cozystack/Dockerfile | 41 -- .../images/cozystack/Dockerfile.dockerignore | 1 - .../templates/cozystack-operator.yaml | 23 +- .../core/installer/templates/cozystack.yaml | 79 --- packages/core/installer/values.yaml | 2 +- 16 files changed, 943 insertions(+), 161 deletions(-) create mode 100644 cmd/cozystack-operator/main.go create mode 100644 internal/fluxinstall/install.go create mode 100644 internal/fluxinstall/manifests.embed.go rename {packages/core/flux-aio/templates => internal/fluxinstall/manifests}/fluxcd.yaml (99%) create mode 120000 packages/core/flux-aio/manifests delete mode 100644 packages/core/flux-aio/templates/_helpers.tpl create mode 100644 packages/core/installer/1.yaml create mode 100644 packages/core/installer/images/cozystack-operator/Dockerfile create mode 100644 packages/core/installer/images/cozystack-operator/Dockerfile.dockerignore delete mode 100644 packages/core/installer/images/cozystack/Dockerfile delete mode 100644 packages/core/installer/images/cozystack/Dockerfile.dockerignore delete mode 100644 packages/core/installer/templates/cozystack.yaml diff --git a/cmd/cozystack-operator/main.go b/cmd/cozystack-operator/main.go new file mode 100644 index 00000000..9ffba5d6 --- /dev/null +++ b/cmd/cozystack-operator/main.go @@ -0,0 +1,462 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 main + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "net/url" + "os" + "strings" + "time" + + // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) + // to ensure that exec-entrypoint and run can make use of them. + _ "k8s.io/client-go/plugin/pkg/client/auth" + + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + sourcev1 "github.com/fluxcd/source-controller/api/v1" + sourcewatcherv1beta1 "github.com/fluxcd/source-watcher/api/v2/v1beta1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/healthz" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" + "sigs.k8s.io/controller-runtime/pkg/webhook" + + "github.com/cozystack/cozystack/internal/fluxinstall" + // +kubebuilder:scaffold:imports +) + +var ( + scheme = runtime.NewScheme() + setupLog = ctrl.Log.WithName("setup") +) + +// stringSliceFlag is a custom flag type that allows multiple values +type stringSliceFlag []string + +func (f *stringSliceFlag) String() string { + return strings.Join(*f, ",") +} + +func (f *stringSliceFlag) Set(value string) error { + *f = append(*f, value) + return nil +} + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(apiextensionsv1.AddToScheme(scheme)) + utilruntime.Must(cozyv1alpha1.AddToScheme(scheme)) + utilruntime.Must(helmv2.AddToScheme(scheme)) + utilruntime.Must(sourcev1.AddToScheme(scheme)) + utilruntime.Must(sourcewatcherv1beta1.AddToScheme(scheme)) + // +kubebuilder:scaffold:scheme +} + +func main() { + var metricsAddr string + var enableLeaderElection bool + var probeAddr string + var secureMetrics bool + var enableHTTP2 bool + var installFlux bool + var cozystackVersion string + var installFluxResources stringSliceFlag + var platformSource string + var platformName string + + flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") + flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") + flag.BoolVar(&enableLeaderElection, "leader-elect", false, + "Enable leader election for controller manager. "+ + "Enabling this will ensure there is only one active controller manager.") + flag.BoolVar(&secureMetrics, "metrics-secure", false, + "If set the metrics endpoint is served securely") + flag.BoolVar(&enableHTTP2, "enable-http2", false, + "If set, HTTP/2 will be enabled for the metrics and webhook servers") + flag.BoolVar(&installFlux, "install-flux", false, "Install Flux components before starting reconcile loop") + flag.Var(&installFluxResources, "install-flux-resource", "Install Flux resource (JSON format). Can be specified multiple times. Applied after Flux installation.") + flag.StringVar(&cozystackVersion, "cozystack-version", "unknown", + "Version of Cozystack") + flag.StringVar(&platformSource, "platform-source", "", "Platform source URL (oci:// or git://). If specified, generates OCIRepository or GitRepository resource.") + flag.StringVar(&platformName, "platform-name", "cozystack-packages", "Name for the generated platform source resource (default: cozystack-packages)") + + opts := zap.Options{ + Development: true, + } + opts.BindFlags(flag.CommandLine) + flag.Parse() + + ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) + + config := ctrl.GetConfigOrDie() + + // Start the controller manager + setupLog.Info("Starting controller manager") + mgr, err := ctrl.NewManager(config, ctrl.Options{ + Scheme: scheme, + Metrics: metricsserver.Options{ + BindAddress: metricsAddr, + SecureServing: secureMetrics, + }, + WebhookServer: webhook.NewServer(webhook.Options{ + Port: 9443, + }), + HealthProbeBindAddress: probeAddr, + LeaderElection: enableLeaderElection, + LeaderElectionID: "cozystack-operator.cozystack.io", + // LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily + // when the Manager ends. This requires the binary to immediately end when the + // Manager is stopped, otherwise, setting this significantly speeds up voluntary + // leader transitions as the new leader don't have to wait LeaseDuration time first. + // + // In the default scaffold provided, the program ends immediately after + // the manager stops, so would be fine to enable this option. However, + // if you are doing or is intended to do any operation such as perform cleanups + // after the manager stops then its usage might be unsafe. + // LeaderElectionReleaseOnCancel: true, + }) + if err != nil { + setupLog.Error(err, "unable to start manager") + os.Exit(1) + } + + // Install Flux before starting reconcile loop + if installFlux { + setupLog.Info("Installing Flux components before starting reconcile loop") + installCtx, installCancel := context.WithTimeout(context.Background(), 5*time.Minute) + defer installCancel() + + // The namespace will be automatically extracted from the embedded manifests + if err := fluxinstall.Install(installCtx, mgr.GetClient(), fluxinstall.WriteEmbeddedManifests); err != nil { + setupLog.Error(err, "failed to install Flux, continuing anyway") + // Don't exit - allow operator to start even if Flux install fails + // This allows the operator to work in environments where Flux is already installed + } else { + setupLog.Info("Flux installation completed successfully") + } + } + + // Install Flux resources after Flux installation + if len(installFluxResources) > 0 { + setupLog.Info("Installing Flux resources", "count", len(installFluxResources)) + installCtx, installCancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer installCancel() + + if err := installFluxResourcesFunc(installCtx, mgr.GetClient(), installFluxResources); err != nil { + setupLog.Error(err, "failed to install Flux resources, continuing anyway") + // Don't exit - allow operator to start even if resource installation fails + } else { + setupLog.Info("Flux resources installation completed successfully") + } + } + + // Generate and install platform source resource if specified + if platformSource != "" { + setupLog.Info("Generating platform source resource", "source", platformSource, "name", platformName) + installCtx, installCancel := context.WithTimeout(context.Background(), 2*time.Minute) + defer installCancel() + + if err := installPlatformSourceResource(installCtx, mgr.GetClient(), platformSource, platformName); err != nil { + setupLog.Error(err, "failed to install platform source resource") + os.Exit(1) + } else { + setupLog.Info("Platform source resource installation completed successfully") + } + } + + // +kubebuilder:scaffold:builder + + if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up health check") + os.Exit(1) + } + if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil { + setupLog.Error(err, "unable to set up ready check") + os.Exit(1) + } + + setupLog.Info("Starting controller manager") + mgrCtx := ctrl.SetupSignalHandler() + if err := mgr.Start(mgrCtx); err != nil { + setupLog.Error(err, "problem running manager") + os.Exit(1) + } +} + +// installFluxResourcesFunc installs Flux resources from JSON strings +func installFluxResourcesFunc(ctx context.Context, k8sClient client.Client, resources []string) error { + logger := log.FromContext(ctx) + + for i, resourceJSON := range resources { + logger.Info("Installing Flux resource", "index", i+1, "total", len(resources)) + + // Parse JSON into unstructured object + var obj unstructured.Unstructured + if err := json.Unmarshal([]byte(resourceJSON), &obj.Object); err != nil { + return fmt.Errorf("failed to parse resource JSON at index %d: %w", i, err) + } + + // Validate that it has required fields + if obj.GetAPIVersion() == "" { + return fmt.Errorf("resource at index %d missing apiVersion", i) + } + if obj.GetKind() == "" { + return fmt.Errorf("resource at index %d missing kind", i) + } + if obj.GetName() == "" { + return fmt.Errorf("resource at index %d missing metadata.name", i) + } + + // Apply the resource (create or update) + logger.Info("Applying Flux resource", + "apiVersion", obj.GetAPIVersion(), + "kind", obj.GetKind(), + "name", obj.GetName(), + "namespace", obj.GetNamespace(), + ) + + // Use server-side apply or create/update + existing := &unstructured.Unstructured{} + existing.SetGroupVersionKind(obj.GroupVersionKind()) + key := client.ObjectKey{ + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + } + + err := k8sClient.Get(ctx, key, existing) + if err != nil { + if client.IgnoreNotFound(err) == nil { + // Resource doesn't exist, create it + if err := k8sClient.Create(ctx, &obj); err != nil { + return fmt.Errorf("failed to create resource %s/%s: %w", obj.GetKind(), obj.GetName(), err) + } + logger.Info("Created Flux resource", "kind", obj.GetKind(), "name", obj.GetName()) + } else { + return fmt.Errorf("failed to check if resource exists: %w", err) + } + } else { + // Resource exists, update it + obj.SetResourceVersion(existing.GetResourceVersion()) + if err := k8sClient.Update(ctx, &obj); err != nil { + return fmt.Errorf("failed to update resource %s/%s: %w", obj.GetKind(), obj.GetName(), err) + } + logger.Info("Updated Flux resource", "kind", obj.GetKind(), "name", obj.GetName()) + } + } + + return nil +} + +// installPlatformSourceResource generates and installs a Flux source resource (OCIRepository or GitRepository) +// based on the platform source URL +func installPlatformSourceResource(ctx context.Context, k8sClient client.Client, sourceURL, resourceName string) error { + logger := log.FromContext(ctx) + + // Parse the source URL to determine type + sourceType, repoURL, ref, err := parsePlatformSource(sourceURL) + if err != nil { + return fmt.Errorf("failed to parse platform source URL: %w", err) + } + + var obj *unstructured.Unstructured + switch sourceType { + case "oci": + obj, err = generateOCIRepository(resourceName, repoURL, ref) + if err != nil { + return fmt.Errorf("failed to generate OCIRepository: %w", err) + } + case "git": + obj, err = generateGitRepository(resourceName, repoURL, ref) + if err != nil { + return fmt.Errorf("failed to generate GitRepository: %w", err) + } + default: + return fmt.Errorf("unsupported source type: %s (expected oci:// or git://)", sourceType) + } + + // Apply the resource (create or update) + logger.Info("Applying platform source resource", + "apiVersion", obj.GetAPIVersion(), + "kind", obj.GetKind(), + "name", obj.GetName(), + "namespace", obj.GetNamespace(), + ) + + existing := &unstructured.Unstructured{} + existing.SetGroupVersionKind(obj.GroupVersionKind()) + key := client.ObjectKey{ + Name: obj.GetName(), + Namespace: obj.GetNamespace(), + } + + err = k8sClient.Get(ctx, key, existing) + if err != nil { + if client.IgnoreNotFound(err) == nil { + // Resource doesn't exist, create it + if err := k8sClient.Create(ctx, obj); err != nil { + return fmt.Errorf("failed to create resource %s/%s: %w", obj.GetKind(), obj.GetName(), err) + } + logger.Info("Created platform source resource", "kind", obj.GetKind(), "name", obj.GetName()) + } else { + return fmt.Errorf("failed to check if resource exists: %w", err) + } + } else { + // Resource exists, update it + obj.SetResourceVersion(existing.GetResourceVersion()) + if err := k8sClient.Update(ctx, obj); err != nil { + return fmt.Errorf("failed to update resource %s/%s: %w", obj.GetKind(), obj.GetName(), err) + } + logger.Info("Updated platform source resource", "kind", obj.GetKind(), "name", obj.GetName()) + } + + return nil +} + +// parsePlatformSource parses the source URL and returns the type, repository URL, and reference +// Supports formats: +// - oci://registry.example.com/repo@sha256:digest +// - oci://registry.example.com/repo (ref will be empty) +// - git://github.com/user/repo@branch +// - git://github.com/user/repo (ref will default to "main") +// - https://github.com/user/repo@branch (treated as git) +func parsePlatformSource(sourceURL string) (sourceType, repoURL, ref string, err error) { + // Normalize the URL by trimming whitespace + sourceURL = strings.TrimSpace(sourceURL) + + // Check for oci:// prefix + if strings.HasPrefix(sourceURL, "oci://") { + // Remove oci:// prefix + rest := strings.TrimPrefix(sourceURL, "oci://") + + // Check for @sha256: digest (look for @ followed by sha256:) + // We need to find the last @ before sha256: to handle paths with @ symbols + sha256Idx := strings.Index(rest, "@sha256:") + if sha256Idx != -1 { + repoURL = "oci://" + rest[:sha256Idx] + ref = rest[sha256Idx+1:] // sha256:digest + } else { + // Check for @ without sha256: (might be a tag) + if atIdx := strings.LastIndex(rest, "@"); atIdx != -1 { + // Could be a tag, but for OCI we expect sha256: digest + // For now, treat everything after @ as the ref + repoURL = "oci://" + rest[:atIdx] + ref = rest[atIdx+1:] + } else { + repoURL = "oci://" + rest + ref = "" // No digest specified + } + } + return "oci", repoURL, ref, nil + } + + // Check for git:// prefix or treat as git for http/https + if strings.HasPrefix(sourceURL, "git://") || strings.HasPrefix(sourceURL, "http://") || strings.HasPrefix(sourceURL, "https://") || strings.HasPrefix(sourceURL, "ssh://") { + // Parse URL to extract ref if present + parsedURL, err := url.Parse(sourceURL) + if err != nil { + return "", "", "", fmt.Errorf("invalid URL: %w", err) + } + + // Check for @ref in the path (e.g., git://host/path@branch) + path := parsedURL.Path + if idx := strings.LastIndex(path, "@"); idx != -1 { + repoURL = fmt.Sprintf("%s://%s%s", parsedURL.Scheme, parsedURL.Host, path[:idx]) + if parsedURL.RawQuery != "" { + repoURL += "?" + parsedURL.RawQuery + } + ref = path[idx+1:] + } else { + // Default to main branch if no ref specified + repoURL = sourceURL + ref = "main" + } + + // Normalize git:// to https:// for GitRepository + if strings.HasPrefix(repoURL, "git://") { + repoURL = strings.Replace(repoURL, "git://", "https://", 1) + } + + return "git", repoURL, ref, nil + } + + return "", "", "", fmt.Errorf("unsupported source URL scheme (expected oci:// or git://): %s", sourceURL) +} + +// generateOCIRepository creates an OCIRepository resource +func generateOCIRepository(name, repoURL, digest string) (*unstructured.Unstructured, error) { + obj := &unstructured.Unstructured{} + obj.SetAPIVersion("source.toolkit.fluxcd.io/v1") + obj.SetKind("OCIRepository") + obj.SetName(name) + obj.SetNamespace("cozy-system") + + spec := map[string]interface{}{ + "interval": "5m0s", + "url": repoURL, + } + + if digest != "" { + // Ensure digest starts with sha256: + if !strings.HasPrefix(digest, "sha256:") { + digest = "sha256:" + digest + } + spec["ref"] = map[string]interface{}{ + "digest": digest, + } + } + + if err := unstructured.SetNestedField(obj.Object, spec, "spec"); err != nil { + return nil, fmt.Errorf("failed to set spec: %w", err) + } + + return obj, nil +} + +// generateGitRepository creates a GitRepository resource +func generateGitRepository(name, repoURL, ref string) (*unstructured.Unstructured, error) { + obj := &unstructured.Unstructured{} + obj.SetAPIVersion("source.toolkit.fluxcd.io/v1") + obj.SetKind("GitRepository") + obj.SetName(name) + obj.SetNamespace("cozy-system") + + spec := map[string]interface{}{ + "interval": "5m0s", + "url": repoURL, + "ref": map[string]interface{}{ + "branch": ref, + }, + } + + if err := unstructured.SetNestedField(obj.Object, spec, "spec"); err != nil { + return nil, fmt.Errorf("failed to set spec: %w", err) + } + + return obj, nil +} diff --git a/internal/fluxinstall/install.go b/internal/fluxinstall/install.go new file mode 100644 index 00000000..19cb346f --- /dev/null +++ b/internal/fluxinstall/install.go @@ -0,0 +1,352 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 fluxinstall + +import ( + "bufio" + "bytes" + "context" + "fmt" + "io" + "os" + "path/filepath" + "strings" + "time" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer/yaml" + k8syaml "k8s.io/apimachinery/pkg/util/yaml" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +// Install installs Flux components using embedded manifests. +// It extracts the manifests and applies them to the cluster. +// The namespace is automatically determined from the Namespace object in the manifests. +func Install(ctx context.Context, k8sClient client.Client, writeEmbeddedManifests func(string) error) error { + logger := log.FromContext(ctx) + + // Create temporary directory for manifests + tmpDir, err := os.MkdirTemp("", "flux-install-*") + if err != nil { + return fmt.Errorf("failed to create temp directory: %w", err) + } + defer os.RemoveAll(tmpDir) + + // Extract embedded manifests (generated by cozypkg) + manifestsDir := filepath.Join(tmpDir, "manifests") + if err := os.MkdirAll(manifestsDir, 0755); err != nil { + return fmt.Errorf("failed to create manifests directory: %w", err) + } + + if err := writeEmbeddedManifests(manifestsDir); err != nil { + return fmt.Errorf("failed to extract embedded manifests: %w", err) + } + + // Find the manifest file (should be fluxcd.yaml from cozypkg) + manifestPath := filepath.Join(manifestsDir, "fluxcd.yaml") + if _, err := os.Stat(manifestPath); err != nil { + // Try to find any YAML file if fluxcd.yaml doesn't exist + entries, err := os.ReadDir(manifestsDir) + if err != nil { + return fmt.Errorf("failed to read manifests directory: %w", err) + } + for _, entry := range entries { + if strings.HasSuffix(entry.Name(), ".yaml") { + manifestPath = filepath.Join(manifestsDir, entry.Name()) + break + } + } + } + + // Parse and apply manifests + objects, err := parseManifests(manifestPath) + if err != nil { + return fmt.Errorf("failed to parse manifests: %w", err) + } + + if len(objects) == 0 { + return fmt.Errorf("no objects found in manifests") + } + + // Inject KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT if set in operator environment + if err := injectKubernetesServiceEnv(objects); err != nil { + logger.Info("Failed to inject KUBERNETES_SERVICE_* env vars, continuing anyway", "error", err) + } + + // Extract namespace from Namespace object in manifests + namespace, err := extractNamespace(objects) + if err != nil { + return fmt.Errorf("failed to extract namespace from manifests: %w", err) + } + + logger.Info("Installing Flux components", "namespace", namespace) + + // Apply manifests using server-side apply + logger.Info("Applying Flux manifests", "count", len(objects), "manifest", manifestPath, "namespace", namespace) + if err := applyManifests(ctx, k8sClient, objects); err != nil { + return fmt.Errorf("failed to apply manifests: %w", err) + } + + logger.Info("Flux installation completed successfully") + return nil +} + +// parseManifests parses YAML manifests into unstructured objects. +func parseManifests(manifestPath string) ([]*unstructured.Unstructured, error) { + data, err := os.ReadFile(manifestPath) + if err != nil { + return nil, fmt.Errorf("failed to read manifest file: %w", err) + } + + return readYAMLObjects(bytes.NewReader(data)) +} + +// readYAMLObjects parses multi-document YAML into unstructured objects. +func readYAMLObjects(reader io.Reader) ([]*unstructured.Unstructured, error) { + var objects []*unstructured.Unstructured + yamlReader := k8syaml.NewYAMLReader(bufio.NewReader(reader)) + + for { + doc, err := yamlReader.Read() + if err != nil { + if err == io.EOF { + break + } + return nil, fmt.Errorf("failed to read YAML document: %w", err) + } + + // Skip empty documents + if len(bytes.TrimSpace(doc)) == 0 { + continue + } + + obj := &unstructured.Unstructured{} + decoder := k8syaml.NewYAMLOrJSONDecoder(bytes.NewReader(doc), len(doc)) + if err := decoder.Decode(obj); err != nil { + // Skip documents that can't be decoded (might be comments or empty) + if err == io.EOF { + continue + } + return nil, fmt.Errorf("failed to decode YAML document: %w", err) + } + + // Skip empty objects (no kind) + if obj.GetKind() == "" { + continue + } + + objects = append(objects, obj) + } + + return objects, nil +} + +// applyManifests applies Kubernetes objects using server-side apply. +func applyManifests(ctx context.Context, k8sClient client.Client, objects []*unstructured.Unstructured) error { + logger := log.FromContext(ctx) + decoder := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) + + // Separate CRDs and namespaces from other resources + var stageOne []*unstructured.Unstructured // CRDs and Namespaces + var stageTwo []*unstructured.Unstructured // Everything else + + for _, obj := range objects { + if isClusterDefinition(obj) { + stageOne = append(stageOne, obj) + } else { + stageTwo = append(stageTwo, obj) + } + } + + // Apply stage one (CRDs and Namespaces) first + if len(stageOne) > 0 { + logger.Info("Applying cluster definitions", "count", len(stageOne)) + if err := applyObjects(ctx, k8sClient, decoder, stageOne); err != nil { + return fmt.Errorf("failed to apply cluster definitions: %w", err) + } + + // Wait a bit for CRDs to be registered + time.Sleep(2 * time.Second) + } + + // Apply stage two (everything else) + if len(stageTwo) > 0 { + logger.Info("Applying resources", "count", len(stageTwo)) + if err := applyObjects(ctx, k8sClient, decoder, stageTwo); err != nil { + return fmt.Errorf("failed to apply resources: %w", err) + } + } + + return nil +} + +// applyObjects applies a list of objects using server-side apply. +func applyObjects(ctx context.Context, k8sClient client.Client, decoder runtime.Decoder, objects []*unstructured.Unstructured) error { + for _, obj := range objects { + // Use server-side apply with force ownership and field manager + // FieldManager is required for apply patch operations + patchOptions := &client.PatchOptions{ + FieldManager: "cozystack-operator", + Force: func() *bool { b := true; return &b }(), + } + + if err := k8sClient.Patch(ctx, obj, client.Apply, patchOptions); err != nil { + return fmt.Errorf("failed to apply object %s/%s: %w", obj.GetKind(), obj.GetName(), err) + } + } + return nil +} + + +// extractNamespace extracts the namespace name from the Namespace object in the manifests. +func extractNamespace(objects []*unstructured.Unstructured) (string, error) { + for _, obj := range objects { + if obj.GetKind() == "Namespace" { + namespace := obj.GetName() + if namespace == "" { + return "", fmt.Errorf("Namespace object has no name") + } + return namespace, nil + } + } + return "", fmt.Errorf("no Namespace object found in manifests") +} + +// isClusterDefinition checks if an object is a CRD or Namespace. +func isClusterDefinition(obj *unstructured.Unstructured) bool { + kind := obj.GetKind() + return kind == "CustomResourceDefinition" || kind == "Namespace" +} + +// injectKubernetesServiceEnv injects KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT +// environment variables into all containers of Deployment, StatefulSet, and DaemonSet objects +// if these variables are set in the operator's environment. +func injectKubernetesServiceEnv(objects []*unstructured.Unstructured) error { + kubernetesHost := os.Getenv("KUBERNETES_SERVICE_HOST") + kubernetesPort := os.Getenv("KUBERNETES_SERVICE_PORT") + + // If neither variable is set, nothing to do + if kubernetesHost == "" && kubernetesPort == "" { + return nil + } + + for _, obj := range objects { + kind := obj.GetKind() + if kind != "Deployment" && kind != "StatefulSet" && kind != "DaemonSet" { + continue + } + + // Navigate to spec.template.spec.containers + spec, found, err := unstructured.NestedMap(obj.Object, "spec", "template", "spec") + if !found || err != nil { + continue + } + + // Update containers + containers, found, err := unstructured.NestedSlice(spec, "containers") + if found && err == nil { + containers = updateContainersEnv(containers, kubernetesHost, kubernetesPort) + if err := unstructured.SetNestedSlice(spec, containers, "containers"); err != nil { + continue + } + } + + // Update initContainers + initContainers, found, err := unstructured.NestedSlice(spec, "initContainers") + if found && err == nil { + initContainers = updateContainersEnv(initContainers, kubernetesHost, kubernetesPort) + if err := unstructured.SetNestedSlice(spec, initContainers, "initContainers"); err != nil { + continue + } + } + + // Update spec in the object + if err := unstructured.SetNestedMap(obj.Object, spec, "spec", "template", "spec"); err != nil { + continue + } + } + + return nil +} + +// updateContainersEnv updates environment variables for a slice of containers. +func updateContainersEnv(containers []interface{}, kubernetesHost, kubernetesPort string) []interface{} { + for i, container := range containers { + containerMap, ok := container.(map[string]interface{}) + if !ok { + continue + } + + env, found, err := unstructured.NestedSlice(containerMap, "env") + if err != nil { + continue + } + + if !found { + env = []interface{}{} + } + + // Update or add KUBERNETES_SERVICE_HOST + if kubernetesHost != "" { + env = setEnvVar(env, "KUBERNETES_SERVICE_HOST", kubernetesHost) + } + + // Update or add KUBERNETES_SERVICE_PORT + if kubernetesPort != "" { + env = setEnvVar(env, "KUBERNETES_SERVICE_PORT", kubernetesPort) + } + + // Update the container's env + if err := unstructured.SetNestedSlice(containerMap, env, "env"); err != nil { + continue + } + + // Update the container in the slice + containers[i] = containerMap + } + + return containers +} + +// setEnvVar updates or adds an environment variable in the env slice. +func setEnvVar(env []interface{}, name, value string) []interface{} { + // Check if variable already exists + for i, envVar := range env { + envVarMap, ok := envVar.(map[string]interface{}) + if !ok { + continue + } + + if envVarMap["name"] == name { + // Update existing variable + envVarMap["value"] = value + env[i] = envVarMap + return env + } + } + + // Add new variable + env = append(env, map[string]interface{}{ + "name": name, + "value": value, + }) + + return env +} + diff --git a/internal/fluxinstall/manifests.embed.go b/internal/fluxinstall/manifests.embed.go new file mode 100644 index 00000000..e6a13a99 --- /dev/null +++ b/internal/fluxinstall/manifests.embed.go @@ -0,0 +1,51 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 fluxinstall + +import ( + "embed" + "fmt" + "io/fs" + "os" + "path" +) + +//go:embed manifests/*.yaml +var embeddedFluxManifests embed.FS + +// WriteEmbeddedManifests extracts embedded Flux manifests to a temporary directory. +func WriteEmbeddedManifests(dir string) error { + manifests, err := fs.ReadDir(embeddedFluxManifests, "manifests") + if err != nil { + return fmt.Errorf("failed to read embedded manifests: %w", err) + } + + for _, manifest := range manifests { + data, err := fs.ReadFile(embeddedFluxManifests, path.Join("manifests", manifest.Name())) + if err != nil { + return fmt.Errorf("failed to read file %s: %w", manifest.Name(), err) + } + + outputPath := path.Join(dir, manifest.Name()) + if err := os.WriteFile(outputPath, data, 0666); err != nil { + return fmt.Errorf("failed to write file %s: %w", outputPath, err) + } + } + + return nil +} + diff --git a/packages/core/flux-aio/templates/fluxcd.yaml b/internal/fluxinstall/manifests/fluxcd.yaml similarity index 99% rename from packages/core/flux-aio/templates/fluxcd.yaml rename to internal/fluxinstall/manifests/fluxcd.yaml index 71a354c6..237db089 100644 --- a/packages/core/flux-aio/templates/fluxcd.yaml +++ b/internal/fluxinstall/manifests/fluxcd.yaml @@ -11623,7 +11623,6 @@ spec: value: /tmp/.sigstore - name: NO_PROXY value: .svc - {{- include "cozy.kubernetes_envs" . | nindent 12 }} image: ghcr.io/fluxcd/source-controller:v1.7.3 imagePullPolicy: IfNotPresent livenessProbe: @@ -11694,7 +11693,6 @@ spec: value: /tmp/.sigstore - name: NO_PROXY value: .svc - {{- include "cozy.kubernetes_envs" . | nindent 12 }} image: ghcr.io/fluxcd/kustomize-controller:v1.7.2 imagePullPolicy: IfNotPresent livenessProbe: @@ -11760,7 +11758,6 @@ spec: value: /tmp/.sigstore - name: NO_PROXY value: .svc - {{- include "cozy.kubernetes_envs" . | nindent 12 }} image: ghcr.io/fluxcd/helm-controller:v1.4.3 imagePullPolicy: IfNotPresent livenessProbe: @@ -11823,7 +11820,6 @@ spec: value: /tmp/.sigstore - name: NO_PROXY value: .svc - {{- include "cozy.kubernetes_envs" . | nindent 12 }} image: ghcr.io/fluxcd/notification-controller:v1.7.4 imagePullPolicy: IfNotPresent livenessProbe: @@ -11894,7 +11890,6 @@ spec: value: /tmp/.sigstore - name: NO_PROXY value: .svc - {{- include "cozy.kubernetes_envs" . | nindent 12 }} image: ghcr.io/fluxcd/source-watcher:v2.0.2 imagePullPolicy: IfNotPresent livenessProbe: @@ -11936,7 +11931,6 @@ spec: name: data - mountPath: /tmp name: tmp - dnsPolicy: ClusterFirstWithHostNet hostNetwork: true priorityClassName: system-cluster-critical securityContext: diff --git a/packages/core/flux-aio/Makefile b/packages/core/flux-aio/Makefile index d50f317d..5583dafa 100644 --- a/packages/core/flux-aio/Makefile +++ b/packages/core/flux-aio/Makefile @@ -13,10 +13,10 @@ diff: cozypkg show -n $(NAMESPACE) $(NAME) --plain | kubectl diff -f- update: - timoni bundle build -f flux-aio.cue > templates/fluxcd.yaml - yq eval '(select(.kind == "Namespace") | .metadata.labels."pod-security.kubernetes.io/enforce") = "privileged"' -i templates/fluxcd.yaml - sed -i templates/fluxcd.yaml \ + timoni bundle build -f flux-aio.cue > manifests/fluxcd.yaml + yq eval '(select(.kind == "Namespace") | .metadata.labels."pod-security.kubernetes.io/enforce") = "privileged"' -i manifests/fluxcd.yaml + sed -i manifests/fluxcd.yaml \ -e '/timoni/d' \ - -e 's|\.cluster\.local\.,||g' -e 's|\.cluster\.local\,||g' -e 's|\.cluster\.local\.||g' \ - -e '/value: .svc/a \ {{- include "cozy.kubernetes_envs" . | nindent 12 }}' \ - -e '/hostNetwork: true/i \ dnsPolicy: ClusterFirstWithHostNet' + -e 's|\.cluster\.local\.,||g' -e 's|\.cluster\.local\,||g' -e 's|\.cluster\.local\.||g' + # TODO: solve dns issue with hostNetwork for installing helmreleases in tenant k8s clusters + #-e '/hostNetwork: true/i \ dnsPolicy: ClusterFirstWithHostNet' diff --git a/packages/core/flux-aio/manifests b/packages/core/flux-aio/manifests new file mode 120000 index 00000000..f9bb5aad --- /dev/null +++ b/packages/core/flux-aio/manifests @@ -0,0 +1 @@ +../../../internal/fluxinstall/manifests \ No newline at end of file diff --git a/packages/core/flux-aio/templates/_helpers.tpl b/packages/core/flux-aio/templates/_helpers.tpl deleted file mode 100644 index e22979ba..00000000 --- a/packages/core/flux-aio/templates/_helpers.tpl +++ /dev/null @@ -1,13 +0,0 @@ -{{- define "cozy.kubernetes_envs" }} -{{- $cozyDeployment := lookup "apps/v1" "Deployment" "cozy-system" "cozystack" }} -{{- $cozyContainers := dig "spec" "template" "spec" "containers" dict $cozyDeployment }} -{{- range $cozyContainers }} -{{- if eq .name "cozystack" }} -{{- range .env }} -{{- if has .name (list "KUBERNETES_SERVICE_HOST" "KUBERNETES_SERVICE_PORT") }} -- {{ toJson . }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} diff --git a/packages/core/installer/1.yaml b/packages/core/installer/1.yaml new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/packages/core/installer/1.yaml @@ -0,0 +1 @@ + diff --git a/packages/core/installer/Makefile b/packages/core/installer/Makefile index 8039d698..6679c136 100644 --- a/packages/core/installer/Makefile +++ b/packages/core/installer/Makefile @@ -20,18 +20,7 @@ diff: update: hack/gen-profiles.sh -image: pre-checks image-matchbox image-cozystack image-talos image-packages - -image-cozystack: update-version - docker buildx build -f images/cozystack/Dockerfile ../../.. \ - --tag $(REGISTRY)/installer:$(call settag,$(TAG)) \ - --cache-from type=registry,ref=$(REGISTRY)/installer:latest \ - --cache-to type=inline \ - --metadata-file images/installer.json \ - $(BUILDX_ARGS) - IMAGE="$(REGISTRY)/installer:$(call settag,$(TAG))@$$(yq e '."containerimage.digest"' images/installer.json -o json -r)" \ - yq -i '.cozystack.image = strenv(IMAGE)' values.yaml - rm -f images/installer.json +image: pre-checks image-matchbox image-talos image-operator image-packages image-talos: test -f ../../../_out/assets/installer-amd64.tar || make talos-installer @@ -63,6 +52,18 @@ update-version: TAG="$(call settag,$(TAG))" \ yq -i '.cozystackOperator.cozystackVersion = strenv(TAG)' values.yaml +image-operator: + docker buildx build -f images/cozystack-operator/Dockerfile ../../.. \ + --tag $(REGISTRY)/cozystack-operator:$(call settag,$(TAG)) \ + --cache-from type=registry,ref=$(REGISTRY)/cozystack-operator:latest \ + --cache-to type=inline \ + --metadata-file images/cozystack-operator.json \ + $(BUILDX_ARGS) + IMAGE="$(REGISTRY)/cozystack-operator:$(call settag,$(TAG))@$$(yq e '."containerimage.digest"' images/cozystack-operator.json -o json -r)" \ + yq -i '.cozystackOperator.image = strenv(IMAGE)' values.yaml + rm -f images/cozystack-operator.json + + image-packages: update-version mkdir -p ../../../_out/assets images flux push artifact \ diff --git a/packages/core/installer/images/cozystack-operator/Dockerfile b/packages/core/installer/images/cozystack-operator/Dockerfile new file mode 100644 index 00000000..8c4cb79c --- /dev/null +++ b/packages/core/installer/images/cozystack-operator/Dockerfile @@ -0,0 +1,23 @@ +FROM golang:1.25-alpine as builder + +ARG TARGETOS +ARG TARGETARCH + +RUN apk add --no-cache make git + +COPY . /src/ +WORKDIR /src + +RUN go mod download + +# Build cozystack-operator +RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build \ + -ldflags="-w -s" \ + -o /cozystack-operator \ + ./cmd/cozystack-operator + +FROM alpine:3.22 + +COPY --from=builder /cozystack-operator /usr/bin/cozystack-operator + +ENTRYPOINT ["/usr/bin/cozystack-operator"] diff --git a/packages/core/installer/images/cozystack-operator/Dockerfile.dockerignore b/packages/core/installer/images/cozystack-operator/Dockerfile.dockerignore new file mode 100644 index 00000000..6803982e --- /dev/null +++ b/packages/core/installer/images/cozystack-operator/Dockerfile.dockerignore @@ -0,0 +1,12 @@ +# Exclude everything except src directory +* +!src/** +!api/** +!cmd/** +!hack/** +!internal/** +!packages/** +!pkg/** +!scripts/** +!go.mod +!go.sum diff --git a/packages/core/installer/images/cozystack/Dockerfile b/packages/core/installer/images/cozystack/Dockerfile deleted file mode 100644 index 606505ba..00000000 --- a/packages/core/installer/images/cozystack/Dockerfile +++ /dev/null @@ -1,41 +0,0 @@ -FROM golang:1.24-alpine AS k8s-await-election-builder - -ARG K8S_AWAIT_ELECTION_GITREPO=https://github.com/LINBIT/k8s-await-election -ARG K8S_AWAIT_ELECTION_VERSION=0.4.1 - -# TARGETARCH is a docker special variable: https://docs.docker.com/engine/reference/builder/#automatic-platform-args-in-the-global-scope -ARG TARGETARCH - -RUN apk add --no-cache git make -RUN git clone ${K8S_AWAIT_ELECTION_GITREPO} /usr/local/go/k8s-await-election/ \ - && cd /usr/local/go/k8s-await-election \ - && git reset --hard v${K8S_AWAIT_ELECTION_VERSION} \ - && make \ - && mv ./out/k8s-await-election-${TARGETARCH} /k8s-await-election - -FROM golang:1.24-alpine AS builder - -ARG TARGETOS -ARG TARGETARCH - -RUN apk add --no-cache make git -RUN apk add helm --repository=https://dl-cdn.alpinelinux.org/alpine/edge/community - -COPY . /src/ -WORKDIR /src - -RUN go mod download - -FROM alpine:3.22 - -RUN wget -O- https://github.com/cozystack/cozypkg/raw/refs/heads/main/hack/install.sh | sh -s -- -v 1.2.0 - -RUN apk add --no-cache make kubectl helm coreutils git jq openssl - -COPY --from=builder /src/scripts /cozystack/scripts -COPY --from=builder /src/packages/core /cozystack/packages/core -COPY --from=builder /src/packages/system /cozystack/packages/system -COPY --from=k8s-await-election-builder /k8s-await-election /usr/bin/k8s-await-election - -WORKDIR /cozystack -ENTRYPOINT ["/usr/bin/k8s-await-election", "/cozystack/scripts/installer.sh" ] diff --git a/packages/core/installer/images/cozystack/Dockerfile.dockerignore b/packages/core/installer/images/cozystack/Dockerfile.dockerignore deleted file mode 100644 index c1d18d8a..00000000 --- a/packages/core/installer/images/cozystack/Dockerfile.dockerignore +++ /dev/null @@ -1 +0,0 @@ -_out diff --git a/packages/core/installer/templates/cozystack-operator.yaml b/packages/core/installer/templates/cozystack-operator.yaml index 3e8c6eee..c4f652fc 100644 --- a/packages/core/installer/templates/cozystack-operator.yaml +++ b/packages/core/installer/templates/cozystack-operator.yaml @@ -59,8 +59,8 @@ spec: {{- if .Values.cozystackOperator.disableTelemetry }} - --disable-telemetry {{- end }} - - --platform-name="cozystack-platform" - - --platform-source="{{ .Values.cozystackOperator.platformSource }}" + - --platform-name=cozystack-platform + - --platform-source={{ .Values.cozystackOperator.platformSource }} env: - name: KUBERNETES_SERVICE_HOST value: localhost @@ -74,3 +74,22 @@ spec: - key: "node.cilium.io/agent-not-ready" operator: "Exists" effect: "NoSchedule" +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.cozystack-platform +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + components: + - install: + namespace: cozy-system + releaseName: cozystack-platform + name: cozystack-platform + path: core/platform diff --git a/packages/core/installer/templates/cozystack.yaml b/packages/core/installer/templates/cozystack.yaml deleted file mode 100644 index c43b0425..00000000 --- a/packages/core/installer/templates/cozystack.yaml +++ /dev/null @@ -1,79 +0,0 @@ ---- -apiVersion: v1 -kind: Namespace -metadata: - name: cozy-system - labels: - cozystack.io/system: "true" - pod-security.kubernetes.io/enforce: privileged ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: cozystack - namespace: cozy-system ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: cozystack -subjects: -- kind: ServiceAccount - name: cozystack - namespace: cozy-system -roleRef: - kind: ClusterRole - name: cluster-admin - apiGroup: rbac.authorization.k8s.io ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: cozystack - namespace: cozy-system -spec: - replicas: 1 - selector: - matchLabels: - app: cozystack - strategy: - type: RollingUpdate - rollingUpdate: - maxSurge: 0 - maxUnavailable: 1 - template: - metadata: - labels: - app: cozystack - spec: - hostNetwork: true - serviceAccountName: cozystack - containers: - - name: cozystack - image: "{{ .Values.cozystack.image }}" - env: - - name: KUBERNETES_SERVICE_HOST - value: localhost - - name: INSTALL_FLUX - value: "true" - - name: KUBERNETES_SERVICE_PORT - value: "7445" - - name: K8S_AWAIT_ELECTION_ENABLED - value: "1" - - name: K8S_AWAIT_ELECTION_NAME - value: cozystack - - name: K8S_AWAIT_ELECTION_LOCK_NAME - value: cozystack - - name: K8S_AWAIT_ELECTION_LOCK_NAMESPACE - value: cozy-system - - name: K8S_AWAIT_ELECTION_IDENTITY - valueFrom: - fieldRef: - fieldPath: metadata.name - tolerations: - - key: "node.kubernetes.io/not-ready" - operator: "Exists" - effect: "NoSchedule" - - key: "node.cilium.io/agent-not-ready" - operator: "Exists" - effect: "NoSchedule" diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index a5ec3df7..7c33fca4 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,6 +1,6 @@ cozystack: image: ghcr.io/cozystack/cozystack/installer:v0.38.2@sha256:9ff92b655de6f9bea3cba4cd42dcffabd9aace6966dcfb1cc02dda2420ea4a15 cozystackOperator: - image: ghcr.io/cozystack/cozystack/cozystack-operator:latest@sha256:446b4afe9ed160a850cc9b61dd6f34b2ae36d69d4cd974d6d35a25180bd73879 + image: ghcr.io/cozystack/cozystack/cozystack-operator:latest@sha256:873a52d9f69932a93f7fa99c3ccac418c80bab409ca3cba781492cba00276c84 platformSource: 'oci://ghcr.io/cozystack/cozystack/platform-packages@sha256:3edff5f9feb4bd66e4b46df9e07e5db3eb6ead051edac74cbda3b222eb940a70' cozystackVersion: latest From 84f2f83b036674ca14d9480008d66e31d099bc8c Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Fri, 19 Dec 2025 12:16:15 +0100 Subject: [PATCH 09/15] refactor packagesources Signed-off-by: Andrei Kvapil --- api/v1alpha1/packagesource_types.go | 28 - api/v1alpha1/zz_generated.deepcopy.go | 28 - internal/operator/bundle_reconciler.go.old | 1235 +++++++++++++++++ .../templates/cozystack-operator.yaml | 18 + .../platform/psds/bootbox-application.yaml | 43 +- packages/core/platform/psds/bootbox.yaml | 1 - .../platform/psds/bucket-application.yaml | 30 + packages/core/platform/psds/bucket.yaml | 62 - .../platform/psds/clickhouse-application.yaml | 27 + packages/core/platform/psds/clickhouse.yaml | 54 - .../{cozystack.yaml => cozystack-engine.yaml} | 2 +- packages/core/platform/psds/dependencies.dot | 190 +++ packages/core/platform/psds/dependencies.svg | 1128 +++++++++++++++ .../core/platform/psds/etcd-application.yaml | 41 +- packages/core/platform/psds/external-dns.yaml | 1 - .../psds/external-secrets-operator.yaml | 1 - .../platform/psds/ferretdb-application.yaml | 27 + packages/core/platform/psds/ferretdb.yaml | 55 - .../psds/foundationdb-application.yaml | 28 + packages/core/platform/psds/foundationdb.yaml | 46 - .../core/platform/psds/hetzner-robotlb.yaml | 1 - .../platform/psds/http-cache-application.yaml | 27 + packages/core/platform/psds/http-cache.yaml | 49 - .../core/platform/psds/info-application.yaml | 27 + packages/core/platform/psds/info.yaml | 52 - .../platform/psds/ingress-application.yaml | 29 + packages/core/platform/psds/ingress.yaml | 56 - .../core/platform/psds/kafka-application.yaml | 28 + packages/core/platform/psds/kafka.yaml | 56 - .../platform/psds/kubernetes-application.yaml | 64 + packages/core/platform/psds/kubernetes.yaml | 98 -- .../platform/psds/monitoring-application.yaml | 27 + packages/core/platform/psds/monitoring.yaml | 63 - .../core/platform/psds/mysql-application.yaml | 28 + packages/core/platform/psds/mysql.yaml | 57 - .../core/platform/psds/nats-application.yaml | 29 + packages/core/platform/psds/nats.yaml | 57 - packages/core/platform/psds/nfs-driver.yaml | 1 - .../platform/psds/postgres-application.yaml | 27 + packages/core/platform/psds/postgres.yaml | 66 - .../platform/psds/rabbitmq-application.yaml | 28 + packages/core/platform/psds/rabbitmq.yaml | 58 - .../core/platform/psds/redis-application.yaml | 28 + packages/core/platform/psds/redis.yaml | 59 - .../platform/psds/seaweedfs-application.yaml | 29 + packages/core/platform/psds/seaweedfs.yaml | 61 - .../psds/tcp-balancer-application.yaml | 27 + packages/core/platform/psds/tcp-balancer.yaml | 48 - packages/core/platform/psds/telepresence.yaml | 1 - .../platform/psds/tenant-application.yaml | 33 + packages/core/platform/psds/tenant.yaml | 52 - packages/core/platform/psds/velero.yaml | 1 - .../psds/virtual-machine-application.yaml | 29 + .../core/platform/psds/virtual-machine.yaml | 56 - .../psds/virtualprivatecloud-application.yaml | 28 + .../platform/psds/virtualprivatecloud.yaml | 50 - .../platform/psds/vm-disk-application.yaml | 28 + packages/core/platform/psds/vm-disk.yaml | 50 - .../psds/vm-instance-application.yaml | 28 + packages/core/platform/psds/vm-instance.yaml | 55 - .../core/platform/psds/vpn-application.yaml | 27 + packages/core/platform/psds/vpn.yaml | 55 - .../crds/cozystack.io_packagesources.yaml | 707 ---------- pkg/generated/openapi/zz_generated.openapi.go | 49 +- 64 files changed, 3311 insertions(+), 2163 deletions(-) create mode 100644 internal/operator/bundle_reconciler.go.old create mode 100644 packages/core/platform/psds/bucket-application.yaml delete mode 100644 packages/core/platform/psds/bucket.yaml create mode 100644 packages/core/platform/psds/clickhouse-application.yaml delete mode 100644 packages/core/platform/psds/clickhouse.yaml rename packages/core/platform/psds/{cozystack.yaml => cozystack-engine.yaml} (98%) create mode 100644 packages/core/platform/psds/dependencies.dot create mode 100644 packages/core/platform/psds/dependencies.svg create mode 100644 packages/core/platform/psds/ferretdb-application.yaml delete mode 100644 packages/core/platform/psds/ferretdb.yaml create mode 100644 packages/core/platform/psds/foundationdb-application.yaml delete mode 100644 packages/core/platform/psds/foundationdb.yaml create mode 100644 packages/core/platform/psds/http-cache-application.yaml delete mode 100644 packages/core/platform/psds/http-cache.yaml create mode 100644 packages/core/platform/psds/info-application.yaml delete mode 100644 packages/core/platform/psds/info.yaml create mode 100644 packages/core/platform/psds/ingress-application.yaml delete mode 100644 packages/core/platform/psds/ingress.yaml create mode 100644 packages/core/platform/psds/kafka-application.yaml delete mode 100644 packages/core/platform/psds/kafka.yaml create mode 100644 packages/core/platform/psds/kubernetes-application.yaml delete mode 100644 packages/core/platform/psds/kubernetes.yaml create mode 100644 packages/core/platform/psds/monitoring-application.yaml delete mode 100644 packages/core/platform/psds/monitoring.yaml create mode 100644 packages/core/platform/psds/mysql-application.yaml delete mode 100644 packages/core/platform/psds/mysql.yaml create mode 100644 packages/core/platform/psds/nats-application.yaml delete mode 100644 packages/core/platform/psds/nats.yaml create mode 100644 packages/core/platform/psds/postgres-application.yaml delete mode 100644 packages/core/platform/psds/postgres.yaml create mode 100644 packages/core/platform/psds/rabbitmq-application.yaml delete mode 100644 packages/core/platform/psds/rabbitmq.yaml create mode 100644 packages/core/platform/psds/redis-application.yaml delete mode 100644 packages/core/platform/psds/redis.yaml create mode 100644 packages/core/platform/psds/seaweedfs-application.yaml delete mode 100644 packages/core/platform/psds/seaweedfs.yaml create mode 100644 packages/core/platform/psds/tcp-balancer-application.yaml delete mode 100644 packages/core/platform/psds/tcp-balancer.yaml create mode 100644 packages/core/platform/psds/tenant-application.yaml delete mode 100644 packages/core/platform/psds/tenant.yaml create mode 100644 packages/core/platform/psds/virtual-machine-application.yaml delete mode 100644 packages/core/platform/psds/virtual-machine.yaml create mode 100644 packages/core/platform/psds/virtualprivatecloud-application.yaml delete mode 100644 packages/core/platform/psds/virtualprivatecloud.yaml create mode 100644 packages/core/platform/psds/vm-disk-application.yaml delete mode 100644 packages/core/platform/psds/vm-disk.yaml create mode 100644 packages/core/platform/psds/vm-instance-application.yaml delete mode 100644 packages/core/platform/psds/vm-instance.yaml create mode 100644 packages/core/platform/psds/vpn-application.yaml delete mode 100644 packages/core/platform/psds/vpn.yaml diff --git a/api/v1alpha1/packagesource_types.go b/api/v1alpha1/packagesource_types.go index b5daa2e1..88940c91 100644 --- a/api/v1alpha1/packagesource_types.go +++ b/api/v1alpha1/packagesource_types.go @@ -79,10 +79,6 @@ type Variant struct { // Components is a list of Helm releases to be installed as part of this variant // +optional Components []Component `json:"components,omitempty"` - - // Applications is a list of application releases to be installed as part of this variant - // +optional - Applications []Application `json:"applications,omitempty"` } // DependencyTarget defines a named group of packages that can be referenced @@ -165,10 +161,6 @@ type Component struct { // +optional Install *ComponentInstall `json:"install,omitempty"` - // Disabled indicates whether this component is disabled (should not be installed) - // +optional - Disabled bool `json:"disabled,omitempty"` - // Libraries is a list of library names that this component depends on // These libraries must be defined at the variant level // +optional @@ -179,26 +171,6 @@ type Component struct { ValuesFiles []string `json:"valuesFiles,omitempty"` } -// Application defines a single application release within a package source -type Application struct { - // Name is the unique identifier for this application within the package source - // +required - Name string `json:"name"` - - // Path is the path to the Helm chart directory - // +required - Path string `json:"path"` - - // Libraries is a list of library names that this application depends on - // These libraries must be defined at the variant level - // +optional - Libraries []string `json:"libraries,omitempty"` - - // Template describes the applications that will be created. - // +required - Template CozystackResourceDefinition `json:"template"` -} - // PackageSourceStatus defines the observed state of PackageSource type PackageSourceStatus struct { // Variants is a comma-separated list of package variant names diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index b2ca8ac9..59f67c3d 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -27,27 +27,6 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Application) DeepCopyInto(out *Application) { - *out = *in - if in.Libraries != nil { - in, out := &in.Libraries, &out.Libraries - *out = make([]string, len(*in)) - copy(*out, *in) - } - in.Template.DeepCopyInto(&out.Template) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Application. -func (in *Application) DeepCopy() *Application { - if in == nil { - return nil - } - out := new(Application) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Component) DeepCopyInto(out *Component) { *out = *in @@ -676,13 +655,6 @@ func (in *Variant) DeepCopyInto(out *Variant) { (*in)[i].DeepCopyInto(&(*out)[i]) } } - if in.Applications != nil { - in, out := &in.Applications, &out.Applications - *out = make([]Application, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Variant. diff --git a/internal/operator/bundle_reconciler.go.old b/internal/operator/bundle_reconciler.go.old new file mode 100644 index 00000000..ddaa1303 --- /dev/null +++ b/internal/operator/bundle_reconciler.go.old @@ -0,0 +1,1235 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 operator + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "strings" + "time" + + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + sourcewatcherv1beta1 "github.com/fluxcd/source-watcher/api/v2/v1beta1" + corev1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// BundleReconciler reconciles Bundle resources +type BundleReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +// +kubebuilder:rbac:groups=cozystack.io,resources=bundles,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=cozystack.io,resources=bundles/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=helm.toolkit.fluxcd.io,resources=helmreleases,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=source.extensions.fluxcd.io,resources=artifactgenerators,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;create;update;patch + +// Reconcile is part of the main kubernetes reconciliation loop +func (r *BundleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + logger := log.FromContext(ctx) + + bundle := &cozyv1alpha1.Bundle{} + if err := r.Get(ctx, req.NamespacedName, bundle); err != nil { + if apierrors.IsNotFound(err) { + // Cleanup orphaned resources + return r.cleanupOrphanedResources(ctx, req.NamespacedName) + } + return ctrl.Result{}, err + } + + // Resolve dependencies from other bundles + resolvedPackages, err := r.resolveDependencies(ctx, bundle) + if err != nil { + // If dependency bundle is not found, requeue to try again later + // Check if the error is wrapped IsNotFound + unwrappedErr := errors.Unwrap(err) + if unwrappedErr != nil && apierrors.IsNotFound(unwrappedErr) { + logger.Info("Dependency bundle not found, requeuing", "bundle", bundle.Name, "error", err) + return ctrl.Result{RequeueAfter: 10 * time.Second}, nil + } + logger.Error(err, "failed to resolve dependencies") + return ctrl.Result{}, err + } + + // Reconcile namespaces from packages + if err := r.reconcileNamespaces(ctx, bundle, resolvedPackages); err != nil { + logger.Error(err, "failed to reconcile namespaces") + return ctrl.Result{}, err + } + + // Check for conflicts between packages with artifact and artifacts + if err := r.checkArtifactConflicts(ctx, bundle, resolvedPackages); err != nil { + logger.Error(err, "failed to check artifact conflicts") + return ctrl.Result{}, err + } + + // Generate ArtifactGenerator for bundle (one generator per bundle with all OutputArtifacts) + if err := r.reconcileArtifactGenerators(ctx, bundle, resolvedPackages); err != nil { + logger.Error(err, "failed to reconcile ArtifactGenerator") + return ctrl.Result{}, err + } + + // Generate HelmReleases for packages + if err := r.reconcileHelmReleases(ctx, bundle, resolvedPackages); err != nil { + logger.Error(err, "failed to reconcile HelmReleases") + return ctrl.Result{}, err + } + + return ctrl.Result{}, nil +} + +// resolveDependencies resolves dependencies from other bundles +func (r *BundleReconciler) resolveDependencies(ctx context.Context, bundle *cozyv1alpha1.Bundle) ([]cozyv1alpha1.BundleRelease, error) { + resolved := make([]cozyv1alpha1.BundleRelease, 0, len(bundle.Spec.Packages)) + packageMap := make(map[string]bool) + + // Add all packages from this bundle + for _, pkg := range bundle.Spec.Packages { + if !pkg.Disabled { + resolved = append(resolved, pkg) + packageMap[pkg.Name] = true + } + } + + // Resolve dependencies from other bundles + for _, dependsOn := range bundle.Spec.DependsOn { + parts := strings.Split(dependsOn, "/") + if len(parts) != 2 { + return nil, fmt.Errorf("invalid dependsOn format: %s (expected bundleName/target)", dependsOn) + } + + bundleName := parts[0] + targetName := parts[1] + + // Get the bundle + depBundle := &cozyv1alpha1.Bundle{} + if err := r.Get(ctx, types.NamespacedName{Name: bundleName}, depBundle); err != nil { + // If bundle is not found, return wrapped error so we can check it in Reconcile + if apierrors.IsNotFound(err) { + return nil, fmt.Errorf("failed to get bundle %s: %w", bundleName, err) + } + return nil, fmt.Errorf("failed to get bundle %s: %w", bundleName, err) + } + + // Find the target + var target *cozyv1alpha1.BundleDependencyTarget + for i := range depBundle.Spec.DependencyTargets { + if depBundle.Spec.DependencyTargets[i].Name == targetName { + target = &depBundle.Spec.DependencyTargets[i] + break + } + } + + if target == nil { + return nil, fmt.Errorf("target %s not found in bundle %s", targetName, bundleName) + } + + // Add packages from target to all packages in this bundle + for i := range resolved { + // Add target packages to dependsOn + for _, targetPkg := range target.Packages { + // Check if already in dependsOn + found := false + for _, dep := range resolved[i].DependsOn { + if dep == targetPkg { + found = true + break + } + } + if !found { + resolved[i].DependsOn = append(resolved[i].DependsOn, targetPkg) + } + } + } + } + + return resolved, nil +} + +// reconcileArtifactGenerators generates a single ArtifactGenerator for the bundle +// Creates one ArtifactGenerator per bundle with all OutputArtifacts from packages and artifacts +func (r *BundleReconciler) reconcileArtifactGenerators(ctx context.Context, bundle *cozyv1alpha1.Bundle, packages []cozyv1alpha1.BundleRelease) error { + logger := log.FromContext(ctx) + + libraryMap := make(map[string]cozyv1alpha1.BundleLibrary) + for _, lib := range bundle.Spec.Libraries { + libraryMap[lib.Name] = lib + } + + // Namespace is always cozy-system + namespace := "cozy-system" + // ArtifactGenerator name is the bundle name + agName := bundle.Name + + // Collect all OutputArtifacts + outputArtifacts := []sourcewatcherv1beta1.OutputArtifact{} + + // Process packages + for _, pkg := range packages { + logger.V(1).Info("processing package for artifact", "bundle", bundle.Name, "package", pkg.Name, "path", pkg.Path, "disabled", pkg.Disabled) + + // Skip packages without path (they might use artifacts) + if pkg.Path == "" { + logger.V(1).Info("skipping package without path", "name", pkg.Name) + continue + } + + // Extract package name from path (last component) + pkgName := r.getPackageNameFromPath(pkg.Path) + if pkgName == "" { + logger.Info("skipping package with invalid path", "name", pkg.Name, "path", pkg.Path) + continue + } + + logger.V(1).Info("extracted package name from path", "name", pkg.Name, "path", pkg.Path, "pkgName", pkgName) + + // Get basePath with default values + basePath := r.getBasePath(bundle) + + // Build copy operations + copyOps := []sourcewatcherv1beta1.CopyOperation{ + { + From: r.buildSourcePath(bundle.Spec.SourceRef.Name, basePath, pkg.Path), + To: fmt.Sprintf("@artifact/%s/", pkgName), + }, + } + + // Add libraries if specified + for _, libName := range pkg.Libraries { + if lib, ok := libraryMap[libName]; ok { + copyOps = append(copyOps, sourcewatcherv1beta1.CopyOperation{ + From: r.buildSourcePath(bundle.Spec.SourceRef.Name, basePath, lib.Path), + To: fmt.Sprintf("@artifact/%s/charts/%s/", pkgName, libName), + }) + } + } + + // Add valuesFiles if specified + for i, valuesFile := range pkg.ValuesFiles { + strategy := "Merge" + if i == 0 { + strategy = "Overwrite" + } + copyOps = append(copyOps, sourcewatcherv1beta1.CopyOperation{ + From: r.buildSourceFilePath(bundle.Spec.SourceRef.Name, basePath, fmt.Sprintf("%s/%s", pkg.Path, valuesFile)), + To: fmt.Sprintf("@artifact/%s/values.yaml", pkgName), + Strategy: strategy, + }) + } + + // Artifact name: bundle-name-package-name (e.g., cozystack-system-cilium) + artifactName := fmt.Sprintf("%s-%s", bundle.Name, pkgName) + + outputArtifacts = append(outputArtifacts, sourcewatcherv1beta1.OutputArtifact{ + Name: artifactName, + Copy: copyOps, + }) + + logger.Info("added OutputArtifact for package", "bundle", bundle.Name, "package", pkg.Name, "artifactName", artifactName) + } + + // Process artifacts + for _, artifact := range bundle.Spec.Artifacts { + logger.Info("processing artifact", "bundle", bundle.Name, "artifact", artifact.Name, "path", artifact.Path) + // Extract artifact name from path (last component) + artifactPathName := r.getPackageNameFromPath(artifact.Path) + if artifactPathName == "" { + logger.Info("skipping artifact with invalid path", "name", artifact.Name, "path", artifact.Path) + continue + } + + // Get basePath with default values + basePath := r.getBasePath(bundle) + + // Build copy operations + copyOps := []sourcewatcherv1beta1.CopyOperation{ + { + From: r.buildSourcePath(bundle.Spec.SourceRef.Name, basePath, artifact.Path), + To: fmt.Sprintf("@artifact/%s/", artifactPathName), + }, + } + + // Add libraries if specified + for _, libName := range artifact.Libraries { + if lib, ok := libraryMap[libName]; ok { + copyOps = append(copyOps, sourcewatcherv1beta1.CopyOperation{ + From: r.buildSourcePath(bundle.Spec.SourceRef.Name, basePath, lib.Path), + To: fmt.Sprintf("@artifact/%s/charts/%s/", artifactPathName, libName), + }) + } + } + + // Artifact name: {bundle-name}-{artifact-name} + artifactName := fmt.Sprintf("%s-%s", bundle.Name, artifact.Name) + + outputArtifacts = append(outputArtifacts, sourcewatcherv1beta1.OutputArtifact{ + Name: artifactName, + Copy: copyOps, + }) + + logger.Info("added OutputArtifact for artifact", "bundle", bundle.Name, "artifact", artifact.Name, "artifactName", artifactName) + } + + // If there are no OutputArtifacts, cleanup and return + if len(outputArtifacts) == 0 { + logger.Info("no OutputArtifacts to generate, skipping ArtifactGenerator creation", "bundle", bundle.Name) + // Cleanup orphaned ArtifactGenerators (to remove existing generator if it exists) + return r.cleanupOrphanedArtifactGenerators(ctx, bundle) + } + + // Build labels: merge bundle labels with default cozystack.io/bundle label + labels := make(map[string]string) + if bundle.Spec.Labels != nil { + for k, v := range bundle.Spec.Labels { + labels[k] = v + } + } + labels["cozystack.io/bundle"] = bundle.Name + + // Create single ArtifactGenerator for the bundle + ag := &sourcewatcherv1beta1.ArtifactGenerator{ + ObjectMeta: metav1.ObjectMeta{ + Name: agName, + Namespace: namespace, + Labels: labels, + }, + Spec: sourcewatcherv1beta1.ArtifactGeneratorSpec{ + Sources: []sourcewatcherv1beta1.SourceReference{ + { + Alias: bundle.Spec.SourceRef.Name, + Kind: bundle.Spec.SourceRef.Kind, + Name: bundle.Spec.SourceRef.Name, + Namespace: bundle.Spec.SourceRef.Namespace, + }, + }, + OutputArtifacts: outputArtifacts, + }, + } + + // Set ownerReference only if deletionPolicy is not Orphan + if bundle.Spec.DeletionPolicy != cozyv1alpha1.DeletionPolicyOrphan { + ag.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: bundle.APIVersion, + Kind: bundle.Kind, + Name: bundle.Name, + UID: bundle.UID, + Controller: func() *bool { b := true; return &b }(), + }, + } + } else { + // Explicitly set empty ownerReferences for Orphan policy + ag.OwnerReferences = []metav1.OwnerReference{} + } + + logger.Info("creating ArtifactGenerator for bundle", "bundle", bundle.Name, "agName", agName, "namespace", namespace, "outputArtifactCount", len(outputArtifacts)) + + if err := r.createOrUpdate(ctx, ag); err != nil { + return fmt.Errorf("failed to reconcile ArtifactGenerator %s: %w", agName, err) + } + + logger.Info("reconciled ArtifactGenerator for bundle", "name", agName, "namespace", namespace, "outputArtifactCount", len(outputArtifacts)) + + // Cleanup orphaned ArtifactGenerators + return r.cleanupOrphanedArtifactGenerators(ctx, bundle) +} + +// reconcileHelmReleases generates HelmReleases from bundle packages +func (r *BundleReconciler) reconcileHelmReleases(ctx context.Context, bundle *cozyv1alpha1.Bundle, packages []cozyv1alpha1.BundleRelease) error { + logger := log.FromContext(ctx) + + // Build package name map for dependency resolution (from current bundle) + packageNameMap := make(map[string]cozyv1alpha1.BundleRelease) + for _, pkg := range packages { + packageNameMap[pkg.Name] = pkg + } + + // Build global package name map from all bundles for finding dependencies + globalPackageMap := make(map[string]cozyv1alpha1.BundleRelease) + bundleList := &cozyv1alpha1.BundleList{} + if err := r.List(ctx, bundleList); err == nil { + for _, b := range bundleList.Items { + for _, pkg := range b.Spec.Packages { + // Only add if not already in map (first occurrence wins, or use current bundle's packages) + if _, exists := globalPackageMap[pkg.Name]; !exists { + globalPackageMap[pkg.Name] = pkg + } + } + } + } + // Override with packages from current bundle (they take precedence) + for _, pkg := range packages { + globalPackageMap[pkg.Name] = pkg + } + + // Build artifact name map from bundle artifacts for conflict checking + artifactNameMap := make(map[string]bool) + for _, artifact := range bundle.Spec.Artifacts { + artifactNameMap[artifact.Name] = true + } + + // Create HelmRelease for each package + for _, pkg := range packages { + // Skip disabled packages + if pkg.Disabled { + logger.V(1).Info("skipping disabled package", "name", pkg.Name, "namespace", pkg.Namespace) + continue + } + + var artifactName string + artifactNamespace := "cozy-system" + + if pkg.Artifact != "" { + // Package uses an artifact reference + // Check if artifact exists in bundle + if !artifactNameMap[pkg.Artifact] { + logger.Error(fmt.Errorf("artifact %s not found in bundle artifacts", pkg.Artifact), "skipping package", "name", pkg.Name) + continue + } + // Artifact name format: {bundle-name}-{artifact-name} + artifactName = fmt.Sprintf("%s-%s", bundle.Name, pkg.Artifact) + } else if pkg.Path != "" { + // Package uses a path + pkgName := r.getPackageNameFromPath(pkg.Path) + if pkgName == "" { + logger.Info("skipping package with invalid path", "name", pkg.Name, "path", pkg.Path) + continue + } + // Artifact name format: {bundle-name}-{package-name} + artifactName = fmt.Sprintf("%s-%s", bundle.Name, pkgName) + } else { + logger.Error(fmt.Errorf("neither artifact nor path specified"), "skipping package", "name", pkg.Name) + continue + } + + // Build labels: merge bundle labels, package labels, and default cozystack.io/bundle label + hrLabels := make(map[string]string) + // First, add bundle-level labels + if bundle.Spec.Labels != nil { + for k, v := range bundle.Spec.Labels { + hrLabels[k] = v + } + } + // Then, add package-level labels (they override bundle labels) + if pkg.Labels != nil { + for k, v := range pkg.Labels { + hrLabels[k] = v + } + } + // Finally, add default bundle label (it always takes precedence) + hrLabels["cozystack.io/bundle"] = bundle.Name + + // Add system-app label if namespace starts with "cozy-" + if pkg.Namespace == "kube-system" || strings.HasPrefix(pkg.Namespace, "cozy-") { + hrLabels["cozystack.io/system-app"] = "true" + } + + // Create HelmRelease + hr := &helmv2.HelmRelease{ + ObjectMeta: metav1.ObjectMeta{ + Name: pkg.Name, + Namespace: pkg.Namespace, + Labels: hrLabels, + }, + Spec: helmv2.HelmReleaseSpec{ + Interval: metav1.Duration{Duration: 5 * 60 * 1000000000}, // 5m + ReleaseName: pkg.ReleaseName, + ChartRef: &helmv2.CrossNamespaceSourceReference{ + Kind: "ExternalArtifact", + Name: artifactName, + Namespace: artifactNamespace, + }, + Install: &helmv2.Install{ + Remediation: &helmv2.InstallRemediation{ + Retries: -1, + }, + }, + Upgrade: &helmv2.Upgrade{ + Remediation: &helmv2.UpgradeRemediation{ + Retries: -1, + }, + }, + }, + } + + // Set ownerReference only if deletionPolicy is not Orphan + if bundle.Spec.DeletionPolicy != cozyv1alpha1.DeletionPolicyOrphan { + hr.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: bundle.APIVersion, + Kind: bundle.Kind, + Name: bundle.Name, + UID: bundle.UID, + Controller: func() *bool { b := true; return &b }(), + }, + } + } else { + // Explicitly set empty ownerReferences for Orphan policy + hr.OwnerReferences = []metav1.OwnerReference{} + } + + // Set values if provided + if pkg.Values != nil { + hr.Spec.Values = pkg.Values + } + + // Add system-app label if TargetNamespace starts with "cozy-" + if hr.Spec.TargetNamespace != "" && (hr.Spec.TargetNamespace == "kube-system" || strings.HasPrefix(hr.Spec.TargetNamespace, "cozy-")) { + hr.Labels["cozystack.io/system-app"] = "true" + } + + // Set DependsOn + if len(pkg.DependsOn) > 0 { + dependsOn := make([]helmv2.DependencyReference, 0, len(pkg.DependsOn)) + for _, depName := range pkg.DependsOn { + depPkg, ok := globalPackageMap[depName] + if !ok { + logger.Info("dependent package not found in any bundle, using same namespace", "name", pkg.Name, "dependsOn", depName) + dependsOn = append(dependsOn, helmv2.DependencyReference{ + Name: depName, + Namespace: pkg.Namespace, + }) + } else { + dependsOn = append(dependsOn, helmv2.DependencyReference{ + Name: depPkg.Name, + Namespace: depPkg.Namespace, + }) + } + } + hr.Spec.DependsOn = dependsOn + } + + // Set valuesFiles annotation + if len(pkg.ValuesFiles) > 0 { + if hr.Annotations == nil { + hr.Annotations = make(map[string]string) + } + hr.Annotations["cozypkg.cozystack.io/values-files"] = strings.Join(pkg.ValuesFiles, ",") + } + + if err := r.createOrUpdate(ctx, hr); err != nil { + return fmt.Errorf("failed to reconcile HelmRelease %s: %w", pkg.Name, err) + } + logger.Info("reconciled HelmRelease", "name", pkg.Name, "namespace", pkg.Namespace) + } + + // Cleanup orphaned HelmReleases + return r.cleanupOrphanedHelmReleases(ctx, bundle) +} + +// createOrUpdate creates or updates a resource +func (r *BundleReconciler) createOrUpdate(ctx context.Context, obj client.Object) error { + existing := obj.DeepCopyObject().(client.Object) + key := client.ObjectKeyFromObject(obj) + + err := r.Get(ctx, key, existing) + if apierrors.IsNotFound(err) { + return r.Create(ctx, obj) + } else if err != nil { + return err + } + + // Preserve resource version + obj.SetResourceVersion(existing.GetResourceVersion()) + // Merge labels and annotations + labels := obj.GetLabels() + if labels == nil { + labels = make(map[string]string) + } + for k, v := range existing.GetLabels() { + if _, ok := labels[k]; !ok { + labels[k] = v + } + } + obj.SetLabels(labels) + + annotations := obj.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + for k, v := range existing.GetAnnotations() { + if _, ok := annotations[k]; !ok { + annotations[k] = v + } + } + obj.SetAnnotations(annotations) + + // Update ownerReferences: always use the ones from obj + // This allows deletionPolicy = Orphan to work by setting empty ownerReferences array + // When ownerReferences field is set in obj (even as empty array), use it + // Empty array will clear ownerReferences (for deletionPolicy = Orphan or when policy changes) + // If ownerReferences field is not set in obj (nil), preserve existing ones + objOwnerRefs := obj.GetOwnerReferences() + if objOwnerRefs != nil { + // obj has ownerReferences set (either populated or empty array), use them + // Empty array (len == 0) means we want to remove all ownerReferences (deletionPolicy = Orphan) + // This handles policy changes from Delete to Orphan + // objOwnerRefs is already set in obj, so it will be used in Update + // No need to do anything else - Update will use the ownerReferences from obj + } else if len(existing.GetOwnerReferences()) > 0 { + // obj doesn't have ownerReferences set (nil), but existing does + // Preserve existing ones (they might be from other owners) + obj.SetOwnerReferences(existing.GetOwnerReferences()) + } + + // For ArtifactGenerator, explicitly update Spec (OutputArtifacts and Sources) + // This ensures that OutputArtifacts from both packages and artifacts are properly updated + if ag, ok := obj.(*sourcewatcherv1beta1.ArtifactGenerator); ok { + if existingAG, ok := existing.(*sourcewatcherv1beta1.ArtifactGenerator); ok { + logger := log.FromContext(ctx) + logger.V(1).Info("updating ArtifactGenerator Spec", "name", ag.Name, "namespace", ag.Namespace, + "outputArtifactCount", len(ag.Spec.OutputArtifacts)) + // Update Spec from obj (which contains the desired state with all OutputArtifacts) + existingAG.Spec = ag.Spec + // Preserve metadata updates we made above + existingAG.SetLabels(ag.GetLabels()) + existingAG.SetAnnotations(ag.GetAnnotations()) + existingAG.SetOwnerReferences(ag.GetOwnerReferences()) + // Use existingAG for Update + obj = existingAG + } + } + + // For HelmRelease, explicitly update Spec to ensure values and dependsOn are properly updated + if hr, ok := obj.(*helmv2.HelmRelease); ok { + if existingHR, ok := existing.(*helmv2.HelmRelease); ok { + logger := log.FromContext(ctx) + logger.V(1).Info("updating HelmRelease Spec", "name", hr.Name, "namespace", hr.Namespace) + + // Check if this HelmRelease is managed through Application API or Controller + // If it has apps.cozystack.io/application.* labels OR cozystack.io/ui=true label, merge values with bundle priority + isApplicationManaged := existingHR.Labels["apps.cozystack.io/application.kind"] != "" && + existingHR.Labels["apps.cozystack.io/application.group"] != "" + isControllerManaged := existingHR.Labels["cozystack.io/ui"] == "true" + + if isApplicationManaged || isControllerManaged { + // For Application/Controller-managed HelmReleases, merge values with bundle priority + logger.V(1).Info("merging values for Application/Controller-managed HelmRelease with bundle priority", "name", hr.Name, "namespace", hr.Namespace, "isApplicationManaged", isApplicationManaged, "isControllerManaged", isControllerManaged) + existingHR.Spec.Chart = hr.Spec.Chart + existingHR.Spec.ChartRef = hr.Spec.ChartRef + existingHR.Spec.Interval = hr.Spec.Interval + existingHR.Spec.Timeout = hr.Spec.Timeout + existingHR.Spec.ReleaseName = hr.Spec.ReleaseName + existingHR.Spec.DependsOn = hr.Spec.DependsOn + existingHR.Spec.Install = hr.Spec.Install + existingHR.Spec.Upgrade = hr.Spec.Upgrade + existingHR.Spec.Uninstall = hr.Spec.Uninstall + existingHR.Spec.Rollback = hr.Spec.Rollback + existingHR.Spec.StorageNamespace = hr.Spec.StorageNamespace + existingHR.Spec.KubeConfig = hr.Spec.KubeConfig + existingHR.Spec.TargetNamespace = hr.Spec.TargetNamespace + existingHR.Spec.PostRenderers = hr.Spec.PostRenderers + existingHR.Spec.ServiceAccountName = hr.Spec.ServiceAccountName + existingHR.Spec.Suspend = hr.Spec.Suspend + + // Merge values: bundle values have priority (override existing) + mergedValues, err := mergeHelmReleaseValuesWithBundlePriority(existingHR.Spec.Values, hr.Spec.Values) + if err != nil { + logger.Error(err, "failed to merge values, using bundle values", "name", hr.Name, "namespace", hr.Namespace) + existingHR.Spec.Values = hr.Spec.Values + } else { + existingHR.Spec.Values = mergedValues + } + } else { + // For bundle-managed HelmReleases, update everything including values + existingHR.Spec = hr.Spec + } + + // Preserve metadata updates we made above + existingHR.SetLabels(hr.GetLabels()) + existingHR.SetAnnotations(hr.GetAnnotations()) + existingHR.SetOwnerReferences(hr.GetOwnerReferences()) + // Use existingHR for Update + obj = existingHR + } + } + + return r.Update(ctx, obj) +} + +// mergeHelmReleaseValues merges two HelmRelease values JSON objects +// Existing values have priority (bundle values are merged into existing) +func mergeHelmReleaseValues(existingValues, bundleValues *apiextensionsv1.JSON) (*apiextensionsv1.JSON, error) { + // If bundle has no values, preserve existing + if bundleValues == nil || len(bundleValues.Raw) == 0 { + return existingValues, nil + } + + // If existing has no values, use bundle values + if existingValues == nil || len(existingValues.Raw) == 0 { + return bundleValues, nil + } + + // Parse both values + var existingMap map[string]interface{} + if err := json.Unmarshal(existingValues.Raw, &existingMap); err != nil { + return nil, fmt.Errorf("failed to unmarshal existing values: %w", err) + } + + var bundleMap map[string]interface{} + if err := json.Unmarshal(bundleValues.Raw, &bundleMap); err != nil { + return nil, fmt.Errorf("failed to unmarshal bundle values: %w", err) + } + + // Merge: existing values have priority (bundle is merged into existing) + mergedMap := deepMergeMaps(bundleMap, existingMap) + + // Marshal back to JSON + mergedJSON, err := json.Marshal(mergedMap) + if err != nil { + return nil, fmt.Errorf("failed to marshal merged values: %w", err) + } + + return &apiextensionsv1.JSON{Raw: mergedJSON}, nil +} + +// mergeHelmReleaseValuesWithBundlePriority merges two HelmRelease values JSON objects +// Bundle values have priority (override existing values) +// All fields from bundle override existing, except nested merges for maps +func mergeHelmReleaseValuesWithBundlePriority(existingValues, bundleValues *apiextensionsv1.JSON) (*apiextensionsv1.JSON, error) { + // If bundle has no values, preserve existing + if bundleValues == nil || len(bundleValues.Raw) == 0 { + return existingValues, nil + } + + // If existing has no values, use bundle values + if existingValues == nil || len(existingValues.Raw) == 0 { + return bundleValues, nil + } + + // Parse both values + var existingMap map[string]interface{} + if err := json.Unmarshal(existingValues.Raw, &existingMap); err != nil { + return nil, fmt.Errorf("failed to unmarshal existing values: %w", err) + } + + var bundleMap map[string]interface{} + if err := json.Unmarshal(bundleValues.Raw, &bundleMap); err != nil { + return nil, fmt.Errorf("failed to unmarshal bundle values: %w", err) + } + + // Merge: start with existing values, then bundle values override (bundle has priority) + mergedMap := deepMergeMaps(existingMap, bundleMap) + + // Marshal back to JSON + mergedJSON, err := json.Marshal(mergedMap) + if err != nil { + return nil, fmt.Errorf("failed to marshal merged values: %w", err) + } + + return &apiextensionsv1.JSON{Raw: mergedJSON}, nil +} + +// deepMergeMaps performs a deep merge of two maps +// Values from override map take precedence, but nested maps are merged recursively +func deepMergeMaps(base, override map[string]interface{}) map[string]interface{} { + result := make(map[string]interface{}) + + // Copy base map + for k, v := range base { + result[k] = v + } + + // Merge override map + for k, v := range override { + if baseVal, exists := result[k]; exists { + // If both are maps, recursively merge + if baseMap, ok := baseVal.(map[string]interface{}); ok { + if overrideMap, ok := v.(map[string]interface{}); ok { + result[k] = deepMergeMaps(baseMap, overrideMap) + continue + } + } + } + // Override takes precedence for non-map values or new keys + result[k] = v + } + + return result +} + +// Helper functions +func (r *BundleReconciler) getPackageNameFromPath(path string) string { + parts := strings.Split(path, "/") + if len(parts) > 0 { + return parts[len(parts)-1] + } + return "" +} + +// getBasePath returns the basePath with default values based on source kind +func (r *BundleReconciler) getBasePath(bundle *cozyv1alpha1.Bundle) string { + // If basePath is explicitly set, use it + if bundle.Spec.BasePath != "" { + return bundle.Spec.BasePath + } + // Default values based on kind + if bundle.Spec.SourceRef.Kind == "OCIRepository" { + return "" // Root for OCI + } + // Default for GitRepository + return "packages" +} + +// buildSourcePath builds the full source path using basePath with glob pattern +func (r *BundleReconciler) buildSourcePath(sourceName, basePath, path string) string { + // Remove leading/trailing slashes and combine + parts := []string{} + if basePath != "" { + parts = append(parts, strings.Trim(basePath, "/")) + } + if path != "" { + parts = append(parts, strings.Trim(path, "/")) + } + + fullPath := strings.Join(parts, "/") + if fullPath == "" { + return fmt.Sprintf("@%s/**", sourceName) + } + return fmt.Sprintf("@%s/%s/**", sourceName, fullPath) +} + +// buildSourceFilePath builds the full source path for a specific file (without glob pattern) +func (r *BundleReconciler) buildSourceFilePath(sourceName, basePath, path string) string { + // Remove leading/trailing slashes and combine + parts := []string{} + if basePath != "" { + parts = append(parts, strings.Trim(basePath, "/")) + } + if path != "" { + parts = append(parts, strings.Trim(path, "/")) + } + + fullPath := strings.Join(parts, "/") + if fullPath == "" { + return fmt.Sprintf("@%s", sourceName) + } + return fmt.Sprintf("@%s/%s", sourceName, fullPath) +} + +func (r *BundleReconciler) cleanupOrphanedArtifactGenerators(ctx context.Context, bundle *cozyv1alpha1.Bundle) error { + logger := log.FromContext(ctx) + + // Find ArtifactGenerators by label + agList := &sourcewatcherv1beta1.ArtifactGeneratorList{} + if err := r.List(ctx, agList, client.MatchingLabels{ + "cozystack.io/bundle": bundle.Name, + }); err != nil { + if apierrors.IsNotFound(err) { + return nil + } + return err + } + + // Desired name: bundle name (one ArtifactGenerator per bundle) + desiredName := bundle.Name + + // Find ArtifactGenerators with this bundle label + for _, ag := range agList.Items { + // Check if it's the desired name + isDesired := ag.Name == desiredName + + if !isDesired { + // Delete ArtifactGenerators that don't match the desired name + // This includes old pattern ArtifactGenerators (for migration from per-package/per-artifact to per-bundle) + logger.Info("deleting orphaned ArtifactGenerator", "name", ag.Name, "bundle", bundle.Name, "desiredName", desiredName) + if err := r.Delete(ctx, &ag); err != nil { + if !apierrors.IsNotFound(err) { + logger.Error(err, "failed to delete orphaned ArtifactGenerator", "name", ag.Name) + } + } else { + logger.Info("deleted orphaned ArtifactGenerator", "name", ag.Name) + } + } + } + + return nil +} + +func (r *BundleReconciler) cleanupOrphanedHelmReleases(ctx context.Context, bundle *cozyv1alpha1.Bundle) error { + logger := log.FromContext(ctx) + + // Find HelmReleases by label + hrList := &helmv2.HelmReleaseList{} + if err := r.List(ctx, hrList, client.MatchingLabels{ + "cozystack.io/bundle": bundle.Name, + }); err != nil { + return err + } + + // Build desired names (excluding disabled packages) + desiredNames := make(map[types.NamespacedName]bool) + for _, pkg := range bundle.Spec.Packages { + // Only include non-disabled packages in desired names + if !pkg.Disabled { + desiredNames[types.NamespacedName{Name: pkg.Name, Namespace: pkg.Namespace}] = true + } + } + + // Find HelmReleases with this bundle label + for _, hr := range hrList.Items { + key := types.NamespacedName{Name: hr.Name, Namespace: hr.Namespace} + if !desiredNames[key] { + logger.Info("deleting orphaned HelmRelease", "name", hr.Name, "namespace", hr.Namespace, "bundle", bundle.Name) + if err := r.Delete(ctx, &hr); err != nil { + if !apierrors.IsNotFound(err) { + logger.Error(err, "failed to delete HelmRelease", "name", hr.Name, "namespace", hr.Namespace) + } + } else { + logger.Info("deleted orphaned HelmRelease", "name", hr.Name, "namespace", hr.Namespace) + } + } + } + + return nil +} + +func (r *BundleReconciler) cleanupOrphanedResources(ctx context.Context, bundleKey types.NamespacedName) (ctrl.Result, error) { + logger := log.FromContext(ctx) + + // Cleanup ArtifactGenerators by label + // Only delete if they have ownerReferences to this bundle (deletionPolicy != Orphan) + agList := &sourcewatcherv1beta1.ArtifactGeneratorList{} + if err := r.List(ctx, agList, client.MatchingLabels{ + "cozystack.io/bundle": bundleKey.Name, + }); err == nil { + for _, ag := range agList.Items { + // Check if this resource has ownerReference to the deleted bundle + hasOwnerRef := false + for _, ownerRef := range ag.OwnerReferences { + if ownerRef.Kind == "Bundle" && ownerRef.Name == bundleKey.Name { + hasOwnerRef = true + break + } + } + + // Only delete if it has ownerReference (deletionPolicy != Orphan) + // If no ownerReference, it means deletionPolicy was Orphan, so we should not delete it + if hasOwnerRef { + logger.Info("deleting orphaned ArtifactGenerator", "name", ag.Name, "bundle", bundleKey.Name) + if err := r.Delete(ctx, &ag); err != nil && !apierrors.IsNotFound(err) { + logger.Error(err, "failed to delete orphaned ArtifactGenerator", "name", ag.Name) + } + } else { + logger.Info("skipping ArtifactGenerator deletion (deletionPolicy=Orphan)", "name", ag.Name, "bundle", bundleKey.Name) + } + } + } + + // Cleanup HelmReleases by label + // Only delete if they have ownerReferences to this bundle (deletionPolicy != Orphan) + hrList := &helmv2.HelmReleaseList{} + if err := r.List(ctx, hrList, client.MatchingLabels{ + "cozystack.io/bundle": bundleKey.Name, + }); err == nil { + for _, hr := range hrList.Items { + // Check if this resource has ownerReference to the deleted bundle + hasOwnerRef := false + for _, ownerRef := range hr.OwnerReferences { + if ownerRef.Kind == "Bundle" && ownerRef.Name == bundleKey.Name { + hasOwnerRef = true + break + } + } + + // Only delete if it has ownerReference (deletionPolicy != Orphan) + // If no ownerReference, it means deletionPolicy was Orphan, so we should not delete it + if hasOwnerRef { + logger.Info("deleting orphaned HelmRelease", "name", hr.Name, "namespace", hr.Namespace, "bundle", bundleKey.Name) + if err := r.Delete(ctx, &hr); err != nil && !apierrors.IsNotFound(err) { + logger.Error(err, "failed to delete orphaned HelmRelease", "name", hr.Name, "namespace", hr.Namespace) + } + } else { + logger.Info("skipping HelmRelease deletion (deletionPolicy=Orphan)", "name", hr.Name, "namespace", hr.Namespace, "bundle", bundleKey.Name) + } + } + } + + return ctrl.Result{}, nil +} + +// reconcileNamespaces creates or updates namespaces based on packages in the bundle. +func (r *BundleReconciler) reconcileNamespaces(ctx context.Context, bundle *cozyv1alpha1.Bundle, packages []cozyv1alpha1.BundleRelease) error { + logger := log.FromContext(ctx) + + // Collect namespaces from packages + // Map: namespace -> {isPrivileged, labels, annotations} + type namespaceInfo struct { + privileged bool + labels map[string]string + annotations map[string]string + } + namespacesMap := make(map[string]namespaceInfo) + + for _, pkg := range packages { + // Skip disabled packages + if pkg.Disabled { + continue + } + + // Skip if namespace is empty + if pkg.Namespace == "" { + continue + } + + info, exists := namespacesMap[pkg.Namespace] + if !exists { + info = namespaceInfo{ + privileged: false, + labels: make(map[string]string), + annotations: make(map[string]string), + } + } + + // If package is privileged, mark namespace as privileged + if pkg.Privileged { + info.privileged = true + } + + // Merge namespace labels from package + if pkg.NamespaceLabels != nil { + for k, v := range pkg.NamespaceLabels { + info.labels[k] = v + } + } + + // Merge namespace annotations from package + if pkg.NamespaceAnnotations != nil { + for k, v := range pkg.NamespaceAnnotations { + info.annotations[k] = v + } + } + + namespacesMap[pkg.Namespace] = info + } + + // Create or update all namespaces + for nsName, info := range namespacesMap { + namespace := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: nsName, + Labels: make(map[string]string), + Annotations: map[string]string{ + "helm.sh/resource-policy": "keep", + }, + }, + } + + // Add system label only for non-tenant namespaces + if !strings.HasPrefix(nsName, "tenant-") { + namespace.Labels["cozystack.io/system"] = "true" + } + + // Add privileged label if needed + if info.privileged { + namespace.Labels["pod-security.kubernetes.io/enforce"] = "privileged" + } + + // Merge namespace labels from packages + for k, v := range info.labels { + namespace.Labels[k] = v + } + + // Merge namespace annotations from packages + for k, v := range info.annotations { + namespace.Annotations[k] = v + } + + if err := r.createOrUpdateNamespace(ctx, namespace); err != nil { + logger.Error(err, "failed to reconcile namespace", "name", nsName, "privileged", info.privileged) + return fmt.Errorf("failed to reconcile namespace %s: %w", nsName, err) + } + logger.Info("reconciled namespace", "name", nsName, "privileged", info.privileged, "labels", info.labels, "annotations", info.annotations) + } + + return nil +} + +// createOrUpdateNamespace creates or updates a namespace. +func (r *BundleReconciler) createOrUpdateNamespace(ctx context.Context, namespace *corev1.Namespace) error { + existing := &corev1.Namespace{} + key := types.NamespacedName{Name: namespace.Name} + + err := r.Get(ctx, key, existing) + if apierrors.IsNotFound(err) { + return r.Create(ctx, namespace) + } else if err != nil { + return err + } + + // Preserve resource version + namespace.SetResourceVersion(existing.GetResourceVersion()) + + // Merge labels + labels := namespace.GetLabels() + if labels == nil { + labels = make(map[string]string) + } + for k, v := range existing.GetLabels() { + if _, ok := labels[k]; !ok { + labels[k] = v + } + } + namespace.SetLabels(labels) + + // Merge annotations + annotations := namespace.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + for k, v := range existing.GetAnnotations() { + if _, ok := annotations[k]; !ok { + annotations[k] = v + } + } + namespace.SetAnnotations(annotations) + + return r.Update(ctx, namespace) +} + +// checkArtifactConflicts checks for conflicts between packages using artifacts and bundle artifacts +func (r *BundleReconciler) checkArtifactConflicts(ctx context.Context, bundle *cozyv1alpha1.Bundle, packages []cozyv1alpha1.BundleRelease) error { + // Build artifact name map from bundle artifacts + artifactNameMap := make(map[string]bool) + for _, artifact := range bundle.Spec.Artifacts { + artifactNameMap[artifact.Name] = true + } + + // Check packages that use artifacts + for _, pkg := range packages { + if pkg.Artifact != "" { + if !artifactNameMap[pkg.Artifact] { + return fmt.Errorf("package %s references artifact %s which is not defined in bundle artifacts", pkg.Name, pkg.Artifact) + } + } + } + + return nil +} + +// removeOwnerReferences removes ownerReferences from all resources with bundle label +func (r *BundleReconciler) removeOwnerReferences(ctx context.Context, bundle *cozyv1alpha1.Bundle) error { + logger := log.FromContext(ctx) + + // Remove ownerReferences from ArtifactGenerators by label + agList := &sourcewatcherv1beta1.ArtifactGeneratorList{} + if err := r.List(ctx, agList, client.MatchingLabels{ + "cozystack.io/bundle": bundle.Name, + }); err == nil { + for i := range agList.Items { + ag := &agList.Items[i] + updated := false + newOwnerRefs := []metav1.OwnerReference{} + + for _, ownerRef := range ag.OwnerReferences { + if ownerRef.Kind == "Bundle" && ownerRef.Name == bundle.Name { + // Skip this ownerReference (remove it) + // Check by name only, not UID, to handle bundle updates + updated = true + } else { + // Keep other ownerReferences + newOwnerRefs = append(newOwnerRefs, ownerRef) + } + } + + if updated { + ag.SetOwnerReferences(newOwnerRefs) + if err := r.Update(ctx, ag); err != nil { + logger.Error(err, "failed to remove ownerReference from ArtifactGenerator", "name", ag.Name, "namespace", ag.Namespace) + } else { + logger.Info("removed ownerReference from ArtifactGenerator", "name", ag.Name, "namespace", ag.Namespace) + } + } + } + } + + // Remove ownerReferences from HelmReleases by label + hrList := &helmv2.HelmReleaseList{} + if err := r.List(ctx, hrList, client.MatchingLabels{ + "cozystack.io/bundle": bundle.Name, + }); err == nil { + for i := range hrList.Items { + hr := &hrList.Items[i] + updated := false + newOwnerRefs := []metav1.OwnerReference{} + + for _, ownerRef := range hr.OwnerReferences { + if ownerRef.Kind == "Bundle" && ownerRef.Name == bundle.Name { + // Skip this ownerReference (remove it) + // Check by name only, not UID, to handle bundle updates + updated = true + } else { + // Keep other ownerReferences + newOwnerRefs = append(newOwnerRefs, ownerRef) + } + } + + if updated { + hr.SetOwnerReferences(newOwnerRefs) + if err := r.Update(ctx, hr); err != nil { + logger.Error(err, "failed to remove ownerReference from HelmRelease", "name", hr.Name, "namespace", hr.Namespace) + } else { + logger.Info("removed ownerReference from HelmRelease", "name", hr.Name, "namespace", hr.Namespace) + } + } + } + } + + return nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *BundleReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + Named("cozystack-bundle"). + For(&cozyv1alpha1.Bundle{}). + Watches( + &helmv2.HelmRelease{}, + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { + hr, ok := obj.(*helmv2.HelmRelease) + if !ok { + return nil + } + // Find the bundle that owns this HelmRelease by label + bundleName := hr.Labels["cozystack.io/bundle"] + if bundleName == "" { + return nil + } + // Reconcile the bundle to recreate the HelmRelease if it was deleted + return []reconcile.Request{{ + NamespacedName: types.NamespacedName{ + Name: bundleName, + }, + }} + }), + ). + Complete(r) +} diff --git a/packages/core/installer/templates/cozystack-operator.yaml b/packages/core/installer/templates/cozystack-operator.yaml index c4f652fc..19153827 100644 --- a/packages/core/installer/templates/cozystack-operator.yaml +++ b/packages/core/installer/templates/cozystack-operator.yaml @@ -93,3 +93,21 @@ spec: releaseName: cozystack-platform name: cozystack-platform path: core/platform + - name: paas-full + components: + - install: + namespace: cozy-system + releaseName: cozystack-platform + name: cozystack-platform + path: core/platform + valuesFiles: + - paas-full.yaml + - name: paas-hosted + components: + - install: + namespace: cozy-system + releaseName: cozystack-platform + name: cozystack-platform + path: core/platform + valuesFiles: + - paas-hosted.yaml diff --git a/packages/core/platform/psds/bootbox-application.yaml b/packages/core/platform/psds/bootbox-application.yaml index b7b3b0dc..8f8e8ae9 100644 --- a/packages/core/platform/psds/bootbox-application.yaml +++ b/packages/core/platform/psds/bootbox-application.yaml @@ -22,42 +22,11 @@ spec: install: releaseName: bootbox-application namespace: cozy-system - applications: - name: bootbox path: apps/bootbox - libraries: - - cozy-lib - template: - spec: - application: - kind: BootBox - plural: bootboxes - singular: bootbox - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"machines":{"description":"Configuration of physical machine instances.","type":"array","default":[],"items":{"type":"object","required":["arch","hostname","ip","leaseTime","uefi"],"properties":{"arch":{"description":"Architecture.","type":"string"},"hostname":{"description":"Hostname.","type":"string"},"ip":{"description":"IP address configuration.","type":"object","required":["address","gateway","netmask"],"properties":{"address":{"description":"IP address.","type":"string"},"gateway":{"description":"IP gateway.","type":"string"},"netmask":{"description":"Netmask.","type":"string"}}},"leaseTime":{"description":"Lease time.","type":"integer"},"mac":{"description":"MAC addresses.","type":"array","items":{"type":"string"}},"nameServers":{"description":"Name servers.","type":"array","items":{"type":"string"}},"timeServers":{"description":"Time servers.","type":"array","items":{"type":"string"}},"uefi":{"description":"UEFI.","type":"boolean"}}}},"whitelist":{"description":"List of client networks.","type":"array","default":[],"items":{"type":"string"}},"whitelistHTTP":{"description":"Secure HTTP by enabling client networks whitelisting.","type":"boolean","default":true}}} - release: - prefix: "" - labels: - cozystack.io/ui: "true" - dashboard: - category: Administration - singular: BootBox - plural: BootBox - name: bootbox - description: PXE hardware provisioning - module: true - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNzEuNTY5OCA3Ni41MzM2QzcxLjIzNzQgNzYuNTMzNiA3MC45MDM2IDc2LjQ4NDcgNzAuNTgyOSA3Ni4zODkyTDM2LjIwNzkgNjYuMDc2N0MzNC4zODg1IDY1LjUzMTEgMzMuMzU2MiA2My42MTQ0IDMzLjkwMTcgNjEuNzk2NkMzNC40NDg5IDU5Ljk3NTUgMzYuMzY1NyA1OC45NDgzIDM4LjE4MTcgNTkuNDkwNEw3MS41Njk4IDY5LjUwNzZMMTA0Ljk1OCA1OS40OTA0QzEwNi43NzYgNTguOTYgMTA4LjY5MSA1OS45NzcyIDEwOS4yMzggNjEuNzk2NkMxMDkuNzgzIDYzLjYxNDQgMTA4Ljc1MSA2NS41MzExIDEwNi45MzIgNjYuMDc2N0w3Mi41NTY3IDc2LjM4OTJDNzIuMjM2IDc2LjQ4NDcgNzEuOTAyMiA3Ni41MzM2IDcxLjU2OTggNzYuNTMzNloiIGZpbGw9IiMyMzFGMjAiLz4KPHBhdGggZD0iTTc0Ljk3MyA1My4wMjE0Qzc0Ljc2NjggNTQuMzI3NiA3My44MDQzIDU1LjM5MzMgNzIuNTY2OCA1NS43NzE0TDM4LjE5MTggNjYuMDgzOUMzNy44NDggNjYuMTg3IDM3LjUzODcgNjYuMjIxNCAzNy4xOTQ5IDY2LjIyMTRDMzYuMzY5OSA2Ni4yMjE0IDM1LjU3OTMgNjUuOTEyIDM0LjkyNjIgNjUuMzYyTDIxLjE3NjIgNTMuMzMwOEMyMC4yNDggNTIuNTQwMSAxOS44MzU1IDUxLjI2ODMgMjAuMDc2MiA1MC4wNjUxQzIwLjMxNjggNDguODYyIDIxLjE3NjIgNDcuODY1MSAyMi4zNDQ5IDQ3LjQ4N0w1My4yODI0IDM3LjE3NDVDNTQuMzEzNyAzNi44MzA4IDU1LjQ0OCAzNy4wMDI2IDU2LjM0MTggMzcuNjIxNEw3My41MjkzIDQ5LjY1MjZDNzQuNjI5MyA1MC40MDg5IDc1LjE3OTMgNTEuNzE1MSA3NC45NzMgNTMuMDIxNFoiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEyMS45NjQgNTMuMzMwOEwxMDguMjE0IDY1LjM2MkMxMDcuNTYgNjUuOTEyIDEwNi43NyA2Ni4yMjE0IDEwNS45NDUgNjYuMjIxNEMxMDUuNjAxIDY2LjIyMTQgMTA1LjI5MiA2Ni4xODcgMTA0Ljk0OCA2Ni4wODM5TDcwLjU3MyA1NS43NzE0QzY5LjMzNTUgNTUuMzkzMyA2OC4zNzMgNTQuMzI3NiA2OC4xNjY3IDUzLjAyMTRDNjcuOTYwNSA1MS43MTUxIDY4LjUxMDUgNTAuNDA4OSA2OS42MTA1IDQ5LjY1MjZMODYuNzk4IDM3LjYyMTRDODcuNjkxNyAzNy4wMDI2IDg4LjgyNjEgMzYuODMwOCA4OS44NTc0IDM3LjE3NDVMMTIwLjc5NSA0Ny40ODdDMTIxLjk2NCA0Ny44NjUxIDEyMi44MjMgNDguODYyIDEyMy4wNjQgNTAuMDY1MUMxMjMuMzA0IDUxLjI2ODMgMTIyLjg5MiA1Mi41NDAxIDEyMS45NjQgNTMuMzMwOFoiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEwOS4zODIgNjMuNjQyNlYxMDcuNDcxQzEwOS4zODIgMTA4Ljg4IDEwOC41MjIgMTEwLjE1MiAxMDcuMjE2IDExMC42NjhMNzIuODQxMiAxMjQuNDE4QzcyLjQyODcgMTI0LjU4OSA3Mi4wMTYyIDEyNC42NTggNzEuNTY5MyAxMjQuNjU4QzcxLjEyMjUgMTI0LjY1OCA3MC43MSAxMjQuNTg5IDcwLjI5NzUgMTI0LjQxOEwzNS45MjI1IDExMC42NjhDMzQuNjE2MiAxMTAuMTUyIDMzLjc1NjggMTA4Ljg4IDMzLjc1NjggMTA3LjQ3MVY2My42NDI2QzMzLjc1NjggNjEuNzUyIDM1LjMwMzcgNjAuMjA1MSAzNy4xOTQzIDYwLjIwNTFIMTA1Ljk0NEMxMDcuODM1IDYwLjIwNTEgMTA5LjM4MiA2MS43NTIgMTA5LjM4MiA2My42NDI2WiIgZmlsbD0iI0VBQkQ0QyIvPgo8cGF0aCBkPSJNMTA3Ljk5OSA2MS40OTU4QzEwNy45OTkgNjIuOTgxMiAxMDcuMDM3IDY0LjI5NzkgMTA1LjY0MyA2NC43MzY4TDcyLjQ2MTMgNzQuODY1QzcyLjEyOTUgNzQuOTY2MiA3MS44MzA4IDc1IDcxLjQ5OSA3NUM3MS4xNjcyIDc1IDcwLjg2ODYgNzQuOTY2MiA3MC41MzY4IDc0Ljg2NUwzNy4zNTQ5IDY0LjczNjhDMzUuOTYxMyA2NC4yOTc5IDM0Ljk5OSA2Mi45ODEyIDM0Ljk5OSA2MS40OTU4QzM0Ljk5OSA2MC4wMTAzIDM1Ljk2MTMgNTguNjkzNyAzNy4zNTQ5IDU4LjI1NDhMNzAuNTM2OCA0OC4xMjY2QzcxLjE2NzIgNDcuOTU3OCA3MS44MzA4IDQ3Ljk1NzggNzIuNDYxMyA0OC4xMjY2TDEwNS42NDMgNTguMjU0OEMxMDcuMDM3IDU4LjY5MzcgMTA3Ljk5OSA2MC4wMTAzIDEwNy45OTkgNjEuNDk1OFoiIGZpbGw9IiM0QzM4MjUiLz4KPHBhdGggZD0iTTc0LjUxMTggNzdDNzUuMzUgNzcgNzYuMTc5NCA3Ni45NjI4IDc3IDc2LjkxMzNWMjEuMDg2N0M3Ni4xNzY1IDIxLjAzNDcgNzUuMzQ3MSAyMSA3NC41MDU5IDIxQzczLjY2NDcgMjEgNzIuODI5NCAyMS4wMzQ3IDcyIDIxLjA4NjdWNzYuOTEwOEM3Mi44MjY1IDc2Ljk2MjggNzMuNjU4OCA3Ni45OTc1IDc0LjUgNzdINzQuNTExOFoiIGZpbGw9InVybCgjcGFpbnQxX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNDQuMDI4MiAzOC4xMTI5TDQzLjIwNzggMzcuMjk1OUM0Mi4wNzczIDM4LjkxMjEgNDEuMDc0NiA0MC42MTQgNDAuMjA4OCA0Mi4zODYxQzUwLjEwMDEgNTIuNDM1NCA1MS4xNDI0IDU3LjI4MzUgNTEuMTI4OSA1OC45MDc0QzUxLjA5MTkgNjMuMDI2IDQ2LjA1MjIgNjkuNDg0NSA0MC4xNDE2IDc1LjQ2NTdDNDAuOTk5NiA3Ny4yMzc1IDQxLjk5MzMgNzguOTQwNSA0My4xMTM3IDgwLjU1OTJDNDMuNDQ5OSA4MC4yMjMgNDMuNzY5MyA3OS45MTM3IDQ0LjA5NTQgNzkuNTg0MkM1Mi42MjUgNzAuOTk3NSA1Ni43OTQgNjQuMjQ5OCA1Ni44NDQ1IDU4Ljk0NzdDNTYuODk0OSA1My42NDU3IDUyLjcwMjQgNDYuODg3OSA0NC4wMjgyIDM4LjExMjlaIiBmaWxsPSJ1cmwoI3BhaW50Ml9saW5lYXJfOTc5Xzc5MikiLz4KPHBhdGggZD0iTTEwNC42OTUgNzkuNTk3NUwxMDUuNjc2IDgwLjU3MjVDMTA2Ljc5NSA3OC45NDkyIDEwNy43ODcgNzcuMjQxNyAxMDguNjQyIDc1LjQ2NTVDMTAyLjczNSA2OS40NzA5IDk3LjY5NDggNjIuOTk1NSA5Ny42NTQ1IDU4Ljg5MzdDOTcuNjE3NSA1NC44OTI4IDEwMi42MjcgNDguNDIwOCAxMDguNTY4IDQyLjM1OUMxMDcuNzAzIDQwLjU5MTcgMTA2LjcwMyAzOC44OTQ0IDEwNS41NzYgMzcuMjgyMkwxMDQuNzU1IDM4LjA5OTJDOTYuMDgxIDQ2Ljg1NzUgOTEuODg4NSA1My42NzkxIDkxLjkzODkgNTguOTQ0MkM5MS45ODk0IDY0LjIwOTIgOTYuMTU4MyA3MS4wMTA3IDEwNC42OTUgNzkuNTk3NVoiIGZpbGw9InVybCgjcGFpbnQzX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNODcuNDM5NiA1OC45MzQ0Qzg3LjQzOTYgNTEuNTM3OCA5MC43Mzc4IDM5LjIzOTMgOTUuODE3OSAyNy42MTY1Qzk0LjE5NzkgMjYuNTEzOSA5Mi40OTUgMjUuNTM4MiA5MC43MjQ0IDI0LjY5ODJDODUuMTYzNSAzNy4yMjg3IDgxLjcyMDcgNTAuNTU2MSA4MS43MjA3IDU4Ljk0NzhDODEuNzIwNyA2Ny4wNjczIDg1LjQ0OTMgODAuNTQyNSA5MS4xMTEgOTMuMTQwM0M5Mi44NDY4IDkyLjI4NTkgOTQuNTE0NyA5MS4zMDAyIDk2LjEwMDQgOTAuMTkxN0M5MC44NTg5IDc4LjQwMDkgODcuNDM5NiA2Ni4wNzU1IDg3LjQzOTYgNTguOTM0NFoiIGZpbGw9InVybCgjcGFpbnQ0X2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNjcuMDM4NCA1OC45MzUzQzY3LjAzODQgNTAuNDk5OCA2My40NTc4IDM3LjA5ODUgNTcuOTYwOCAyNC43MjI3QzU2LjIxNTggMjUuNTYxMyA1NC41Mzc3IDI2LjUzMjUgNTIuOTQxMiAyNy42Mjc1QzU4LjAzMTQgMzkuMjQzNSA2MS4zMjI4IDUxLjU0NTQgNjEuMzIyOCA1OC45MzUzQzYxLjMyMjggNjYuMDczIDU3LjkwMzYgNzguMzk1IDUyLjY2MjEgOTAuMTcyNEM1NC4yNDgyIDkxLjI4MDIgNTUuOTE2MSA5Mi4yNjU4IDU3LjY1MTQgOTMuMTIxQzYzLjMxOTkgODAuNTI2NiA2Ny4wMzg0IDY3LjA2MTQgNjcuMDM4NCA1OC45MzUzWiIgZmlsbD0idXJsKCNwYWludDVfbGluZWFyXzk3OV83OTIpIi8+CjxwYXRoIGQ9Ik03NC40MjI5IDc0Ljk4N0w2MC42NzI5IDk1LjYxMkM2MC4wMTk3IDk2LjYwODkgNTguOTU0MSA5Ny4xNTg5IDU3LjgxOTcgOTcuMTU4OUM1Ny40MDcyIDk3LjE1ODkgNTYuOTYwNCA5Ny4wOTAxIDU2LjU0NzkgOTYuOTE4M0wyMi4xNzI5IDgzLjE2ODNDMjEuMTQxNiA4Mi43NTU4IDIwLjM4NTQgODEuODk2NCAyMC4xMTA0IDgwLjg2NTFDMTkuODM1NCA3OS43OTk1IDIwLjA3NiA3OC42NjUxIDIwLjc2MzUgNzcuODQwMUwzNC41MTM1IDYwLjY1MjZDMzUuMzcyOSA1OS41NTI2IDMyLjczOTEgNTcuODQwNCAzNC4wNzk3IDU4LjIxODVMNzIuNTY2NiA2OS43OTY0QzczLjU5NzkgNzAuMTA1OCA3NC40MjI5IDcwLjg5NjQgNzQuODAxIDcxLjkyNzZDNzUuMTc5MSA3Mi45NTg5IDc1LjA0MTYgNzQuMDkzMyA3NC40MjI5IDc0Ljk4N1oiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEyMy4wMjkgODAuNjI0MkMxMjIuNzU0IDgxLjY1NTUgMTIxLjk5OCA4Mi41NDkyIDEyMS4wMDEgODIuOTI3NEw4Ni42MjYxIDk2LjkxOEM4Ni4xNzkyIDk3LjA4OTkgODUuNzY2NyA5Ny4xNTg2IDg1LjMxOTkgOTcuMTU4NkM4NC4xODU1IDk3LjE1ODYgODMuMTE5OSA5Ni42MDg2IDgyLjQ2NjcgOTUuNjExN0w2OC43MTY3IDc0Ljk4NjdDNjguMDk4IDc0LjA5MyA2Ny45NjA1IDcyLjk1ODYgNjguMzM4NiA3MS45Mjc0QzY4LjcxNjcgNzAuODk2MSA2OS41NDE3IDcwLjEwNTUgNzAuNTczIDY5Ljc5NjFMMTA4LjQ2OSA1OC40MzMxQzEwOS44MSA1OC4wMjA2IDEwNy43MzIgNTkuNTUyNCAxMDguNjI2IDYwLjYxOEwxMjIuMzc2IDc3LjU5OTJDMTIzLjA2NCA3OC40MjQyIDEyMy4zMDQgNzkuNTU4NiAxMjMuMDI5IDgwLjYyNDJaIiBmaWxsPSIjRkZEQzgzIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfOTc5Xzc5MiIgeDE9IjI0IiB5MT0iMy41IiB4Mj0iMTgxIiB5Mj0iMTQ3IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM0ODAwMDAiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjQUUyMzAwIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQxX2xpbmVhcl85NzlfNzkyIiB4MT0iNzQuNSIgeTE9IjE3LjIzNjkiIHgyPSI3NC41IiB5Mj0iNzkuOTEzMyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDJfbGluZWFyXzk3OV83OTIiIHgxPSI0OC40OTMiIHkxPSIxNS44OTI4IiB4Mj0iNDguNDkzIiB5Mj0iMTAwLjk1NCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDNfbGluZWFyXzk3OV83OTIiIHgxPSIxMDAuMjkiIHkxPSIxNS44OTI2IiB4Mj0iMTAwLjI5IiB5Mj0iMTAwLjk1MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDRfbGluZWFyXzk3OV83OTIiIHgxPSI4OC45MTIyIiB5MT0iMTUuODkyOSIgeDI9Ijg4LjkxMjIiIHkyPSIxMDAuOTU0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkQyMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjA2IiBzdG9wLWNvbG9yPSIjRkZCNTAwIi8+CjxzdG9wIG9mZnNldD0iMC4xNCIgc3RvcC1jb2xvcj0iI0ZGOEMwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMjEiIHN0b3AtY29sb3I9IiNGRjczMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjI2IiBzdG9wLWNvbG9yPSIjRkY2QTAwIi8+CjxzdG9wIG9mZnNldD0iMC4zMyIgc3RvcC1jb2xvcj0iI0ZDNEYwRSIvPgo8c3RvcCBvZmZzZXQ9IjAuNDMiIHN0b3AtY29sb3I9IiNGOTJGMUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUxIiBzdG9wLWNvbG9yPSIjRjgxQjI3Ii8+CjxzdG9wIG9mZnNldD0iMC41NyIgc3RvcC1jb2xvcj0iI0Y3MTQyQiIvPgo8c3RvcCBvZmZzZXQ9IjAuNjgiIHN0b3AtY29sb3I9IiNERjE2MkUiLz4KPHN0b3Agb2Zmc2V0PSIwLjc5IiBzdG9wLWNvbG9yPSIjQUYxQTM4Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzRCMjE0QyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50NV9saW5lYXJfOTc5Xzc5MiIgeDE9IjU5Ljg1NyIgeTE9IjE1Ljg5MzgiIHgyPSI1OS44NTciIHkyPSIxMDAuOTU1IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkQyMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjA2IiBzdG9wLWNvbG9yPSIjRkZCNTAwIi8+CjxzdG9wIG9mZnNldD0iMC4xNCIgc3RvcC1jb2xvcj0iI0ZGOEMwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMjEiIHN0b3AtY29sb3I9IiNGRjczMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjI2IiBzdG9wLWNvbG9yPSIjRkY2QTAwIi8+CjxzdG9wIG9mZnNldD0iMC4zMyIgc3RvcC1jb2xvcj0iI0ZDNEYwRSIvPgo8c3RvcCBvZmZzZXQ9IjAuNDMiIHN0b3AtY29sb3I9IiNGOTJGMUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUxIiBzdG9wLWNvbG9yPSIjRjgxQjI3Ii8+CjxzdG9wIG9mZnNldD0iMC41NyIgc3RvcC1jb2xvcj0iI0Y3MTQyQiIvPgo8c3RvcCBvZmZzZXQ9IjAuNjgiIHN0b3AtY29sb3I9IiNERjE2MkUiLz4KPHN0b3Agb2Zmc2V0PSIwLjc5IiBzdG9wLWNvbG9yPSIjQUYxQTM4Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzRCMjE0QyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "whitelistHTTP"], ["spec", "whitelist"], ["spec", "machines"]] - secrets: - exclude: [] - include: [] - services: - exclude: [] - include: - - resourceNames: - - bootbox - ingresses: - exclude: [] - include: - - resourceNames: - - bootbox + libraries: ["cozy-lib"] + - name: bootbox-rd + path: system/bootbox-rd + install: + namespace: cozy-system + releaseName: bootbox-rd diff --git a/packages/core/platform/psds/bootbox.yaml b/packages/core/platform/psds/bootbox.yaml index 05673c95..a7ce246e 100644 --- a/packages/core/platform/psds/bootbox.yaml +++ b/packages/core/platform/psds/bootbox.yaml @@ -17,7 +17,6 @@ spec: components: - name: bootbox path: system/bootbox - disabled: true install: privileged: true namespace: cozy-bootbox diff --git a/packages/core/platform/psds/bucket-application.yaml b/packages/core/platform/psds/bucket-application.yaml new file mode 100644 index 00000000..a50c116f --- /dev/null +++ b/packages/core/platform/psds/bucket-application.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.bucket-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.objectstorage-controller + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: bucket-system + path: system/bucket + - name: bucket + path: apps/bucket + libraries: ["cozy-lib"] + - name: bucket-rd + path: system/bucket-rd + install: + namespace: cozy-system + releaseName: bucket-rd diff --git a/packages/core/platform/psds/bucket.yaml b/packages/core/platform/psds/bucket.yaml deleted file mode 100644 index 47b66bf8..00000000 --- a/packages/core/platform/psds/bucket.yaml +++ /dev/null @@ -1,62 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.bucket-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.objectstorage-controller - libraries: - - name: cozy-lib - path: library/cozy-lib - components: - - name: bucket-system - path: apps/bucket - libraries: - - cozy-lib - applications: - - name: bucket - path: apps/bucket - libraries: - - cozy-lib - template: - spec: - application: - kind: Bucket - plural: buckets - singular: bucket - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{}} - release: - prefix: bucket- - labels: - cozystack.io/ui: "true" - dashboard: - singular: Bucket - plural: Buckets - category: IaaS - weight: 80 - description: S3 compatible storage - tags: - - storage - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzA5MSkiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03MiAzMC4xNjQxTDExNy45ODMgMzYuNzc4OVY0MC42NzM5QzExNy45ODMgNDYuNDY1MyA5Ny4zODYyIDUxLjEzMzIgNzEuOTgyNyA1MS4xMzMyQzQ2LjU3OTIgNTEuMTMzMiAyNiA0Ni40NjUzIDI2IDQwLjY3MzlWMzYuNDQzMUw3MiAzMC4xNjQxWk03MiA1OC4yNjc4QzkxLjIwODQgNTguMjY3OCAxMDcuNjU4IDU1LjU5ODYgMTE0LjU0NyA1MS44MDQ4TDExNi44MDMgNDguMTExTDExNy43MjMgNDQuNzUzVjQ4LjkxNzFMMTAyLjY3OSAxMTEuMDMzQzEwMi42NzkgMTE0Ljg5NSA4OC45NTMzIDExOCA3Mi4wMTcyIDExOEM1NS4wODEyIDExOCA0MS4zNzQzIDExNC44OTUgNDEuMzc0MyAxMTEuMDMzTDI2LjMzIDQ4LjkxNzFWNDQuODM2OUwyOS44MDA3IDUxLjkzODJDMzYuNzA2NSA1NS42NjUzIDUyLjk5OTcgNTguMjY3OCA3MiA1OC4yNjc4WiIgZmlsbD0iIzhDMzEyMyIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTcyLjAwMDMgMjZDOTcuNDAzOCAyNiAxMTggMzAuNjgzOSAxMTggMzYuNDQyQzExOCA0Mi4yIDk3LjM4NjYgNDYuODUwNyA3Mi4wMDAzIDQ2Ljg1MDdDNDYuNjE0MSA0Ni44NTA3IDI2LjAxNzYgNDIuMjM0NSAyNi4wMTc2IDM2LjQ0MkMyNi4wMTc2IDMwLjY0OTQgNDYuNTk2OCAyNiA3Mi4wMDAzIDI2Wk03Mi4wMDAzIDU0LjEwMzdDOTUuNjg1NyA1NC4xMDM3IDExNS4xNzIgNTAuMDU4IDExNy43MDYgNDQuODE5N0wxMDIuNjYyIDEwNi45MzdDMTAyLjY2MiAxMTAuNzk5IDg4LjkzNjQgMTEzLjkwNSA3Mi4wMDAzIDExMy45MDVDNTUuMDY0MyAxMTMuOTA1IDQxLjMzOSAxMTAuODE2IDQxLjMzOSAxMDYuOTU0TDI2LjI5NTkgNDQuODM3QzI4Ljg0NjYgNTAuMDU4IDQ4LjMzMzMgNTQuMTAzNyA3Mi4wMDAzIDU0LjEwMzdaIiBmaWxsPSIjRTA1MjQzIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNjEuMTcyNSA2MC4wMjkzSDgxLjA5MjhWNzkuMTY3Nkg2MS4xNzI1VjYwLjAyOTNaTTQ1LjMzMDEgOTUuMzY4OEM0NS4zMzAxIDkwLjE0MiA0OS43MTA0IDg1LjkzNDIgNTUuMTUxMSA4NS45MzQyQzYwLjU5MTcgODUuOTM0MiA2NC45NzIxIDkwLjE0MiA2NC45NzIxIDk1LjM2ODhDNjQuOTcyMSAxMDAuNTk2IDYwLjU5MTcgMTA0LjgwMyA1NS4xNTExIDEwNC44MDNDNDkuNzEwNCAxMDQuODAzIDQ1LjMzMDEgMTAwLjU5NiA0NS4zMzAxIDk1LjM2ODhaTTk2LjQ0ODcgMTA0LjM2OEg3Ni43NzIyTDg2LjYxMDUgODYuNzczN0w5Ni40NDg3IDEwNC4zNjhaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18zMDkxIiB4MT0iMCIgeTE9IjAiIHgyPSIxNTEiIHkyPSIxODAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0ZGRjBFRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNFQzg4N0QiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`bucket-{{ .name }}`}}" - - "{{`bucket-{{ .name }}-credentials`}}" - ingresses: - exclude: [] - include: - - resourceNames: - - "{{`bucket-{{ .name }}-ui`}}" diff --git a/packages/core/platform/psds/clickhouse-application.yaml b/packages/core/platform/psds/clickhouse-application.yaml new file mode 100644 index 00000000..f22a003d --- /dev/null +++ b/packages/core/platform/psds/clickhouse-application.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.clickhouse-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.clickhouse-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: clickhouse + path: apps/clickhouse + libraries: ["cozy-lib"] + - name: clickhouse-rd + path: system/clickhouse-rd + install: + namespace: cozy-system + releaseName: clickhouse-rd diff --git a/packages/core/platform/psds/clickhouse.yaml b/packages/core/platform/psds/clickhouse.yaml deleted file mode 100644 index 25a2eb69..00000000 --- a/packages/core/platform/psds/clickhouse.yaml +++ /dev/null @@ -1,54 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.clickhouse-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.clickhouse-operator - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: clickhouse - path: apps/clickhouse - libraries: - - cozy-lib - template: - spec: - application: - kind: ClickHouse - singular: clickhouse - plural: clickhouses - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["cleanupStrategy","enabled","resticPassword","s3AccessKey","s3Bucket","s3Region","s3SecretKey","schedule"],"properties":{"cleanupStrategy":{"description":"Retention strategy for cleaning up old backups.","type":"string","default":"--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"resticPassword":{"description":"Password for Restic backup encryption.","type":"string","default":""},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3Bucket":{"description":"S3 bucket used for storing backups.","type":"string","default":"s3.example.org/clickhouse-backups"},"s3Region":{"description":"AWS S3 region where backups are stored.","type":"string","default":"us-east-1"},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * *"}}},"clickhouseKeeper":{"description":"ClickHouse Keeper configuration.","type":"object","default":{},"properties":{"enabled":{"description":"Deploy ClickHouse Keeper for cluster coordination.","type":"boolean","default":true},"replicas":{"description":"Number of Keeper replicas.","type":"integer","default":3},"resourcesPreset":{"description":"Default sizing preset.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"logStorageSize":{"description":"Size of Persistent Volume for logs.","default":"2Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"logTTL":{"description":"TTL (expiration time) for `query_log` and `query_thread_log`.","type":"integer","default":15},"replicas":{"description":"Number of ClickHouse replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each ClickHouse replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"shards":{"description":"Number of ClickHouse shards.","type":"integer","default":1},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"},"readonly":{"description":"User is readonly (default: false).","type":"boolean"}}}}}} - release: - prefix: clickhouse- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: ClickHouse - plural: ClickHouse - description: Managed ClickHouse service - tags: [] - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzIwMikiLz4KPHBhdGggZD0iTTIzIDEwNUgzNFYxMTZIMjNWMTA1WiIgZmlsbD0iI0ZGMDAwMCIvPgo8cGF0aCBkPSJNMjMgMjhIMzRWMTA1SDIzVjI4Wk00NSAyOEg1NS45OTk5VjExNkg0NVYyOFpNNjYuOTk5OSAyOEg3Ny45OTk5VjExNkg2Ni45OTk5VjI4Wk04OC45OTk5IDI4SDk5Ljk5OTlWMTE2SDg4Ljk5OTlWMjhaTTExMSA2My43NDk5SDEyMlY4MC4yNDk5SDExMVY2My43NDk5WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMzIwMiIgeDE9Ii0wLjQ5OTk5OCIgeTE9IjEuNSIgeDI9IjE1My41IiB5Mj0iMTYyIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkNDMDAiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkY3QTAwIi8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "shards"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "logStorageSize"], ["spec", "logTTL"], ["spec", "users"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "s3Region"], ["spec", "backup", "s3Bucket"], ["spec", "backup", "schedule"], ["spec", "backup", "cleanupStrategy"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "backup", "resticPassword"], ["spec", "clickhouseKeeper"], ["spec", "clickhouseKeeper", "enabled"], ["spec", "clickhouseKeeper", "size"], ["spec", "clickhouseKeeper", "resourcesPreset"], ["spec", "clickhouseKeeper", "replicas"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`clickhouse-{{ .name }}-credentials`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`chendpoint-clickhouse-{{ .name }}`}}" diff --git a/packages/core/platform/psds/cozystack.yaml b/packages/core/platform/psds/cozystack-engine.yaml similarity index 98% rename from packages/core/platform/psds/cozystack.yaml rename to packages/core/platform/psds/cozystack-engine.yaml index 65294516..bd1bf76e 100644 --- a/packages/core/platform/psds/cozystack.yaml +++ b/packages/core/platform/psds/cozystack-engine.yaml @@ -2,7 +2,7 @@ apiVersion: cozystack.io/v1alpha1 kind: PackageSource metadata: - name: cozystack.cozystack + name: cozystack.cozystack-engine spec: variants: - name: default diff --git a/packages/core/platform/psds/dependencies.dot b/packages/core/platform/psds/dependencies.dot new file mode 100644 index 00000000..3aa641fd --- /dev/null +++ b/packages/core/platform/psds/dependencies.dot @@ -0,0 +1,190 @@ +digraph { + nodesep="0.5";rankdir="LR";ranksep="1.0"; + n40[fillcolor="lightblue",label="bootbox",shape="box",style="rounded,filled"]; + n45[fillcolor="lightblue",label="bootbox-application",shape="box",style="rounded,filled"]; + n64[fillcolor="lightblue",label="bucket-application",shape="box",style="rounded,filled"]; + n17[fillcolor="lightblue",label="capi-operator",shape="box",style="rounded,filled"]; + n65[fillcolor="lightblue",label="capi-providers-bootstrap",shape="box",style="rounded,filled"]; + n1[fillcolor="lightblue",label="capi-providers-core",shape="box",style="rounded,filled"]; + n58[fillcolor="lightblue",label="capi-providers-cpprovider",shape="box",style="rounded,filled"]; + n22[fillcolor="lightblue",label="capi-providers-infraprovider",shape="box",style="rounded,filled"]; + n13[fillcolor="lightblue",label="cert-manager",shape="box",style="rounded,filled"]; + n51[fillcolor="lightblue",label="clickhouse-application",shape="box",style="rounded,filled"]; + n50[fillcolor="lightblue",label="clickhouse-operator",shape="box",style="rounded,filled"]; + n52[fillcolor="lightblue",label="cozy-proxy",shape="box",style="rounded,filled"]; + n9[fillcolor="lightblue",label="cozystack",shape="box",style="rounded,filled"]; + n36[fillcolor="lightblue",label="cozystack-core",shape="box",style="rounded,filled"]; + n7[fillcolor="lightblue",label="etcd-application",shape="box",style="rounded,filled"]; + n18[fillcolor="lightblue",label="etcd-operator",shape="box",style="rounded,filled"]; + n53[fillcolor="lightblue",label="external-dns",shape="box",style="rounded,filled"]; + n46[fillcolor="lightblue",label="external-secrets-operator",shape="box",style="rounded,filled"]; + n8[fillcolor="lightblue",label="ferretdb-application",shape="box",style="rounded,filled"]; + n23[fillcolor="lightblue",label="foundationdb-application",shape="box",style="rounded,filled"]; + n14[fillcolor="lightblue",label="foundationdb-operator",shape="box",style="rounded,filled"]; + n37[fillcolor="lightblue",label="goldpinger",shape="box",style="rounded,filled"]; + n42[fillcolor="lightblue",label="gpu-operator",shape="box",style="rounded,filled"]; + n30[fillcolor="lightblue",label="grafana-operator",shape="box",style="rounded,filled"]; + n48[fillcolor="lightblue",label="hetzner-robotlb",shape="box",style="rounded,filled"]; + n2[fillcolor="lightblue",label="http-cache-application",shape="box",style="rounded,filled"]; + n66[fillcolor="lightblue",label="info-application",shape="box",style="rounded,filled"]; + n59[fillcolor="lightblue",label="ingress-application",shape="box",style="rounded,filled"]; + n4[fillcolor="lightblue",label="kafka-application",shape="box",style="rounded,filled"]; + n3[fillcolor="lightblue",label="kafka-operator",shape="box",style="rounded,filled"]; + n41[fillcolor="lightblue",label="kamaji",shape="box",style="rounded,filled"]; + n10[fillcolor="lightblue",label="keycloak",shape="box",style="rounded,filled"]; + n54[fillcolor="lightblue",label="keycloak-operator",shape="box",style="rounded,filled"]; + n15[fillcolor="lightblue",label="kubernetes-application",shape="box",style="rounded,filled"]; + n61[fillcolor="lightblue",label="kubevirt",shape="box",style="rounded,filled"]; + n31[fillcolor="lightblue",label="kubevirt-cdi",shape="box",style="rounded,filled"]; + n55[fillcolor="lightblue",label="linstor",shape="box",style="rounded,filled"]; + n56[fillcolor="lightblue",label="mariadb-operator",shape="box",style="rounded,filled"]; + n62[fillcolor="lightblue",label="metallb",shape="box",style="rounded,filled"]; + n35[fillcolor="lightblue",label="monitoring",shape="box",style="rounded,filled"]; + n24[fillcolor="lightblue",label="monitoring-agents",shape="box",style="rounded,filled"]; + n47[fillcolor="lightblue",label="monitoring-application",shape="box",style="rounded,filled"]; + n32[fillcolor="lightblue",label="multus",shape="box",style="rounded,filled"]; + n39[fillcolor="lightblue",label="mysql-application",shape="box",style="rounded,filled"]; + n20[fillcolor="lightblue",label="nats-application",shape="box",style="rounded,filled"]; + n28[fillcolor="lightblue",label="networking",shape="box",style="rounded,filled"]; + n25[fillcolor="lightblue",label="nfs-driver",shape="box",style="rounded,filled"]; + n29[fillcolor="lightblue",label="objectstorage-controller",shape="box",style="rounded,filled"]; + n11[fillcolor="lightblue",label="postgres-application",shape="box",style="rounded,filled"]; + n43[fillcolor="lightblue",label="postgres-operator",shape="box",style="rounded,filled"]; + n16[fillcolor="lightblue",label="rabbitmq-application",shape="box",style="rounded,filled"]; + n5[fillcolor="lightblue",label="rabbitmq-operator",shape="box",style="rounded,filled"]; + n26[fillcolor="lightblue",label="redis-application",shape="box",style="rounded,filled"]; + n27[fillcolor="lightblue",label="redis-operator",shape="box",style="rounded,filled"]; + n19[fillcolor="lightblue",label="reloader",shape="box",style="rounded,filled"]; + n67[fillcolor="lightblue",label="seaweedfs-application",shape="box",style="rounded,filled"]; + n12[fillcolor="lightblue",label="snapshot-controller",shape="box",style="rounded,filled"]; + n21[fillcolor="lightblue",label="tcp-balancer-application",shape="box",style="rounded,filled"]; + n33[fillcolor="lightblue",label="telepresence",shape="box",style="rounded,filled"]; + n57[fillcolor="lightblue",label="tenant-application",shape="box",style="rounded,filled"]; + n44[fillcolor="lightblue",label="velero",shape="box",style="rounded,filled"]; + n38[fillcolor="lightblue",label="vertical-pod-autoscaler",shape="box",style="rounded,filled"]; + n49[fillcolor="lightblue",label="victoria-metrics-operator",shape="box",style="rounded,filled"]; + n34[fillcolor="lightblue",label="virtual-machine-application",shape="box",style="rounded,filled"]; + n6[fillcolor="lightblue",label="virtualprivatecloud-application",shape="box",style="rounded,filled"]; + n63[fillcolor="lightblue",label="vm-disk-application",shape="box",style="rounded,filled"]; + n68[fillcolor="lightblue",label="vm-instance-application",shape="box",style="rounded,filled"]; + n60[fillcolor="lightblue",label="vpn-application",shape="box",style="rounded,filled"]; + n40->n28; + n40->n45; + n45->n28; + n64->n28; + n64->n29; + n17->n28; + n65->n28; + n65->n17; + n1->n28; + n1->n17; + n58->n28; + n58->n17; + n58->n41; + n22->n28; + n22->n17; + n22->n61; + n13->n28; + n51->n50; + n50->n28; + n50->n35; + n50->n36; + n52->n28; + n9->n28; + n9->n28; + n9->n10; + n7->n28; + n18->n28; + n18->n13; + n53->n28; + n46->n28; + n8->n28; + n23->n28; + n23->n14; + n14->n28; + n14->n13; + n37->n28; + n37->n24; + n42->n28; + n30->n28; + n48->n28; + n2->n28; + n66->n28; + n59->n28; + n4->n28; + n4->n3; + n3->n28; + n3->n35; + n41->n28; + n10->n28; + n10->n43; + n54->n28; + n15->n28; + n15->n17; + n15->n65; + n15->n1; + n15->n58; + n15->n22; + n61->n28; + n61->n35; + n31->n28; + n55->n28; + n55->n13; + n55->n35; + n55->n19; + n56->n28; + n56->n35; + n56->n13; + n62->n28; + n24->n28; + n24->n35; + n24->n37; + n24->n49; + n24->n38; + n47->n28; + n32->n28; + n39->n28; + n39->n56; + n20->n28; + n28->n13; + n28->n13; + n25->n28; + n29->n28; + n11->n28; + n16->n28; + n16->n5; + n5->n28; + n26->n28; + n26->n27; + n27->n28; + n19->n28; + n67->n28; + n12->n28; + n12->n13; + n21->n28; + n33->n28; + n57->n28; + n57->n59; + n57->n67; + n57->n66; + n57->n47; + n57->n45; + n57->n7; + n44->n28; + n44->n24; + n38->n28; + n38->n24; + n49->n28; + n49->n13; + n34->n28; + n34->n61; + n34->n31; + n6->n28; + n6->n32; + n63->n28; + n63->n31; + n68->n28; + n68->n61; + n60->n28; + +} diff --git a/packages/core/platform/psds/dependencies.svg b/packages/core/platform/psds/dependencies.svg new file mode 100644 index 00000000..9b6d7003 --- /dev/null +++ b/packages/core/platform/psds/dependencies.svg @@ -0,0 +1,1128 @@ + + + + + + + + + +n40 + +bootbox + + + +n45 + +bootbox-application + + + +n40->n45 + + + + + +n28 + +networking + + + +n40->n28 + + + + + +n45->n28 + + + + + +n64 + +bucket-application + + + +n64->n28 + + + + + +n29 + +objectstorage-controller + + + +n64->n29 + + + + + +n17 + +capi-operator + + + +n17->n28 + + + + + +n65 + +capi-providers-bootstrap + + + +n65->n17 + + + + + +n65->n28 + + + + + +n1 + +capi-providers-core + + + +n1->n17 + + + + + +n1->n28 + + + + + +n58 + +capi-providers-cpprovider + + + +n58->n17 + + + + + +n41 + +kamaji + + + +n58->n41 + + + + + +n58->n28 + + + + + +n22 + +capi-providers-infraprovider + + + +n22->n17 + + + + + +n61 + +kubevirt + + + +n22->n61 + + + + + +n22->n28 + + + + + +n13 + +cert-manager + + + +n13->n28 + + + + + +n51 + +clickhouse-application + + + +n50 + +clickhouse-operator + + + +n51->n50 + + + + + +n36 + +cozystack-core + + + +n50->n36 + + + + + +n35 + +monitoring + + + +n50->n35 + + + + + +n50->n28 + + + + + +n52 + +cozy-proxy + + + +n52->n28 + + + + + +n9 + +cozystack + + + +n10 + +keycloak + + + +n9->n10 + + + + + +n9->n28 + + + + + +n9->n28 + + + + + +n7 + +etcd-application + + + +n7->n28 + + + + + +n18 + +etcd-operator + + + +n18->n13 + + + + + +n18->n28 + + + + + +n53 + +external-dns + + + +n53->n28 + + + + + +n46 + +external-secrets-operator + + + +n46->n28 + + + + + +n8 + +ferretdb-application + + + +n8->n28 + + + + + +n23 + +foundationdb-application + + + +n14 + +foundationdb-operator + + + +n23->n14 + + + + + +n23->n28 + + + + + +n14->n13 + + + + + +n14->n28 + + + + + +n37 + +goldpinger + + + +n24 + +monitoring-agents + + + +n37->n24 + + + + + +n37->n28 + + + + + +n42 + +gpu-operator + + + +n42->n28 + + + + + +n30 + +grafana-operator + + + +n30->n28 + + + + + +n48 + +hetzner-robotlb + + + +n48->n28 + + + + + +n2 + +http-cache-application + + + +n2->n28 + + + + + +n66 + +info-application + + + +n66->n28 + + + + + +n59 + +ingress-application + + + +n59->n28 + + + + + +n4 + +kafka-application + + + +n3 + +kafka-operator + + + +n4->n3 + + + + + +n4->n28 + + + + + +n3->n35 + + + + + +n3->n28 + + + + + +n41->n28 + + + + + +n10->n28 + + + + + +n43 + +postgres-operator + + + +n10->n43 + + + + + +n54 + +keycloak-operator + + + +n54->n28 + + + + + +n15 + +kubernetes-application + + + +n15->n17 + + + + + +n15->n65 + + + + + +n15->n1 + + + + + +n15->n58 + + + + + +n15->n22 + + + + + +n15->n28 + + + + + +n61->n35 + + + + + +n61->n28 + + + + + +n31 + +kubevirt-cdi + + + +n31->n28 + + + + + +n55 + +linstor + + + +n55->n13 + + + + + +n55->n35 + + + + + +n55->n28 + + + + + +n19 + +reloader + + + +n55->n19 + + + + + +n56 + +mariadb-operator + + + +n56->n13 + + + + + +n56->n35 + + + + + +n56->n28 + + + + + +n62 + +metallb + + + +n62->n28 + + + + + +n24->n37 + + + + + +n24->n35 + + + + + +n24->n28 + + + + + +n38 + +vertical-pod-autoscaler + + + +n24->n38 + + + + + +n49 + +victoria-metrics-operator + + + +n24->n49 + + + + + +n47 + +monitoring-application + + + +n47->n28 + + + + + +n32 + +multus + + + +n32->n28 + + + + + +n39 + +mysql-application + + + +n39->n56 + + + + + +n39->n28 + + + + + +n20 + +nats-application + + + +n20->n28 + + + + + +n28->n13 + + + + + +n28->n13 + + + + + +n25 + +nfs-driver + + + +n25->n28 + + + + + +n29->n28 + + + + + +n11 + +postgres-application + + + +n11->n28 + + + + + +n16 + +rabbitmq-application + + + +n16->n28 + + + + + +n5 + +rabbitmq-operator + + + +n16->n5 + + + + + +n5->n28 + + + + + +n26 + +redis-application + + + +n26->n28 + + + + + +n27 + +redis-operator + + + +n26->n27 + + + + + +n27->n28 + + + + + +n19->n28 + + + + + +n67 + +seaweedfs-application + + + +n67->n28 + + + + + +n12 + +snapshot-controller + + + +n12->n13 + + + + + +n12->n28 + + + + + +n21 + +tcp-balancer-application + + + +n21->n28 + + + + + +n33 + +telepresence + + + +n33->n28 + + + + + +n57 + +tenant-application + + + +n57->n45 + + + + + +n57->n7 + + + + + +n57->n66 + + + + + +n57->n59 + + + + + +n57->n47 + + + + + +n57->n28 + + + + + +n57->n67 + + + + + +n44 + +velero + + + +n44->n24 + + + + + +n44->n28 + + + + + +n38->n24 + + + + + +n38->n28 + + + + + +n49->n13 + + + + + +n49->n28 + + + + + +n34 + +virtual-machine-application + + + +n34->n61 + + + + + +n34->n31 + + + + + +n34->n28 + + + + + +n6 + +virtualprivatecloud-application + + + +n6->n32 + + + + + +n6->n28 + + + + + +n63 + +vm-disk-application + + + +n63->n31 + + + + + +n63->n28 + + + + + +n68 + +vm-instance-application + + + +n68->n61 + + + + + +n68->n28 + + + + + +n60 + +vpn-application + + + +n60->n28 + + + + + diff --git a/packages/core/platform/psds/etcd-application.yaml b/packages/core/platform/psds/etcd-application.yaml index dbaeb9ab..1abcec12 100644 --- a/packages/core/platform/psds/etcd-application.yaml +++ b/packages/core/platform/psds/etcd-application.yaml @@ -16,39 +16,12 @@ spec: libraries: - name: cozy-lib path: library/cozy-lib - components: [] - applications: + components: - name: etcd path: extra/etcd - libraries: - - cozy-lib - template: - spec: - application: - kind: Etcd - plural: etcds - singular: etcd - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"replicas":{"description":"Number of etcd replicas.","type":"integer","default":3},"resources":{"description":"Resource configuration for etcd.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","default":"1000m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","default":"512Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"size":{"description":"Persistent Volume size.","default":"4Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} - release: - prefix: "" - labels: - cozystack.io/ui: "true" - internal.cozystack.io/tenantmodule: "true" - dashboard: - category: Administration - singular: Etcd - plural: Etcd - name: etcd - description: Storage for Kubernetes clusters - module: true - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NjMpIi8+CjxwYXRoIGQ9Ik0xMjIuNDQyIDczLjQ3MjlDMTIxLjk1OSA3My41MTM0IDEyMS40NzQgNzMuNTMyMiAxMjAuOTU4IDczLjUzMjJDMTE3Ljk2NSA3My41MzIyIDExNS4wNjEgNzIuODMwNCAxMTIuNDQyIDcxLjU0NTFDMTEzLjMxNCA2Ni41NDIxIDExMy42ODUgNjEuNTAxOSAxMTMuNTg4IDU2LjQ4MDJDMTEwLjc0OCA1Mi4zNzIzIDEwNy41MDIgNDguNDk2NSAxMDMuODM4IDQ0LjkyNTdDMTA1LjQyOCA0MS45NDU0IDEwNy43NzggMzkuMzgxMSAxMTAuNzExIDM3LjU2MjhMMTExLjk3MSAzNi43ODQyTDExMC45ODkgMzUuNjc3NEMxMDUuOTMyIDI5Ljk4MzIgOTkuODk3MSAyNS41ODA5IDkzLjA1NDcgMjIuNTkzN0w5MS42OTAyIDIyTDkxLjM0MzcgMjMuNDQyM0M5MC41Mjc3IDI2LjgwMzYgODguODIyMiAyOS44MzYgODYuNDgwNyAzMi4yNjk1QzgxLjk4MDMgMjkuODc3NCA3Ny4yNzg4IDI3Ljk0NCA3Mi40MzA1IDI2LjQ3OTdDNjcuNTkzNyAyNy45NDA4IDYyLjkwMDUgMjkuODY4NiA1OC40MDIgMzIuMjU3MUM1Ni4wNzAxIDI5LjgyNjggNTQuMzY4OCAyNi44MDE4IDUzLjU1NiAyMy40NTAxTDUzLjIwNzIgMjIuMDA4M0w1MS44NDc3IDIyLjU5OTJDNDUuMDkxNCAyNS41NDMxIDM4Ljg5MDEgMzAuMDY0NyAzMy45MTYyIDM1LjY3NDJMMzIuOTMxOCAzNi43ODMzTDM0LjE5IDM3LjU2MTlDMzcuMTE0MiAzOS4zNzMzIDM5LjQ1NzYgNDEuOTIyNCA0MS4wNDQ0IDQ0Ljg4NjZDMzcuMzkxNyA0OC40NDM1IDM0LjE0OTUgNTIuMzA3IDMxLjMxMTkgNTYuMzk1OUMzMS4yMDE0IDYxLjQxNTQgMzEuNTUzNSA2Ni40OTI0IDMyLjQyOTcgNzEuNTY0NEMyOS44MjMxIDcyLjgzNzggMjYuOTM1OCA3My41MzE4IDIzLjk2MjggNzMuNTMxOEMyMy40NDA5IDczLjUzMTggMjIuOTUyNyA3My41MTI5IDIyLjQ3ODIgNzMuNDczM0wyMSA3My4zNjA2TDIxLjEzODUgNzQuODM2NUMyMS44NjI5IDgyLjMwMzMgMjQuMTgxNCA4OS40MDUzIDI4LjAzMzQgOTUuOTQ3MUwyOC43ODUzIDk3LjIyMzdMMjkuOTE0MiA5Ni4yNjU2QzMyLjUzMDUgOTQuMDQ2NSAzNS42OTE3IDkyLjU3NyAzOS4wNTMgOTEuOTg0N0M0MS4yNjg5IDk2LjUxNTUgNDMuODk1MyAxMDAuNzcyIDQ2Ljg3NDcgMTA0LjcyNUM1MS42Mjg3IDEwNi4zODcgNTYuNTgxOSAxMDcuNjI5IDYxLjY5NzEgMTA4LjM2N0M2Mi4xODc3IDExMS43NSA2MS43OTcgMTE1LjI0OSA2MC40NjI0IDExOC40ODRMNTkuODk5NSAxMTkuODU1TDYxLjM0NjkgMTIwLjE3NEM2NS4wNTI5IDEyMC45ODkgNjguNzkxNyAxMjEuNDA0IDcyLjQ1MjYgMTIxLjQwNEw4My41NTUxIDEyMC4xNzRMODUuMDAzOSAxMTkuODU1TDg0LjQzOTcgMTE4LjQ4MkM4My4xMDg3IDExNS4yNDYgODIuNzE4IDExMS43NDMgODMuMjA4NiAxMDguMzZDODguMzAzNiAxMDcuNjIxIDkzLjIzODQgMTA2LjM4MiA5Ny45NzQ4IDEwNC43MjVDMTAwLjk1NyAxMDAuNzY5IDEwMy41ODYgOTYuNTA5NSAxMDUuODA1IDkxLjk3MjhDMTA5LjE3NyA5Mi41NjE0IDExMi4zNTYgOTQuMDMxNyAxMTQuOTg5IDk2LjI1NzNMMTE2LjExOCA5Ny4yMTQxTDExNi44NjYgOTUuOTQwN0MxMjAuNzI1IDg5LjM5MDUgMTIzLjA0MyA4Mi4yODkxIDEyMy43NTYgNzQuODM0MkwxMjMuODk1IDczLjM2MUwxMjIuNDQyIDczLjQ3MjlaTTg4LjMxOTcgOTEuNTE4MUM4My4wNjczIDkyLjk0NjYgNzcuNzMzIDkzLjY2NzcgNzIuNDMwNSA5My42Njc3QzY3LjExMzcgOTMuNjY3NyA2MS43ODU5IDkyLjk0NyA1Ni41MjkgOTEuNTE4MUM1My42NDQ4IDg3LjAzNjYgNTEuMzY0NSA4Mi4yMzU3IDQ5LjcyMzQgNzcuMTgxMkM0OC4wODkyIDcyLjE1MDIgNDcuMTMyOSA2Ni44Nzk1IDQ2Ljg1NTQgNjEuNDUyMkM1MC4yNTA0IDU3LjI1NDcgNTQuMTExIDUzLjU3NzYgNTguMzc2NyA1MC40ODIzQzYyLjcxMTQgNDcuMzI5NCA2Ny40MjcxIDQ0Ljc2NzkgNzIuNDMwNSA0Mi44NDFDNzcuNDI1NiA0NC43NjgzIDgyLjEzMjYgNDcuMzI2MiA4Ni40NTcyIDUwLjQ2NTdDOTAuNzM5NCA1My41Nzc2IDk0LjYxNzEgNTcuMjgzMiA5OC4wMjg3IDYxLjUwN0M5Ny43Mzc4IDY2LjkwMzQgOTYuNzcgNzIuMTQzOCA5NS4xMzMgNzcuMTY2NUM5My40OTYxIDgyLjIyIDkxLjIwODQgODcuMDM2MSA4OC4zMTk3IDkxLjUxODFaTTc2Ljc2ODQgNjYuMTk3NEM3Ni43Njg0IDY5LjkwODEgNzkuNzc1NCA3Mi45MDk2IDgzLjQ4MSA3Mi45MDk2Qzg3LjE4NTcgNzIuOTA5NiA5MC4xODk1IDY5LjkwODYgOTAuMTg5NSA2Ni4xOTc0QzkwLjE4OTUgNjIuNTAxIDg3LjE4NTcgNTkuNDg4MSA4My40ODEgNTkuNDg4MUM3OS43NzU0IDU5LjQ4ODEgNzYuNzY4NCA2Mi41MDEgNzYuNzY4NCA2Ni4xOTc0Wk02OC4wOTU0IDY2LjE5NzRDNjguMDk1NCA2OS45MDgxIDY1LjA4ODggNzIuOTA5NiA2MS4zODMyIDcyLjkwOTZDNTcuNjc0OSA3Mi45MDk2IDU0LjY3NjYgNjkuOTA4NiA1NC42NzY2IDY2LjE5NzRDNTQuNjc2NiA2Mi41MDI0IDU3LjY3NTMgNTkuNDg5NCA2MS4zODMyIDU5LjQ4OTRDNjUuMDg4OCA1OS40ODk0IDY4LjA5NTQgNjIuNTAyNCA2OC4wOTU0IDY2LjE5NzRaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yOTYzIiB4MT0iNS41IiB5MT0iMTEiIHgyPSIxNDEiIHkyPSIxMjQuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNTNCMkYwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzQxOUVEQSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "size"], ["spec", "storageClass"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resources", "cpu"], ["spec", "resources", "memory"]] - secrets: - exclude: [] - include: [] - services: - exclude: [] - include: - - resourceNames: - - etcd + libraries: ["cozy-lib"] + - name: etcd-rd + path: system/etcd-rd + install: + namespace: cozy-system + releaseName: etcd-rd diff --git a/packages/core/platform/psds/external-dns.yaml b/packages/core/platform/psds/external-dns.yaml index 8cee73a1..a3f6ca6e 100644 --- a/packages/core/platform/psds/external-dns.yaml +++ b/packages/core/platform/psds/external-dns.yaml @@ -16,7 +16,6 @@ spec: components: - name: external-dns path: system/external-dns - disabled: true install: namespace: cozy-external-dns releaseName: external-dns diff --git a/packages/core/platform/psds/external-secrets-operator.yaml b/packages/core/platform/psds/external-secrets-operator.yaml index d626cc93..bc69dcce 100644 --- a/packages/core/platform/psds/external-secrets-operator.yaml +++ b/packages/core/platform/psds/external-secrets-operator.yaml @@ -16,7 +16,6 @@ spec: components: - name: external-secrets-operator path: system/external-secrets-operator - disabled: true install: namespace: cozy-external-secrets-operator releaseName: external-secrets-operator diff --git a/packages/core/platform/psds/ferretdb-application.yaml b/packages/core/platform/psds/ferretdb-application.yaml new file mode 100644 index 00000000..447745a5 --- /dev/null +++ b/packages/core/platform/psds/ferretdb-application.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.ferretdb-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: ferretdb + path: apps/ferretdb + libraries: [cozy-lib] + - name: ferretdb-rd + path: system/ferretdb-rd + install: + namespace: cozy-system + releaseName: ferretdb-rd diff --git a/packages/core/platform/psds/ferretdb.yaml b/packages/core/platform/psds/ferretdb.yaml deleted file mode 100644 index 538c4a74..00000000 --- a/packages/core/platform/psds/ferretdb.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.ferretdb-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: ferretdb - path: apps/ferretdb - libraries: - - cozy-lib - template: - spec: - application: - kind: FerretDB - plural: ferretdbs - singular: ferretdb - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["destinationPath","enabled","endpointURL","retentionPolicy","s3AccessKey","s3SecretKey","schedule"],"properties":{"destinationPath":{"description":"Path to store the backup (e.g. s3://bucket/path/to/folder/).","type":"string","default":"s3://bucket/path/to/folder/"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"endpointURL":{"description":"S3 endpoint URL for uploads.","type":"string","default":"http://minio-gateway-service:9000"},"retentionPolicy":{"description":"Retention policy.","type":"string","default":"30d"},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * * *"}}},"bootstrap":{"description":"Bootstrap configuration.","type":"object","default":{},"properties":{"enabled":{"description":"Restore database cluster from a backup.","type":"boolean","default":false},"oldName":{"description":"Name of database cluster before deletion.","type":"string","default":""},"recoveryTime":{"description":"Timestamp (RFC3339) for point-in-time recovery; empty means latest.","type":"string","default":""}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"quorum":{"description":"Configuration for quorum-based synchronous replication.","type":"object","default":{},"required":["maxSyncReplicas","minSyncReplicas"],"properties":{"maxSyncReplicas":{"description":"Maximum number of synchronous replicas allowed (must be less than total replicas).","type":"integer","default":0},"minSyncReplicas":{"description":"Minimum number of synchronous replicas required for commit.","type":"integer","default":0}}},"replicas":{"description":"Number of replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each FerretDB replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}}}} - release: - prefix: ferretdb- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: FerretDB - plural: FerretDB - description: Managed FerretDB service - tags: - - database - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NTIpIi8+CjxwYXRoIGQ9Ik02OS41OTIzIDIyLjEzMUM1OC4yNjYyIDIzLjY3ODcgNDYuOTAzNyAzMC44NzE0IDQwLjMzMDIgNDAuNjY3OUMzOS4yNzQgNDIuMjUyMSAzNy40NTMxIDQ1LjU0OCAzNy40NTMxIDQ1Ljg3NTdDMzcuNDUzMSA0NS45MTIyIDM4LjMyNzIgNDUuMzg0MSAzOS4zODMzIDQ0LjY5MjFDNTIuMzg0NyAzNi4xMTU2IDY3Ljg5ODkgMzQuNTMxNCA4MC41MTc4IDQwLjQ4NThDODMuMjY3NCA0MS43Nzg3IDg0Ljk5NzMgNDMuMDM1MSA4Ny40NTU1IDQ1LjQ5MzNDOTEuNTg5IDQ5LjY0NSA5NC42MTE3IDU1LjE5ODggOTYuNzA1OCA2Mi41MDA3Qzk3Ljc5ODMgNjYuMjUxOCA5OC43MDg4IDcxLjM2ODYgOTguOTQ1NSA3NC44NDY1Qzk5LjAwMDEgNzUuNzkzNCA5OS4xNDU4IDc2LjYzMSA5OS4yMzY5IDc2LjY4NTZDOTkuNzQ2NyA3Ni45OTUyIDEwMi4wNDEgNzMuNjYyOSAxMDMuNjYyIDcwLjI3NkMxMDYuMjI5IDY0Ljg4NjEgMTA3LjQzMSA1OS41ODcyIDEwNy40MTMgNTMuNzA1N0MxMDcuMzk1IDQ1LjM4NDEgMTA0LjUxOCAzOC4zOTE3IDk4LjcyNyAzMi41NjQ4QzkzLjU5MiAyNy4zOTM0IDg3LjEwOTUgMjMuODQyNiA4MC4zMTc1IDIyLjQ1ODdDNzguNzMzMyAyMi4xNDkyIDc3LjU2NzkgMjIuMDU4MSA3NC41OTk5IDIyLjAwMzVDNzIuNTQyMiAyMS45ODUzIDcwLjMwMjUgMjIuMDM5OSA2OS41OTIzIDIyLjEzMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00NS41MiA0Ni40NDAyQzQ0LjMzNjQgNDcuMDIyOSA0Mi4zNTE2IDQ4Ljg0MzggNDAuNjAzNSA1MC45Mzc5QzM5LjgyMDUgNTEuODY2NiAzOC42MzY5IDUzLjAxMzcgMzcuNzYyOSA1My42NjkzQzM1LjcyMzQgNTUuMTk4OSAzMi4yNDU1IDU4LjYwNCAzMC40NzkyIDYwLjgwNzNDMjEuMjY1NCA3Mi4yMjQ0IDE4LjY5NzkgODUuMjQ0IDIzLjA4NjMgOTguMzE4MkMyNi42OTE3IDEwOS4wMjUgMzUuMDMxNSAxMTYuMTI3IDQ3Ljg1MDggMTE5LjM1QzUyLjg0MDEgMTIwLjYyNCA2MC4zMjQgMTIxLjMzNSA2My40NTYgMTIwLjg0M0w2NC4yNTcyIDEyMC43MTVMNjMuMDE5IDExOS45ODdDNTYuMTkwNiAxMTYuMDE4IDUxLjQxOTggMTA5LjMxNyA1MC4wOTA1IDEwMS44NjlDNDkuNjg5OSA5OS42MTEgNDkuNjcxNyA5NS42MDUgNTAuMDcyMyA5My40MDE3QzUwLjk2NDUgODguNDQ4OCA1My40NTkyIDgzLjg5NjUgNTYuODQ2MSA4MS4wNTU5QzU4LjQzMDMgNzkuNzI2NiA2MS4xOTgxIDc4LjM2MDkgNjMuNDAxNCA3Ny44MzI5QzY2LjcxNTUgNzcuMDMxNyA2OC43MzY3IDc2LjEyMTIgNzAuODMwNyA3NC40NjQyQzcyLjE3ODIgNzMuNDA4IDczLjM2MTggNzEuODA1NiA3NC4zNDUxIDY5LjcyOThDNzUuMTgyNyA2Ny45NjM1IDc2Ljk2NzIgNjIuMzU1MSA3Ni45NjcyIDYxLjQ2MjhDNzYuOTY3MiA2MC44NDM3IDc2LjMyOTkgNjAuMDA2MSA3NS40MTk1IDU5LjQ0MTZDNzQuOTQ2IDU5LjE1MDIgNzQuMTk5NCA1OC45ODY0IDcyLjI4NzUgNTguNzg2MUM2NC4wNTY5IDU3LjkzMDIgNTkuOTU5OSA1Ni40MzcxIDU1LjAwNyA1Mi41MjIxQzU0LjI5NjggNTEuOTU3NiA1My40NDEgNTEuMzIwMyA1My4wOTUgNTEuMTAxOEM1Mi43NDkgNTAuOTAxNSA1Mi4wNTcxIDUwLjEzNjcgNTEuNTgzNiA0OS40MjY1QzUwLjE0NTEgNDcuMzMyNSA0OC4zNjA2IDQ1Ljk4NSA0Ni45OTQ5IDQ1Ljk2NjhDNDYuNzAzNiA0NS45NjY4IDQ2LjAyOTggNDYuMTg1MyA0NS41MiA0Ni40NDAyWk01NC40NjA3IDU0Ljg3MTFDNTUuMDc5OCA1NS4xODA2IDU1Ljc1MzUgNTUuNTgxMiA1NS45NzIgNTUuNzQ1MUw1Ni4zNzI3IDU2LjA3MjlMNTUuNzM1MyA1OC42MjIyQzU1LjE4OTEgNjAuODQzNyA1NS4wOTggNjEuNDA4MiA1NS4xNTI2IDYyLjk5MjRDNTUuMjA3MyA2NC41NTg0IDU1LjI2MTkgNjQuOTA0MyA1NS42MjYxIDY1LjQxNDJDNTYuMjI3IDY2LjIzMzYgNTcuMjY0OSA2Ni43MjUzIDU4LjQzMDMgNjYuNzI1M0M2MC4wODczIDY2LjcyNTMgNjEuMzgwMiA2NS43Nzg0IDYzLjUyODkgNjIuOTU2QzY0LjE0OCA2Mi4xNTQ4IDY0LjYzOTYgNjEuNzE3NyA2NS4zNjggNjEuMzcxOEM2Ni40OTcgNjAuODA3MyA2Ny4yOTgyIDYwLjc1MjcgNjkuODExIDYwLjk3MTJMNzEuNDg2MyA2MS4xMzVWNjIuMTE4M0M3MS40ODYzIDYzLjY2NjEgNzIuMzA1NyA2NC41NTg0IDczLjk4MDkgNjQuODEzM0w3NC43ODIxIDY0LjkyMjZMNzQuNDkwOCA2NS41OTYzQzczLjIxNjEgNjguNjczNiA2OS45Mzg1IDcyLjE1MTYgNjYuODYxMSA3My42OTk0QzY2LjM2OTUgNzMuOTM2MSA2NS4yNTg3IDc0LjM3MzEgNjQuNDAyOSA3NC42NjQ1QzYzLjAwMDggNzUuMTE5NyA2Mi42MTg0IDc1LjE3NDMgNjAuMjE0OCA3NS4xNzQzQzU3LjgyOTQgNzUuMTc0MyA1Ny40Mjg4IDc1LjExOTcgNTYuMTE3NyA3NC42ODI3QzUyLjE2NjMgNzMuMzcxNiA0OS4yMzQ3IDcwLjQ1ODEgNDcuOTA1NCA2Ni41NDMyQzQ3LjQzMTkgNjUuMTU5MyA0Ny40MTM3IDYxLjEzNSA0Ny44ODcyIDU5LjQ1OThDNDguNTI0NSA1Ny4xNDcyIDQ5LjY1MzUgNTUuMjM1MyA1MC44MzcxIDU0LjQ4ODdDNTEuNjAxOCA1My45OTcgNTMuMDIyMiA1NC4xNjA5IDU0LjQ2MDcgNTQuODcxMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTMuMDIyIDYxLjczNjFDMTEzLjAyMiA2Mi41NTU1IDExMi4xMTEgNjYuMzQzMSAxMTEuMzQ3IDY4LjcxMDJDMTA4LjQ3IDc3LjU3ODEgMTAzLjI2MiA4NS41MzU1IDk2LjQ2OTcgOTEuMzQ0M0M5MS42OTg5IDk1LjQ0MTMgODguMzExOSA5Ny4yNDQgODIuOTQwMiA5OC41NzMzQzc5LjQ4MDUgOTkuNDI5MSA3Ny4yMjI2IDk5LjcwMjMgNzIuODM0MSA5OS44MTE1QzY3LjM1MzIgOTkuOTU3MiA2MS45NDUxIDk5LjQ2NTUgNTcuMTAxNCA5OC40MDk0QzU2LjE3MjcgOTguMjA5MSA1NS4zODk4IDk4LjA4MTYgNTUuMzM1MSA5OC4xMzYzQzU1LjExNjYgOTguMzM2NiA1NS45NTQyIDEwMS4xMjMgNTYuNjgyNiAxMDIuNTk4QzU4LjAxMTkgMTA1LjMyOSA1OS41MjMyIDEwNy4zNjggNjIuMjE4MiAxMTAuMDYzQzY1LjA1ODggMTEyLjkwNCA2Ny4xNzExIDExNC40NyA3MC40NDg3IDExNi4xNjNDNzguNTcgMTIwLjM1MSA4Ny44OTMxIDEyMC45MTYgOTcuNDUzIDExNy43NjZDMTA3LjU0MSAxMTQuNDcgMTE0Ljk1MiAxMDguNTE2IDExOC45NCAxMDAuNTAzQzEyMS41OTggOTUuMTg2NCAxMjIuNjkxIDg5LjUwNTEgMTIyLjI5IDgzLjAyMjdDMTIxLjc5OSA3NS4wMjg4IDExOC44NDkgNjcuMTk4OSAxMTQuNTcgNjIuNTczOEMxMTMuODk2IDYxLjg0NTQgMTEzLjI3NyA2MS4yNjI3IDExMy4xODYgNjEuMjYyN0MxMTMuMDk1IDYxLjI2MjcgMTEzLjAyMiA2MS40ODEyIDExMy4wMjIgNjEuNzM2MVoiIGZpbGw9IndoaXRlIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgzXzI5NTIiIHgxPSI1LjUiIHkxPSIxMSIgeDI9IjE0MSIgeTI9IjEyNC41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM0NUFEQzYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMjE2Nzc4Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "quorum"], ["spec", "quorum", "minSyncReplicas"], ["spec", "quorum", "maxSyncReplicas"], ["spec", "users"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "schedule"], ["spec", "backup", "retentionPolicy"], ["spec", "backup", "endpointURL"], ["spec", "backup", "destinationPath"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "bootstrap"], ["spec", "bootstrap", "enabled"], ["spec", "bootstrap", "recoveryTime"], ["spec", "bootstrap", "oldName"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`ferretdb-{{ .name }}-credentials`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`ferretdb-{{ .name }}`}}" diff --git a/packages/core/platform/psds/foundationdb-application.yaml b/packages/core/platform/psds/foundationdb-application.yaml new file mode 100644 index 00000000..4488b033 --- /dev/null +++ b/packages/core/platform/psds/foundationdb-application.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.foundationdb-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.foundationdb-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: foundationdb + path: apps/foundationdb + libraries: ["cozy-lib"] + - name: foundationdb-rd + path: system/foundationdb-rd + install: + namespace: cozy-system + releaseName: foundationdb-rd diff --git a/packages/core/platform/psds/foundationdb.yaml b/packages/core/platform/psds/foundationdb.yaml deleted file mode 100644 index 8e6d8e49..00000000 --- a/packages/core/platform/psds/foundationdb.yaml +++ /dev/null @@ -1,46 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.foundationdb-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.foundationdb-operator - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: foundationdb - path: apps/foundationdb - libraries: - - cozy-lib - template: - spec: - application: - kind: FoundationDB - singular: foundationdb - plural: foundationdbs - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"automaticReplacements":{"description":"Enable automatic pod replacements","type":"boolean","default":true},"backup":{"description":"Backup configuration","type":"object","default":{"enabled":false,"retentionPolicy":"7d","s3":{"bucket":"","credentials":{"accessKeyId":"","secretAccessKey":""},"endpoint":"","region":"us-east-1"}},"required":["enabled","retentionPolicy","s3"],"properties":{"enabled":{"description":"Enable backups","type":"boolean","default":false},"retentionPolicy":{"description":"Retention policy for backups","type":"string","default":"7d"},"s3":{"description":"S3 configuration for backups","type":"object","default":{"bucket":"","credentials":{"accessKeyId":"","secretAccessKey":""},"endpoint":"","region":"us-east-1"},"required":["bucket","credentials","endpoint","region"],"properties":{"bucket":{"description":"S3 bucket name","type":"string"},"credentials":{"description":"S3 credentials","type":"object","default":{"accessKeyId":"","secretAccessKey":""},"required":["accessKeyId","secretAccessKey"],"properties":{"accessKeyId":{"description":"S3 access key ID","type":"string"},"secretAccessKey":{"description":"S3 secret access key","type":"string"}}},"endpoint":{"description":"S3 endpoint URL","type":"string"},"region":{"description":"S3 region","type":"string","default":"us-east-1"}}}}},"cluster":{"description":"Cluster configuration","type":"object","default":{"faultDomain":{"key":"kubernetes.io/hostname","valueFrom":"spec.nodeName"},"processCounts":{"cluster_controller":1,"stateless":-1,"storage":3},"redundancyMode":"double","storageEngine":"ssd-2","version":"7.3.63"},"required":["faultDomain","processCounts","redundancyMode","storageEngine","version"],"properties":{"faultDomain":{"description":"Fault domain configuration","type":"object","default":{"key":"kubernetes.io/hostname","valueFrom":"spec.nodeName"},"required":["key","valueFrom"],"properties":{"key":{"description":"Fault domain key","type":"string","default":"kubernetes.io/hostname"},"valueFrom":{"description":"Fault domain value source","type":"string","default":"spec.nodeName"}}},"processCounts":{"description":"Process counts for different roles","type":"object","default":{"cluster_controller":1,"stateless":-1,"storage":3},"required":["cluster_controller","stateless","storage"],"properties":{"cluster_controller":{"description":"Number of cluster controller processes","type":"integer","default":1},"stateless":{"description":"Number of stateless processes (-1 for automatic)","type":"integer","default":-1},"storage":{"description":"Number of storage processes (determines cluster size)","type":"integer","default":3}}},"redundancyMode":{"description":"Database redundancy mode (single, double, triple, three_datacenter, three_datacenter_fallback)","type":"string","default":"double"},"storageEngine":{"description":"Storage engine (ssd-2, ssd-redwood-v1, ssd-rocksdb-v1, memory)","type":"string","default":"ssd-2"},"version":{"description":"Version of FoundationDB to use","type":"string","default":"7.3.63"}}},"customParameters":{"description":"Custom parameters to pass to FoundationDB","type":"array","default":[],"items":{"type":"string"}},"imageType":{"description":"Container image deployment type","type":"string","default":"unified","enum":["unified","split"]},"monitoring":{"description":"Monitoring configuration","type":"object","default":{"enabled":true},"required":["enabled"],"properties":{"enabled":{"description":"Enable WorkloadMonitor integration","type":"boolean","default":true}}},"resources":{"description":"Explicit CPU and memory configuration for each FoundationDB instance. When left empty, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each instance","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each instance","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted. Allowed values: `small`, `medium`, `large`, `xlarge`, `2xlarge`.","type":"string","default":"medium","enum":["small","medium","large","xlarge","2xlarge"]},"securityContext":{"description":"Security context for containers","type":"object","default":{"runAsGroup":4059,"runAsUser":4059},"required":["runAsGroup","runAsUser"],"properties":{"runAsGroup":{"description":"Group ID to run the container","type":"integer","default":4059},"runAsUser":{"description":"User ID to run the container","type":"integer","default":4059}}},"storage":{"description":"Storage configuration","type":"object","default":{"size":"16Gi","storageClass":""},"required":["size","storageClass"],"properties":{"size":{"description":"Size of persistent volumes for each instance","default":"16Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"Storage class (if not set, uses cluster default)","type":"string"}}}}} - release: - prefix: foundationdb- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: FoundationDB - plural: FoundationDB - description: Managed FoundationDB service - tags: - - database - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF84NThfMzA3MikiLz4KPHBhdGggZD0iTTEzNS43ODQgNzUuNjQ0NkwxMzUuOTM5IDg3Ljc2MzhMODkuNjg0NiA4MS41MzYyTDYyLjA4NjggODQuNTA3OUwzNS4zNDE3IDgxLjQzMjlMOC43NTE2NyA4NC41ODU0TDguNzI1ODMgODEuNTEwNEwzNS4zNjc2IDc3LjU4MjZWNjQuMTcxM0w2Mi4yOTM1IDcwLjczNDhMNjIuMzQ1MiA4MS4yNzc4TDg5LjQ3NzkgNzcuNjg2TDg5LjQwMDQgNjQuMTk3MkwxMzUuNzg0IDc1LjY0NDZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNODkuNDc3OCA4Ni4wMzI1TDEzNS44ODggOTAuODM4OFYxMDIuNzI2SDguNjQ4MjVMOC41MTkwNCA5OS41NzNIMzUuMjY0MUMzNS4yNjQxIDk5LjU3MyAzNS4yNjQxIDkwLjczNTUgMzUuMjY0MSA4Ni4wNTgzQzQ0LjI1NjcgODYuOTM2OSA2Mi4wODY3IDg4LjY5NDEgNjIuMDg2NyA4OC42OTQxVjk5LjI2MjlIODkuNDc3OFY4Ni4wMzI1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTYyLjI5MzQgNjYuODg0Nkw2Mi4yMTU4IDYzLjYyODZDNjIuMjE1OCA2My42Mjg2IDc5LjgxMzMgNTguMzU3MSA4OC45MDkyIDU1LjY2OTdDODguOTA5MiA1MS4zMDI2IDg4LjkwOTIgNDcuMDkwNiA4OC45MDkyIDQyQzEwNC44NzkgNDguNDA4NSAxMjAuMjI4IDU0LjYxMDIgMTM1LjczMyA2MC44Mzc4QzEzNS43MzMgNjQuNzEzOSAxMzUuNzMzIDY4LjQzNSAxMzUuNzMzIDcyLjU2OTVDMTE5Ljg0MSA2OC4yMDI0IDEwNC4yODQgNjMuOTEyOSA4OS4xNjc2IDU5Ljc1MjVDNzkuOTY4NCA2Mi4yMDc0IDYyLjI5MzQgNjYuODg0NiA2Mi4yOTM0IDY2Ljg4NDZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzUuMzk2MiA4MS43MDczTDguODA2MTIgODQuODU5OEw4Ljc4MDI3IDgxLjc4NDhMMzUuNDIyIDc3Ljg1N1Y2NC40NDU3TDYyLjM0OCA3MS4wMDkzTDYyLjM5OTYgODEuNTUyMkw4OS41MzIzIDc3Ljk2MDRMODkuNDU0OCA2NC40NzE2TDEzNS44MzkgNzUuOTE5TDEzNS45OTQgODguMDM4Mkw4OS43MzkxIDgxLjgxMDZMNjIuMTQxMiA4NC43ODIzTDM1LjM5NjIgODEuNzA3M1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik04OS41MzIzIDg2LjMwNjlMMTM1Ljk0MiA5MS4xMTMzVjEwM0g4LjcwMjdMOC41NzM0OSA5OS44NDc0SDM1LjMxODZDMzUuMzE4NiA5OS44NDc0IDM1LjMxODYgOTEuMDA5OSAzNS4zMTg2IDg2LjMzMjhDNDQuMzExMSA4Ny4yMTE0IDYyLjE0MTIgODguOTY4NSA2Mi4xNDEyIDg4Ljk2ODVWOTkuNTM3M0g4OS41MzIzVjg2LjMwNjlaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNjIuMzQ4MyA2Ny4xNTlMNjIuMjcwOCA2My45MDMxQzYyLjI3MDggNjMuOTAzMSA3OS44NjgyIDU4LjYzMTYgODguOTY0MiA1NS45NDQyQzg4Ljk2NDIgNTEuNTc3MSA4OC45NjQyIDQ3LjM2NTEgODguOTY0MiA0Mi4yNzQ0QzEwNC45MzQgNDguNjgyOSAxMjAuMjgzIDU0Ljg4NDcgMTM1Ljc4NyA2MS4xMTIzQzEzNS43ODcgNjQuOTg4NCAxMzUuNzg3IDY4LjcwOTQgMTM1Ljc4NyA3Mi44NDM5QzExOS44OTUgNjguNDc2OSAxMDQuMzM5IDY0LjE4NzMgODkuMjIyNiA2MC4wMjdDODAuMDIzMyA2Mi40ODE4IDYyLjM0ODMgNjcuMTU5IDYyLjM0ODMgNjcuMTU5WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQwX3JhZGlhbF84NThfMzA3MiIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgtMjkuNSAtMTgpIHJvdGF0ZSgzOS42OTYzKSBzY2FsZSgzMDIuMTY4IDI3NS4yNzEpIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0JFRERGRiIvPgo8c3RvcCBvZmZzZXQ9IjAuMjU5NjE1IiBzdG9wLWNvbG9yPSIjOUVDQ0ZEIi8+CjxzdG9wIG9mZnNldD0iMC41OTEzNDYiIHN0b3AtY29sb3I9IiMzRjlBRkIiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMEI3MEUwIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== - # keysOrder: [] diff --git a/packages/core/platform/psds/hetzner-robotlb.yaml b/packages/core/platform/psds/hetzner-robotlb.yaml index db24a771..8660890c 100644 --- a/packages/core/platform/psds/hetzner-robotlb.yaml +++ b/packages/core/platform/psds/hetzner-robotlb.yaml @@ -16,7 +16,6 @@ spec: components: - name: hetzner-robotlb path: system/hetzner-robotlb - disabled: true install: namespace: cozy-hetzner-robotlb releaseName: robotlb diff --git a/packages/core/platform/psds/http-cache-application.yaml b/packages/core/platform/psds/http-cache-application.yaml new file mode 100644 index 00000000..67537b4f --- /dev/null +++ b/packages/core/platform/psds/http-cache-application.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.http-cache-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: http-cache + path: apps/http-cache + libraries: [cozy-lib] + - name: http-cache-rd + path: system/http-cache-rd + install: + namespace: cozy-system + releaseName: http-cache-rd diff --git a/packages/core/platform/psds/http-cache.yaml b/packages/core/platform/psds/http-cache.yaml deleted file mode 100644 index 49802f98..00000000 --- a/packages/core/platform/psds/http-cache.yaml +++ /dev/null @@ -1,49 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.http-cache-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: http-cache - path: apps/http-cache - libraries: - - cozy-lib - template: - spec: - application: - kind: HTTPCache - plural: httpcaches - singular: httpcache - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"endpoints":{"description":"Endpoints configuration, as a list of .","type":"array","default":[],"items":{"type":"string"}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"haproxy":{"description":"HAProxy configuration.","type":"object","default":{},"required":["replicas","resourcesPreset"],"properties":{"replicas":{"description":"Number of HAProxy replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"nginx":{"description":"Nginx configuration.","type":"object","default":{},"required":["replicas","resourcesPreset"],"properties":{"replicas":{"description":"Number of Nginx replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} - release: - prefix: http-cache- - labels: - cozystack.io/ui: "true" - dashboard: - category: NaaS - singular: HTTP Cache - plural: HTTP Cache - description: Layer7 load balancer and caching service - tags: - - cache - - network - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyNSkiLz4KPHBhdGggZD0iTTI2LjAwMjYgMzcuODU4OEMyNi4wMDI2IDYwLjkxOSAyNi4wMDI2IDgzLjk4MTQgMjYuMDAyNiAxMDcuMDQ2QzI1Ljk3MyAxMDguMzIzIDI2LjE5OTYgMTA5LjU5MyAyNi42NjkyIDExMC43ODNDMjcuMTM4NyAxMTEuOTcyIDI3Ljg0MTggMTEzLjA1NiAyOC43Mzc0IDExMy45NzJDMzAuNDUzOSAxMTUuNjU5IDMyLjcgMTE2LjcwOSAzNS4xMDA5IDExNi45NDhDMzcuNTAxOSAxMTcuMTg3IDM5LjkxMjYgMTE2LjYgNDEuOTMxIDExNS4yODRDNDMuMjgyIDExNC4zNzEgNDQuMzg4MSAxMTMuMTQzIDQ1LjE1MjcgMTExLjcwN0M0NS45MTc0IDExMC4yNzEgNDYuMzE3NSAxMDguNjcxIDQ2LjMxODEgMTA3LjA0NkM0Ni4zMTgxIDkwLjM1MjggNDYuMjg2MSA3My42NTk3IDQ2LjMxODEgNTYuOTY2NkM2MS42MTY4IDc1LjE4ODkgNzYuOTQ3NCA5My4zODU2IDkyLjMxIDExMS41NTdDOTQuNDQ0NCAxMTMuNzA4IDk3LjA4NzUgMTE1LjI5MSA5OS45OTcgMTE2LjE2MkMxMDIuOTA2IDExNy4wMzIgMTA1Ljk4OSAxMTcuMTYyIDEwOC45NjIgMTE2LjUzOUMxMTEuMDYxIDExNi4xMjggMTEyLjk3MyAxMTUuMDU3IDExNC40MTUgMTEzLjQ4NUMxMTUuODU3IDExMS45MTMgMTE2Ljc1NCAxMDkuOTIxIDExNi45NzQgMTA3LjgwNEMxMTcuMDA5IDg0LjI2ODEgMTE3LjAwOSA2MC43MzQzIDExNi45NzQgMzcuMjAyNUMxMTYuNzU0IDM0LjY5MDcgMTE1LjU5NSAzMi4zNTIyIDExMy43MjYgMzAuNjQ4NkMxMTEuODU4IDI4Ljk0NSAxMDkuNDE1IDI4IDEwNi44ODEgMjhDMTA0LjM0NiAyOCAxMDEuOTAzIDI4Ljk0NSAxMDAuMDM1IDMwLjY0ODZDOTguMTY2MyAzMi4zNTIyIDk3LjAwNzQgMzQuNjkwNyA5Ni43ODY5IDM3LjIwMjVDOTYuNzg2OSA1NC4xNjMyIDk2LjY4NDQgNzEuMTA0OCA5Ni43ODY5IDg4LjA1OTFDODEuNzYxNiA3MC40MzU4IDY2LjkyMTkgNTIuNjU5NiA1MS45NTQzIDM0Ljk3MjVDNDkuOTgxIDMyLjQ1NTQgNDcuMzY4NSAzMC41MDczIDQ0LjM4NjMgMjkuMzI5MUM0MS40MDQxIDI4LjE1MDkgMzguMTU5OSAyNy43ODUyIDM0Ljk4ODMgMjguMjY5OEMzMi41ODU3IDI4LjUzNTkgMzAuMzU4MyAyOS42NDkzIDI4LjcwOTkgMzEuNDA4NEMyNy4wNjE1IDMzLjE2NzUgMjYuMTAxIDM1LjQ1NTkgMjYuMDAyNiAzNy44NTg4WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODFfMjgyNSIgeDE9IjEwIiB5MT0iMTUuNSIgeDI9IjE0NCIgeTI9IjEzMS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEM1NEEiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDE5NjM5Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "endpoints"], ["spec", "haproxy"], ["spec", "haproxy", "replicas"], ["spec", "haproxy", "resources"], ["spec", "haproxy", "resourcesPreset"], ["spec", "nginx"], ["spec", "nginx", "replicas"], ["spec", "nginx", "resources"], ["spec", "nginx", "resourcesPreset"]] - secrets: - exclude: [] - include: [] diff --git a/packages/core/platform/psds/info-application.yaml b/packages/core/platform/psds/info-application.yaml new file mode 100644 index 00000000..25b8b798 --- /dev/null +++ b/packages/core/platform/psds/info-application.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.info-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: info + path: extra/info + libraries: ["cozy-lib"] + - name: info-rd + path: system/info-rd + install: + namespace: cozy-system + releaseName: info-rd diff --git a/packages/core/platform/psds/info.yaml b/packages/core/platform/psds/info.yaml deleted file mode 100644 index d99d703e..00000000 --- a/packages/core/platform/psds/info.yaml +++ /dev/null @@ -1,52 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.info-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: info - path: extra/info - libraries: - - cozy-lib - template: - spec: - application: - kind: Info - plural: infos - singular: info - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{}} - release: - prefix: "" - labels: - cozystack.io/ui: "true" - internal.cozystack.io/tenantmodule: "true" - dashboard: - name: info - category: Administration - singular: Info - plural: Info - description: Info - module: true - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF8xNDRfMykiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzE0NF8zKSI+CjxwYXRoIGQ9Ik03Ny42NDA3IDk3LjA4NDRMODIuODMzIDk3LjM2MDRWMTA0LjYzN0g2MS4xNzI4Vjk3LjcxOTdMNjQuMTc3MSA5Ny40NDk1QzY1LjgxMDEgOTcuMjY4NCA2Ni44MTA2IDk2LjcxOTMgNjYuODEwNiA5NC41MzQzVjY5LjIzMTRDNjYuODEwNiA2Ny4yMjE3IDY2LjI3MDEgNjYuNTg2NCA2NC41MzY1IDY2LjU4NjRMNjEuMzU2OCA2Ni40MDgxVjU4Ljg1ODRINzcuNjQ2NUw3Ny42NDA3IDk3LjA4NDRaTTcxLjI3MjYgMzkuMzYzQzc1LjI4MDQgMzkuMzYzIDc4LjE4NyA0Mi4zNzMxIDc4LjE4NyA0Ni4xODgzQzc4LjE4NyA1MC4wMTQ5IDc1LjI3MTggNTIuODM4MSA3MS4xNzc4IDUyLjgzODFDNjYuOTk3NSA1Mi44MzgxIDY0LjI2NjMgNTAuMDE0OSA2NC4yNjYzIDQ2LjE4ODNDNjQuMjY2MyA0Mi4zNzMxIDY2Ljk5NzUgMzkuMzYzIDcxLjI3MjYgMzkuMzYzWk03MiAxMThDNDYuNjM2OCAxMTggMjYgOTcuMzYzMiAyNiA3MkMyNiA0Ni42MzY4IDQ2LjYzNjggMjYgNzIgMjZDOTcuMzU3NSAyNiAxMTggNDYuNjM2OCAxMTggNzJDMTE4IDk3LjM2MzIgOTcuMzU3NSAxMTggNzIgMTE4Wk03MiAzNC42MjVDNTEuMzkyIDM0LjYyNSAzNC42MjUgNTEuMzkyIDM0LjYyNSA3MkMzNC42MjUgOTIuNjA4IDUxLjM5MiAxMDkuMzc1IDcyIDEwOS4zNzVDOTIuNjA4IDEwOS4zNzUgMTA5LjM3NSA5Mi42MDggMTA5LjM3NSA3MkMxMDkuMzc1IDUxLjM5MiA5Mi42MDggMzQuNjI1IDcyIDM0LjYyNVoiIGZpbGw9IndoaXRlIi8+CjwvZz4KPGRlZnM+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQwX3JhZGlhbF8xNDRfMyIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgxLjMyMjk4ZS0wNSAtNy41MDAwMSkgcm90YXRlKDQ0LjcxNzgpIHNjYWxlKDIxNS4zMTcgMzEyLjQ1NSkiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDBCNUU3Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwMzk4NCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzE0NF8zIj4KPHJlY3Qgd2lkdGg9IjkyIiBoZWlnaHQ9IjkyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjYgMjYpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`kubeconfig-{{ .namespace }}`}}" - - "{{`{{ .namespace }}`}}" diff --git a/packages/core/platform/psds/ingress-application.yaml b/packages/core/platform/psds/ingress-application.yaml new file mode 100644 index 00000000..638c2f1c --- /dev/null +++ b/packages/core/platform/psds/ingress-application.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.ingress-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: ingress-system + path: system/ingress-nginx + - name: ingress + path: extra/ingress + libraries: ["cozy-lib"] + - name: ingress-rd + path: system/ingress-rd + install: + namespace: cozy-system + releaseName: ingress-rd diff --git a/packages/core/platform/psds/ingress.yaml b/packages/core/platform/psds/ingress.yaml deleted file mode 100644 index 51604e6a..00000000 --- a/packages/core/platform/psds/ingress.yaml +++ /dev/null @@ -1,56 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.ingress-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: - - name: ingress-system - path: system/ingress-nginx - applications: - - name: ingress - path: extra/ingress - libraries: - - cozy-lib - template: - spec: - application: - kind: Ingress - plural: ingresses - singular: ingress - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"cloudflareProxy":{"description":"Restoring original visitor IPs when Cloudflare proxied is enabled.","type":"boolean","default":false},"replicas":{"description":"Number of ingress-nginx replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each ingress-nginx replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"List of client networks.","type":"array","default":[],"items":{"type":"string"}}}} - release: - prefix: "" - labels: - cozystack.io/ui: "true" - internal.cozystack.io/tenantmodule: "true" - dashboard: - category: Administration - singular: Ingress - plural: Ingress - name: ingress - description: NGINX Ingress Controller - module: true - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODRfMzIyOSkiLz4KPHBhdGggZD0iTTg2LjkyNzQgMzcuMTA3NEgxN1YxMDcuMDM1SDg2LjkyNzRWMzcuMTA3NFoiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTEyNy42NDMgMjlIMTA3LjQ1NVY0OS4xODgzSDEyNy42NDNWMjlaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik0xMjcuNjQzIDYxLjcyNjZIMTA3LjQ1NVY4MS45MTQ5SDEyNy42NDNWNjEuNzI2NloiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTEyNy42NDMgOTQuNDUyMUgxMDcuNDU1VjExNC42NEgxMjcuNjQzVjk0LjQ1MjFaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik04OC41MTM3IDcyLjA3MTNIMTA2LjI3IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik04Ny41Njc0IDgwLjQyNDhMMTA3LjczIDk1Ljc4MDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTg3LjU2NzQgNjMuNzE4MUwxMDcuNzMgNDguMzYyMyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4NF8zMjI5IiB4MT0iMTAiIHkxPSIxNS41IiB4Mj0iMTQ0IiB5Mj0iMTMxLjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzAwREE1MyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDk2MzkiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "whitelist"], ["spec", "cloudflareProxy"], ["spec", "resources"], ["spec", "resourcesPreset"]] - secrets: - exclude: [] - include: [] - services: - exclude: [] - include: - - resourceNames: - - "{{`{{ slice .namespace 7 }}-ingress-controller`}}" diff --git a/packages/core/platform/psds/kafka-application.yaml b/packages/core/platform/psds/kafka-application.yaml new file mode 100644 index 00000000..4a5ca158 --- /dev/null +++ b/packages/core/platform/psds/kafka-application.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.kafka-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.kafka-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: kafka + path: apps/kafka + libraries: ["cozy-lib"] + - name: kafka-rd + path: system/kafka-rd + install: + namespace: cozy-system + releaseName: kafka-rd diff --git a/packages/core/platform/psds/kafka.yaml b/packages/core/platform/psds/kafka.yaml deleted file mode 100644 index 5c69b905..00000000 --- a/packages/core/platform/psds/kafka.yaml +++ /dev/null @@ -1,56 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.kafka-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.kafka-operator - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: kafka - path: apps/kafka - libraries: - - cozy-lib - template: - spec: - application: - kind: Kafka - plural: kafkas - singular: kafka - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"kafka":{"description":"Kafka configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of Kafka replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size for Kafka.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the Kafka data.","type":"string","default":""}}},"topics":{"description":"Topics configuration.","type":"array","default":[],"items":{"type":"object","required":["config","name","partitions","replicas"],"properties":{"config":{"description":"Topic configuration.","type":"object","x-kubernetes-preserve-unknown-fields":true},"name":{"description":"Topic name.","type":"string"},"partitions":{"description":"Number of partitions.","type":"integer"},"replicas":{"description":"Number of replicas.","type":"integer"}}}},"zookeeper":{"description":"ZooKeeper configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of ZooKeeper replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size for ZooKeeper.","default":"5Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the ZooKeeper data.","type":"string","default":""}}}}} - release: - prefix: kafka- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: Kafka - plural: Kafka - description: Managed Kafka service - tags: - - messaging - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyMCkiLz4KPHBhdGggZD0iTTkxLjAzMDcgNzcuODE4NUM4Ni44NTc3IDc3LjgxODUgODMuMTE2NiA3OS42ODE4IDgwLjU1NDcgODIuNjE1NEw3My45OTAxIDc3LjkzMTVDNzQuNjg2OSA3NS45OTc4IDc1LjA4NyA3My45MjE1IDc1LjA4NyA3MS43NDgyQzc1LjA4NyA2OS42MTI2IDc0LjcwMDggNjcuNTcxMSA3NC4wMjY5IDY1LjY2Nkw4MC41NzY5IDYxLjAzMThDODMuMTM4NSA2My45NTA1IDg2Ljg2OTkgNjUuODAzNyA5MS4wMzA3IDY1LjgwMzdDOTguNzMyOCA2NS44MDM3IDEwNSA1OS40ODg0IDEwNSA1MS43MjQ3QzEwNSA0My45NjEgOTguNzMyOCAzNy42NDU3IDkxLjAzMDcgMzcuNjQ1N0M4My4zMjg1IDM3LjY0NTcgNzcuMDYxNCA0My45NjEgNzcuMDYxNCA1MS43MjQ3Qzc3LjA2MTQgNTMuMTE0MyA3Ny4yNjk3IDU0LjQ1NDMgNzcuNjQzNSA1NS43MjMzTDcxLjA4OTEgNjAuMzU5OEM2OC4zNTEyIDU2LjkzNjUgNjQuNDA5IDU0LjU0NjMgNTkuOTE3NCA1My44MTY2VjQ1Ljg1NTNDNjYuMjQ1MSA0NC41MTU4IDcxLjAxMjggMzguODQ5NSA3MS4wMTI4IDMyLjA3OUM3MS4wMTI4IDI0LjMxNTMgNjQuNzQ1NyAxOCA1Ny4wNDM1IDE4QzQ5LjM0MTQgMTggNDMuMDc0MiAyNC4zMTUzIDQzLjA3NDIgMzIuMDc5QzQzLjA3NDIgMzguNzU4OSA0Ny43MTg0IDQ0LjM1NTIgNTMuOTE5NiA0NS43OTAzVjUzLjg1NTFDNDUuNDU2NyA1NS4zNTIzIDM5IDYyLjc5NjEgMzkgNzEuNzQ4MkMzOSA4MC43NDQgNDUuNTIwNiA4OC4yMTUxIDU0LjA0NDYgODkuNjYxM1Y5OC4xNzcyQzQ3Ljc4MDEgOTkuNTY1IDQzLjA3NDIgMTA1LjE5NiA0My4wNzQyIDExMS45MjFDNDMuMDc0MiAxMTkuNjg1IDQ5LjM0MTQgMTI2IDU3LjA0MzUgMTI2QzY0Ljc0NTcgMTI2IDcxLjAxMjggMTE5LjY4NSA3MS4wMTI4IDExMS45MjFDNzEuMDEyOCAxMDUuMTk2IDY2LjMwNyA5OS41NjUgNjAuMDQyNCA5OC4xNzcyVjg5LjY2MTFDNjQuMzU2OSA4OC45Mjg2IDY4LjI2MDEgODYuNjQwNyA3MS4wMjUyIDgzLjIyMzRMNzcuNjMzNyA4Ny45Mzc2Qzc3LjI2NjkgODkuMTk1MiA3Ny4wNjE0IDkwLjUyMTkgNzcuMDYxNCA5MS44OTc1Qzc3LjA2MTQgOTkuNjYxMiA4My4zMjg1IDEwNS45NzYgOTEuMDMwNyAxMDUuOTc2Qzk4LjczMjggMTA1Ljk3NiAxMDUgOTkuNjYxMiAxMDUgOTEuODk3NUMxMDUgODQuMTMzOCA5OC43MzI4IDc3LjgxODUgOTEuMDMwNyA3Ny44MTg1Wk05MS4wMzA3IDQ0Ljg5ODVDOTQuNzY1NiA0NC44OTg1IDk3LjgwMzQgNDcuOTYxNSA5Ny44MDM0IDUxLjcyNDdDOTcuODAzNCA1NS40ODc5IDk0Ljc2NTYgNTguNTUwNiA5MS4wMzA3IDU4LjU1MDZDODcuMjk1OCA1OC41NTA2IDg0LjI1OCA1NS40ODc5IDg0LjI1OCA1MS43MjQ3Qzg0LjI1OCA0Ny45NjE1IDg3LjI5NTggNDQuODk4NSA5MS4wMzA3IDQ0Ljg5ODVaTTUwLjI3MDUgMzIuMDc5QzUwLjI3MDUgMjguMzE1OCA1My4zMDg2IDI1LjI1MzEgNTcuMDQzNSAyNS4yNTMxQzYwLjc3ODUgMjUuMjUzMSA2My44MTYzIDI4LjMxNTggNjMuODE2MyAzMi4wNzlDNjMuODE2MyAzNS44NDIyIDYwLjc3ODUgMzguOTA0OSA1Ny4wNDM1IDM4LjkwNDlDNTMuMzA4NiAzOC45MDQ5IDUwLjI3MDUgMzUuODQyMiA1MC4yNzA1IDMyLjA3OVpNNjMuODE2MyAxMTEuOTIxQzYzLjgxNjMgMTE1LjY4NCA2MC43Nzg1IDExOC43NDcgNTcuMDQzNSAxMTguNzQ3QzUzLjMwODYgMTE4Ljc0NyA1MC4yNzA1IDExNS42ODQgNTAuMjcwNSAxMTEuOTIxQzUwLjI3MDUgMTA4LjE1OCA1My4zMDg2IDEwNS4wOTUgNTcuMDQzNSAxMDUuMDk1QzYwLjc3ODUgMTA1LjA5NSA2My44MTYzIDEwOC4xNTggNjMuODE2MyAxMTEuOTIxWk01Ny4wNDMgODEuMjY4MUM1MS44MzM5IDgxLjI2ODEgNDcuNTk2MiA3Ni45OTggNDcuNTk2MiA3MS43NDgyQzQ3LjU5NjIgNjYuNDk4MiA1MS44MzM5IDYyLjIyNzMgNTcuMDQzIDYyLjIyNzNDNjIuMjUxOSA2Mi4yMjczIDY2LjQ4OTUgNjYuNDk4MiA2Ni40ODk1IDcxLjc0ODJDNjYuNDg5NSA3Ni45OTggNjIuMjUxOSA4MS4yNjgxIDU3LjA0MyA4MS4yNjgxWk05MS4wMzA3IDk4LjcyMzdDODcuMjk1OCA5OC43MjM3IDg0LjI1OCA5NS42NjA3IDg0LjI1OCA5MS44OTc1Qzg0LjI1OCA4OC4xMzQzIDg3LjI5NTggODUuMDcxNiA5MS4wMzA3IDg1LjA3MTZDOTQuNzY1NiA4NS4wNzE2IDk3LjgwMzQgODguMTM0MyA5Ny44MDM0IDkxLjg5NzVDOTcuODAzNCA5NS42NjA3IDk0Ljc2NTYgOTguNzIzNyA5MS4wMzA3IDk4LjcyMzdaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4MV8yODIwIiB4MT0iMTQwIiB5MT0iMTMwLjUiIHgyPSI0IiB5Mj0iOS40OTk5OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcC8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzQzNDE0MSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "topics"], ["spec", "kafka"], ["spec", "kafka", "replicas"], ["spec", "kafka", "resources"], ["spec", "kafka", "resourcesPreset"], ["spec", "kafka", "size"], ["spec", "kafka", "storageClass"], ["spec", "zookeeper"], ["spec", "zookeeper", "replicas"], ["spec", "zookeeper", "resources"], ["spec", "zookeeper", "resourcesPreset"], ["spec", "zookeeper", "size"], ["spec", "zookeeper", "storageClass"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`kafka-{{ .name }}-clients-ca`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`kafka-{{ .name }}-kafka-bootstrap`}}" diff --git a/packages/core/platform/psds/kubernetes-application.yaml b/packages/core/platform/psds/kubernetes-application.yaml new file mode 100644 index 00000000..719672bc --- /dev/null +++ b/packages/core/platform/psds/kubernetes-application.yaml @@ -0,0 +1,64 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.kubernetes-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.capi-operator + - cozystack.capi-providers-bootstrap + - cozystack.capi-providers-core + - cozystack.capi-providers-cpprovider + - cozystack.capi-providers-infraprovider + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: kubernetes-ingress-nginx + path: system/ingress-nginx + - name: kubernetes-cert-manager-crds + path: system/cert-manager-crds + - name: kubernetes-volumesnapshot-crd + path: system/vsnap-crd + - name: kubernetes-velero + path: system/velero + - name: kubernetes-gateway-api-crds + path: system/gateway-api-crds + - name: kubernetes-victoria-metrics-operator + path: system/victoria-metrics-operator + - name: kubernetes-kubevirt-csi-node + path: system/kubevirt-csi-node + - name: kubernetes-vertical-pod-autoscaler-crds + path: system/vertical-pod-autoscaler-crds + - name: kubernetes-coredns + path: system/coredns + - name: kubernetes-cert-manager + path: system/cert-manager + - name: kubernetes-fluxcd-operator + path: system/fluxcd-operator + - name: kubernetes-fluxcd + path: system/fluxcd + - name: kubernetes-monitoring-agents + path: system/monitoring-agents + - name: kubernetes-cilium + path: system/cilium + - name: kubernetes-gpu-operator + path: system/gpu-operator + - name: kubernetes-vertical-pod-autoscaler + path: system/vertical-pod-autoscaler + - name: kubernetes + path: apps/kubernetes + libraries: ["cozy-lib"] + - name: kubernetes-rd + path: system/kubernetes-rd + install: + namespace: cozy-system + releaseName: kubernetes-rd diff --git a/packages/core/platform/psds/kubernetes.yaml b/packages/core/platform/psds/kubernetes.yaml deleted file mode 100644 index 350f9750..00000000 --- a/packages/core/platform/psds/kubernetes.yaml +++ /dev/null @@ -1,98 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.kubernetes-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.capi-operator - - cozystack.capi-providers-bootstrap - - cozystack.capi-providers-core - - cozystack.capi-providers-cpprovider - - cozystack.capi-providers-infraprovider - libraries: - - name: cozy-lib - path: library/cozy-lib - components: - - name: kubernetes-ingress-nginx - path: system/ingress-nginx - - name: kubernetes-cert-manager-crds - path: system/cert-manager-crds - - name: kubernetes-volumesnapshot-crd - path: system/vsnap-crd - - name: kubernetes-velero - path: system/velero - - name: kubernetes-gateway-api-crds - path: system/gateway-api-crds - - name: kubernetes-victoria-metrics-operator - path: system/victoria-metrics-operator - - name: kubernetes-kubevirt-csi-node - path: system/kubevirt-csi-node - - name: kubernetes-vertical-pod-autoscaler-crds - path: system/vertical-pod-autoscaler-crds - - name: kubernetes-coredns - path: system/coredns - - name: kubernetes-cert-manager - path: system/cert-manager - - name: kubernetes-fluxcd-operator - path: system/fluxcd-operator - - name: kubernetes-fluxcd - path: system/fluxcd - - name: kubernetes-monitoring-agents - path: system/monitoring-agents - - name: kubernetes-cilium - path: system/cilium - - name: kubernetes-gpu-operator - path: system/gpu-operator - - name: kubernetes-vertical-pod-autoscaler - path: system/vertical-pod-autoscaler - applications: - - name: kubernetes - path: apps/kubernetes - libraries: - - cozy-lib - template: - spec: - application: - kind: Kubernetes - singular: kubernetes - plural: kuberneteses - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"addons":{"description":"Cluster addons configuration.","type":"object","default":{},"required":["certManager","cilium","coredns","fluxcd","gatewayAPI","gpuOperator","ingressNginx","monitoringAgents","velero","verticalPodAutoscaler"],"properties":{"certManager":{"description":"Cert-manager addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable cert-manager.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"cilium":{"description":"Cilium CNI plugin.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"coredns":{"description":"CoreDNS addon.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"fluxcd":{"description":"FluxCD GitOps operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable FluxCD.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"gatewayAPI":{"description":"Gateway API addon.","type":"object","default":{},"required":["enabled"],"properties":{"enabled":{"description":"Enable Gateway API.","type":"boolean","default":false}}},"gpuOperator":{"description":"NVIDIA GPU Operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable GPU Operator.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"ingressNginx":{"description":"Ingress-NGINX controller.","type":"object","default":{},"required":["enabled","exposeMethod","valuesOverride"],"properties":{"enabled":{"description":"Enable the controller (requires nodes labeled `ingress-nginx`).","type":"boolean","default":false},"exposeMethod":{"description":"Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`.","type":"string","default":"Proxied"},"hosts":{"description":"Domains routed to this tenant cluster when `exposeMethod` is `Proxied`.","type":"array","default":[],"items":{"type":"string"}},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"monitoringAgents":{"description":"Monitoring agents.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable monitoring agents.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"velero":{"description":"Velero backup/restore addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable Velero.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"verticalPodAutoscaler":{"description":"Vertical Pod Autoscaler.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}}}},"controlPlane":{"description":"Kubernetes control-plane configuration.","type":"object","default":{},"required":["apiServer","controllerManager","konnectivity","replicas","scheduler"],"properties":{"apiServer":{"description":"API Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for API Server.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"medium","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"controllerManager":{"description":"Controller Manager configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Controller Manager.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"konnectivity":{"description":"Konnectivity configuration.","type":"object","default":{},"required":["server"],"properties":{"server":{"description":"Konnectivity Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Konnectivity.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"replicas":{"description":"Number of control-plane replicas.","type":"integer","default":2},"scheduler":{"description":"Scheduler configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Scheduler.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"host":{"description":"External hostname for Kubernetes cluster. Defaults to `.` if empty.","type":"string","default":""},"nodeGroups":{"description":"Worker nodes configuration map.","type":"object","default":{"md0":{"ephemeralStorage":"20Gi","gpus":[],"instanceType":"u1.medium","maxReplicas":10,"minReplicas":0,"resources":{},"roles":["ingress-nginx"]}},"additionalProperties":{"type":"object","required":["ephemeralStorage","instanceType","maxReplicas","minReplicas","resources"],"properties":{"ephemeralStorage":{"description":"Ephemeral storage size.","default":"20Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"description":"Name of GPU, such as \"nvidia.com/AD102GL_L40S\".","type":"string"}}}},"instanceType":{"description":"Virtual machine instance type.","type":"string","default":"u1.medium"},"maxReplicas":{"description":"Maximum number of replicas.","type":"integer","default":10},"minReplicas":{"description":"Minimum number of replicas.","type":"integer","default":0},"resources":{"description":"CPU and memory resources for each worker node.","type":"object","properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"roles":{"description":"List of node roles.","type":"array","items":{"type":"string"}}}}},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"},"version":{"description":"Kubernetes version (vMAJOR.MINOR). Supported: 1.28–1.33.","type":"string","default":"v1.33","enum":["v1.28","v1.29","v1.30","v1.31","v1.32","v1.33"]}}} - release: - prefix: kubernetes- - labels: - cozystack.io/ui: "true" - dashboard: - category: IaaS - singular: Kubernetes - plural: Kubernetes - weight: 40 - description: Managed Kubernetes service - tags: - - compute - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjg0NSkiLz4KPHBhdGggZD0iTTcxLjk5NjggMTlDNzAuMzAzOSAxOS4wMDAyIDY4LjkzMTIgMjAuNTMyMiA2OC45MzE0IDIyLjQyMjFDNjguOTMxNCAyMi40NTExIDY4LjkzNzMgMjIuNDc4OCA2OC45Mzc5IDIyLjUwNzZDNjguOTM1NCAyMi43NjQ0IDY4LjkyMzEgMjMuMDczNyA2OC45MzE0IDIzLjI5NzNDNjguOTcxNyAyNC4zODczIDY5LjIwODIgMjUuMjIxNiA2OS4zNTA2IDI2LjIyNThDNjkuNjA4NCAyOC4zNzUyIDY5LjgyNDUgMzAuMTU2OSA2OS42OTEyIDMxLjgxM0M2OS41NjE1IDMyLjQzNzUgNjkuMTAzNyAzMy4wMDg2IDY4LjY5NTYgMzMuNDA1Nkw2OC42MjM1IDM0LjcwODZDNjYuNzgzOSAzNC44NjE3IDY0LjkzMTkgMzUuMTQyMSA2My4wODIxIDM1LjU2NDFDNTUuMTIyNiAzNy4zNzk4IDQ4LjI2OTUgNDEuNDk5MSA0My4wNTIgNDcuMDYwOUM0Mi43MTM0IDQ2LjgyODggNDIuMTIxMSA0Ni40MDE5IDQxLjk0NSA0Ni4yNzEyQzQxLjM5NzcgNDYuMzQ1NCA0MC44NDQ1IDQ2LjUxNTEgNDAuMTI0MSA0Ni4wOTM1QzM4Ljc1MjIgNDUuMTY1NyAzNy41MDI4IDQzLjg4NTEgMzUuOTkxIDQyLjM0MjRDMzUuMjk4MiA0MS42MDQ0IDM0Ljc5NjYgNDAuOTAxOCAzMy45NzM1IDQwLjE5MDRDMzMuNzg2NiA0MC4wMjg5IDMzLjUwMTQgMzkuODEwNCAzMy4yOTIzIDM5LjY0NDJDMzIuNjQ4OSAzOS4xMjg4IDMxLjg5IDM4Ljg2IDMxLjE1NyAzOC44MzQ4QzMwLjIxNDcgMzguODAyNCAyOS4zMDc1IDM5LjE3MjUgMjguNzEzOCAzOS45MjA2QzI3LjY1ODQgNDEuMjUwNiAyNy45OTYzIDQzLjI4MzMgMjkuNDY3MSA0NC40NjE0QzI5LjQ4MiA0NC40NzM0IDI5LjQ5NzkgNDQuNDgyNyAyOS41MTI5IDQ0LjQ5NDNDMjkuNzE1IDQ0LjY1ODkgMjkuOTYyNSA0NC44Njk4IDMwLjE0ODMgNDUuMDA3NkMzMS4wMjE3IDQ1LjY1NTUgMzEuODE5NSA0NS45ODcyIDMyLjY4OTcgNDYuNTAxNUMzNC41MjMxIDQ3LjYzOTEgMzYuMDQzIDQ4LjU4MjMgMzcuMjQ4NiA0OS43MTk2QzM3LjcxOTQgNTAuMjIzNyAzNy44MDE2IDUxLjExMjIgMzcuODY0MyA1MS40OTY0TDM4Ljg0NjggNTIuMzc4MkMzMy41ODcyIDYwLjMzMDggMzEuMTUzIDcwLjE1MzkgMzIuNTkxNSA4MC4xNjI3TDMxLjMwNzcgODAuNTM3OEMzMC45NjkzIDgwLjk3NjggMzAuNDkxMiA4MS42Njc2IDI5Ljk5MTEgODEuODczOEMyOC40MTM4IDgyLjM3MjkgMjYuNjM4NyA4Mi41NTYyIDI0LjQ5NTYgODIuNzgxOUMyMy40ODk0IDgyLjg2NiAyMi42MjEzIDgyLjgxNTggMjEuNTU0NiA4My4wMTg4QzIxLjMxOTggODMuMDYzNSAyMC45OTI3IDgzLjE0OTEgMjAuNzM1OCA4My4yMDk3QzIwLjcyNjkgODMuMjExNiAyMC43MTg2IDgzLjIxNDIgMjAuNzA5NiA4My4yMTYyQzIwLjY5NTYgODMuMjE5NSAyMC42NzcyIDgzLjIyNjMgMjAuNjYzOCA4My4yMjk0QzE4Ljg1NyA4My42NjggMTcuNjk2MyA4NS4zMzY1IDE4LjA2OTkgODYuOTgwNUMxOC40NDM3IDg4LjYyNDggMjAuMjA4NiA4OS42MjQ4IDIyLjAyNjIgODkuMjMxMkMyMi4wMzkzIDg5LjIyODIgMjIuMDU4NCA4OS4yMjc3IDIyLjA3MiA4OS4yMjQ2QzIyLjA5MjYgODkuMjE5OSAyMi4xMTA2IDg5LjIwOTkgMjIuMTMxIDg5LjIwNDlDMjIuMzg0NCA4OS4xNDkgMjIuNzAxOSA4OS4wODY4IDIyLjkyMzYgODkuMDI3MkMyMy45NzIzIDg4Ljc0NTEgMjQuNzMxOCA4OC4zMzA2IDI1LjY3NDYgODcuOTY3N0MyNy43MDI5IDg3LjIzNjggMjkuMzgyOCA4Ni42MjYyIDMxLjAxOTUgODYuMzg4M0MzMS43MDMgODYuMzM0NSAzMi40MjMyIDg2LjgxMiAzMi43ODE0IDg3LjAxMzRMMzQuMTE3NyA4Ni43ODMxQzM3LjE5MjYgOTYuMzYxMyA0My42MzY2IDEwNC4xMDMgNTEuNzk2MyAxMDguOTYxTDUxLjIzOTYgMTEwLjMwM0M1MS40NDAzIDExMC44MjQgNTEuNjYxNiAxMTEuNTMgNTEuNTEyMSAxMTIuMDQ1QzUwLjkxNzEgMTEzLjU5NSA0OS44OTggMTE1LjIzMSA0OC43Mzc0IDExNy4wNTVDNDguMTc1NSAxMTcuODk4IDQ3LjYwMDQgMTE4LjU1MiA0Ny4wOTM0IDExOS41MTZDNDYuOTcyIDExOS43NDcgNDYuODE3NSAxMjAuMTAyIDQ2LjcwMDQgMTIwLjM0NkM0NS45MTI1IDEyMi4wMzkgNDYuNDkwNCAxMjMuOTkgNDguMDAzOCAxMjQuNzIyQzQ5LjUyNjggMTI1LjQ1OSA1MS40MTcxIDEyNC42ODIgNTIuMjM1MiAxMjIuOTg1QzUyLjIzNjQgMTIyLjk4MiA1Mi4yNDA2IDEyMi45OCA1Mi4yNDE3IDEyMi45NzhDNTIuMjQyNiAxMjIuOTc2IDUyLjI0MDkgMTIyLjk3MyA1Mi4yNDE3IDEyMi45NzFDNTIuMzU4MiAxMjIuNzMxIDUyLjUyMzMgMTIyLjQxNSA1Mi42MjE2IDEyMi4xODhDNTMuMDU2IDEyMS4xODkgNTMuMjAwNSAxMjAuMzMyIDUzLjUwNTkgMTE5LjM2NUM1NC4zMTcgMTE3LjMxOCA1NC43NjI2IDExNS4xNyA1NS44NzkxIDExMy44MzJDNTYuMTg0OSAxMTMuNDY2IDU2LjY4MzMgMTEzLjMyNSA1Ny4yMDAxIDExMy4xODZMNTcuODk0NCAxMTEuOTIyQzY1LjAwOCAxMTQuNjY1IDcyLjk3MDUgMTE1LjQwMiA4MC45MjQ1IDExMy41ODdDODIuNzM5MSAxMTMuMTczIDg0LjQ5MDggMTEyLjYzNyA4Ni4xODQzIDExMS45OTRDODYuMzc5NCAxMTIuMzQyIDg2Ljc0MiAxMTMuMDExIDg2LjgzOTMgMTEzLjE3OUM4Ny4zNjQ0IDExMy4zNTEgODcuOTM3NyAxMTMuNDM5IDg4LjQwNDcgMTE0LjEzM0M4OS4yNDAxIDExNS41NjcgODkuODExNCAxMTcuMjYzIDkwLjUwNzMgMTE5LjMxMkM5MC44MTI4IDEyMC4yNzkgOTAuOTYzOCAxMjEuMTM2IDkxLjM5ODEgMTIyLjEzNkM5MS40OTcxIDEyMi4zNjMgOTEuNjYxNCAxMjIuNjg0IDkxLjc3OCAxMjIuOTI1QzkyLjU5NDQgMTI0LjYyOCA5NC40OTA3IDEyNS40MDcgOTYuMDE1OSAxMjQuNjY5Qzk3LjUyOTIgMTIzLjkzNyA5OC4xMDc3IDEyMS45ODYgOTcuMzE5NCAxMjAuMjkzQzk3LjIwMjMgMTIwLjA0OSA5Ny4wNDEyIDExOS42OTUgOTYuOTE5OCAxMTkuNDY0Qzk2LjQxMjcgMTE4LjQ5OSA5NS44Mzc3IDExNy44NTIgOTUuMjc1OCAxMTcuMDA5Qzk0LjExNTIgMTE1LjE4NSA5My4xNTI2IDExMy42NyA5Mi41NTc1IDExMi4xMkM5Mi4zMDg3IDExMS4zMiA5Mi41OTk1IDExMC44MjMgOTIuNzkzMyAxMTAuMzAzQzkyLjY3NzIgMTEwLjE3IDkyLjQyODggMTA5LjQxNCA5Mi4yODI0IDEwOS4wNTlDMTAwLjc2MiAxMDQuMDI5IDEwNy4wMTcgOTUuOTk4NSAxMDkuOTU1IDg2LjcyMzlDMTEwLjM1MSA4Ni43ODY1IDExMS4wNDEgODYuOTA5MSAxMTEuMjY1IDg2Ljk1NDJDMTExLjcyNiA4Ni42NDg3IDExMi4xNDkgODYuMjUwMSAxMTIuOTgxIDg2LjMxNTlDMTE0LjYxNyA4Ni41NTM3IDExNi4yOTcgODcuMTY0NSAxMTguMzI2IDg3Ljg5NTNDMTE5LjI2OCA4OC4yNTgxIDEyMC4wMjggODguNjc5MyAxMjEuMDc3IDg4Ljk2MTRDMTIxLjI5OCA4OS4wMjEgMTIxLjYxNiA4OS4wNzY2IDEyMS44NjkgODkuMTMyNUMxMjEuODg5IDg5LjEzNzUgMTIxLjkwOCA4OS4xNDc1IDEyMS45MjggODkuMTUyMkMxMjEuOTQyIDg5LjE1NTMgMTIxLjk2MSA4OS4xNTU4IDEyMS45NzQgODkuMTU4OEMxMjMuNzkyIDg5LjU1MiAxMjUuNTU3IDg4LjU1MjYgMTI1LjkzIDg2LjkwODFDMTI2LjMwMyA4NS4yNjQxIDEyNS4xNDMgODMuNTk1MiAxMjMuMzM2IDgzLjE1N0MxMjMuMDc0IDgzLjA5NyAxMjIuNzAxIDgyLjk5NSAxMjIuNDQ2IDgyLjk0NjVDMTIxLjM3OSA4Mi43NDM1IDEyMC41MTEgODIuNzkzNSAxMTkuNTA1IDgyLjcwOTVDMTE3LjM2MSA4Mi40ODM5IDExNS41ODYgODIuMzAwNCAxMTQuMDA5IDgxLjgwMTRDMTEzLjM2NiA4MS41NTA3IDExMi45MDggODAuNzgxOSAxMTIuNjg2IDgwLjQ2NTVMMTExLjQ0OCA4MC4xMDM1QzExMi4wOSA3NS40MzggMTExLjkxNyA3MC41ODI1IDExMC44MDYgNjUuNzI0M0MxMDkuNjg1IDYwLjgyMDggMTA3LjcwNCA1Ni4zMzYxIDEwNS4wNjIgNTIuMzg0OEMxMDUuMzc5IDUyLjA5NDggMTA1Ljk3OSA1MS41NjEyIDEwNi4xNDkgNTEuNDA0M0MxMDYuMTk5IDUwLjg1MTcgMTA2LjE1NiA1MC4yNzIyIDEwNi43MjUgNDkuNjYwM0MxMDcuOTMxIDQ4LjUyMyAxMDkuNDUxIDQ3LjU3OTkgMTExLjI4NCA0Ni40NDIzQzExMi4xNTQgNDUuOTI3OSAxMTIuOTU5IDQ1LjU5NjQgMTEzLjgzMiA0NC45NDg0QzExNC4wMyA0NC44MDE5IDExNC4yOTkgNDQuNTY5OSAxMTQuNTA3IDQ0LjQwMjJDMTE1Ljk3NyA0My4yMjM3IDExNi4zMTYgNDEuMTkxMSAxMTUuMjYgMzkuODYxNEMxMTQuMjA0IDM4LjUzMTcgMTEyLjE1OSAzOC40MDY1IDExMC42ODggMzkuNTg1QzExMC40NzkgMzkuNzUxNiAxMTAuMTk1IDM5Ljk2ODggMTEwLjAwNyA0MC4xMzEyQzEwOS4xODQgNDAuODQyNiAxMDguNjc2IDQxLjU0NTIgMTA3Ljk4MyA0Mi4yODMyQzEwNi40NzEgNDMuODI1OSAxMDUuMjIyIDQ1LjExMyAxMDMuODUgNDYuMDQwOUMxMDMuMjU1IDQ2LjM4ODUgMTAyLjM4NSA0Ni4yNjgyIDEwMS45OSA0Ni4yNDQ5TDEwMC44MjQgNDcuMDgwNkM5NC4xNzUzIDQwLjA3NjMgODUuMTIzNSAzNS41OTgyIDc1LjM3NjYgMzQuNzI4M0M3NS4zNDk0IDM0LjMxNzkgNzUuMzEzNyAzMy41NzYxIDc1LjMwNDYgMzMuMzUyOUM3NC45MDU2IDMyLjk2OTMgNzQuNDIzNSAzMi42NDE4IDc0LjMwMjQgMzEuODEzQzc0LjE2OTEgMzAuMTU2OSA3NC4zOTE3IDI4LjM3NTIgNzQuNjQ5NiAyNi4yMjU4Qzc0Ljc5MTkgMjUuMjIxNiA3NS4wMjg0IDI0LjM4NzMgNzUuMDY4OCAyMy4yOTczQzc1LjA3OCAyMy4wNDk1IDc1LjA2MzIgMjIuNjkgNzUuMDYyMiAyMi40MjIxQzc1LjA2MiAyMC41MzIyIDczLjY4OTggMTguOTk5OCA3MS45OTY4IDE5Wk02OC4xNTg1IDQyLjg4ODZMNjcuMjQ4IDU5LjA0NDdMNjcuMTgyNSA1OS4wNzc2QzY3LjEyMTQgNjAuNTIyOSA2NS45Mzc1IDYxLjY3NyA2NC40ODM5IDYxLjY3N0M2My44ODg0IDYxLjY3NyA2My4zMzg4IDYxLjQ4NDkgNjIuODkyMiA2MS4xNTcxTDYyLjg2NiA2MS4xNzAzTDQ5LjY4MDcgNTEuNzc5NEM1My43MzMxIDQ3Ljc3NTkgNTguOTE2NCA0NC44MTcyIDY0Ljg5IDQzLjQ1NDZDNjUuOTgxMiA0My4yMDU2IDY3LjA3MTkgNDMuMDIwOSA2OC4xNTg1IDQyLjg4ODZaTTc1Ljg0MTcgNDIuODg4NkM4Mi44MTU5IDQzLjc1MDQgODkuMjY1NyA0Ni45MjMyIDk0LjIwODEgNTEuNzg2TDgxLjEwOCA2MS4xMTc2TDgxLjA2MjEgNjEuMDk3OUM3OS44OTk0IDYxLjk1MTIgNzguMjYxMSA2MS43Mzk0IDc3LjM1NDggNjAuNTk3OEM3Ni45ODM1IDYwLjEzMDEgNzYuNzg4NyA1OS41ODAxIDc2Ljc2NTMgNTkuMDI0OUw3Ni43NTIyIDU5LjAxODRMNzUuODQxNyA0Mi44ODg2Wk00NC44OTkxIDU3LjgxNEw1Ni45MzgyIDY4LjYzM0w1Ni45MjUxIDY4LjY5ODhDNTguMDExNyA2OS42NDc5IDU4LjE3MiA3MS4yOTQ5IDU3LjI2NTcgNzIuNDM2OEM1Ni44OTQ0IDcyLjkwNDUgNTYuMzk3NSA3My4yMTgyIDU1Ljg2MzkgNzMuMzY0N0w1NS44NTA4IDczLjQxNzNMNDAuNDE4OCA3Ny44OTIzQzM5LjYzMzQgNzAuNjc2NSA0MS4zMjYxIDYzLjY2MjEgNDQuODk5MSA1Ny44MTRaTTk5LjAwOTQgNTcuODIwNkMxMDAuNzk4IDYwLjczMzYgMTAyLjE1MyA2My45ODcxIDEwMi45NTkgNjcuNTE0M0MxMDMuNzU2IDcwLjk5OTEgMTAzLjk1NiA3NC40Nzc4IDEwMy42MjcgNzcuODM5N0w4OC4xMTY2IDczLjM1MTVMODguMTAzNSA3My4yODU3Qzg2LjcxNDUgNzIuOTA0MyA4NS44NjA5IDcxLjQ4NDggODYuMTg0MyA3MC4wNjExQzg2LjMxNjggNjkuNDc3OCA4Ni42MjQ5IDY4Ljk4NDQgODcuMDQyMyA2OC42MTk4TDg3LjAzNTggNjguNTg2OUw5OS4wMDk0IDU3LjgyMDZaTTY5LjUyNzQgNjkuNDY4OEg3NC40NTk2TDc3LjUyNTEgNzMuMzE4Nkw3Ni40MjQ3IDc4LjEyMjZMNzEuOTk2OCA4MC4yNjE0TDY3LjU1NTggNzguMTE2MUw2Ni40NTU0IDczLjMxMkw2OS41Mjc0IDY5LjQ2ODhaTTg1LjMzOTMgODIuNjQzN0M4NS41NDg5IDgyLjYzMzEgODUuNzU3NiA4Mi42NTIgODUuOTYxNiA4Mi42ODk4TDg1Ljk4NzggODIuNjU2OUwxMDEuOTUgODUuMzY4MkM5OS42MTQyIDkxLjk2MjQgOTUuMTQ0IDk3LjY3NSA4OS4xNzExIDEwMS40OThMODIuOTc0NyA4Ni40NjA2TDgyLjk5NDQgODYuNDM0M0M4Mi40MjUyIDg1LjEwNTUgODIuOTk0OCA4My41NDcyIDg0LjMwNDQgODIuOTEzNUM4NC42Mzk3IDgyLjc1MTMgODQuOTkgODIuNjYxNCA4NS4zMzkzIDgyLjY0MzdaTTU4LjUyOTggODIuNzA5NUM1OS43NDggODIuNzI2NyA2MC44NDA2IDgzLjU3NjEgNjEuMTIzNyA4NC44MjJDNjEuMjU2MiA4NS40MDUyIDYxLjE5MTcgODUuOTgzMSA2MC45NzMgODYuNDkzNUw2MS4wMTg5IDg2LjU1MjdMNTQuODg4IDEwMS40MzlDNDkuMTU1OSA5Ny43NDMyIDQ0LjU5MDQgOTIuMjA5OSA0Mi4xNDgxIDg1LjQyMDhMNTcuOTczMSA4Mi43MjI3TDU3Ljk5OTMgODIuNzU1NkM1OC4xNzYzIDgyLjcyMjkgNTguMzU1OCA4Mi43MDcxIDU4LjUyOTggODIuNzA5NVpNNzEuODk4NiA4OS4yMzEyQzcyLjMyMjkgODkuMjE1NSA3Mi43NTM0IDg5LjMwMyA3My4xNjI3IDg5LjUwMUM3My42OTkyIDg5Ljc2MDYgNzQuMTEzNiA5MC4xNjkyIDc0LjM3NDUgOTAuNjU5Mkg3NC40MzM0TDgyLjIzNDYgMTA0LjgyMUM4MS4yMjIxIDEwNS4xNjIgODAuMTgxMyAxMDUuNDU0IDc5LjExNjcgMTA1LjY5N0M3My4xNTA1IDEwNy4wNTggNjcuMjAzMiAxMDYuNjQ1IDYxLjgxOCAxMDQuODAyTDY5LjU5OTUgOTAuNjY1OEg2OS42MTI2QzcwLjA3OTUgODkuNzg4OCA3MC45NjUgODkuMjY1NiA3MS44OTg2IDg5LjIzMTJaIiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjI1Ii8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgxXzI4NDUiIHgxPSIxMCIgeTE9IjE1LjUiIHgyPSIxNDQiIHkyPSIxMzEuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNEQ4N0ZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzA1NDdEMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "storageClass"], ["spec", "nodeGroups"], ["spec", "nodeGroups", "md0"], ["spec", "nodeGroups", "md0", "minReplicas"], ["spec", "nodeGroups", "md0", "maxReplicas"], ["spec", "nodeGroups", "md0", "instanceType"], ["spec", "nodeGroups", "md0", "ephemeralStorage"], ["spec", "nodeGroups", "md0", "roles"], ["spec", "nodeGroups", "md0", "resources"], ["spec", "nodeGroups", "md0", "gpus"], ["spec", "version"], ["spec", "host"], ["spec", "addons"], ["spec", "addons", "certManager"], ["spec", "addons", "certManager", "enabled"], ["spec", "addons", "certManager", "valuesOverride"], ["spec", "addons", "cilium"], ["spec", "addons", "cilium", "valuesOverride"], ["spec", "addons", "gatewayAPI"], ["spec", "addons", "gatewayAPI", "enabled"], ["spec", "addons", "ingressNginx"], ["spec", "addons", "ingressNginx", "enabled"], ["spec", "addons", "ingressNginx", "exposeMethod"], ["spec", "addons", "ingressNginx", "hosts"], ["spec", "addons", "ingressNginx", "valuesOverride"], ["spec", "addons", "gpuOperator"], ["spec", "addons", "gpuOperator", "enabled"], ["spec", "addons", "gpuOperator", "valuesOverride"], ["spec", "addons", "fluxcd"], ["spec", "addons", "fluxcd", "enabled"], ["spec", "addons", "fluxcd", "valuesOverride"], ["spec", "addons", "monitoringAgents"], ["spec", "addons", "monitoringAgents", "enabled"], ["spec", "addons", "monitoringAgents", "valuesOverride"], ["spec", "addons", "verticalPodAutoscaler"], ["spec", "addons", "verticalPodAutoscaler", "valuesOverride"], ["spec", "addons", "velero"], ["spec", "addons", "velero", "enabled"], ["spec", "addons", "velero", "valuesOverride"], ["spec", "addons", "coredns"], ["spec", "addons", "coredns", "valuesOverride"], ["spec", "controlPlane"], ["spec", "controlPlane", "replicas"], ["spec", "controlPlane", "apiServer"], ["spec", "controlPlane", "apiServer", "resources"], ["spec", "controlPlane", "apiServer", "resourcesPreset"], ["spec", "controlPlane", "controllerManager"], ["spec", "controlPlane", "controllerManager", "resources"], ["spec", "controlPlane", "controllerManager", "resourcesPreset"], ["spec", "controlPlane", "scheduler"], ["spec", "controlPlane", "scheduler", "resources"], ["spec", "controlPlane", "scheduler", "resourcesPreset"], ["spec", "controlPlane", "konnectivity"], ["spec", "controlPlane", "konnectivity", "server"], ["spec", "controlPlane", "konnectivity", "server", "resources"], ["spec", "controlPlane", "konnectivity", "server", "resourcesPreset"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`kubernetes-{{ .name }}-admin-kubeconfig`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`kubernetes-{{ .name }}`}}" - ingresses: - exclude: [] - include: - - resourceNames: - - "{{`kubernetes-{{ .name }}`}}" diff --git a/packages/core/platform/psds/monitoring-application.yaml b/packages/core/platform/psds/monitoring-application.yaml new file mode 100644 index 00000000..0f01eddd --- /dev/null +++ b/packages/core/platform/psds/monitoring-application.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.monitoring-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: monitoring + path: extra/monitoring + libraries: ["cozy-lib"] + - name: monitoring-rd + path: system/monitoring-rd + install: + namespace: cozy-system + releaseName: monitoring-rd diff --git a/packages/core/platform/psds/monitoring.yaml b/packages/core/platform/psds/monitoring.yaml deleted file mode 100644 index 6958bb6a..00000000 --- a/packages/core/platform/psds/monitoring.yaml +++ /dev/null @@ -1,63 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.monitoring-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: monitoring - path: extra/monitoring - libraries: - - cozy-lib - template: - spec: - application: - kind: Monitoring - singular: monitoring - plural: monitorings - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"alerta":{"description":"Configuration for the Alerta service.","type":"object","default":{},"properties":{"alerts":{"description":"Alert routing configuration.","type":"object","default":{},"properties":{"slack":{"description":"Configuration for Slack alerts.","type":"object","default":{},"required":["url"],"properties":{"url":{"description":"Configuration uri for Slack alerts.","type":"string","default":""}}},"telegram":{"description":"Configuration for Telegram alerts.","type":"object","default":{},"required":["chatID","token"],"properties":{"chatID":{"description":"Telegram chat ID(s), separated by commas.","type":"string","default":""},"disabledSeverity":{"description":"List of severities without alerts (e.g. \"informational,warning\").","type":"string","default":""},"token":{"description":"Telegram bot token.","type":"string","default":""}}}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"storage":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the database.","type":"string","default":""}}},"grafana":{"description":"Configuration for Grafana.","type":"object","default":{},"properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"size":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}},"host":{"description":"The hostname used to access Grafana externally (defaults to 'grafana' subdomain for the tenant host).","type":"string","default":""},"logsStorages":{"description":"Configuration of logs storage instances.","type":"array","default":[{"name":"generic","retentionPeriod":"1","storage":"10Gi","storageClassName":"replicated"}],"items":{"type":"object","required":["name","retentionPeriod","storage","storageClassName"],"properties":{"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for logs.","type":"string","default":"1"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}},"metricsStorages":{"description":"Configuration of metrics storage instances.","type":"array","default":[{"deduplicationInterval":"15s","name":"shortterm","retentionPeriod":"3d","storage":"10Gi","storageClassName":""},{"deduplicationInterval":"5m","name":"longterm","retentionPeriod":"14d","storage":"10Gi","storageClassName":""}],"items":{"type":"object","required":["deduplicationInterval","name","retentionPeriod","storage"],"properties":{"deduplicationInterval":{"description":"Deduplication interval for metrics.","type":"string"},"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for metrics.","type":"string"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the data.","type":"string"},"vminsert":{"description":"Configuration for vminsert.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmselect":{"description":"Configuration for vmselect.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmstorage":{"description":"Configuration for vmstorage.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}}}}} - release: - prefix: "" - labels: - cozystack.io/ui: "true" - internal.cozystack.io/tenantmodule: "true" - dashboard: - category: Administration - singular: Monitoring - plural: Monitoring - name: monitoring - description: Monitoring and observability stack - module: true - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzI2OCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zMjY4KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMzg0NTRGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNNTQuMTcyMiAzOC43NzU3SDMzLjEwMzJDMzIuMTMwNyAzOC43NzU3IDMxLjQ4MjQgMzguMTI3NCAzMS40ODI0IDM3LjE1NDlDMzEuNDgyNCAzNi4xODI0IDMyLjEzMDcgMzUuNTM0MiAzMy4xMDMyIDM1LjUzNDJINTQuMTcyMkM1NS4xNDQ3IDM1LjUzNDIgNTUuNzkzIDM2LjE4MjQgNTUuNzkzIDM3LjE1NDlDNTUuNzkyOCAzOC4xMjc0IDU1LjE0NDUgMzguNzc1NyA1NC4xNzIyIDM4Ljc3NTdaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik02My44OTYzIDQ1LjI1OTFINDEuMjA2N0M0MC4yMzQyIDQ1LjI1OTEgMzkuNTg1OSA0NC42MTA4IDM5LjU4NTkgNDMuNjM4M0MzOS41ODU5IDQyLjY2NTggNDAuMjM0MiA0Mi4wMTc2IDQxLjIwNjcgNDIuMDE3Nkg2My44OTYzQzY0Ljg2ODggNDIuMDE3NiA2NS41MTcxIDQyLjY2NTggNjUuNTE3MSA0My42MzgzQzY1LjUxNzEgNDQuNjEwOCA2NC44Njg4IDQ1LjI1OTEgNjMuODk2MyA0NS4yNTkxWiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMzQuNzI0IDQ1LjI1OTFIMzMuMTAzMkMzMi4xMzA3IDQ1LjI1OTEgMzEuNDgyNCA0NC42MTA4IDMxLjQ4MjQgNDMuNjM4M0MzMS40ODI0IDQyLjY2NTggMzIuMTMwNyA0Mi4wMTc2IDMzLjEwMzIgNDIuMDE3NkgzNC43MjRDMzUuNjk2NCA0Mi4wMTc2IDM2LjM0NDcgNDIuNjY1OCAzNi4zNDQ3IDQzLjYzODNDMzYuMzQ0NyA0NC42MTA4IDM1LjY5NjMgNDUuMjU5MSAzNC43MjQgNDUuMjU5MVoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgMzguNzc1N0g2MC42NTQ5QzU5LjY4MjQgMzguNzc1NyA1OS4wMzQyIDM4LjEyNzQgNTkuMDM0MiAzNy4xNTQ5QzU5LjAzNDIgMzYuMTgyNCA1OS42ODI0IDM1LjUzNDIgNjAuNjU0OSAzNS41MzQySDYzLjg5NjNDNjQuODY4OCAzNS41MzQyIDY1LjUxNzEgMzYuMTgyNCA2NS41MTcxIDM3LjE1NDlDNjUuNTE3MSAzOC4xMjc0IDY0Ljg2ODggMzguNzc1NyA2My44OTYzIDM4Ljc3NTdaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik00Ny42ODkzIDUxLjc0MTNIMzMuMTAzMkMzMi4xMzA3IDUxLjc0MTMgMzEuNDgyNCA1MS4wOTMxIDMxLjQ4MjQgNTAuMTIwNkMzMS40ODI0IDQ5LjE0ODEgMzIuMTMwNyA0OC41IDMzLjEwMzIgNDguNUg0Ny42ODkzQzQ4LjY2MTggNDguNSA0OS4zMTAxIDQ5LjE0ODMgNDkuMzEwMSA1MC4xMjA4QzQ5LjMxMDEgNTEuMDkzMyA0OC42NjE4IDUxLjc0MTMgNDcuNjg5MyA1MS43NDEzWiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNjMuODk2OCA1MS43NDEzSDU0LjE3MjVDNTMuMiA1MS43NDEzIDUyLjU1MTggNTEuMDkzMSA1Mi41NTE4IDUwLjEyMDZDNTIuNTUxOCA0OS4xNDgxIDUzLjIwMDIgNDguNSA1NC4xNzI3IDQ4LjVINjMuODk2OUM2NC44Njk0IDQ4LjUgNjUuNTE3NyA0OS4xNDgzIDY1LjUxNzcgNTAuMTIwOEM2NS41MTc3IDUxLjA5MzMgNjQuODY5MiA1MS43NDEzIDYzLjg5NjggNTEuNzQxM1oiIGZpbGw9IiNFQ0JBMTYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNTguMjI0SDMzLjEwMzJDMzIuMTMwNyA1OC4yMjQgMzEuNDgyNCA1Ny41NzU3IDMxLjQ4MjQgNTYuNjAzMkMzMS40ODI0IDU1LjYzMDcgMzIuMTMwNyA1NC45ODI0IDMzLjEwMzIgNTQuOTgyNEg1NC4xNzIyQzU1LjE0NDcgNTQuOTgyNCA1NS43OTMgNTUuNjMwNyA1NS43OTMgNTYuNjAzMkM1NS43OTMgNTcuNTc1NyA1NS4xNDQ1IDU4LjIyNCA1NC4xNzIyIDU4LjIyNFoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgNjQuNzA3NEg0MS4yMDY3QzQwLjIzNDIgNjQuNzA3NCAzOS41ODU5IDY0LjA1OTEgMzkuNTg1OSA2My4wODY2QzM5LjU4NTkgNjIuMTE0MSA0MC4yMzQyIDYxLjQ2NTggNDEuMjA2NyA2MS40NjU4SDYzLjg5NjNDNjQuODY4OCA2MS40NjU4IDY1LjUxNzEgNjIuMTE0MSA2NS41MTcxIDYzLjA4NjZDNjUuNTE3MSA2NC4wNTkxIDY0Ljg2ODggNjQuNzA3NCA2My44OTYzIDY0LjcwNzRaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik0zNC43MjQgNjQuNzA3NEgzMy4xMDMyQzMyLjEzMDcgNjQuNzA3NCAzMS40ODI0IDY0LjA1OTEgMzEuNDgyNCA2My4wODY2QzMxLjQ4MjQgNjIuMTE0MSAzMi4xMzA3IDYxLjQ2NTggMzMuMTAzMiA2MS40NjU4SDM0LjcyNEMzNS42OTY0IDYxLjQ2NTggMzYuMzQ0NyA2Mi4xMTQxIDM2LjM0NDcgNjMuMDg2NkMzNi4zNDQ3IDY0LjA1OTEgMzUuNjk2MyA2NC43MDc0IDM0LjcyNCA2NC43MDc0WiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNDcuNjg5MyA3MS4xODk4SDMzLjEwMzJDMzIuMTMwNyA3MS4xODk4IDMxLjQ4MjQgNzAuNTQxNSAzMS40ODI0IDY5LjU2OUMzMS40ODI0IDY4LjU5NjUgMzIuMTMwNyA2Ny45NDgyIDMzLjEwMzIgNjcuOTQ4Mkg0Ny42ODkzQzQ4LjY2MTggNjcuOTQ4MiA0OS4zMTAxIDY4LjU5NjUgNDkuMzEwMSA2OS41NjlDNDkuMzEwMSA3MC41NDE1IDQ4LjY2MTggNzEuMTg5OCA0Ny42ODkzIDcxLjE4OThaIiBmaWxsPSIjNDJCMDVDIi8+CjxwYXRoIGQ9Ik02My44OTY4IDcxLjE4OThINTQuMTcyNUM1My4yIDcxLjE4OTggNTIuNTUxOCA3MC41NDE1IDUyLjU1MTggNjkuNTY5QzUyLjU1MTggNjguNTk2NSA1My4yIDY3Ljk0ODIgNTQuMTcyNSA2Ny45NDgySDYzLjg5NjhDNjQuODY5MiA2Ny45NDgyIDY1LjUxNzUgNjguNTk2NSA2NS41MTc1IDY5LjU2OUM2NS41MTc1IDcwLjU0MTUgNjQuODY5MiA3MS4xODk4IDYzLjg5NjggNzEuMTg5OFoiIGZpbGw9IiM3MzgzQkYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNzcuNjcyMkgzMy4xMDMyQzMyLjEzMDcgNzcuNjcyMiAzMS40ODI0IDc3LjAyMzkgMzEuNDgyNCA3Ni4wNTE0QzMxLjQ4MjQgNzUuMDc4OSAzMi4xMzA3IDc0LjQzMDcgMzMuMTAzMiA3NC40MzA3SDU0LjE3MjJDNTUuMTQ0NyA3NC40MzA3IDU1Ljc5MyA3NS4wNzg5IDU1Ljc5MyA3Ni4wNTE0QzU1Ljc5MjggNzcuMDIzOSA1NS4xNDQ1IDc3LjY3MjIgNTQuMTcyMiA3Ny42NzIyWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNNjMuODk2MyA3Ny42NzIySDYwLjY1NDlDNTkuNjgyNCA3Ny42NzIyIDU5LjAzNDIgNzcuMDIzOSA1OS4wMzQyIDc2LjA1MTRDNTkuMDM0MiA3NS4wNzg5IDU5LjY4MjQgNzQuNDMwNyA2MC42NTQ5IDc0LjQzMDdINjMuODk2M0M2NC44Njg4IDc0LjQzMDcgNjUuNTE3MSA3NS4wNzg5IDY1LjUxNzEgNzYuMDUxNEM2NS41MTcxIDc3LjAyMzkgNjQuODY4OCA3Ny42NzIyIDYzLjg5NjMgNzcuNjcyMloiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTEwMS4xNzIgNzcuNjcyMkg4MC4xMDMyQzc5LjEzMDcgNzcuNjcyMiA3OC40ODI0IDc3LjAyMzkgNzguNDgyNCA3Ni4wNTE0Qzc4LjQ4MjQgNzUuMDc4OSA3OS4xMzA3IDc0LjQzMDcgODAuMTAzMiA3NC40MzA3SDEwMS4xNzJDMTAyLjE0NSA3NC40MzA3IDEwMi43OTMgNzUuMDc4OSAxMDIuNzkzIDc2LjA1MTRDMTAyLjc5MyA3Ny4wMjM5IDEwMi4xNDUgNzcuNjcyMiAxMDEuMTcyIDc3LjY3MjJaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik0xMTAuODk2IDc3LjY3MjJIMTA3LjY1NUMxMDYuNjgyIDc3LjY3MjIgMTA2LjAzNCA3Ny4wMjM5IDEwNi4wMzQgNzYuMDUxNEMxMDYuMDM0IDc1LjA3ODkgMTA2LjY4MiA3NC40MzA3IDEwNy42NTUgNzQuNDMwN0gxMTAuODk2QzExMS44NjkgNzQuNDMwNyAxMTIuNTE3IDc1LjA3ODkgMTEyLjUxNyA3Ni4wNTE0QzExMi41MTcgNzcuMDIzOSAxMTEuODY5IDc3LjY3MjIgMTEwLjg5NiA3Ny42NzIyWiIgZmlsbD0iIzQyQjA1QyIvPgo8cGF0aCBkPSJNNjMuODk2MyA1OC4yMjRINjAuNjU0OUM1OS42ODI0IDU4LjIyNCA1OS4wMzQyIDU3LjU3NTcgNTkuMDM0MiA1Ni42MDMyQzU5LjAzNDIgNTUuNjMwNyA1OS42ODI0IDU0Ljk4MjQgNjAuNjU0OSA1NC45ODI0SDYzLjg5NjNDNjQuODY4OCA1NC45ODI0IDY1LjUxNzEgNTUuNjMwNyA2NS41MTcxIDU2LjYwMzJDNjUuNTE3MSA1Ny41NzU3IDY0Ljg2ODggNTguMjI0IDYzLjg5NjMgNTguMjI0WiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMTEyLjUxNyA1MS43NDExQzExMi41MTcgNjAuNjU0OSAxMDUuMjI0IDY3Ljk0OCA5Ni4zMTA0IDY3Ljk0OEM4Ny4zOTY2IDY3Ljk0OCA4MC4xMDM1IDYwLjY1NDkgODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNDIuODI3MyA4Ny4zOTY2IDM1LjUzNDIgOTYuMzEwNCAzNS41MzQyQzEwNS4yMjQgMzUuNTM0MiAxMTIuNTE3IDQyLjgyNzMgMTEyLjUxNyA1MS43NDExWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNTIuMjI3MyA4MC4xMDM1IDUyLjg3NTUgODAuMTAzNSA1My4zNjE5SDk2LjMxMDRWMzUuNTM0MkM4Ny4zOTY2IDM1LjUzNDIgODAuMTAzNSA0Mi44MjczIDgwLjEwMzUgNTEuNzQxMVoiIGZpbGw9IiM0MkIwNUMiLz4KPC9nPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zMjY4IiB4MT0iMS4yMzIzOWUtMDYiIHkxPSItOS41MDAwMSIgeDI9IjE2OCIgeTI9IjE2MiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjOEZEREZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNzVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zMjY4Ij4KPHJlY3Qgd2lkdGg9Ijk0IiBoZWlnaHQ9Ijk0IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjUgMjUpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "metricsStorages"], ["spec", "logsStorages"], ["spec", "alerta"], ["spec", "alerta", "storage"], ["spec", "alerta", "storageClassName"], ["spec", "alerta", "resources"], ["spec", "alerta", "resources", "limits"], ["spec", "alerta", "resources", "limits", "cpu"], ["spec", "alerta", "resources", "limits", "memory"], ["spec", "alerta", "resources", "requests"], ["spec", "alerta", "resources", "requests", "cpu"], ["spec", "alerta", "resources", "requests", "memory"], ["spec", "alerta", "alerts"], ["spec", "alerta", "alerts", "telegram"], ["spec", "alerta", "alerts", "telegram", "token"], ["spec", "alerta", "alerts", "telegram", "chatID"], ["spec", "alerta", "alerts", "telegram", "disabledSeverity"], ["spec", "alerta", "alerts", "slack"], ["spec", "alerta", "alerts", "slack", "url"], ["spec", "grafana"], ["spec", "grafana", "db"], ["spec", "grafana", "db", "size"], ["spec", "grafana", "resources"], ["spec", "grafana", "resources", "limits"], ["spec", "grafana", "resources", "limits", "cpu"], ["spec", "grafana", "resources", "limits", "memory"], ["spec", "grafana", "resources", "requests"], ["spec", "grafana", "resources", "requests", "cpu"], ["spec", "grafana", "resources", "requests", "memory"]] - secrets: - exclude: [] - include: - - resourceNames: - - grafana-admin-password - services: - exclude: [] - include: - - resourceNames: - - grafana-service - - alerta - ingresses: - exclude: [] - include: - - resourceNames: - - grafana-ingress - - alerta diff --git a/packages/core/platform/psds/mysql-application.yaml b/packages/core/platform/psds/mysql-application.yaml new file mode 100644 index 00000000..4b22e36e --- /dev/null +++ b/packages/core/platform/psds/mysql-application.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.mysql-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.mariadb-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: mysql + path: apps/mysql + libraries: ["cozy-lib"] + - name: mysql-rd + path: system/mysql-rd + install: + namespace: cozy-system + releaseName: mysql-rd diff --git a/packages/core/platform/psds/mysql.yaml b/packages/core/platform/psds/mysql.yaml deleted file mode 100644 index 9a0ff4c7..00000000 --- a/packages/core/platform/psds/mysql.yaml +++ /dev/null @@ -1,57 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.mysql-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.mariadb-operator - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: mysql - path: apps/mysql - libraries: - - cozy-lib - template: - spec: - application: - kind: MySQL - plural: mysqls - singular: mysql - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["cleanupStrategy","enabled","resticPassword","s3AccessKey","s3Bucket","s3Region","s3SecretKey","schedule"],"properties":{"cleanupStrategy":{"description":"Retention strategy for cleaning up old backups.","type":"string","default":"--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"resticPassword":{"description":"Password for Restic backup encryption.","type":"string","default":""},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3Bucket":{"description":"S3 bucket used for storing backups.","type":"string","default":"s3.example.org/mysql-backups"},"s3Region":{"description":"AWS S3 region where backups are stored.","type":"string","default":"us-east-1"},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * *"}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of MariaDB replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each MariaDB replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","required":["maxUserConnections","password"],"properties":{"maxUserConnections":{"description":"Maximum number of connections.","type":"integer"},"password":{"description":"Password for the user.","type":"string"}}}}}} - release: - prefix: mysql- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: MySQL - plural: MySQL - description: Managed MariaDB service - tags: - - database - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5MzApIi8+CjxwYXRoIGQ9Ik0xMzMuMTkxIDI5LjAwMjJDMTMxLjIxMyAyOS4wNjU0IDEzMS44MzkgMjkuNjM1NCAxMjcuNTY0IDMwLjY4NzNDMTIzLjI0OCAzMS43NDk2IDExNy45NzUgMzEuNDIzOSAxMTMuMzI3IDMzLjM3MzNDOTkuNDUxNiAzOS4xOTI0IDk2LjY2NzYgNTkuMDgxMyA4NC4wNTM1IDY2LjIwNTlDNzQuNjI0NyA3MS41MzE4IDY1LjExMiA3MS45NTY1IDU2LjU1OTQgNzQuNjM2NUM1MC45Mzg5IDc2LjM5OSA0NC43OTA2IDgwLjAxMzUgMzkuNjk4MiA4NC40MDE4QzM1Ljc0NTUgODcuODA5MyAzNS42NDIzIDkwLjgwNTQgMzEuNTEyMyA5NS4wNzkxQzI3LjA5NDcgOTkuNjUwNCAxMy45NTUxIDk1LjE1NjQgOCAxMDIuMTUzQzkuOTE4MzUgMTA0LjA5MyAxMC43NTk0IDEwNC42MzYgMTQuNTM5OCAxMDQuMTMzQzEzLjc1NzEgMTA1LjYxNiA5LjE0MzMyIDEwNi44NjYgMTAuMDQ2NSAxMDkuMDQ5QzEwLjk5NjggMTExLjM0NSAyMi4xNTExIDExMi45MDEgMzIuMjkwOCAxMDYuNzhDMzcuMDEzMSAxMDMuOTI5IDQwLjc3NDMgOTkuODE5MyA0OC4xMjg4IDk4LjgzODRDNTcuNjQ1OSA5Ny41Njk5IDY4LjYwOTMgOTkuNjUyIDc5LjYyNjggMTAxLjI0MUM3Ny45OTMyIDEwNi4xMTIgNzQuNzEzMyAxMDkuMzUxIDcyLjA4NiAxMTMuMjMxQzcxLjI3MjQgMTE0LjEwNyA3My43MjAyIDExNC4yMDUgNzYuNTEyNiAxMTMuNjc1QzgxLjUzNTkgMTEyLjQzMyA4NS4xNTYxIDExMS40MzMgODguOTQ3MiAxMDkuMjI3QzkzLjYwNDcgMTA2LjUxNSA5NC4zMTA0IDk5LjU2MzkgMTAwLjAyNSA5OC4wNTk5QzEwMy4yMDkgMTAyLjk1NCAxMTEuODY5IDEwNC4xMSAxMTcuMjQyIDEwMC4xOTVDMTEyLjUyNyA5OC44NjA3IDExMS4yMjQgODguODI0NCAxMTIuODE1IDg0LjQwMThDMTE0LjMyMyA4MC4yMTU2IDExNS44MTMgNzMuNTE5MiAxMTcuMzMxIDY3Ljk4NTVDMTE4Ljk2MSA2Mi4wNDI1IDExOS41NjIgNTQuNTUxOSAxMjEuNTM1IDUxLjUyNDdDMTI0LjUwMyA0Ni45NzAxIDEyNy43ODMgNDUuNDA2IDEzMC42MyA0Mi44Mzc3QzEzMy40NzcgNDAuMjY5NSAxMzYuMDgzIDM3Ljc2OTQgMTM1Ljk5OCAzMS44OTI3QzEzNS45NyAyOS45OTk4IDEzNC45OTIgMjguOTQ0NyAxMzMuMTkxIDI5LjAwMjJaIiBmaWxsPSIjMDQyNDRFIi8+CjxwYXRoIGQ9Ik0xMjguOTUzIDMyLjQ4NDRDMTI5LjQyNyAzNC4xMDA0IDEzMC4xNjggMzQuODQyMSAxMzMuMzc1IDM1LjEzODdDMTMyLjkwNiAzOS4yMDQxIDEzMC4xOTUgNDEuNDI3NiAxMjcuMTU0IDQzLjU2MTFDMTI0LjQ3OSA0NS40Mzc2IDEyMS41NDcgNDcuMjQ0NSAxMTkuNjY0IDUwLjE3NTdDMTE3LjczNCA1My4xNzg1IDExNi41MDkgNjMuNDU1NCAxMTMuNTE3IDczLjYwNDRDMTEwLjkzMSA4Mi4zNzM4IDEwNy4wMjUgOTEuMDQ0NSAxMDAuMjA0IDk0Ljg0MzdDOTkuNDkxOSA5My4wNTAyIDEwMC4yOTUgODkuNzQgOTguODc4IDg4LjY1MkM5Ny45NjExIDkxLjI2NzQgOTYuOTI0MiA5My43NjI3IDk1LjcwOTggOTYuMDgyMUM5MS43MDc3IDEwMy43MzIgODUuNzgyMiAxMDkuNDU5IDc1Ljg4MDEgMTExLjIwOEM4MC41Nzg1IDEwNC44NSA4NS4wNzEgOTguMjg0NCA4NS4xNjgzIDg3LjMyNjJDODEuODYxNyA4OC4wNDE3IDgxLjkzMTkgOTUuODUyMiA3OC41MzQ1IDk3Ljk0MDJDNzYuMzU2MyA5OC4xNzcyIDc0LjE0OTggOTguMTc1OCA3MS45MjkxIDk4LjA0MjRDNjIuODA5MSA5Ny40OTU5IDUzLjQ1MzUgOTQuNzU0OSA0NC45MjE5IDk3LjQ5MjNDMzkuMTEyOCA5OS4zNTY4IDM0LjM2MTkgMTAzLjc1NSAyOS40NDI4IDEwNS44ODhDMjMuNjYxNCAxMDguMzk2IDE5LjI4MzEgMTA5LjQyNyAxMi4wODM2IDEwOC4zOTZDMTEuMTY5NSAxMDcuMTY0IDE3LjM1MjYgMTA1LjU3NSAxNi45ODI5IDEwMi45MDJDMTQuMTY1MyAxMDIuNTkgMTIuNTI5MyAxMDMuMjczIDEwLjA4MDEgMTAyLjE2QzEwLjM1MDUgMTAxLjY2MiAxMC43NDc5IDEwMS4yNDcgMTEuMjQ4MyAxMDAuOTAxQzE1LjczNzMgOTcuNzk0IDI4LjQ4ODIgMTAwLjE2NyAzMS45MDA2IDk2LjgxNjdDMzQuMDA3IDk0Ljc1IDM1LjM4ODkgOTIuNTg2NyAzNi44MTk3IDkwLjQ4MzhDMzguMjA3MiA4OC40NDM0IDM5LjY0MTUgODYuNDU5NyA0MS44MjY4IDg0LjY3MTlDNDIuNjMzNyA4NC4wMTE4IDQzLjUxMSA4My4zNTk2IDQ0LjQ0MjEgODIuNzIzQzQ4LjE2NiA4MC4xNzQzIDUyLjc3MjkgNzcuODYyOCA1Ny4zMDY2IDc2LjI2OTRDNjMuNDgyNiA3NC4wOTg0IDY5Ljc0MSA3My45MTk1IDc2LjMyMzcgNzEuNDA0M0M4MC4zOTA0IDY5Ljg1IDg0LjgxMjcgNjcuOTMwMiA4OC40MTc0IDY1LjI0MzlDODkuMjczMyA2NC42MDUxIDkwLjA4MzEgNjMuOTI0NSA5MC44MzE5IDYzLjE5NDlDMTAxLjEyNSA1My4xNjA4IDEwMy4xNjUgMzUuNDYxIDExOS4yMjQgMzMuODExNkMxMjEuMTY2IDMzLjYxMjEgMTIyLjc1NiAzMy42NzY3IDEyNC4yMDMgMzMuNjMyN0MxMjUuODcxIDMzLjU4MyAxMjcuMzQ3IDMzLjM4OTMgMTI4Ljk1MyAzMi40ODQ0Wk0xMDkuMzc1IDg5LjEzMzlDMTA5LjU2NyA5Mi4yMDEzIDExMS4zNDggOTguMjg3MiAxMTIuOTIgOTkuNzY2M0MxMDkuODQxIDEwMC41MTUgMTA0LjUzNyA5OS4yNzggMTAzLjE3NyA5Ny4xMDYyQzEwMy44NzYgOTMuOTcwNyAxMDcuNTE0IDkxLjEwNDEgMTA5LjM3NSA4OS4xMzM5WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEzMC4xMDkgMzUuOTE4N0MxMjkuNDkgMzcuMjE2OSAxMjguMzA1IDM4Ljg5MDggMTI4LjMwNSA0Mi4xOTU2QzEyOC4zIDQyLjc2MyAxMjcuODc1IDQzLjE1MTcgMTI3Ljg2NyA0Mi4yNzdDMTI3Ljg5OSAzOS4wNDcgMTI4Ljc1NCAzNy42NTA3IDEyOS42NjIgMzUuODE1NUMxMzAuMDg1IDM1LjA2MzYgMTMwLjMzOSAzNS4zNzM4IDEzMC4xMDkgMzUuOTE4N1pNMTI5LjQ4NiAzNS40Mjk3QzEyOC43NTYgMzYuNjY4NCAxMjYuOTk4IDM4LjkyNzggMTI2LjcwNyA0Mi4yMjAzQzEyNi42NTMgNDIuNzg0OCAxMjYuMTk0IDQzLjEzNDMgMTI2LjI2NCA0Mi4yNjE4QzEyNi41ODEgMzkuMDQ3NyAxMjcuOTg2IDM3LjAzNiAxMjkuMDUyIDM1LjI4NzNDMTI5LjUzNiAzNC41NzYxIDEyOS43NjMgMzQuOTA3NCAxMjkuNDg2IDM1LjQyOTdaTTEyOC45MTggMzQuNzgxN0MxMjguMDg2IDM1Ljk1NDMgMTI1LjM4IDM4LjY2NzggMTI0LjgxNCA0MS45MjQ3QzEyNC43MTIgNDIuNDgxOSAxMjQuMjI1IDQyLjc5MjggMTI0LjM2OCA0MS45MjlDMTI0Ljk1NCAzOC43NTIgMTI3LjI4NyAzNi4yNTUgMTI4LjQ5NiAzNC42MDM3QzEyOS4wMzggMzMuOTM0NiAxMjkuMjM3IDM0LjI4NCAxMjguOTE4IDM0Ljc4MTdaTTEyOC40MTEgMzQuMDU4OEwxMjguMTM3IDM0LjM0OTlDMTI2LjkyNyAzNS42NDcyIDEyNC4xMTYgMzguODExNCAxMjMuMTc5IDQxLjcwNzRDMTIyLjk5OSA0Mi4yNDUgMTIyLjQ3NCA0Mi40ODQ4IDEyMi43MzcgNDEuNjQ5M0MxMjMuNzYzIDM4LjU4NjQgMTI2LjU4OSAzNS4yODczIDEyOC4wMTggMzMuODIyN0MxMjguNjUgMzMuMjM2NCAxMjguNzk2IDMzLjYxMDYgMTI4LjQxMSAzNC4wNTg4Wk0xMTMuODg2IDQwLjYxNjJDMTE0LjUxMyAzNy45MjMxIDExNi42MDcgMzYuNjk2IDEyMC4yMjMgMzYuOTk1M0MxMjEuMDk2IDQxLjAxNTEgMTE2LjIxMyA0Mi42MzY2IDExMy44ODYgNDAuNjE2MloiIGZpbGw9IiMwNDI0NEUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMjkzMCIgeDE9IjE0MC41IiB5MT0iMTQxIiB4Mj0iNS45OTk5OSIgeTI9Ii01LjUwMjI4ZS0wNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQzQ5QTZDIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0U3QkY5MyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "s3Region"], ["spec", "backup", "s3Bucket"], ["spec", "backup", "schedule"], ["spec", "backup", "cleanupStrategy"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "backup", "resticPassword"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`mysql-{{ .name }}-credentials`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`mysql-{{ .name }}-primary`}}" - - "{{`mysql-{{ .name }}-secondary`}}" diff --git a/packages/core/platform/psds/nats-application.yaml b/packages/core/platform/psds/nats-application.yaml new file mode 100644 index 00000000..b09c5a30 --- /dev/null +++ b/packages/core/platform/psds/nats-application.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.nats-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: nats-system + path: system/nats + - name: nats + path: apps/nats + libraries: ["cozy-lib"] + - name: nats-rd + path: system/nats-rd + install: + namespace: cozy-system + releaseName: nats-rd diff --git a/packages/core/platform/psds/nats.yaml b/packages/core/platform/psds/nats.yaml deleted file mode 100644 index ec2a9a97..00000000 --- a/packages/core/platform/psds/nats.yaml +++ /dev/null @@ -1,57 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.nats-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: - - name: nats-system - path: system/nats - applications: - - name: nats - path: apps/nats - libraries: - - cozy-lib - template: - spec: - application: - kind: NATS - plural: natses - singular: nats - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"config":{"description":"NATS configuration.","type":"object","default":{},"properties":{"merge":{"description":"Additional configuration to merge into NATS config.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true},"resolver":{"description":"Additional resolver configuration to merge into NATS config.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"jetstream":{"description":"Jetstream configuration.","type":"object","default":{},"required":["enabled","size"],"properties":{"enabled":{"description":"Enable or disable Jetstream for persistent messaging in NATS.","type":"boolean","default":true},"size":{"description":"Jetstream persistent storage size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"replicas":{"description":"Number of replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each NATS replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}}}} - release: - prefix: nats- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: NATS - plural: NATS - description: Managed NATS service - tags: - - messaging - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyMSkiLz4KPHJlY3Qgd2lkdGg9IjE0NCIgaGVpZ2h0PSIxNDQiIHJ4PSIyNCIgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMC4zIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTE3LjQ4IDI1SDI3Vjk4Ljk2OTNINjYuMDY4OUw4Ny43MDc1IDExOVY5OC45NjkzSDExNy40OFYyNVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4xMzUyIDcyLjQ1NTJWNDIuNjI1SDEwMi43NzNWODEuMTk5OUg4Ni42NTE5TDU0LjExNCA1MC44NDE0VjgxLjIzMjJINDMuNDQ0M1Y0Mi42MjVINjAuMTI2Mkw5Mi4xMzUyIDcyLjQ1NTJaIiBmaWxsPSJibGFjayIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4MV8yODIxIiB4MT0iMTAiIHkxPSIxNS41IiB4Mj0iMTQ0IiB5Mj0iMTMxLjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzM4NUM5MyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMzMkE1NzQiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "jetstream"], ["spec", "jetstream", "enabled"], ["spec", "jetstream", "size"], ["spec", "config"], ["spec", "config", "merge"], ["spec", "config", "resolver"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`nats-{{ .name }}-credentials`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`nats-{{ .name }}`}}" diff --git a/packages/core/platform/psds/nfs-driver.yaml b/packages/core/platform/psds/nfs-driver.yaml index ae07b800..aa1effec 100644 --- a/packages/core/platform/psds/nfs-driver.yaml +++ b/packages/core/platform/psds/nfs-driver.yaml @@ -16,7 +16,6 @@ spec: components: - name: nfs-driver path: system/nfs-driver - disabled: true install: privileged: true namespace: cozy-nfs-driver diff --git a/packages/core/platform/psds/postgres-application.yaml b/packages/core/platform/psds/postgres-application.yaml new file mode 100644 index 00000000..b5953069 --- /dev/null +++ b/packages/core/platform/psds/postgres-application.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.postgres-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: postgres + path: apps/postgres + libraries: ["cozy-lib"] + - name: postgres-rd + path: system/postgres-rd + install: + namespace: cozy-system + releaseName: postgres-rd diff --git a/packages/core/platform/psds/postgres.yaml b/packages/core/platform/psds/postgres.yaml deleted file mode 100644 index 79ec3a71..00000000 --- a/packages/core/platform/psds/postgres.yaml +++ /dev/null @@ -1,66 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.postgres-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: postgres - path: apps/postgres - libraries: - - cozy-lib - template: - spec: - application: - kind: Postgres - singular: postgres - plural: postgreses - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["enabled"],"properties":{"destinationPath":{"description":"Destination path for backups (e.g. s3://bucket/path/).","type":"string","default":"s3://bucket/path/to/folder/"},"enabled":{"description":"Enable regular backups.","type":"boolean","default":false},"endpointURL":{"description":"S3 endpoint URL for uploads.","type":"string","default":"http://minio-gateway-service:9000"},"retentionPolicy":{"description":"Retention policy (e.g. \"30d\").","type":"string","default":"30d"},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * * *"}}},"bootstrap":{"description":"Bootstrap configuration.","type":"object","default":{},"required":["enabled","oldName"],"properties":{"enabled":{"description":"Whether to restore from a backup.","type":"boolean","default":false},"oldName":{"description":"Previous cluster name before deletion.","type":"string","default":""},"recoveryTime":{"description":"Timestamp (RFC3339) for point-in-time recovery; empty means latest.","type":"string","default":""}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"extensions":{"description":"List of enabled PostgreSQL extensions.","type":"array","items":{"type":"string"}},"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"postgresql":{"description":"PostgreSQL server configuration.","type":"object","default":{},"properties":{"parameters":{"description":"PostgreSQL server parameters.","type":"object","default":{},"properties":{"max_connections":{"description":"Maximum number of concurrent connections to the database server.","type":"integer","default":100}}}}},"quorum":{"description":"Quorum configuration for synchronous replication.","type":"object","default":{},"required":["maxSyncReplicas","minSyncReplicas"],"properties":{"maxSyncReplicas":{"description":"Maximum number of synchronous replicas allowed (must be less than total replicas).","type":"integer","default":0},"minSyncReplicas":{"description":"Minimum number of synchronous replicas required for commit.","type":"integer","default":0}}},"replicas":{"description":"Number of Postgres replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each PostgreSQL replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"},"replication":{"description":"Whether the user has replication privileges.","type":"boolean"}}}}}} - release: - prefix: postgres- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: PostgreSQL - plural: PostgreSQL - description: Managed PostgreSQL service - tags: - - database - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMjg0OSkiLz4KPHBhdGggZD0iTTk0LjQ4MSA5My4zMDQ5Qzk1LjA3MTggODguMzQ3NyA5NC44OTQ4IDg3LjYyMDggOTguNTYxMiA4OC40MjM4TDk5LjQ5MiA4OC41MDYxQzEwMi4zMTEgODguNjM1MyAxMDUuOTk5IDg4LjA0OTUgMTA4LjE2NiA4Ny4wMzU4QzExMi44MyA4NC44NTY0IDExNS41OTUgODEuMjE3NiAxMTAuOTk2IDgyLjE3MzhDMTAwLjUwNiA4NC4zNTMyIDk5Ljc4NDkgODAuNzc1OSA5OS43ODQ5IDgwLjc3NTlDMTEwLjg2MiA2NC4yMjQgMTE1LjQ5MyA0My4yMTI4IDExMS40OTYgMzguMDY5N0MxMDAuNTk0IDI0LjA0MTIgODEuNzIzMSAzMC42NzUgODEuNDA3MyAzMC44NDcyTDgxLjMwNjggMzAuODY1OUM3OS4yMzQgMzAuNDMyOCA3Ni45MTQzIDMwLjE3NCA3NC4zMDg1IDMwLjEzMTZDNjkuNTYxMyAzMC4wNTMgNjUuOTU5MSAzMS4zODQ5IDYzLjIyNjYgMzMuNDcyMUM2My4yMjY2IDMzLjQ3MjEgMjkuNTYyMSAxOS41MDQ3IDMxLjEyODIgNTEuMDM3NUMzMS40NjEzIDU3Ljc0NTQgNDAuNjc1OCAxMDEuNzk1IDUxLjY2NTkgODguNDkwMUM1NS42ODI3IDgzLjYyNDkgNTkuNTY0NiA3OS41MTEzIDU5LjU2NDYgNzkuNTExM0M2MS40OTIyIDgwLjgwMDkgNjMuOCA4MS40NTg4IDY2LjIyMDQgODEuMjIyNUw2Ni40MDc1IDgxLjA2MThDNjYuMzQ4OSA4MS42NjU5IDY2LjM3NDcgODIuMjU2NyA2Ni40ODI0IDgyLjk1NjJDNjMuNjUxNyA4Ni4xNDE5IDY0LjQ4MzUgODYuNzAxMiA1OC44MjMxIDg3Ljg3NDVDNTMuMDk2NSA4OS4wNjMxIDU2LjQ2MDkgOTEuMTc5MyA1OC42NTY5IDkxLjczMjRDNjEuMzE5OSA5Mi40MDMgNjcuNDgwNCA5My4zNTMgNzEuNjQ0IDg3LjQ4NDVMNzEuNDc4MiA4OC4xNTQxQzcyLjU4ODggODkuMDQ4OSA3Mi41MTM3IDk0LjU4NTQgNzIuNjcxMiA5OC41NDExQzcyLjgyODkgMTAyLjQ5NyA3My4wOTE5IDEwNi4xODkgNzMuODkyNiAxMDguMzY1Qzc0LjY5MzMgMTEwLjU0MSA3NS42MzgxIDExNi4xNDcgODMuMDc3MSAxMTQuNTQxQzg5LjI5NDMgMTEzLjIgOTQuMDQ3OCAxMTEuMjY5IDk0LjQ4MSA5My4zMDQ5WiIgZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iNiIvPgo8cGF0aCBkPSJNMTEwLjk5OCA4Mi4xNzI3QzEwMC41MDYgODQuMzUyMSA5OS43ODQ5IDgwLjc3NDggOTkuNzg0OSA4MC43NzQ4QzExMC44NjIgNjQuMjIxOCAxMTUuNDkzIDQzLjIxMDIgMTExLjQ5NyAzOC4wNjc4QzEwMC41OTUgMjQuMDQwMSA4MS43MjMxIDMwLjY3NDMgODEuNDA4MiAzMC44NDY1TDgxLjMwNjggMzAuODY0OEM3OS4yMzQxIDMwLjQzMTUgNzYuOTE0NCAzMC4xNzMzIDc0LjMwNzMgMzAuMTMwNUM2OS41NiAzMC4wNTIxIDY1Ljk1OTEgMzEuMzgzOCA2My4yMjY3IDMzLjQ3MDZDNjMuMjI2NyAzMy40NzA2IDI5LjU2MTUgMTkuNTAzOCAzMS4xMjcyIDUxLjAzNjRDMzEuNDYwMyA1Ny43NDQ3IDQwLjY3NDYgMTAxLjc5NSA1MS42NjUxIDg4LjQ4OTVDNTUuNjgyMSA4My42MjQzIDU5LjU2MzQgNzkuNTEwNiA1OS41NjM0IDc5LjUxMDZDNjEuNDkxMiA4MC44MDAyIDYzLjc5OSA4MS40NTgxIDY2LjIxODQgODEuMjIxOEw2Ni40MDYzIDgxLjA2MTFDNjYuMzQ3OSA4MS42NjUyIDY2LjM3NDYgODIuMjU2IDY2LjQ4MTYgODIuOTU1NUM2My42NTAzIDg2LjE0MTIgNjQuNDgyMiA4Ni43MDA1IDU4LjgyMjMgODcuODczOEM1My4wOTUzIDg5LjA2MjUgNTYuNDU5NyA5MS4xNzg2IDU4LjY1NjMgOTEuNzMxN0M2MS4zMTkzIDkyLjQwMjMgNjcuNDgwMiA5My4zNTI0IDcxLjY0MyA4Ny40ODM4TDcxLjQ3NyA4OC4xNTM0QzcyLjU4NjQgODkuMDQ4MiA3My4zNjU0IDkzLjk3MzkgNzMuMjM0OCA5OC40MzlDNzMuMTA0MiAxMDIuOTA0IDczLjAxNzEgMTA1Ljk3IDczLjg5MTIgMTA4LjM2NEM3NC43NjUzIDExMC43NTkgNzUuNjM2NSAxMTYuMTQ2IDgzLjA3NjkgMTE0LjU0MUM4OS4yOTQxIDExMy4xOTkgOTIuNTE1OSAxMDkuNzIyIDkyLjk2NDEgMTAzLjkyMkM5My4yODIyIDk5Ljc5ODggOTQuMDAxOSAxMDAuNDA4IDk0LjA0NzQgOTYuNzIxOUw5NC42MjQ3IDk0Ljk3NjZDOTUuMjkwNSA4OS4zODcyIDk0LjczMDUgODcuNTg0IDk4LjU2MDggODguNDIyN0w5OS40OTE3IDg4LjUwNUMxMDIuMzExIDg4LjYzNDIgMTA2LjAwMSA4OC4wNDg0IDEwOC4xNjYgODcuMDM0N0MxMTIuODI5IDg0Ljg1NTMgMTE1LjU5NSA4MS4yMTY2IDExMC45OTcgODIuMTcyN0gxMTAuOTk4WiIgZmlsbD0iIzMzNjc5MSIvPgo8cGF0aCBkPSJNNzIuMDkzMyA4NS4zNzdDNzEuODA0NSA5NS43Nzc0IDcyLjE2NTkgMTA2LjI1IDczLjE3NjQgMTA4Ljc5NkM3NC4xODc2IDExMS4zNDEgNzYuMzUxNCAxMTYuMjkyIDgzLjc5MjUgMTE0LjY4NkM5MC4wMDkxIDExMy4zNDQgOTIuMjcxIDExMC43NDcgOTMuMjUyNiAxMDUuMDE0QzkzLjk3NTUgMTAwLjc5NiA5NS4zNjkxIDg5LjA4MSA5NS41NDc5IDg2LjY4MDkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik02My4xNzUgMzMuMjM5M0M2My4xNzUgMzMuMjM5MyAyOS40ODY4IDE5LjM3MzIgMzEuMDUzIDUwLjkwNThDMzEuMzg2IDU3LjYxNDEgNDAuNjAxIDEwMS42NjUgNTEuNTkxMyA4OC4zNTk3QzU1LjYwNzUgODMuNDkzOCA1OS4yMzk3IDc5LjY3NzYgNTkuMjM5NyA3OS42Nzc2IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNODEuMzcxMyAzMC43MDc4QzgwLjIwNTIgMzEuMDc2IDEwMC4xMTEgMjMuMzc5NiAxMTEuNDIzIDM3LjkzNjhDMTE1LjQxOSA0My4wNzk1IDExMC43ODkgNjQuMDkxMSA5OS43MTE1IDgwLjY0NDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik05OS43MTEgODAuNjQ0OEM5OS43MTEgODAuNjQ0OCAxMDAuNDMzIDg0LjIyMyAxMTAuOTI0IDgyLjA0MjJDMTE1LjUyMSA4MS4wODYxIDExMi43NTUgODQuNzI1MiAxMDguMDkzIDg2LjkwNTdDMTA0LjI2NyA4OC42OTQgOTUuNjg4MyA4OS4xNTIzIDk1LjU0ODIgODYuNjgxMkM5NS4xODc2IDgwLjMwNTMgMTAwLjA2MyA4Mi4yNDIzIDk5LjcxMSA4MC42NDQ4Wk05OS43MTEgODAuNjQ0OEM5OS4zOTI5IDc5LjIwNiA5Ny4yMTI4IDc3Ljc5MzkgOTUuNzcwNSA3NC4yNzI1Qzk0LjUxMTQgNzEuMTk5IDc4LjUwMTkgNDcuNjI4OSAxMDAuMjEgNTEuMTI5NEMxMDEuMDA2IDUwLjk2MzcgOTQuNTQ4NSAzMC4zMzQ4IDc0LjIzMjUgMjkuOTk5NEM1My45MjExIDI5LjY2MzkgNTQuNTg3NSA1NS4xNTQ1IDU0LjU4NzUgNTUuMTU0NSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiLz4KPHBhdGggZD0iTTY2LjQwNzcgODIuODI1M0M2My41NzYgODYuMDEwOCA2NC40MDg4IDg2LjU3MDIgNTguNzQ4NSA4Ny43NDM5QzUzLjAyMTQgODguOTMyNyA1Ni4zODYyIDkxLjA0ODUgNTguNTgyMiA5MS42MDEzQzYxLjI0NTIgOTIuMjcyNCA2Ny40MDYxIDkzLjIyMjQgNzEuNTY4OSA4Ny4zNTI0QzcyLjgzNjYgODUuNTY1MSA3MS41NjE0IDgyLjcxMzQgNjkuODIwMSA4MS45ODY0QzY4Ljk3ODcgODEuNjM1NCA2Ny44NTM3IDgxLjE5NTYgNjYuNDA3NyA4Mi44MjUzWiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTY2LjIyMjUgODIuNzY5MUM2NS45MzcyIDgwLjg5NjEgNjYuODMzNiA3OC42Njc0IDY3Ljc5NDMgNzYuMDU5OUM2OS4yMzggNzIuMTQ3NyA3Mi41NjkgNjguMjM0OCA2OS45MDQ0IDU1LjgyNDZDNjcuOTE4MiA0Ni41NzY3IDU0LjU5NjMgNTMuOSA1NC41ODggNTUuMTU0QzU0LjU3OTggNTYuNDA3NSA1NS4xOTA1IDYxLjUwOTkgNTQuMzY1NCA2Ny40NTE1QzUzLjI4ODggNzUuMjA0OCA1OS4yNjQzIDgxLjc2MjEgNjYuMTQ1MSA4MS4wOTEzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNNjMuMDUyOCA1NC45NjY1QzYyLjk5MjggNTUuMzk0OCA2My44MzE0IDU2LjUzNzcgNjQuOTI0OSA1Ni42OTA0QzY2LjAxNjYgNTYuODQzNyA2Ni45NTEgNTUuOTUwNiA2Ny4wMTAyIDU1LjUyMjdDNjcuMDY5NCA1NS4wOTQ1IDY2LjIzMTggNTQuNjIyNyA2NS4xMzc5IDU0LjQ2OTRDNjQuMDQ1NiA1NC4zMTU4IDYzLjExMDggNTQuNTM5MyA2My4wNTMxIDU0Ljk2NjVINjMuMDUyOFoiIGZpbGw9IndoaXRlIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz4KPHBhdGggZD0iTTk2LjMwMzQgNTQuMDkyNEM5Ni4zNjI3IDU0LjUyMDcgOTUuNTI1MSA1NS42NjM1IDk0LjQzMTMgNTUuODE2MkM5My4zMzg5IDU1Ljk2OTYgOTIuNDA0NSA1NS4wNzY1IDkyLjM0NDYgNTQuNjQ4NkM5Mi4yODY4IDU0LjIyMDMgOTMuMTI0NyA1My43NDg2IDk0LjIxNzMgNTMuNTk1M0M5NS4zMSA1My40NDE5IDk2LjI0NDIgNTMuNjY1MiA5Ni4zMDM0IDU0LjA5MjZWNTQuMDkyNFoiIGZpbGw9IndoaXRlIiBzdHJva2U9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMDAuMjEgNTEuMTI4OUMxMDAuMzkgNTQuNDg4MyA5OS40OTIgNTYuNzc2NSA5OS4zNzg3IDYwLjM1MjdDOTkuMjExIDY1LjU1MDggMTAxLjg0IDcxLjUwMDUgOTcuODc4OSA3Ny40NTc1IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yODQ5IiB4MT0iMTQwIiB5MT0iMTMwLjUiIHgyPSI0IiB5Mj0iOS40OTk5OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDAyQzRDIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNDc3QiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= - #tabs: - # services: - # labelSelector: - # cnpg.io/cluster: "{reqs[0]['metadata','name']}" - # workloadMonitors: - # labelSelector: - # helm.toolkit.fluxcd.io/name: "{reqs[0]['metadata','name']}" - - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "postgresql"], ["spec", "postgresql", "parameters"], ["spec", "postgresql", "parameters", "max_connections"], ["spec", "quorum"], ["spec", "quorum", "minSyncReplicas"], ["spec", "quorum", "maxSyncReplicas"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "retentionPolicy"], ["spec", "backup", "destinationPath"], ["spec", "backup", "endpointURL"], ["spec", "backup", "schedule"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "bootstrap"], ["spec", "bootstrap", "enabled"], ["spec", "bootstrap", "recoveryTime"], ["spec", "bootstrap", "oldName"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`postgres-{{ .name }}-credentials`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`postgres-{{ .name }}-r`}}" - - "{{`postgres-{{ .name }}-ro`}}" - - "{{`postgres-{{ .name }}-rw`}}" - - "{{`postgres-{{ .name }}-external-write`}}" diff --git a/packages/core/platform/psds/rabbitmq-application.yaml b/packages/core/platform/psds/rabbitmq-application.yaml new file mode 100644 index 00000000..7dc68b31 --- /dev/null +++ b/packages/core/platform/psds/rabbitmq-application.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.rabbitmq-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.rabbitmq-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: rabbitmq + path: apps/rabbitmq + libraries: ["cozy-lib"] + - name: rabbitmq-rd + path: system/rabbitmq-rd + install: + namespace: cozy-system + releaseName: rabbitmq-rd diff --git a/packages/core/platform/psds/rabbitmq.yaml b/packages/core/platform/psds/rabbitmq.yaml deleted file mode 100644 index f0670edd..00000000 --- a/packages/core/platform/psds/rabbitmq.yaml +++ /dev/null @@ -1,58 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.rabbitmq-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.rabbitmq-operator - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: rabbitmq - path: apps/rabbitmq - libraries: - - cozy-lib - template: - spec: - application: - kind: RabbitMQ - plural: rabbitmqs - singular: rabbitmq - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of RabbitMQ replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration for each RabbitMQ replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}},"vhosts":{"description":"Virtual hosts configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","required":["roles"],"properties":{"roles":{"description":"Virtual host roles list.","type":"object","properties":{"admin":{"description":"List of admin users.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of readonly users.","type":"array","items":{"type":"string"}}}}}}}}} - release: - prefix: rabbitmq- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: RabbitMQ - plural: RabbitMQ - description: Managed RabbitMQ service - tags: - - messaging - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NzIpIi8+CjxwYXRoIGQ9Ik0xMTEuNDExIDYyLjhIODIuNDkzOUM4MS43OTY5IDYyLjc5OTcgODEuMTI4NSA2Mi41MjI4IDgwLjYzNTYgNjIuMDMwMUM4MC4xNDI3IDYxLjUzNzMgNzkuODY1NiA2MC44NjkxIDc5Ljg2NTMgNjAuMTcyMlYzMC4wNDEyQzc5Ljg2NTMgMjcuODEgNzguMDU1NiAyNiA3NS44MjQ5IDI2SDY1LjUwMjFDNjMuMjcgMjYgNjEuNDYxNCAyNy44MSA2MS40NjE0IDMwLjA0MTJWNTkuOTg5OEM2MS40NjE0IDYxLjU0MzUgNjAuMjA1IDYyLjgwNjUgNTguNjUwOCA2Mi44MTMzTDQ5LjE3NDMgNjIuODU4NEM0Ny42MDY5IDYyLjg2NjkgNDYuMzMzNiA2MS41OTU1IDQ2LjMzNjYgNjAuMDI5OEw0Ni4zOTU0IDMwLjA0OEM0Ni40MDA1IDI3LjgxMzQgNDQuNTkwMiAyNiA0Mi4zNTUgMjZIMzIuMDQwN0MyOS44MDgzIDI2IDI4IDI3LjgxIDI4IDMwLjA0MTJWMTE0LjQxMkMyOCAxMTYuMzk0IDI5LjYwNjEgMTE4IDMxLjU4NzEgMTE4SDExMS40MTFDMTEzLjM5NCAxMTggMTE1IDExNi4zOTQgMTE1IDExNC40MTJWNjYuMzg4QzExNSA2NC40MDU4IDExMy4zOTQgNjIuOCAxMTEuNDExIDYyLjhaTTk3Ljg1MDggOTQuNDc3OUM5Ny44NTA4IDk3LjA3NTUgOTUuNzQ0NSA5OS4xODE3IDkzLjE0NjQgOTkuMTgxN0g4NC45ODg0QzgyLjM5IDk5LjE4MTcgODAuMjgzNiA5Ny4wNzU1IDgwLjI4MzYgOTQuNDc3OVY4Ni4zMjE3QzgwLjI4MzYgODMuNzIzOCA4Mi4zOSA4MS42MTc5IDg0Ljk4ODQgODEuNjE3OUg5My4xNDY0Qzk1Ljc0NDUgODEuNjE3OSA5Ny44NTA4IDgzLjcyMzggOTcuODUwOCA4Ni4zMjE3Vjk0LjQ3NzlaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yOTcyIiB4MT0iNSIgeTE9Ii03LjUiIHgyPSIxNDEiIHkyPSIxMjQuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkY4MjJGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGNjYwMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "vhosts"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`rabbitmq-{{ .name }}-default-user`}}" - - matchLabels: - apps.cozystack.io/user-secret: "true" - services: - exclude: [] - include: - - resourceNames: - - "{{`rabbitmq-{{ .name }}`}}" diff --git a/packages/core/platform/psds/redis-application.yaml b/packages/core/platform/psds/redis-application.yaml new file mode 100644 index 00000000..41a2a9dc --- /dev/null +++ b/packages/core/platform/psds/redis-application.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.redis-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.redis-operator + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: redis + path: apps/redis + libraries: ["cozy-lib"] + - name: redis-rd + path: system/redis-rd + install: + namespace: cozy-system + releaseName: redis-rd diff --git a/packages/core/platform/psds/redis.yaml b/packages/core/platform/psds/redis.yaml deleted file mode 100644 index de82f954..00000000 --- a/packages/core/platform/psds/redis.yaml +++ /dev/null @@ -1,59 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.redis-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.redis-operator - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: redis - path: apps/redis - libraries: - - cozy-lib - template: - spec: - application: - kind: Redis - plural: redises - singular: redis - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"authEnabled":{"description":"Enable password generation.","type":"boolean","default":true},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of Redis replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each Redis replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} - release: - prefix: redis- - labels: - cozystack.io/ui: "true" - dashboard: - category: PaaS - singular: Redis - plural: Redis - description: Managed Redis service - tags: - - cache - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzIxMykiLz4KPHBhdGggZD0iTTEyMC4xNDkgOTUuNTQ5MUMxMTQuNTg2IDk4LjQ0ODUgODUuNzcwOSAxMTAuMjk2IDc5LjYzNjMgMTEzLjQ5NUM3My41MDE2IDExNi42OTMgNzAuMDkzNyAxMTYuNjYyIDY1LjI0NzIgMTE0LjM0NkM2MC40MDEyIDExMi4wMjkgMjkuNzM2NCA5OS42NDIzIDI0LjIxMjUgOTcuMDAxOUMyMS40NTE5IDk1LjY4MjcgMjAgOTQuNTY4NyAyMCA5My41MTY2VjgyLjk4MDlDMjAgODIuOTgwOSA1OS45MjIgNzQuMjkwMSA2Ni4zNjY5IDcxLjk3NzhDNzIuODExNSA2OS42NjU2IDc1LjA0NzYgNjkuNTgyMSA4MC41MzIgNzEuNTkxQzg2LjAxNzMgNzMuNjAwOCAxMTguODEyIDc5LjUxNzYgMTI0LjIzMyA4MS41MDI5TDEyNC4yMyA5MS44ODk2QzEyNC4yMzEgOTIuOTMxMSAxMjIuOTggOTQuMDczNiAxMjAuMTQ5IDk1LjU0OTFaIiBmaWxsPSIjOTEyNjI2Ii8+CjxwYXRoIGQ9Ik0xMjAuMTQ3IDg1LjA3NTJDMTE0LjU4NSA4Ny45NzM0IDg1Ljc3IDk5LjgyMTggNzkuNjM1NCAxMDMuMDJDNzMuNTAxMSAxMDYuMjE5IDcwLjA5MzIgMTA2LjE4NyA2NS4yNDcyIDEwMy44NzFDNjAuNDAwNyAxMDEuNTU1IDI5LjczNzEgODkuMTY2OCAyNC4yMTM2IDg2LjUyOEMxOC42OTAxIDgzLjg4NzYgMTguNTc0NCA4Mi4wNzA0IDI0LjAwMDMgNzkuOTQ1OEMyOS40MjYxIDc3LjgyMDUgNTkuOTIxNSA2NS44NTYxIDY2LjM2NzIgNjMuNTQzOEM3Mi44MTE4IDYxLjIzMjQgNzUuMDQ3NSA2MS4xNDgxIDgwLjUzMTkgNjMuMTU3OEM4Ni4wMTY4IDY1LjE2NjggMTE0LjY2IDc2LjU2NzYgMTIwLjA3OSA3OC41NTI1QzEyNS41MDEgODAuNTM5OSAxMjUuNzA5IDgyLjE3NjMgMTIwLjE0NyA4NS4wNzUyWiIgZmlsbD0iI0M2MzAyQiIvPgo8cGF0aCBkPSJNMTIwLjE0OSA3OC41MDJDMTE0LjU4NiA4MS40MDE4IDg1Ljc3MDkgOTMuMjQ5MyA3OS42MzYzIDk2LjQ0ODhDNzMuNTAxNiA5OS42NDYyIDcwLjA5MzcgOTkuNjE1MiA2NS4yNDcyIDk3LjI5ODVDNjAuNDAwOCA5NC45ODMgMjkuNzM2NCA4Mi41OTUyIDI0LjIxMjUgNzkuOTU0N0MyMS40NTE5IDc4LjYzNTUgMjAgNzcuNTIzMiAyMCA3Ni40NzA3VjY1LjkzMzhDMjAgNjUuOTMzOCA1OS45MjIgNTcuMjQzNCA2Ni4zNjY5IDU0LjkzMTFDNzIuODExNSA1Mi42MTg5IDc1LjA0NzYgNTIuNTM1IDgwLjUzMiA1NC41NDQzQzg2LjAxNzcgNTYuNTUzNiAxMTguODEzIDYyLjQ2OTMgMTI0LjIzMyA2NC40NTVMMTI0LjIzIDc0Ljg0MjhDMTI0LjIzMSA3NS44ODQgMTIyLjk4IDc3LjAyNjQgMTIwLjE0OSA3OC41MDJaIiBmaWxsPSIjOTEyNjI2Ii8+CjxwYXRoIGQ9Ik0xMjAuMTQ3IDY4LjAyODJDMTE0LjU4NSA3MC45MjcxIDg1Ljc3IDgyLjc3NDcgNzkuNjM1NCA4NS45NzM3QzczLjUwMTEgODkuMTcxNiA3MC4wOTMyIDg5LjE0MDIgNjUuMjQ3MiA4Ni44MjM1QzYwLjQwMDcgODQuNTA4NCAyOS43MzcxIDcyLjEyMDEgMjQuMjEzNiA2OS40ODA5QzE4LjY5MDEgNjYuODQxMyAxOC41NzQ0IDY1LjAyMzcgMjQuMDAwMyA2Mi44OTg0QzI5LjQyNjEgNjAuNzc0MiA1OS45MjE5IDQ4LjgwOSA2Ni4zNjcyIDQ2LjQ5NzJDNzIuODExOCA0NC4xODUzIDc1LjA0NzUgNDQuMTAxNCA4MC41MzE5IDQ2LjExMDhDODYuMDE2OCA0OC4xMTk3IDExNC42NiA1OS41MTk3IDEyMC4wNzkgNjEuNTA1NUMxMjUuNTAxIDYzLjQ5MjQgMTI1LjcwOSA2NS4xMjkyIDEyMC4xNDcgNjguMDI4MloiIGZpbGw9IiNDNjMwMkIiLz4KPHBhdGggZD0iTTEyMC4xNDkgNjAuODIyNEMxMTQuNTg2IDYzLjcyMTQgODUuNzcwOSA3NS41Njk4IDc5LjYzNjMgNzguNzY5MkM3My41MDE2IDgxLjk2NzEgNzAuMDkzNyA4MS45MzU3IDY1LjI0NzIgNzkuNjE5QzYwLjQwMDggNzcuMzAzNSAyOS43MzY0IDY0LjkxNTIgMjQuMjEyNSA2Mi4yNzZDMjEuNDUxOSA2MC45NTU2IDIwIDU5Ljg0MjggMjAgNTguNzkxNVY0OC4yNTQyQzIwIDQ4LjI1NDIgNTkuOTIyIDM5LjU2NDIgNjYuMzY2OSAzNy4yNTI0QzcyLjgxMTUgMzQuOTM5NyA3NS4wNDc2IDM0Ljg1NjcgODAuNTMyIDM2Ljg2NTZDODYuMDE3NyAzOC44NzQ5IDExOC44MTMgNDQuNzkwNSAxMjQuMjMzIDQ2Ljc3NjNMMTI0LjIzIDU3LjE2MzdDMTI0LjIzMSA1OC4yMDQgMTIyLjk4IDU5LjM0NjUgMTIwLjE0OSA2MC44MjI0WiIgZmlsbD0iIzkxMjYyNiIvPgo8cGF0aCBkPSJNMTIwLjE0NyA1MC4zNDlDMTE0LjU4NSA1My4yNDc5IDg1Ljc2OTggNjUuMDk2MyA3OS42MzUyIDY4LjI5NDFDNzMuNTAwOSA3MS40OTIgNzAuMDkzIDcxLjQ2MDYgNjUuMjQ2OSA2OS4xNDUxQzYwLjQwMDkgNjYuODI4MyAyOS43MzY5IDU0LjQ0MDkgMjQuMjEzOCA1MS44MDEzQzE4LjY4OTkgNDkuMTYyMSAxOC41NzQ2IDQ3LjM0NDEgMjQgNDUuMjE5MkMyOS40MjU5IDQzLjA5NDYgNTkuOTIxNyAzMS4xMzEgNjYuMzY3IDI4LjgxODRDNzIuODExNiAyNi41MDYxIDc1LjA0NzMgMjYuNDIzIDgwLjUzMTcgMjguNDMyNEM4Ni4wMTY2IDMwLjQ0MTcgMTE0LjY1OSA0MS44NDE4IDEyMC4wNzkgNDMuODI3NUMxMjUuNTAxIDQ1LjgxMjggMTI1LjcwOSA0Ny40NSAxMjAuMTQ3IDUwLjM0OVoiIGZpbGw9IiNDNjMwMkIiLz4KPHBhdGggZD0iTTg0Ljg1NDEgNDAuMDk5NEw3NS44OTI2IDQxLjAyOThMNzMuODg2NSA0NS44NTdMNzAuNjQ2MyA0MC40NzAzTDYwLjI5ODMgMzkuNTQwNEw2OC4wMTk3IDM2Ljc1NThMNjUuNzAzIDMyLjQ4MTRMNzIuOTMyMSAzNS4zMDg4TDc5Ljc0NzEgMzMuMDc3NUw3Ny45MDUyIDM3LjQ5NzJMODQuODU0MSA0MC4wOTk0Wk03My4zNTE1IDYzLjUxODRMNTYuNjI2NiA1Ni41ODE2TDgwLjU5MiA1Mi45MDI5TDczLjM1MTUgNjMuNTE4NFpNNTAuMTYzNyA0Mi43ODI2QzU3LjIzODEgNDIuNzgyNiA2Mi45NzMgNDUuMDA1NyA2Mi45NzMgNDcuNzQ3NUM2Mi45NzMgNTAuNDkwMSA1Ny4yMzgxIDUyLjcxMjggNTAuMTYzNyA1Mi43MTI4QzQzLjA4OTMgNTIuNzEyOCAzNy4zNTQ1IDUwLjQ4OTcgMzcuMzU0NSA0Ny43NDc1QzM3LjM1NDUgNDUuMDA1NyA0My4wODkzIDQyLjc4MjYgNTAuMTYzNyA0Mi43ODI2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTk1LjQ0MzQgNDEuNDE3NEwxMDkuNjI3IDQ3LjAyMjRMOTUuNDU1NiA1Mi42MjJMOTUuNDQzNCA0MS40MTc0WiIgZmlsbD0iIzYyMUIxQyIvPgo8cGF0aCBkPSJNNzkuNzUyOSA0Ny42MjYxTDk1LjQ0NDkgNDEuNDE4OUw5NS40NTcxIDUyLjYyMzZMOTMuOTE4NCA1My4yMjU0TDc5Ljc1MjkgNDcuNjI2MVoiIGZpbGw9IiM5QTI5MjgiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMzIxMyIgeDE9IjE4OSIgeTE9IjIxMC41IiB4Mj0iMCIgeTI9IjAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0E4MDAwMCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkNGQ0YiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "authEnabled"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`redis-{{ .name }}-auth`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`rfs-redis-{{ .name }}`}}" - - "{{`rfrm-redis-{{ .name }}`}}" - - "{{`rfrs-redis-{{ .name }}`}}" - - "{{`redis-{{ .name }}-external-lb`}}" diff --git a/packages/core/platform/psds/seaweedfs-application.yaml b/packages/core/platform/psds/seaweedfs-application.yaml new file mode 100644 index 00000000..70de6662 --- /dev/null +++ b/packages/core/platform/psds/seaweedfs-application.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.seaweedfs-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: seaweedfs-system + path: system/seaweedfs + - name: seaweedfs + path: extra/seaweedfs + libraries: ["cozy-lib"] + - name: seaweedfs-rd + path: system/seaweedfs-rd + install: + namespace: cozy-system + releaseName: seaweedfs-rd diff --git a/packages/core/platform/psds/seaweedfs.yaml b/packages/core/platform/psds/seaweedfs.yaml deleted file mode 100644 index d37b128f..00000000 --- a/packages/core/platform/psds/seaweedfs.yaml +++ /dev/null @@ -1,61 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.seaweedfs-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: - - name: seaweedfs-system - path: system/seaweedfs - applications: - - name: seaweedfs - path: extra/seaweedfs - libraries: - - cozy-lib - template: - spec: - application: - kind: SeaweedFS - singular: seaweedfs - plural: seaweedfses - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of database replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}},"filer":{"description":"Filer service configuration.","type":"object","default":{},"properties":{"grpcHost":{"description":"The hostname used to expose or access the filer service externally.","type":"string","default":""},"grpcPort":{"description":"The port used to access the filer service externally.","type":"integer","default":443},"replicas":{"description":"Number of filer replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"A list of IP addresses or CIDR ranges that are allowed to access the filer service.","type":"array","default":[],"items":{"type":"string"}}}},"host":{"description":"The hostname used to access SeaweedFS externally (defaults to 's3' subdomain for the tenant host).","type":"string","default":""},"master":{"description":"Master service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of master replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"replicationFactor":{"description":"Replication factor: number of replicas for each volume in the SeaweedFS cluster.","type":"integer","default":2},"s3":{"description":"S3 service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of S3 replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"topology":{"description":"The topology of the SeaweedFS cluster.","type":"string","default":"Simple","enum":["Simple","MultiZone","Client"]},"volume":{"description":"Volume service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of volume replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"zones":{"description":"A map of zones for MultiZone topology. Each zone can have its own number of replicas and size.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"replicas":{"description":"Number of replicas in the zone.","type":"integer"},"size":{"description":"Zone storage size.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}}} - release: - prefix: "" - labels: - cozystack.io/ui: "true" - internal.cozystack.io/tenantmodule: "true" - dashboard: - category: Administration - singular: SeaweedFS - plural: SeaweedFS - name: seaweedfs - description: Seaweedfs - module: true - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTEzOC42ODUgMTIxLjA1N0MxMzguNjg1IDEyNi42NTIgMTM2LjQ2MiAxMzIuMDE3IDEzMi41MDQgMTM1Ljk3M0MxMjguNTQ3IDEzOS45MjkgMTIzLjE3OSAxNDIuMTUxIDExNy41ODIgMTQyLjE1MUMxMTEuOTg1IDE0Mi4xNTEgMTA2LjYxOCAxMzkuOTI5IDEwMi42NiAxMzUuOTczQzk4LjcwMjggMTMyLjAxNyA5Ni40Nzk1IDEyNi42NTIgOTYuNDc5NSAxMjEuMDU3Qzk2LjQ3OTUgMTE4LjI4NyA5Ny4wMjUzIDExNS41NDQgOTguMDg1OCAxMTIuOTg1Qzk5LjE0NjMgMTEwLjQyNSAxMDAuNzAxIDEwOC4xIDEwMi42NiAxMDYuMTQxQzEwNC42MiAxMDQuMTgyIDEwNi45NDYgMTAyLjYyOSAxMDkuNTA3IDEwMS41NjlDMTEyLjA2NyAxMDAuNTA5IDExNC44MTEgOTkuOTYyOSAxMTcuNTgyIDk5Ljk2MjlDMTIwLjM1MyA5OS45NjI5IDEyMy4wOTggMTAwLjUwOSAxMjUuNjU4IDEwMS41NjlDMTI4LjIxOCAxMDIuNjI5IDEzMC41NDQgMTA0LjE4MiAxMzIuNTA0IDEwNi4xNDFDMTM0LjQ2NCAxMDguMSAxMzYuMDE4IDExMC40MjUgMTM3LjA3OSAxMTIuOTg1QzEzOC4xMzkgMTE1LjU0NCAxMzguNjg1IDExOC4yODcgMTM4LjY4NSAxMjEuMDU3WiIgZmlsbD0idXJsKCNwYWludDFfcmFkaWFsXzY3OV8xOTEwKSIvPgo8cGF0aCBkPSJNMTEwLjMzNiAxMjYuMTQ3SDEyMy42OFYxMzYuODIzSDExMC4zMzZWMTI2LjE0N1oiIGZpbGw9IiMwRjVFOUMiLz4KPHBhdGggZD0iTTExOS4yNyAxMTIuMjk0QzExOS4yNyAxMTIuNzE0IDExOS4xNzggMTEzLjEzMSAxMTkgMTEzLjUxOUMxMTguODIxIDExMy45MDggMTE4LjU2IDExNC4yNjEgMTE4LjIzIDExNC41NThDMTE3LjkwMSAxMTQuODU1IDExNy41MDkgMTE1LjA5MSAxMTcuMDc5IDExNS4yNTJDMTE2LjY0OCAxMTUuNDEzIDExNi4xODYgMTE1LjQ5NiAxMTUuNzIgMTE1LjQ5NkMxMTQuNzc4IDExNS40OTYgMTEzLjg3NSAxMTUuMTU4IDExMy4yMSAxMTQuNTU4QzExMi41NDQgMTEzLjk1NyAxMTIuMTcgMTEzLjE0MyAxMTIuMTcgMTEyLjI5NEMxMTIuMTcgMTExLjQ0NSAxMTIuNTQ0IDExMC42MyAxMTMuMjEgMTEwLjAzQzExMy44NzUgMTA5LjQyOSAxMTQuNzc4IDEwOS4wOTIgMTE1LjcyIDEwOS4wOTJDMTE2LjE4NiAxMDkuMDkyIDExNi42NDggMTA5LjE3NSAxMTcuMDc5IDEwOS4zMzZDMTE3LjUwOSAxMDkuNDk2IDExNy45MDEgMTA5LjczMiAxMTguMjMgMTEwLjAzQzExOC41NiAxMTAuMzI3IDExOC44MjEgMTEwLjY4IDExOSAxMTEuMDY4QzExOS4xNzggMTExLjQ1NyAxMTkuMjcgMTExLjg3MyAxMTkuMjcgMTEyLjI5NFoiIGZpbGw9IiM1OTY4NkYiLz4KPHBhdGggZD0iTTEyOC4xMSAxMTQuMTAzQzEyOC4xMSAxMTQuOTUzIDEyNy43MzYgMTE1Ljc2NyAxMjcuMDcgMTE2LjM2OEMxMjYuNDA0IDExNi45NjggMTI1LjUwMSAxMTcuMzA1IDEyNC41NiAxMTcuMzA1QzEyNC4wOTQgMTE3LjMwNSAxMjMuNjMyIDExNy4yMjMgMTIzLjIwMSAxMTcuMDYyQzEyMi43NzEgMTE2LjkwMSAxMjIuMzc5IDExNi42NjUgMTIyLjA1IDExNi4zNjhDMTIxLjcyIDExNi4wNyAxMjEuNDU4IDExNS43MTcgMTIxLjI4IDExNS4zMjlDMTIxLjEwMiAxMTQuOTQgMTIxLjAxIDExNC41MjQgMTIxLjAxIDExNC4xMDNDMTIxLjAxIDExMy42ODMgMTIxLjEwMiAxMTMuMjY2IDEyMS4yOCAxMTIuODc4QzEyMS40NTggMTEyLjQ5IDEyMS43MiAxMTIuMTM3IDEyMi4wNSAxMTEuODM5QzEyMi4zNzkgMTExLjU0MiAxMjIuNzcxIDExMS4zMDYgMTIzLjIwMSAxMTEuMTQ1QzEyMy42MzIgMTEwLjk4NCAxMjQuMDk0IDExMC45MDEgMTI0LjU2IDExMC45MDFDMTI1LjUwMSAxMTAuOTAxIDEyNi40MDQgMTExLjIzOSAxMjcuMDcgMTExLjgzOUMxMjcuNzM2IDExMi40NCAxMjguMTEgMTEzLjI1NCAxMjguMTEgMTE0LjEwM1oiIGZpbGw9IiM1OTY4NkYiLz4KPHBhdGggZD0iTTEyMi4zMzMgMTE4Ljk3NkMxMjIuMzMzIDExOS44MjYgMTIxLjk1OCAxMjAuNjQgMTIxLjI5MyAxMjEuMjQxQzEyMC42MjcgMTIxLjg0MSAxMTkuNzI0IDEyMi4xNzggMTE4Ljc4MiAxMjIuMTc4QzExOC4zMTYgMTIyLjE3OCAxMTcuODU1IDEyMi4wOTYgMTE3LjQyNCAxMjEuOTM1QzExNi45OTMgMTIxLjc3NCAxMTYuNjAyIDEyMS41MzggMTE2LjI3MiAxMjEuMjQxQzExNS45NDMgMTIwLjk0MyAxMTUuNjgxIDEyMC41OSAxMTUuNTAzIDEyMC4yMDJDMTE1LjMyNCAxMTkuODEzIDExNS4yMzIgMTE5LjM5NyAxMTUuMjMyIDExOC45NzZDMTE1LjIzMiAxMTguNTU2IDExNS4zMjQgMTE4LjE0IDExNS41MDMgMTE3Ljc1MUMxMTUuNjgxIDExNy4zNjMgMTE1Ljk0MyAxMTcuMDEgMTE2LjI3MiAxMTYuNzEyQzExNi42MDIgMTE2LjQxNSAxMTYuOTkzIDExNi4xNzkgMTE3LjQyNCAxMTYuMDE4QzExNy44NTUgMTE1Ljg1NyAxMTguMzE2IDExNS43NzQgMTE4Ljc4MiAxMTUuNzc0QzExOS43MjQgMTE1Ljc3NCAxMjAuNjI3IDExNi4xMTIgMTIxLjI5MyAxMTYuNzEyQzEyMS45NTggMTE3LjMxMyAxMjIuMzMzIDExOC4xMjcgMTIyLjMzMyAxMTguOTc2WiIgZmlsbD0iIzU5Njg2RiIvPgo8cGF0aCBkPSJNMTE1LjMwOCAxMjEuOTA1QzExMy43MzUgMTIxLjQyNiAxMTUuNzA3IDEyMC42OCAxMTUuNDI5IDEyMC41NzNDMTE0LjY1MyAxMjAuMjc2IDExNS43MyAxMTkuMzMzIDExNi43NCAxMTguNTM5QzExNy42MjggMTE3Ljg0MSAxMTcuNjU5IDExNy44MzkgMTE3Ljg5MiAxMTguNDY4QzExOC4wMjQgMTE4LjgyMyAxMTguMzcxIDExOS4yMDYgMTE4LjY2NSAxMTkuMzE5QzExOS4yODkgMTE5LjU1OCAxMjAuOTUxIDExOS4yNjkgMTIwLjk1MSAxMTguODM1QzEyMC45NTEgMTE4LjIyMyAxMjEuNDE1IDExOC42OTkgMTIxLjc5NCAxMTkuNTMxQzEyMi40NTcgMTIwLjk4NyAxMjIuNDM3IDEyMi40NzIgMTIxLjQ1IDEyMi40NzJDMTIwLjg1OSAxMjIuNDcyIDEyMC4zMSAxMjIuNjkxIDEyMC4xOSAxMjMuMTQ3QzExNS4wNDYgMTI0LjYgMTE2LjQ3MSAxMjMuMjg0IDExNS4zMDggMTIxLjkwNVpNMTIzLjA5NCAxMTguMDU0QzEyMS42MDkgMTE3LjQ2NiAxMjAuNTQ3IDExNC44MzggMTIwLjU0NyAxMTMuMzA5QzEyMC41NDcgMTExLjMyMyAxMjIuNTQxIDEwOS4wOTUgMTI0LjMxNyAxMDkuMDk1QzEyOC4zMTUgMTA5LjA5NSAxMzAuNjg0IDExMi4yNjEgMTI4LjgzOCAxMTguNDA5QzEyOC4zODUgMTE5LjkxOSAxMjMuOTMzIDExOC4zODcgMTIzLjA5NCAxMTguMDU0Wk0xMjUuODY2IDExNS42NDlDMTI3LjU0NCAxMTQuNDc0IDEyNS44NTcgMTExLjc1NSAxMjMuOTgxIDExMi42MUMxMjIuNDc5IDExMy4yOTQgMTIzLjExOSAxMTYuMTE1IDEyNC43NyAxMTYuMTY0QzEyNC45NjEgMTE2LjE2OSAxMjUuNDU0IDExNS45MzggMTI1Ljg2NiAxMTUuNjQ5Wk0xMjQuMzM5IDExNC41NzlDMTIzLjc3MSAxMTQuMzgxIDEyMy44MDMgMTEzLjI1NiAxMjQuMzgzIDExMy4wMzRDMTI0LjkwMiAxMTIuODM1IDEyNS42MDQgMTEzLjM5OCAxMjUuNjA0IDExNC4wMTRDMTI1LjYwNCAxMTQuNDg5IDEyNC45MzYgMTE0Ljc4NyAxMjQuMzM5IDExNC41NzlaTTExMi4zMTkgMTE2Ljk4QzEwOS45NiAxMTUuNjcgMTEwLjI4NiAxMTEuMDA2IDExMi40MTcgMTA4Ljk2NUMxMTQuMzk2IDEwNy4wNjkgMTE4Ljc3OCAxMDcuMTAzIDExOS43NjQgMTA5LjQ2MkMxMjAuNDE1IDExMS4wMjEgMTIwLjIyOCAxMTIuNiAxMTkuMzk4IDExNC4wNzdDMTE4LjE5NCAxMTYuMjE5IDExNC4yNDIgMTE4LjA0OSAxMTIuMzE5IDExNi45OFpNMTE2LjU2IDExMy41OTNDMTE3LjMyNSAxMTIuOTAxIDExNy4yOTcgMTEyLjA2IDExNi41NzIgMTExLjI1OUMxMTUuNzc3IDExMC4zNzkgMTE0LjY5MiAxMTAuMzQ1IDExNC4wMzUgMTExLjM0N0MxMTMuNTI0IDExMi4xMjcgMTEzLjQzMSAxMTIuNTI4IDExMy45NDMgMTEzLjMwOUMxMTQuNTggMTE0LjI4IDExNS42NyAxMTQuMzk5IDExNi41NiAxMTMuNTkzWk0xMTQuMzc0IDExMi4zNEMxMTQuMTI4IDExMS42OTggMTE0Ljk4NSAxMTAuOTgxIDExNS42OCAxMTEuMjQ3QzExNS45NzQgMTExLjM2IDExNi4xNjQgMTExLjcxOCAxMTYuMTAyIDExMi4wNDRDMTE1Ljk2MSAxMTIuNzg1IDExNC42MzIgMTEzLjAxMiAxMTQuMzc0IDExMi4zNFoiIGZpbGw9IiNEM0Q2REEiLz4KPHBhdGggZD0iTTExOC40NjMgMTIxLjAwOEwxMTcuOTQ1IDEyMC43OEMxMTcuNTEgMTIwLjY4NSAxMTcuMjMxIDEyMS4xMDcgMTE3LjEzNiAxMjEuNTQzTDExNi44ODEgMTIyLjcwOUMxMTYuNzg2IDEyMy4xNDUgMTE3LjA2MSAxMjMuNTcxIDExNy40OTYgMTIzLjY2NkwxMTguNDQ3IDEyMy44NzRDMTE4Ljg4MiAxMjMuOTY5IDExOS4zMTEgMTIzLjY5NCAxMTkuNDA2IDEyMy4yNTlMMTE5LjY4NSAxMjEuNTU2QzExOS43OCAxMjEuMTIgMTE5LjQ3OSAxMjEuMjI4IDExOS4wNDMgMTIxLjEzM0wxMTguNjI4IDEyMS4wNDNDMTE4LjU3MyAxMjEuMzIxIDExOC41MTYgMTIxLjYxMyAxMTguNDcxIDEyMS44MzNDMTE4LjQzOCAxMjEuOTk4IDExOC40MDcgMTIyLjE0OCAxMTguMzc5IDEyMi4yODJDMTE4LjM1MSAxMjIuNDE1IDExOC4zMjcgMTIyLjUzMyAxMTguMzA1IDEyMi42MzVDMTE4LjI4MiAxMjIuNzM4IDExOC4yNjIgMTIyLjgyNSAxMTguMjQ1IDEyMi44OTdDMTE4LjIyOCAxMjIuOTY5IDExOC4yMTQgMTIzLjAyNSAxMTguMjAyIDEyMy4wNjhDMTE4LjE5NiAxMjMuMDg5IDExOC4xOTMgMTIzLjEwNyAxMTguMTg4IDEyMy4xMjFDMTE4LjE4MyAxMjMuMTM1IDExOC4xNzggMTIzLjE0NSAxMTguMTc1IDEyMy4xNTJDMTE4LjE3MyAxMjMuMTU1IDExOC4xNzIgMTIzLjE1NiAxMTguMTcxIDEyMy4xNThDMTE4LjE3IDEyMy4xNTkgMTE4LjE2OCAxMjMuMTYgMTE4LjE2NyAxMjMuMTZMMTE4LjE2NSAxMjMuMTU4QzExOC4xNjQgMTIzLjE1NiAxMTguMTYzIDEyMy4xNTIgMTE4LjE2MyAxMjMuMTQ4QzExOC4xNjIgMTIzLjE0IDExOC4xNjIgMTIzLjEyOSAxMTguMTYzIDEyMy4xMTVDMTE4LjE2MyAxMjMuMSAxMTguMTYzIDEyMy4wODMgMTE4LjE2NSAxMjMuMDYxQzExOC4xNjggMTIzLjAxOCAxMTguMTc1IDEyMi45NjEgMTE4LjE4MyAxMjIuODkxQzExOC4xOTIgMTIyLjgyIDExOC4yMDMgMTIyLjczNiAxMTguMjE2IDEyMi42NEMxMTguMjI5IDEyMi41NDMgMTE4LjI0NiAxMjIuNDMxIDExOC4yNjQgMTIyLjMwOEMxMTguMjgxIDEyMi4xODUgMTE4LjMwMSAxMjIuMDUxIDExOC4zMjMgMTIxLjkwM0MxMTguMzQ2IDEyMS43NTUgMTE4LjM3IDEyMS41OTIgMTE4LjM5NyAxMjEuNDE5QzExOC40MTYgMTIxLjI5OSAxMTguNDQyIDEyMS4xNCAxMTguNDYzIDEyMS4wMDhaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDMuNTgxIDExNi4zNjdDMTAzLjQ3OSAxMTYuMTAzIDEwMy42MjIgMTE1LjY5OSAxMDMuODk4IDExNS40NjlDMTA0LjMwMyAxMTUuMTMzIDEwNC41MDQgMTE1LjE1NSAxMDQuOTMgMTE1LjU4MUMxMDUuMjIgMTE1Ljg3MSAxMDUuMzU1IDExNi4yNzYgMTA1LjIzIDExNi40NzlDMTA0LjkwMiAxMTcuMDA5IDEwMy43OTggMTE2LjkzNCAxMDMuNTgxIDExNi4zNjdaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDYuMDM4IDExMi4yODFDMTA1LjY4IDExMS44NDkgMTA1LjcwMiAxMTEuNjYgMTA2LjE2NSAxMTEuMTk3QzEwNi42ODkgMTEwLjY3NCAxMDYuNzY0IDExMC42NzQgMTA3LjI4NyAxMTEuMTk3QzEwNy43NTEgMTExLjY2IDEwNy43NzMgMTExLjg0OSAxMDcuNDE1IDExMi4yODFDMTA3LjE3NiAxMTIuNTY4IDEwNi44NjYgMTEyLjgwMyAxMDYuNzI2IDExMi44MDNDMTA2LjU4NiAxMTIuODAzIDEwNi4yNzcgMTEyLjU2OCAxMDYuMDM4IDExMi4yODFaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDYuMDM4IDEwNy4yMjRDMTA1LjY4MiAxMDYuNzk1IDEwNS42OTQgMTA2LjYxMiAxMDYuMTA2IDEwNi4yMDFDMTA2LjY1IDEwNS42NTcgMTA3LjczOCAxMDUuODggMTA3LjczOCAxMDYuNTM2QzEwNy43MzggMTA2Ljk3IDEwNy4wNzIgMTA3Ljc0NyAxMDYuNyAxMDcuNzQ3QzEwNi41NzUgMTA3Ljc0NyAxMDYuMjc3IDEwNy41MTIgMTA2LjAzOCAxMDcuMjI0WiIgZmlsbD0iIzk4QzZEOCIvPgo8cGF0aCBkPSJNMTE3Ljk1NSAxMzYuNTQxQzExNC41NzggMTM2LjExMSAxMTAuMDg3IDEzNC44ODEgMTA5LjQxIDEzNC4yNzRDMTA4LjEyMyAxMzMuMTE5IDEwOC45NDIgMTI3Ljg3OSAxMTAuNDY2IDEyNi41NEMxMTEuMzg3IDEyNS43MzEgMTE1LjAzOSAxMjQuNjYzIDExNy4xODIgMTI1LjE2OUMxMTkuNjQyIDEyNS43NDkgMTIzLjkzMiAxMjguNjQ4IDEyNC4yNSAxMjkuNTA4QzEyNC42MjUgMTMwLjUyMiAxMjQuMDQ4IDEzNC41NDEgMTIzLjMyMyAxMzUuNTM2QzEyMi42OTQgMTM2LjM5OSAxMjAuMzI1IDEzNi44NDMgMTE3Ljk1NSAxMzYuNTQxWk0xMjAuNTQgMTM0LjA4NEMxMjEuMjk3IDEzMy4zOTkgMTIxLjM0MiAxMzEuODQyIDEyMC42MjcgMTMxLjEyNkMxMTkuNDkgMTI5Ljk4OSAxMTcuMTEyIDEzMC44NjkgMTE3LjExMiAxMzIuNDI4QzExNy4xMTIgMTM0LjMwNCAxMTkuMTg5IDEzNS4zMDcgMTIwLjU0IDEzNC4wODRaTTExOC41ODIgMTMzLjEyNUMxMTguMzExIDEzMi40MTkgMTE4LjY4IDEzMS42MDggMTE5LjI3MiAxMzEuNjA4QzEyMCAxMzEuNjA4IDEyMC4yMjggMTMyLjE3MyAxMTkuODEyIDEzMi45NDlDMTE5LjM4MSAxMzMuNzU1IDExOC44NTMgMTMzLjgzIDExOC41ODIgMTMzLjEyNVpNMTE2LjQyMiAxMzMuMTQzQzExNy4wOTQgMTMyLjMzMyAxMTYuNzExIDEzMS4xNzYgMTE1LjY4MSAxMzAuOTAyQzExNC41ODEgMTMwLjYxIDExNC4wNTIgMTMxLjE4MyAxMTQuODY5IDEzMS43OEMxMTUuNjgzIDEzMi4zNzUgMTE1LjU1MSAxMzIuNjc5IDExNC41MzMgMTMyLjU1N0MxMTMuMzI3IDEzMi40MTMgMTEyLjgzMyAxMzEuNTY2IDExMy4yNTQgMTMwLjM2MkMxMTMuNjgxIDEyOS4xNDIgMTE1LjE5NyAxMjguODYzIDExNS43NTMgMTI5LjkwMkMxMTYuMTkzIDEzMC43MjUgMTE2LjYyNyAxMzAuNzkzIDExNi45IDEzMC4wODNDMTE3LjIyOSAxMjkuMjI0IDExNS45MTQgMTI4LjIzNyAxMTQuNDQgMTI4LjIzN0MxMTEuOTkzIDEyOC4yMzcgMTEwLjgxNiAxMzEuMDc0IDExMi41NDYgMTMyLjgwM0MxMTMuNSAxMzMuNzU4IDExNS43NDkgMTMzLjk1NSAxMTYuNDIyIDEzMy4xNDNaIiBmaWxsPSIjN0JBOUI5Ii8+CjxwYXRoIGQ9Ik0xMjAuMTE4IDEzOC41OTJDMTE4Ljc1MSAxMzcuMjk3IDEyMS45MTYgMTM2LjA5NiAxMjMuNjA2IDEzOC4yODNDMTI0LjQ2OSAxMzkuMzIyIDEyMi44NTMgMTM5Ljk3NiAxMjAuMTE4IDEzOC41OTJaTTEwNi4xMiAxMzUuNjU4QzEwNC43NTEgMTM0LjI4OSAxMDYuOTYzIDEzMy45MDQgMTA4LjU4MSAxMzUuMjNMMTA5Ljk0MSAxMzUuOTJMMTA4LjA1OSAxMzYuMDYxQzEwNy4yMTUgMTM2LjA2MiAxMDYuMzQzIDEzNS44ODEgMTA2LjEyIDEzNS42NThWMTM1LjY1OFpNMTI1LjM2MyAxMjcuODY2QzEyNS4wODIgMTI3LjQxIDEyOC4zMzMgMTI2LjI2NyAxMjguNjg4IDEyNi40ODZDMTI4Ljg0NiAxMjYuNTg0IDEyOC45NzUgMTI3LjMzNyAxMjguOTc1IDEyOC4xNjFDMTI4Ljk3NSAxMjkuMjM5IDEyOC44NCAxMjkuNjU4IDEyOC40OSAxMjkuNjU4QzEyOC4yMjIgMTI5LjY1OCAxMjUuNDc2IDEyOC4wNDcgMTI1LjM2MyAxMjcuODY2Wk0xMTguNjQxIDEyMS4wOTVDMTE0Ljg3MSAxMjAuNzUzIDExNS4zNzggMTE5LjMyNyAxMTYuMzYxIDExOC40OTlDMTE2LjkyOCAxMTguMDIxIDExNy4zNCAxMTcuNzc5IDExNy45MTMgMTE3LjY2N0MxMTcuOTEzIDExNy42NjcgMTE3Ljg3MiAxMTkuMDQ2IDExOC42NjYgMTE5LjMxOUMxMTkuMjk3IDExOS41MzYgMTIwLjI3OCAxMTkuMDY0IDEyMC40NzEgMTE4LjY3NUMxMjIuMTg4IDExNS4yMDEgMTIxLjQxNSAxMTguNjk5IDEyMS43OTQgMTE5LjUzMkMxMjMuMjM4IDEyNC4wMDcgMTIwLjE4OCAxMjEuNzMgMTE4LjY0MSAxMjEuMDk1Wk0xMDQuOTEyIDEyMS4yM0MxMDQuMjQyIDEyMC40ODcgMTAzLjY5MyAxMTkuNzI5IDEwMy42OTMgMTE5LjU0NEMxMDMuNjkzIDExOS4xMTYgMTA0Ljc0NiAxMTkuMTEyIDEwNS44NjMgMTE5LjUzN0MxMDYuNTkzIDExOS44MTQgMTEwLjM0NyAxMjAuMDA2IDExMC4zNDcgMTIxLjE1M0MxMTAuMzQ3IDEyMS44OTkgMTA4Ljg5IDEyMy43NjIgMTA4LjcyNiAxMjMuNzYyQzEwOC41NjMgMTIzLjc2MiAxMDUuNTgzIDEyMS45NzIgMTA0LjkxMiAxMjEuMjNaIiBmaWxsPSIjQTZCM0MyIi8+CjxwYXRoIGQ9Ik0xMTguNDYzIDEyMS4wMDhDMTE4LjQ0MiAxMjEuMTQgMTE4LjQxNiAxMjEuMjk5IDExOC4zOTcgMTIxLjQxOUMxMTguMzcgMTIxLjU5MiAxMTguMzQ1IDEyMS43NTUgMTE4LjMyMyAxMjEuOTAzQzExOC4zIDEyMi4wNTEgMTE4LjI4MSAxMjIuMTg1IDExOC4yNjMgMTIyLjMwOEMxMTguMjQ1IDEyMi40MzEgMTE4LjIyOSAxMjIuNTQyIDExOC4yMTYgMTIyLjYzOUMxMTguMjAzIDEyMi43MzYgMTE4LjE5MSAxMjIuODIgMTE4LjE4MyAxMjIuODlDMTE4LjE3NSAxMjIuOTYxIDExOC4xNjggMTIzLjAxOCAxMTguMTY1IDEyMy4wNjFDMTE4LjE2MyAxMjMuMDgzIDExOC4xNjQgMTIzLjEgMTE4LjE2MyAxMjMuMTE1QzExOC4xNjIgMTIzLjEyOSAxMTguMTYyIDEyMy4xNCAxMTguMTYzIDEyMy4xNDhDMTE4LjE2MyAxMjMuMTUyIDExOC4xNjQgMTIzLjE1NiAxMTguMTY1IDEyMy4xNThMMTE4LjE2NyAxMjMuMTZDMTE4LjE2OCAxMjMuMTYgMTE4LjE3IDEyMy4xNTkgMTE4LjE3MSAxMjMuMTU4QzExOC4xNzIgMTIzLjE1NyAxMTguMTczIDEyMy4xNTUgMTE4LjE3NSAxMjMuMTUyQzExOC4xNzggMTIzLjE0NSAxMTguMTgyIDEyMy4xMzUgMTE4LjE4NyAxMjMuMTIxQzExOC4xOTIgMTIzLjEwNyAxMTguMTk2IDEyMy4wODkgMTE4LjIwMiAxMjMuMDY3QzExOC4yMTMgMTIzLjAyNSAxMTguMjI4IDEyMi45NjkgMTE4LjI0NSAxMjIuODk3QzExOC4yNjIgMTIyLjgyNSAxMTguMjgyIDEyMi43MzggMTE4LjMwNSAxMjIuNjM1QzExOC4zMjcgMTIyLjUzMyAxMTguMzUxIDEyMi40MTUgMTE4LjM3OSAxMjIuMjgxQzExOC40MDYgMTIyLjE0OCAxMTguNDM4IDEyMS45OTggMTE4LjQ3MSAxMjEuODMzQzExOC41MTYgMTIxLjYxMyAxMTguNTczIDEyMS4zMjEgMTE4LjYyOCAxMjEuMDQzTDExOC40NjMgMTIxLjAwOFoiIGZpbGw9IiM0QzlDQkIiLz4KPHBhdGggZD0iTTMwLjk5ODYgMTQyLjY3M0MyNi40NDg5IDE0MC45MTYgMjEuNDY2NCAxMzYuODA1IDE4Ljc5MjEgMTMyLjYwM0MxNS40MDUzIDEyNy4yODEgMTQuNDA1MiAxMjMuNDE5IDE1LjA2MzYgMTE4LjIwM0MxNS42ODA2IDExMy4zMTUgMTcuMzU1OCAxMTAuNTU3IDIyLjIyMzIgMTA2LjQxM0MyOS4wNDE3IDEwMC42MDggMzQuNDg0NiA5Ny45Nzk5IDQwLjU5NDcgOTcuNTQxNUM0OS44MjEyIDk2Ljg3OTQgNTUuMDk3OCA5OS44MTA5IDU3LjY0NjUgMTA3LjAxNUM1OC41MDQzIDEwOS40MzkgNTguNjg1NiAxMTUuNTcgNTguMDU0NCAxMjAuODA5QzU3LjgzMTEgMTIyLjY2MyA1Ny40Nzg5IDEyNi4wNTUgNTcuMjcxOCAxMjguMzQ4QzU2LjU0NjcgMTM2LjM3NSA1NC40MTQ3IDE0MC40MTcgNDkuNjI1MyAxNDIuODQzQzQ4LjI5NzkgMTQzLjUxNiA0Ny43MTk5IDE0My41NjEgNDAuNjkyNCAxNDMuNTM5QzMzLjUxNTEgMTQzLjUxNiAzMy4wODEgMTQzLjQ3OCAzMC45OTg2IDE0Mi42NzNaTTAuMDc5NTc2NSAxMDQuOTY1QzAuMDgxNTcyMyAxMDMuODUzIDAuMTQ0NDAzIDEwMy40MzggMC4yMTk0MjcgMTA0LjA0NEMwLjI5NDQ1MSAxMDQuNjUgMC4yOTI4OTkgMTA1LjU2IDAuMjE1OTk2IDEwNi4wNjdDMC4xMzkwNzkgMTA2LjU3MyAwLjA3NzY4MzggMTA2LjA3OCAwLjA3OTU3NjUgMTA0Ljk2NVpNMC4wMDE3MzM1MSAxMDIuMjRDMC4wMTc4OTkyIDEwMS44NDggMC4wOTc3ODk3IDEwMS43NjggMC4yMDUzOTggMTAyLjAzN0MwLjMwMjc3MiAxMDIuMjggMC4yOTA3OTcgMTAyLjU3MSAwLjE3ODc4NyAxMDIuNjgzQzAuMDY2Nzc0OCAxMDIuNzk1IC0wLjAxMjkwMjEgMTAyLjU5NiAwLjAwMTczMzUxIDEwMi4yNFpNMC4wMjgzNDQ0IDc1LjEzMjZDMC4wMjgzNDQ0IDc0LjY2OTEgMC4xMDQ4NTcgNzQuNDc5NSAwLjE5ODM2OSA3NC43MTEyQzAuMjkxODg0IDc0Ljk0MyAwLjI5MTg4NCA3NS4zMjIyIDAuMTk4MzY5IDc1LjU1MzlDMC4xMDQ4NTcgNzUuNzg1NyAwLjAyODM0NDQgNzUuNTk2MSAwLjAyODM0NDQgNzUuMTMyNloiIGZpbGw9InVybCgjcGFpbnQyX3JhZGlhbF82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTM1LjMxMzMgMTEyLjU0NEwzNy45IDExMS4wOTFMMzkuMzUxNyAxMjEuNDZMMzkuMjQ4IDEyOC45MjZMMzUuMzcwMyAxMzAuODUxTDMyLjkyMjkgMTI2LjQzN0wzNS4zMTMzIDExMi41NDRaIiBmaWxsPSIjMzA2MEFEIi8+CjxwYXRoIGQ9Ik0zOC43Mjk1IDExNi42OUwzOS4zNTE2IDEyNC41NzFMNDMuMjkxOSAxMjUuOTE5TDQzLjM5NTYgMTA5LjIyNUw0MC4xODEyIDExMC4wNTRMMzguNzI5NSAxMTYuNjlaIiBmaWxsPSIjNjA2MzY4Ii8+CjxwYXRoIGQ9Ik0zNS4zNjk5IDEzMC44NTFDMzMuMDMyNCAxMjkuNzMgMjkuNzMwMSAxMjYuNDA4IDI4LjY2MjEgMTI0LjEwM0MyOC4wMzMyIDEyMi43NDUgMjcuNjM5NyAxMjIuMzEgMjYuODkyMyAxMjIuMTQ2QzI1Ljc4NzkgMTIxLjkwMyAyNS44MDg0IDEyMS45NzEgMjYuMzIxOCAxMjAuMjU4QzI2LjU5MzYgMTE5LjM1IDI2LjkwMzIgMTE4Ljk1NCAyNy4zNDA2IDExOC45NTRDMjcuNjg2MiAxMTguOTU0IDI5LjE1OTcgMTE3Ljg0MSAzMC42MTQ5IDExNi40OEMzMi4wNzAyIDExNS4xMTkgMzMuNzIyNiAxMTMuNjc3IDM0LjI4NjkgMTEzLjI3NUwzNS4zMTI5IDExMi41NDRMMzUuNjc2NyAxMTQuMjQxQzM3LjA0NDMgMTIwLjYxOCAzNy4wMjcgMTI0LjI2NiAzNS42MTk4IDEyNi4yNDNDMzQuNTUyMSAxMjcuNzQ0IDM0Ljg0MTcgMTI4LjM5MyAzNi41NzkxIDEyOC4zOTNDMzcuMzk3IDEyOC4zOTMgMzcuODIyMiAxMjguMTg1IDM4LjEzMDUgMTI3LjYzNEMzOC42NzQ4IDEyNi42NjMgMzguNjMxNSAxMjAuOTY4IDM4LjA0NTQgMTE2LjQyNkMzNy4zNDQ2IDExMC45OTUgMzcuMzEyNyAxMTEuMTY3IDM5LjE1NzggMTEwLjM5OEM0MC4wMzYgMTEwLjAzMSA0MC44MTggMTA5Ljc5NyA0MC44OTU1IDEwOS44NzdDNDAuOTczMSAxMDkuOTU2IDQwLjgxOTEgMTExLjIzNSA0MC41NTM0IDExMi43MThDMzkuNjA2NyAxMTguMDAzIDM5LjkzMTUgMTIzLjIzOCA0MS4yNzUyIDEyNC4zNTNDNDEuNjg1MSAxMjQuNjkzIDQxLjcyMzMgMTIzLjk2OSA0MS41NDUyIDExOS4yMzJDNDEuMzE1NiAxMTMuMTIzIDQxLjUxNzQgMTEwLjkxOSA0Mi40MDc1IDEwOS44MkM0Mi45MTk4IDEwOS4xODggNDMuMjEzIDEwOS4xMTYgNDQuNDk1OSAxMDkuMzFDNDYuOTU2NiAxMDkuNjgyIDQ2Ljk1MDYgMTA5LjY2OCA0Ni4yMDk5IDExMy4yNTRDNDUuODQ5NiAxMTQuOTk5IDQ1LjQ0ODMgMTE3LjIyNCA0NS4zMTggMTE4LjJMNDUuMDgxMiAxMTkuOTczTDQ1Ljk0NDYgMTE5LjY0NUM0Ni40MTk1IDExOS40NjUgNDcuNDQxMyAxMTguOTk0IDQ4LjIxNTMgMTE4LjU5OUw0OS42MjI2IDExNy44ODFMNDkuMzg5MyAxMTguNjdDNDkuMjYxIDExOS4xMDUgNDkuMDY3MiAxMjAuNzAxIDQ4Ljk1ODcgMTIyLjIxOEw0OC43NjE0IDEyNC45NzZMNDcuMTA5NSAxMjQuMzI1QzQ2LjIwMSAxMjMuOTY3IDQ1LjMxMTYgMTIzLjY3NCA0NS4xMzMxIDEyMy42NzRDNDQuOTQxIDEyMy42NzQgNDQuODA4NSAxMjUuNTMyIDQ0LjgwODUgMTI4LjIyNEM0NC44MDg1IDEzMS44OTEgNDQuNzE3MSAxMzIuNzc1IDQ0LjMzODYgMTMyLjc3NUM0MS4wMTk4IDEzMi4yOTUgMzguNzg0MiAxMzIuNDU4IDM1LjM2OTkgMTMwLjg1MVoiIGZpbGw9IiNFRUMyM0IiLz4KPHBhdGggZD0iTTQxLjE2MzkgMTMyLjQxOEM0MS4xNjM5IDEzMi4yODMgNDEuMzQwOCAxMzAuNTE1IDQxLjY2OTIgMTI4LjE0NUM0MS45OTc3IDEyNS43NzUgNDIuMzU3NyAxMjIuOTYxIDQyLjQ2OTIgMTIxLjg5M0M0Mi41ODA4IDEyMC44MjQgNDIuNzk2OSAxMjAuMDI3IDQyLjk0OTUgMTIwLjEyMUM0My42NDQzIDEyMC41NTEgNDQuMjkzOCAxMjkuMzc1IDQ0LjA0NzQgMTMxLjQyQzQzLjg5MDkgMTMyLjcxOSA0My42NTk1IDEzMi43MzcgNDMuMzAxOSAxMzIuNjc3QzQyLjY2MDIgMTMyLjU3IDQxLjkxMDEgMTMyLjUxMyA0MS4xNjM5IDEzMi40MThaTTMyLjU5NjkgMTIyLjczNUMzMS42ODEzIDEyMi41ODMgMzAuODI0MiAxMjEuNDQyIDMwLjgyNDIgMTIwLjM3NEMzMC44MjQyIDExOS40MDcgMzIuMjM4MSAxMTcuOTM3IDMzLjE2ODUgMTE3LjkzN0MzNC42NjY2IDExNy45MzcgMzUuODM5MiAxMjAuNTEzIDM0Ljk0ODQgMTIxLjg0N0MzNC41NTE3IDEyMi40NDEgMzMuNDE0NyAxMjIuODcgMzIuNTk2OSAxMjIuNzM1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExNC4wMjEgMTM3LjQ5OEMxMDcuMzE4IDEzNS43NCAxMDYuMjczIDEzNC4xMDQgMTA2LjYwOSAxMjUuODkxQzEwNi43MTYgMTIzLjI4MSAxMDYuODg1IDEyMC41MzkgMTA2Ljk4NiAxMTkuNzk3QzEwNy41NDUgMTE1LjY2NCAxMDguMzQyIDExMi4xNzMgMTA5LjA4NiAxMTAuNTk5QzEwOS43NDQgMTA5LjIwNiAxMDkuODQyIDEwOC43MTIgMTA5LjUzNSAxMDguMzQyQzEwOC40NSAxMDcuMDM1IDExMC4zNzEgMTA0Ljk5NSAxMTEuOTEgMTA1LjgxOUMxMTIuNDU3IDEwNi4xMTEgMTEyLjkxOCAxMDYuMDc3IDExMy45NDUgMTA1LjY2NUMxMTcuMDYyIDEwNC40MTkgMTIzLjExNyAxMDUuNTcxIDEyNi44MTQgMTA4LjExNUMxMjguMTQ5IDEwOS4wMzMgMTI4LjQ4NSAxMDkuMTM2IDEyOS4wMzggMTA4Ljc5MUMxMzAuNTIzIDEwNy44NjMgMTMyLjQ1MSAxMTAuNTczIDEzMS4yNSAxMTEuOUMxMzAuNzg3IDExMi40MTIgMTMwLjc1NSAxMTIuNzA1IDEzMS4wNjUgMTEzLjU5NkMxMzEuODUgMTE1Ljg0NiAxMzEuNzk0IDExNi4xMDQgMTI4LjAwNiAxMjcuNzE5QzEyNS41OCAxMzUuMTYgMTI0LjU0MyAxMzcuMzY1IDEyMy4yNjQgMTM3LjgxMUMxMjEuNjUzIDEzOC4zNzMgMTE2LjcyMyAxMzguMjA2IDExNC4wMjEgMTM3LjQ5OFpNMTIyLjU0MSAxMzUuMjI5QzEyMy4wMDMgMTM0LjU0MSAxMjMuMzU5IDEzMy4zMTMgMTIzLjUxMyAxMzEuODc4QzEyMy43OTQgMTI5LjI1IDEyMy44MTkgMTI5LjI4MyAxMjAuMzE3IDEyNy42MDFDMTE3LjY4NSAxMjYuMzM4IDExMy44MzMgMTI1Ljk3MiAxMTEuODU1IDEyNi43OThDMTEwLjgyOSAxMjcuMjI3IDExMC41OTUgMTI3LjU1NiAxMTAuMDU5IDEyOS4zMjdDMTA5LjExNiAxMzIuNDQzIDEwOS43MDMgMTM0LjMwOCAxMTEuODMyIDEzNC45NThDMTEzLjEzOSAxMzUuMzU3IDEyMC4wOSAxMzYuNDMgMTIwLjk4IDEzNi4zN0MxMjEuNTA0IDEzNi4zMzUgMTIyLjA4MiAxMzUuOTEyIDEyMi41NDEgMTM1LjIyOVpNMTE5LjQ1MSAxMjIuNDJDMTE5LjYzIDEyMi4wODEgMTE5LjY4NSAxMjEuNTU2IDExOS42ODUgMTIxLjU1NkMxMjAuMTU2IDEyMS42NTQgMTIwLjQ4IDEyMS42ODMgMTIwLjcyNiAxMjEuNzE5QzEyMS4xMDUgMTIxLjc3NCAxMjEuNTY0IDEyMS41ODcgMTIxLjc0NSAxMjEuMzAzQzEyMi4xNDkgMTIwLjY3MSAxMjAuNDc0IDExNy43MDEgMTE5LjU0OCAxMTcuNDA4QzExOC42NjggMTE3LjEyOCAxMTUuOTM1IDExOC44MjcgMTE1LjkzNSAxMTkuNjUzQzExNS45MzUgMTIwLjAyMiAxMTYuNTUzIDEyMC40MTEgMTE2LjgzMSAxMjAuNTE4QzExNi45ODIgMTIwLjU3NiAxMTcuMjUyIDEyMC43MzggMTE3LjU3NiAxMjAuOTM4QzExNy4zOCAxMjEuMzUxIDExNy4zNDYgMTIxLjQ3OCAxMTcuMzEyIDEyMS43MjRDMTE3LjIwNCAxMjIuNDk4IDExNy40MzUgMTIyLjY4NiAxMTguNDE2IDEyMi45MTJDMTE5LjE1MSAxMjIuOTkxIDExOS4yNSAxMjIuODQ1IDExOS40NTEgMTIyLjQyWk0xMjcuMjY1IDExNi44MzZDMTMwLjkzMyAxMTMuNDc1IDEyNy4wNzQgMTA3LjQxIDEyMi43MDUgMTA5LjY3QzEyMS42MjYgMTEwLjIyOCAxMjAuNjU0IDExMi4wMTkgMTIwLjY1NCAxMTMuNDQ5QzEyMC42NTQgMTE1LjY2NCAxMjIuODMxIDExNy45MzcgMTI0Ljk1NyAxMTcuOTQxQzEyNS43MzMgMTE3Ljk0MyAxMjYuNDE0IDExNy42MTcgMTI3LjI2NSAxMTYuODM2Wk0xMTcuMTQxIDExNS42MjJDMTE5LjAzNSAxMTQuNDY4IDExOS44MDQgMTExLjc5NSAxMTguODAyIDEwOS44NTdDMTE4LjA4MiAxMDguNDY0IDExNy4wMDggMTA3LjgzIDExNS4zNjYgMTA3LjgzQzExMS41MDggMTA3LjgzIDEwOS40ODUgMTEzLjIzNCAxMTIuNDY1IDExNS41NzhDMTEzLjU3IDExNi40NDggMTE1Ljc1NCAxMTYuNDY4IDExNy4xNDEgMTE1LjYyMloiIGZpbGw9IiMwOTk2RDEiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMzMuMTc1NyAyNkwzMi4zODEgMjcuMjE5QzMxLjk0NDkgMjcuODg5IDMxLjI4MzYgMjkuMzI0OCAzMC45MDkxIDMwLjQwODhDMzAuNTM0NyAzMS40OTI4IDI5Ljk5MjIgMzIuOTcwMSAyOS43MDQzIDMzLjY5MjhDMjkuNDE2MyAzNC40MTU0IDI5LjE3MzMgMzYuMTE1IDI5LjE2MzggMzcuNDdDMjkuMTQzNiA0MC4zNTMgMjguNzQ5NCA0MS44ODg4IDI3LjYzNjQgNDMuNDIyNUMyNi45MjEyIDQ0LjQwOCAyNi42NzUxIDQ0LjUyMjMgMjUuNDUzMiA0NC40NDFDMjMuODk5NSA0NC4zMzc3IDIyLjgxNTMgNDUuMDgxNSAyMS4yMTcgNDcuMzQ4MUMyMC43MTY1IDQ4LjA1OCAyMC4xMzY3IDQ4LjYzOTMgMTkuOTI4OSA0OC42MzkzQzE5LjcyMTEgNDguNjM5MyAxOS4xODA1IDQ4LjIzMTkgMTguNzI2MiA0Ny43MzUxQzE4LjI3MTkgNDcuMjM4MiAxNy45OTQ0IDQ3LjAxMTUgMTguMTExIDQ3LjIyOThDMTguNDkgNDcuOTM5NiAxNy41OTA0IDUzLjI2MTUgMTYuODM3OCA1NC43NjQyQzE1Ljk2NyA1Ni41MDI4IDE0LjM4NzIgNTcuNzIzMyAxMi41MzU0IDU4LjA4NDNDMTEuMDA1OSA1OC4zODI2IDExLjIyODMgNTguMDkgOC43MTc5NSA2My4wOTQ2QzYuNjYzMzQgNjcuMTkwNyA1Ljk2OTM1IDY3LjgyNjQgMi42NTUzMyA2OC42NTQyQzEuNDk3MTcgNjguOTQzNCAwLjQ1ODc1OSA2OS43MTQyIDAgNzAuNTI4N1Y3Mi44MjYzQzAuMzU2MTkzIDcyLjc0NzMgMC44Mjg3MjggNzIuNjIwMyAxLjYxNDk5IDcyLjM4NzNDMi45OTQ4NiA3MS45NzgyIDQuODIzNDggNzEuNDgwNiA1LjY3ODEgNzEuMjgwNkM3LjcyOTM0IDcwLjgwMDYgOS4zOTM1MSA2OS4yMTk1IDkuOTIyNzkgNjcuMjQ2N0MxMC4yNDI0IDY2LjA1NTQgMTAuNzAzMyA2NS40MjQxIDExLjk5OTIgNjQuNDA1OEMxMy4yODQgNjMuMzk2MiAxMy43NTY1IDYyLjc1NDYgMTQuMDY3MSA2MS41OTY5QzE0LjM3MzkgNjAuNDUzMiAxNC43MDExIDYwLjAwNCAxNS40NDA3IDU5LjcwNjNDMTcuMDE1MyA1OS4wNzI0IDIwLjY0NDQgNTUuODY1NSAyMS4yMzYzIDU0LjU4NThDMjEuNTM3MyA1My45MzQ5IDIyLjExOTggNTIuNTM5OSAyMi41Mjg3IDUxLjQ4NjJDMjMuMjYzNCA0OS41OTMyIDI1LjAxOTUgNDcuMzI2MSAyNS43NTAxIDQ3LjMyNjFDMjUuOTU3NCA0Ny4zMjYxIDI3LjEwOSA0Ni43MjQ4IDI4LjMwOTMgNDUuOTkwOEMzMS4yMzc2IDQ0LjIwMDMgMzEuNTk5MSA0My40MTM2IDMxLjU5OTEgMzguODYxNEMzMS41OTkxIDM1LjY4MTQgMzEuNjg3IDM1LjE1NTcgMzIuMzQ2OCAzNC4zNjg0QzMzLjAwMzcgMzMuNTg0NyAzMy4wOTk3IDMzLjAyNDkgMzMuMTM1MSAyOS43MzkxTDMzLjE3NTcgMjZaTTI0LjMzMzggNjMuNTk1OEMyNC4yMDM3IDYzLjYxMzUgMjQuMDczOCA2My42NjE4IDIzLjkyNTggNjMuNzM2MkMyMi45Mzk3IDY0LjIzMTUgMjIuNjEzNiA2NC45MTAyIDIxLjU5NzMgNjguNTg2QzIxLjAxNzkgNzAuNjgxNSAyMC40MjEyIDcyLjA4MTkgMTkuODc5OCA3Mi42MTc4QzE5LjQyMzUgNzMuMDY5NSAxOC45MzgzIDczLjg4MjMgMTguODAxIDc0LjQyNDJDMTguMTgxIDc2Ljg3MTUgMTYuNzQ1NCA3OC42MDczIDE0LjQ0OTUgNzkuNjg3MUMxMi40NTU1IDgwLjYyNDkgMTAuNjQwNyA4Mi4xMTc5IDkuMTExMDIgODQuMDc5OEM4LjMyMTA5IDg1LjA5MjkgNy40ODc1MiA4Ni4wMjkgNy4yNTY3OCA4Ni4xNjA5QzYuNzYxNjQgODYuNDQ0IDUuNzA4OTkgODguODk0MSA0LjYwNzg1IDkyLjMyOEMzLjcxMDkyIDk1LjEyNSAxLjcxMDY1IDk3LjQ2ODIgMC40Nzg1MTQgOTcuMTY1OEMwLjI1NDkzMSA5Ny4xMTA5IDAuMTA2OTExIDk3LjExMzcgMCA5Ny4yOTAxVjEwNC40OTJDMC41NTY0MTEgMTAzLjY2NCAxLjIzNDIgMTAyLjYyOSAyLjU2MzQ3IDEwMC41NEM0LjM0NTExIDk3LjczOTcgNi40NjM4NSA5NC40ODY3IDcuMjcxNzMgOTMuMzEyNEM4LjA3OTYgOTIuMTM4MSA5LjM1Njg3IDkwLjE0ODggMTAuMTA4NiA4OC44OTE2QzExLjIzNDIgODcuMDA5MiAxMi4xMDE2IDg2LjEyNDMgMTUuMDI4NCA4My44ODMzTDE4LjU4MzEgODEuMTYyN0wyMC40MDUzIDc1Ljk4ODFDMjMuMTg5NSA2OC4wODE3IDIzLjk1ODUgNjcuMTk5NyAyNy43NjI0IDY3LjU1MTVDMjkuNDYwNSA2Ny43MDg1IDMwLjYzMzQgNjcuNjE5NiAzMi4wNzM0IDY3LjIyNjdDMzQuMTgyNiA2Ni42NTEyIDM0LjQ3OTkgNjYuMTg3MiAzMy4zNTUxIDY1LjIzMThDMzIuNjU1NCA2NC42Mzc2IDMxLjMxNTMgNjQuNjQgMjguMjM4OCA2NS4yNDE4QzI3LjMzOTcgNjUuNDE3NyAyNi45MzQzIDY1LjI3NTcgMjUuODkzMiA2NC40MTc4QzI1LjEwNTEgNjMuNzY4NCAyNC43MjQxIDYzLjU0MjYgMjQuMzMzOCA2My41OTU4Wk0zMS43MTY2IDgzLjI1OThDMzEuNjYwNSA4My4yNzQ5IDMxLjU5MjEgODMuMzEyNiAzMS41MTE1IDgzLjM3MjFDMzEuMjcwOSA4My41NSAzMC42NTM2IDgzLjc5IDMwLjEzNzkgODMuOTA1NEMyOS4zODc2IDg0LjA3MzQgMjkuMDQ5OCA4NC40OTMyIDI4LjQ0ODIgODYuMDA0NUMyOC4wMzQ3IDg3LjA0MzIgMjcuNDkxNSA4OC4xMTUzIDI3LjI0MTIgODguMzg2M0MyNi45OTA5IDg4LjY1NzMgMjYuNDc1IDg5LjU1MSAyNi4wOTQxIDkwLjM3MzJDMjQuOTQyMiA5Mi44NTkyIDIzLjUyODIgOTQuMDYxOCAxOS45MDExIDk1LjY0MjFDMTYuNjEwNyA5Ny4wNzU2IDE2LjU2NyA5Ny4xMDg2IDE1LjY2NzEgOTguOTgwMkMxNS4xMDI3IDEwMC4xNTQgMTQuNjc5MiAxMDEuNzU3IDE0LjU0OTkgMTAzLjIwNUMxNC4yNzMxIDEwNi4zMDIgMTMuNTk2MiAxMDcuMDMxIDkuNTIxMTggMTA4LjYxNkM1LjkxNDk3IDExMC4wMTkgMy41NzcwMiAxMTEuNzQ1IDMuNDE1ODMgMTEzLjEyM0MzLjI0MDQxIDExNC42MjMgMi41OTgxMyAxMTUuMDg0IDAuOTI5MjYgMTE0LjkwN0MwLjUzOTUyOSAxMTQuODY2IDAuMjQ0MzMyIDExNC44NTEgMCAxMTQuODgxVjEyMUMxLjAyNjU4IDExOS42NTggMi43MTkyMiAxMTguMzYxIDYuMjI0OTcgMTE2LjIwNkMxMC4zNjA0IDExMy42NjUgMTIuNzA2NSAxMTEuNTc1IDEzLjU3NzkgMTA5LjY1NEMxMy45MjYgMTA4Ljg4NyAxNC42NTQ3IDEwNy4zOTMgMTUuMTk3MSAxMDYuMzM0QzE1LjczOTUgMTA1LjI3NSAxNi4yODQ1IDEwMy45MDEgMTYuNDA4NCAxMDMuMjgxQzE2LjczMjQgMTAxLjY2IDE4LjMwMzIgMTAwLjM0OSAyMC42NjU5IDk5LjcyNkMyNS4xNzcgOTguNTM3MiAyNS43NDYxIDk4LjAxNjMgMjYuMzUyNSA5NC41MzU0QzI2Ljg1NjEgOTEuNjQ1MiAyOC42MTIgODguMDY2MSAzMC41MjY3IDg2LjAyNDZDMzEuMzA5NSA4NS4xOSAzMS45NDk1IDg0LjE4IDMxLjk0OTUgODMuNzc5MUMzMS45NDk1IDgzLjM3NjYgMzEuODg0OSA4My4yMTQ2IDMxLjcxNjYgODMuMjU5OFoiIGZpbGw9IiMzNTkxMzYiLz4KPHBhdGggZD0iTTguMDgxNzcgNzQuNDA4M0M2LjAzNDE5IDczLjg3MDUgNS44OTQ0MyA3My43MzAyIDYuMDQyNzEgNzIuMzYxNUM2LjEzMDI1IDcxLjU1MzMgNi4yNDAxNyA3MC44NTc1IDYuMjg2OTYgNzAuODE1NEM2LjMzMzc2IDcwLjc3MzMgNy43MDQ0MyA3MS4wNjg3IDkuMzMyOTIgNzEuNDcxOUMxMS45NzY4IDcyLjEyNjQgMTIuNDg2NiA3Mi4xMjM4IDE0LjA5NDcgNzEuNDQ3NEMxNi40MDQxIDcwLjQ3NiAxNy4yMzgzIDY4Ljc3NTMgMTYuNDAyMiA2Ni43NDMxQzE1Ljk0MjQgNjUuNjI1NyAxNC45MjA0IDY0LjgyODEgMTIuMjM4NCA2My40OTRDNy42NDE3IDYxLjIwNzUgNi41MzA2MiA1OS45OTkgNi4yNzQ2NSA1Ny4wMDc2QzUuODkzMzcgNTIuNTUxOSA4Ljg0Njg5IDQ5Ljk4MzYgMTQuMzUyMiA0OS45ODM2QzE1Ljk3MzMgNDkuOTgzNiAxNy44NDg3IDUwLjE5MzcgMTguNTE5NiA1MC40NTA1QzE5LjYzNjggNTAuODc4MSAxOS42OTM3IDUxLjAzOTkgMTkuMTk0NSA1Mi4zNzEyQzE4LjcxODIgNTMuNjQxNiAxOC41MDI3IDUzLjc2ODggMTcuNDg2MSA1My4zNzk2QzE1LjUxOTkgNTIuNjI3IDEyLjE5NDggNTIuODU1NCAxMS4wMDU4IDUzLjgyNDdDOS43OTA1OCA1NC44MTUzIDkuNTU3MzYgNTYuOTI1MiAxMC41MzI0IDU4LjEwNzlDMTAuODcyNyA1OC41MjA3IDEyLjkwODcgNTkuNzc5IDE1LjA1NjkgNjAuOTA0MUMxOC40NjI4IDYyLjY4ODEgMTkuMDgyIDYzLjIyMTQgMTkuODk1MSA2NS4wNzE5QzIxLjExNTIgNjcuODQ4NyAyMC42Nzg4IDcwLjM0MzcgMTguNjA3OCA3Mi40MzIzQzE2LjE2MDcgNzQuOTAwMiAxMi41NDEzIDc1LjU3OTYgOC4wODE3NyA3NC40MDgzWk0yOC45MzI4IDc0LjM4MjNDMjUuMjM2NSA3Mi45OTU4IDIzLjcxMzggNzAuNTQwNSAyMy43MTM4IDY1Ljk2NjdDMjMuNzEzOCA2Mi41MDM0IDI0LjU1ODggNjAuNDY5NyAyNi44MzMzIDU4LjQ1OTNDMjguMzk2NCA1Ny4wNzc2IDI4Ljk4NjcgNTYuODY4NiAzMS4zMjY4IDU2Ljg2ODZDMzIuODE2OCA1Ni44Njg2IDM0LjY4MjEgNTcuMjEyOSAzNS41MDA1IDU3LjYzODlDMzcuMzE2OSA1OC41ODQ2IDM4LjgzMTkgNjEuNzQyNiAzOC44NDY2IDY0LjYxNDNMMzguODU3MyA2Ni43MDQ0SDMyLjk0MjNIMjcuMDI3M0wyNy4zNDIgNjguMDU2OUMyNy41MTUgNjguODAwNyAyOC4zMzU0IDcwLjAzOTEgMjkuMTY1IDcwLjgwOUMzMC41NzczIDcyLjExOTYgMzAuODk0OSA3Mi4xOTc5IDM0LjE1NDcgNzIuMDM4NUMzNy4zOTM4IDcxLjg4MDEgMzcuNjQ2MyA3MS45NDA5IDM3Ljc4NCA3Mi45MTIyQzM3Ljk2MjYgNzQuMTcyNSAzNy4xODgyIDc0LjUyMzYgMzMuNTI0MiA3NC44NDM0QzMxLjgwODUgNzQuOTkzMiAzMC4xMDU2IDc0LjgyMjIgMjguOTMyOCA3NC4zODIzWk0zNS4wODgxIDYyLjUyNDJDMzQuOTU1OCA2MC42NzMgMzMuMzY0NCA1OS4zMjc2IDMxLjMwNzIgNTkuMzI3NkMyOS43MDg2IDU5LjMyNzYgMjguNzI4MSA2MC4wOTA5IDI3LjY2MiA2Mi4xNjU1QzI2Ljc0NTcgNjMuOTQ4NiAyNy40MTIgNjQuMjk2NSAzMS40NDg4IDY0LjE0MjVMMzUuMTkzNiA2My45OTk2TDM1LjA4ODEgNjIuNTI0MlpNNDQuMzkxNCA3NC4zNzA4QzQyLjU3MTEgNzMuNTQ2OCA0MS43MDU5IDcyLjEyODYgNDEuNjQyMSA2OS44NjQ3QzQxLjU0MTYgNjYuMjk0NCA0NC4xMTEgNjQuMTQ2OCA0OS4yNTc2IDYzLjQ5OTRDNTEuODQxNCA2My4xNzQ0IDUyLjA0OTUgNjMuMDU3NyA1MS43NTkzIDYyLjA5NjlDNTAuOTY1IDU5LjQ2NjYgNDguMjQyMyA1OC41NjQ0IDQ0LjkyNzYgNTkuODMzMUM0My40MzAzIDYwLjQwNjMgNDMuNDg2OCA2MC40MzEzIDQzLjA1MTQgNTkuMDAzMkM0Mi43ODAxIDU4LjExMzUgNDIuOTk4MiA1Ny44NTExIDQ0LjM5NSA1Ny4zODdDNDYuOTM2NCA1Ni41NDI3IDUxLjM3NDUgNTYuNjM0MiA1Mi43Nzc5IDU3LjU2QzU0LjkzOTIgNTguOTg1NyA1NS4zNzUxIDYwLjYwMTkgNTUuNTQ4NyA2Ny44MzI4TDU1LjcxMDYgNzQuNTc0NUw1NC4xMjMgNzQuNTc0QzUzLjAzNzcgNzQuNTczMyA1Mi41MzUzIDc0LjMzOTYgNTIuNTM1MyA3My44MzU0QzUyLjUzNTMgNzIuOTA2NiA1Mi4wNTI4IDcyLjkwMjQgNTAuNzUyIDczLjgxOTZDNDkuMjAxMyA3NC45MTMgNDYuMTY5NyA3NS4xNzU3IDQ0LjM5MTQgNzQuMzcwOFpNNTAuOTQ3NyA3MC44MTc1QzUxLjcwOTkgNjkuOTczNSA1Mi4wNDY4IDY4Ljk4NiA1Mi4wNDY4IDY3LjU5NjZWNjUuNTkyOUw0OS44MTgyIDY1Ljg0NThDNDUuNzE5IDY2LjMxMSA0My44NzQ5IDY5LjUxMTggNDYuNTA1OCA3MS41OTUzQzQ4LjAzNzEgNzIuODA3OSA0OS4zNTk0IDcyLjU3NjMgNTAuOTQ3NyA3MC44MTc1Wk05Mi4wMDIgNzQuNTc4OEM4OC40MDI0IDczLjQ4NjQgODYuMjQxOSA3MC4yNDY2IDg2LjI0MTkgNjUuOTQxQzg2LjI0MTkgNjAuNDA0MiA4OS41MjExIDU2LjgzMjUgOTQuNjQxIDU2Ljc5MjVDOTguNjk4OSA1Ni43NjA5IDEwMS4yNjMgNTkuNDY3OSAxMDEuNTAzIDY0LjAzNjZMMTAxLjYzIDY2LjQ1ODVMOTYuMjU2MiA2Ni41ODg1QzkzLjMwMDcgNjYuNjYgOTAuNjE1OCA2Ni44MTYgOTAuMjg5NyA2Ni45MzUxQzg5LjM4MTggNjcuMjY2OCA5MC40Nzg4IDY5Ljk0NyA5Mi4wMzA2IDcxLjE4ODZDOTMuMTU5OSA3Mi4wOTIxIDkzLjc3MSA3Mi4xOTEyIDk2LjgxNzggNzEuOTY1QzEwMC4xOTMgNzEuNzE0NCAxMDAuMzE4IDcxLjc0NDkgMTAwLjUzMSA3Mi44Njg0QzEwMC43MyA3My45MTMzIDEwMC41MDkgNzQuMDgzNSA5OC4zNTc5IDc0LjU0OEM5NS42MTAzIDc1LjE0MTIgOTMuODgyOSA3NS4xNDk2IDkyLjAwMiA3NC41Nzg4Wk05Ny45NjU5IDYzLjA4MjNDOTcuOTY1OSA2MS4xMjMxIDk2LjE4NTggNTkuMzI3NiA5NC4yNDM0IDU5LjMyNzZDOTIuMjQ5NCA1OS4zMjc2IDkwLjE0OTkgNjEuMjU2MiA5MC4xNDk5IDYzLjA4NzhDOTAuMTQ5OSA2NC4yMDcgOTAuMjc5NyA2NC4yNDU1IDk0LjA1NzkgNjQuMjQ1NUM5Ny44NDE0IDY0LjI0NTUgOTcuOTY1OSA2NC4yMDg0IDk3Ljk2NTkgNjMuMDgyM1pNMTEwLjA0MiA3NC40N0MxMDYuMTQ5IDczLjQzIDEwMy45MyA2OS40MDI5IDEwNC41NCA2NC40ODYyQzEwNS4xNjYgNTkuNDQ0MiAxMDcuOTUxIDU2Ljg3MzYgMTEyLjc5MiA1Ni44NzA1QzExNS4zNzQgNTYuODY5IDExNS44MDUgNTcuMDI0OSAxMTcuMjYgNTguNDlDMTE4Ljg3OCA2MC4xMTg1IDExOS45NDEgNjIuODM0MyAxMTkuOTQ2IDY1LjM1MkwxMTkuOTQ5IDY2LjcwNDRIMTE0LjA4N0MxMDguNDg4IDY2LjcwNDQgMTA4LjIyNSA2Ni43NTAxIDEwOC4yMjUgNjcuNzIwM0MxMDguMjI1IDcwLjcxMjIgMTEwLjk1MiA3Mi4zNDQyIDExNS4zNTcgNzEuOTg4MkMxMTguMTM2IDcxLjc2MzcgMTE4LjQyMyA3MS44MzE1IDExOC42NjcgNzIuNzY3NEMxMTguOTk4IDc0LjA0NDMgMTE4Ljk2OCA3NC4wNzIgMTE2LjY5IDc0LjYwNDNDMTE0LjM2NyA3NS4xNDcgMTEyLjQzIDc1LjEwNzggMTEwLjA0MiA3NC40N1pNMTE2LjExOSA2Mi43NzAxQzExNS44NjQgNjAuODc4NyAxMTQuMTU5IDU5LjMyNzYgMTEyLjMzNSA1OS4zMjc2QzExMC41NjYgNTkuMzI3NiAxMDguMjI0IDYxLjYwMTQgMTA4LjIyNCA2My4zMTk1QzEwOC4yMjQgNjQuMjEyOCAxMDguNTI3IDY0LjI3NDYgMTEyLjI1NSA2NC4xNDI0QzExNi4yNDEgNjQuMDAxMSAxMTYuMjgzIDYzLjk4NjIgMTE2LjExOSA2Mi43NzAxWk0xMjYuODk0IDc0LjI0N0MxMjQuODI2IDczLjIyMDggMTIzLjUzMiA3MS4zNTg5IDEyMi44OTQgNjguNDg4OUMxMjEuOTc1IDY0LjM2MDUgMTIzLjA3NCA2MC40OTE0IDEyNS44MyA1OC4xNTY3QzEyNy44MjcgNTYuNDY1NyAxMzEuODM4IDU2LjMzMDUgMTMzLjgwNSA1Ny44ODc5TDEzNS4wOTIgNTguOTA3MlY1My45NTM2VjQ5SDEzNy4wNDZIMTM5VjYxLjc4NjVWNzQuNTczMUgxMzcuMjlDMTM1Ljc2MiA3NC41NzMxIDEzNS41OCA3NC40MzMxIDEzNS41OCA3My4yNTc5VjcxLjk0MjdMMTM0LjQ4MSA3Mi45NzkyQzEzMi4yMzMgNzUuMDk5OCAxMjkuNTI1IDc1LjU1MjMgMTI2Ljg5NCA3NC4yNDdaTTEzMy42NjQgNzAuNjc2NkMxMzQuOTc2IDY5LjM1NTcgMTM1LjA5MiA2OC45NTM3IDEzNS4wOTIgNjUuNzIwOUMxMzUuMDkyIDYyLjQ1NzIgMTM0Ljk4NSA2Mi4wOTQ1IDEzMy42MDcgNjAuNzA3NkMxMzIuMzY1IDU5LjQ1NzUgMTMxLjg2NSA1OS4yNjIyIDEzMC41NTQgNTkuNTE1NEMxMjYuMTQ0IDYwLjM2NzIgMTI0LjgzNSA2OC4xNDIzIDEyOC41OTggNzEuMTIyOUMxMzAuMzQ4IDcyLjUwODEgMTMxLjk4OCA3Mi4zNjM1IDEzMy42NjQgNzAuNjc2NlpNNjEuNDEwNyA2Ni4wNTg0QzYwLjAyMiA2MS4zNzU0IDU4Ljg4NTkgNTcuMzkxOSA1OC44ODU5IDU3LjIwNjJDNTguODg1OSA1Ny4wMjA2IDU5LjcyNzQgNTYuODY4NiA2MC43NTU5IDU2Ljg2ODZINjIuNjI1OUw2NC4yNTUxIDYzLjg3NjZDNjUuMTUxMiA2Ny43MzEgNjUuOTU2IDcwLjY2MzMgNjYuMDQzNyA3MC4zOTI5QzY2LjEzMTMgNzAuMTIyNCA2Ny4wNTU3IDY3LjAyNDEgNjguMDk3OCA2My41MDc4TDY5Ljk5MjYgNTcuMTE0NUg3MS41OTY5SDczLjIwMTJMNzQuODg2NSA2My4yNjE5Qzc1LjgxMzQgNjYuNjQzIDc2LjY4MzIgNjkuNzQxMiA3Ni44MTk0IDcwLjE0N0M3Ni45NTU3IDcwLjU1MjcgNzcuODQxOSA2Ny43MzEgNzguNzg5IDYzLjg3NjZMODAuNTEwOSA1Ni44Njg2SDgyLjQ1MTdDODMuOTUxNyA1Ni44Njg2IDg0LjMzMDMgNTcuMDMxNiA4NC4xMTkgNTcuNTg2QzgzLjk2ODYgNTcuOTgwNiA4Mi42OTU2IDYxLjk2NDEgODEuMjkwMiA2Ni40MzgyTDc4LjczNDkgNzQuNTczMUg3Ni45NjM1SDc1LjE5MjFMNzMuNTgxMiA2OC43OTQ1QzcyLjY5NTIgNjUuNjE2MyA3MS44NTg1IDYyLjY4NDEgNzEuNzIxNyA2Mi4yNzgzQzcxLjQ0NjUgNjEuNDYxNiA3MS41OTExIDYxLjA3MzMgNjkuMTExNCA2OS4yODYzTDY3LjUxNTIgNzQuNTczMUg2NS43MjU0SDYzLjkzNTZMNjEuNDEwNyA2Ni4wNTg0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTE5Ljk3NDYgMTE5LjI3NEMxOS4wMTU4IDExOC4xMTkgMjAuMzM4MSAxMTYuMTY2IDIxLjU2MDQgMTE2LjkzMkMyMi43NjMyIDExNy42ODYgMjIuMzMwNSAxMTkuNzYxIDIwLjk3MDQgMTE5Ljc2MUMyMC42NDUgMTE5Ljc2MSAyMC4xOTY5IDExOS41NDIgMTkuOTc0NiAxMTkuMjc0WiIgZmlsbD0idXJsKCNwYWludDNfcmFkaWFsXzY3OV8xOTEwKSIvPgo8cGF0aCBkPSJNMjMuODM2IDExMi42M0MyMi4xMTUyIDExMS42ODkgMjEuODAyOSAxMDkuNzk3IDIzLjE0NjUgMTA4LjQ1M0MyNC4wODU3IDEwNy41MTQgMjUuMjEgMTA3LjM5NCAyNi4yNTA3IDEwOC4xMjNDMjcuODU3MSAxMDkuMjQ5IDI3LjQ2NTUgMTEyLjAxMyAyNS42MDc5IDExMi42NkMyNS42MDc5IDExMi42NiAyNC40NzQ1IDExMi45NzMgMjMuODM2IDExMi42M1oiIGZpbGw9InVybCgjcGFpbnQ0X3JhZGlhbF82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTMzLjc4NTUgMTIwLjAzNkMzMy43ODU1IDEyMC4xODggMzMuNzU1NyAxMjAuMzM4IDMzLjY5NzYgMTIwLjQ3OUMzMy42Mzk1IDEyMC42MTkgMzMuNTU0NCAxMjAuNzQ2IDMzLjQ0NzEgMTIwLjg1M0MzMy4zMzk4IDEyMC45NjEgMzMuMjEyNCAxMjEuMDQ2IDMzLjA3MjMgMTIxLjEwNEMzMi45MzIxIDEyMS4xNjIgMzIuNzgxOCAxMjEuMTkyIDMyLjYzMDEgMTIxLjE5MkMzMi40NzgzIDEyMS4xOTIgMzIuMzI4MSAxMjEuMTYyIDMyLjE4NzkgMTIxLjEwNEMzMi4wNDc3IDEyMS4wNDYgMzEuOTIwMyAxMjAuOTYxIDMxLjgxMyAxMjAuODUzQzMxLjcwNTcgMTIwLjc0NiAzMS42MjA2IDEyMC42MTkgMzEuNTYyNiAxMjAuNDc5QzMxLjUwNDUgMTIwLjMzOCAzMS40NzQ2IDEyMC4xODggMzEuNDc0NiAxMjAuMDM2QzMxLjQ3NDYgMTE5LjczIDMxLjU5NjMgMTE5LjQzNiAzMS44MTMgMTE5LjIxOUMzMi4wMjk3IDExOS4wMDMgMzIuMzIzNiAxMTguODgxIDMyLjYzMDEgMTE4Ljg4MUMzMi45MzY1IDExOC44ODEgMzMuMjMwNCAxMTkuMDAzIDMzLjQ0NzEgMTE5LjIxOUMzMy42NjM4IDExOS40MzYgMzMuNzg1NSAxMTkuNzMgMzMuNzg1NSAxMjAuMDM2WiIgZmlsbD0iYmxhY2siLz4KPHBhdGggZD0iTTEyMC43MjEgMTE4LjI3NkMxMjAuNzIxIDExOC42MjMgMTIwLjU2NSAxMTguOTU2IDEyMC4yODcgMTE5LjIwMUMxMjAuMDA5IDExOS40NDYgMTE5LjYzMiAxMTkuNTg0IDExOS4yMzkgMTE5LjU4NEMxMTguODQ2IDExOS41ODQgMTE4LjQ2OSAxMTkuNDQ2IDExOC4xOTEgMTE5LjIwMUMxMTcuOTEzIDExOC45NTYgMTE3Ljc1NyAxMTguNjIzIDExNy43NTcgMTE4LjI3NkMxMTcuNzU3IDExOC4xMDUgMTE3Ljc5NSAxMTcuOTM1IDExNy44NyAxMTcuNzc2QzExNy45NDQgMTE3LjYxNyAxMTguMDUzIDExNy40NzMgMTE4LjE5MSAxMTcuMzUyQzExOC4zMjkgMTE3LjIzIDExOC40OTIgMTE3LjEzNCAxMTguNjcyIDExNy4wNjhDMTE4Ljg1MSAxMTcuMDAzIDExOS4wNDQgMTE2Ljk2OSAxMTkuMjM5IDExNi45NjlDMTE5LjQzMyAxMTYuOTY5IDExOS42MjYgMTE3LjAwMyAxMTkuODA2IDExNy4wNjhDMTE5Ljk4NiAxMTcuMTM0IDEyMC4xNDkgMTE3LjIzIDEyMC4yODcgMTE3LjM1MkMxMjAuNDI0IDExNy40NzMgMTIwLjUzMyAxMTcuNjE3IDEyMC42MDggMTE3Ljc3NkMxMjAuNjgyIDExNy45MzUgMTIwLjcyMSAxMTguMTA1IDEyMC43MjEgMTE4LjI3NloiIGZpbGw9IiM1OTY4NkYiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82NzlfMTkxMCIgeDE9IjExIiB5MT0iLTQuNzc3NjhlLTA3IiB4Mj0iMTY0LjUiIHkyPSIxNTAuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNjRCN0ZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNURBRCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50MV9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTI0LjkwNCAxMjguNjM2KSByb3RhdGUoLTAuMDQ4NTUyKSBzY2FsZSgzNi4yODAyIDMxLjQwMzIpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzExNzdDRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM3RUM3RkYiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50Ml9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzkuMzUxMiAxMjEuNDYpIHJvdGF0ZSgtMC4wNTczKSBzY2FsZSg1MC4yMjc2IDUxLjMwOTEpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzExNzdDRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM3RUM3RkYiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50M19yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjAuOTU0OCAxMTguMjYpIHNjYWxlKDEuMzA5MjkgMS41MDEyNykiPgo8c3RvcCBzdG9wLWNvbG9yPSIjODhBM0QwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzVEODNCRiIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50NF9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQuNzg0MyAxMTAuMjIxKSBzY2FsZSgyLjQ3Mjc3IDIuNTY5NTQpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzg4QTNEMCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM1RDgzQkYiLz4KPC9yYWRpYWxHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "topology"], ["spec", "replicationFactor"], ["spec", "db"], ["spec", "db", "replicas"], ["spec", "db", "size"], ["spec", "db", "storageClass"], ["spec", "db", "resources"], ["spec", "db", "resourcesPreset"], ["spec", "master"], ["spec", "master", "replicas"], ["spec", "master", "resources"], ["spec", "master", "resourcesPreset"], ["spec", "filer"], ["spec", "filer", "replicas"], ["spec", "filer", "resources"], ["spec", "filer", "resourcesPreset"], ["spec", "filer", "grpcHost"], ["spec", "filer", "grpcPort"], ["spec", "filer", "whitelist"], ["spec", "volume"], ["spec", "volume", "replicas"], ["spec", "volume", "size"], ["spec", "volume", "storageClass"], ["spec", "volume", "resources"], ["spec", "volume", "resourcesPreset"], ["spec", "volume", "zones"], ["spec", "s3"], ["spec", "s3", "replicas"], ["spec", "s3", "resources"], ["spec", "s3", "resourcesPreset"]] - secrets: - exclude: [] - include: [] - services: - exclude: [] - include: - - resourceNames: - - "{{`seaweedfs-{{ .name }}-s3`}}" - ingresses: - exclude: [] - include: - - resourceNames: - - "{{`ingress-seaweedfs-{{ .name }}-s3`}}" diff --git a/packages/core/platform/psds/tcp-balancer-application.yaml b/packages/core/platform/psds/tcp-balancer-application.yaml new file mode 100644 index 00000000..0ba031e7 --- /dev/null +++ b/packages/core/platform/psds/tcp-balancer-application.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.tcp-balancer-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: tcp-balancer + path: apps/tcp-balancer + libraries: ["cozy-lib"] + - name: tcp-balancer-rd + path: system/tcp-balancer-rd + install: + namespace: cozy-system + releaseName: tcp-balancer-rd diff --git a/packages/core/platform/psds/tcp-balancer.yaml b/packages/core/platform/psds/tcp-balancer.yaml deleted file mode 100644 index 34fc4ed7..00000000 --- a/packages/core/platform/psds/tcp-balancer.yaml +++ /dev/null @@ -1,48 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.tcp-balancer-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: tcp-balancer - path: apps/tcp-balancer - libraries: - - cozy-lib - template: - spec: - application: - kind: TCPBalancer - plural: tcpbalancers - singular: tcpbalancer - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"httpAndHttps":{"description":"HTTP and HTTPS configuration.","type":"object","default":{},"required":["mode","targetPorts"],"properties":{"endpoints":{"description":"Endpoint addresses list.","type":"array","default":[],"items":{"type":"string"}},"mode":{"description":"Mode for balancer.","type":"string","default":"tcp","enum":["tcp","tcp-with-proxy"]},"targetPorts":{"description":"Target ports configuration.","type":"object","default":{},"required":["http","https"],"properties":{"http":{"description":"HTTP port number.","type":"integer","default":80},"https":{"description":"HTTPS port number.","type":"integer","default":443}}}}},"replicas":{"description":"Number of HAProxy replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each TCP Balancer replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"List of allowed client networks.","type":"array","default":[],"items":{"type":"string"}},"whitelistHTTP":{"description":"Secure HTTP by whitelisting client networks (default: false).","type":"boolean","default":false}}} - release: - prefix: tcp-balancer- - labels: - cozystack.io/ui: "true" - dashboard: - category: NaaS - singular: TCP Balancer - plural: TCP Balancer - description: Layer4 load balancer service - tags: - - network - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMjk4NSkiLz4KPHBhdGggZD0iTTcyLjE2NDUgNTkuNDI0M0w2Mi41IDQ4LjQ5OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjI2IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTQxLjY4NTUgNTEuMDIxNUw0OS4yNDcgNjIuMDY5MyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTcyLjE2NDYgNTkuNDQxNEw4MS43MjYzIDQ4LjM5MzZNODMuNzE3MSA3MS42Mjk0TDk1LjA2NCA2Mi4wNjc4TTgzLjcxNzEgNzEuNjEwOEw5NS4wNjQgODEuNTkzTTgxLjgyOTEgOTQuMjAxN0w3Mi4xNjQ2IDgzLjQ4MTFNNjIuNTAwMSA5NC4yMDE3TDcyLjE2NDYgODMuNDkwNE00OS4yNTU5IDgxLjE3MjRMNjAuMTgyMSA3MS42MTA4TTYwLjE5MTUgNzEuNjEwOEw0OS4yNjUyIDYyLjA0OTFMNzIuMTY0NiA1OS40MjI3TDk1LjA2NCA2Mi4wNDkxIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMjYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNODEuNzE2OCA0OC4zOTM2TDgzLjcxNyA3MS42MTA4TDgxLjgyOSA5NC4xOTI0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMjYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDY0IDgxLjU5MjVMNzIuMTY0NiA4My40ODA1TTQ5LjI1NTkgODEuMTcxOUw3Mi4xNTUzIDgzLjQ5OTIiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4yNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik02Mi41MDEyIDk0LjIwMTRMNjAuMTczOCA3MS42MTk4TTYyLjUwMTIgNDguNDk2MUw2MC4xNzM4IDcxLjYxMDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4yNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0zOC43NSA2NC45OTQ4TDQ5LjI1NTcgNjIuMDUwNk01MS40NjE1IDQwLjYxODdMNjIuNTA5MyA0OC40OTc5TTYyLjQ5MDYgNDguNDk3OUw2NS4wMTQyIDM1LjY4MzZMODEuNzE2OCA0OC4zOTUxIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNzkuMjAzMSAzNS42ODM2TDgxLjcyNjcgNDguMzk1MU05Mi43NTU4IDQwLjYxODdMODEuNzA4IDQ4LjM5NTFNMTAyLjYyNiA1MS4wMjE1TDgxLjcxNzQgNDguMzk1MU0xMDIuNjI2IDUxLjAwMjhMOTUuMDY0NSA2Mi4wNTA2TDEwNS43NzYgNjQuOTk0OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTk1LjA2MzkgNjIuMDUwNkwxMDUuNTcgNzguMDE0OE03OS4yMDI1IDM1LjY4MzZMNjIuNSA0OC40OTc5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDYzNyA2Mi4wNTExTDkyLjczNjMgNDAuNjE5MU05NS4wNjM3IDgxLjU5NTFMMTA1LjU2OSA3OC4wMTUzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDY1IDgxLjU5NDlMMTA1Ljc3NiA2NC45OTUxTTk1LjA2NSA4MS41OTQ5TDEwMi42MjYgOTEuNzgyOE05NS4wNjUgODEuNTk0OUw5Mi43Mzc3IDEwMi4xODZNODEuODMwMSA5NC4yMDM1TDkyLjc1NjQgMTAyLjE4NiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTgxLjgyOSA5NC4yMDNMMTAyLjYyNSA5MS43ODIyTTgxLjgyOSA5NC4yMDNMNzkuMzI0MSAxMDcuMTExTTgxLjgyOSA5NC4yMDNMNjUuMDE0MyAxMDcuMTAxTTYyLjUgOTQuMjAzTDY1LjAyMzYgMTA3LjEzOSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTYyLjUwMTIgOTQuMjAzMUw3OS4zMjUzIDEwNy4xMTFNNTEuNDYyOCAxMDIuMTg1TDYyLjUxMDUgOTQuMjAzMUw0MS42NzY4IDkxLjg4NTFMNDkuMjU2OSA4MS4xNzM4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNTEuNDYxOCAxMDIuMTg1TDQ5LjI1NiA4MS4xNzMxTDM4LjY0NzUgNzcuOTExMUw0OS4yNTYgNjIuMDQ5OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTQ5LjI1NTcgODEuMTc0NUwzOC43NSA2NC45OTUzTTUxLjQ2MTUgNDAuNjE5MUw0OS4yNTU3IDYyLjA1MTEiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik00MS42ODU1IDUxLjAyMTdMNjIuNDgxOSA0OC40OTgiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik00My4zNzYgMzYuODMzOEw1MS40NjA5IDQwLjYxOTJMNTAuODM0NiAzMS43OTU5TDY1LjAxMzYgMzUuNjg0MSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik01OC45Mjg5IDI4LjIyNDRMNjUuMDEzNiAzNS42ODMxTDY3LjUzNzMgMjYuNzM4M0w3OS4yMDE5IDM1LjY4MzFNNTEuNDYwOSA0MC42MTgxTDU4LjkxOTYgMjguMjI0NCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik03Ni41NjY3IDI2LjQ0MDRMNzkuMjAyNSAzNS42ODQzTDg1LjI5NjYgMjguMjI1Nk02NS4wMDQ5IDM1LjY4NDNMNzYuNTU3NCAyNi40NDA0TTkyLjc1NTIgNDAuNjE5NEw4NS4yNzc5IDI4LjIyNTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTIuNzU0OSA0MC42MTkyTDkzLjQ5MzIgMzEuNzk1OU05Mi43NTQ5IDQwLjYxOTJMMTAxLjAzNiAzNi40MTMyTTkyLjc1NDkgNDAuNjE5MkwxMDcuMTQ5IDQyLjgyNU03OS4yMDIxIDM1LjY4NDFMOTMuNDgzOSAzMS43OTU5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTEwMi42MjUgNTEuMDIxNEwxMDcuMTM5IDQyLjgyNDRNMTAyLjYyNSA1MS4wMjE0TDEwMS4wNDUgMzYuNDIxOU0xMDIuNjI1IDUxLjAyMTRMMTEyLjA4MyA1MC4yODNNMTAyLjYyNSA1MS4wMjE0TDExNS41NiA1OC4zNzczIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTEwNS43NzQgNjQuOTk0OUwxMTIuMDgzIDUwLjI4MzJNMTA1Ljc3NCA2NC45OTQ5TDExNS41NDEgNTguMzc3NE0xMDUuNzc0IDY0Ljk5NDlMMTE2LjcgNjcuMjAwN0wxMDUuNTY4IDc4LjAxNDkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMTE3LjAxOSA3NS45MTIxTDEwNS41NjkgNzguMDE1MUwxMTUuMzM3IDg0LjUyOTdMMTAyLjYyNSA5MS43ODI3TTEwNS43NzUgNjQuOTk1MUwxMTcuMDE5IDc1LjkyMTQiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMTAyLjYyNSA5MS43ODMzTDExMS45NzEgOTIuNzI3M00xMDUuNTc4IDc4LjAxNTZMMTExLjk3MSA5Mi43MThNMTA3LjA1NSAxMDAuMDY0TDEwMi42NDMgOTEuNzgzM0wxMDAuOTYxIDEwNi4yOCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0xMDAuOTQzIDEwNi4yNzlMOTIuNzQ1OCAxMDIuMTg1TTkyLjc1NTEgMTAyLjE4NUw5My4zODEzIDExMS4zNDVNOTIuNzU1MSAxMDIuMTg1TDEwNy4wMzcgMTAwLjA4Mk05Mi43NTUxIDEwMi4xODVMODUuMjg3MSAxMTQuNzk0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTc5LjMyMzIgMTA3LjEwM0w4NS4yNzcgMTE0Ljc2N003OS4zMjMyIDEwNy4xMDNMOTMuMzk5MyAxMTEuMzA5TTc5LjMyMzIgMTA3LjEwM0w3Ni41NjU5IDExNi41NjFNNzkuMzIzMiAxMDcuMTAzTDY3LjU1NTcgMTE2LjU2MSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik02NS4wMTM2IDEwNy4xMDJMNjcuNTM3MyAxMTYuNTYxTTY1LjAxMzYgMTA3LjEwMkw3Ni41NTY4IDExNi41NjFNNjUuMDEzNiAxMDcuMTAyTDU5LjAyMjQgMTE0Ljc2Nk01MS40NjA5IDEwMi4xODZMNTkuMDIyNCAxMTQuNzk0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTY1LjAxMzkgMTA3LjEwMUw1MC43MzIyIDExMS41MTNNNTAuNzIyOCAxMTEuNTMyTDUxLjQ2MTIgMTAyLjE4NUw0My4yNjQyIDEwNi42OTlMNDEuNjg0NiA5MS44ODQ4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTUxLjQ2MSAxMDIuMTg2TDM3LjA2NzEgMTAwLjE5NU00MS42ODQ0IDkxLjg4NkwzNy4wNTc4IDEwMC4xNjdNNDEuNjg0NCA5MS44ODZMMzIuMjI1NSA5Mi44MzAxTTQxLjY4NDQgOTEuODg2TDI4LjY3MzggODQuNjQyM0wzOC42NDY3IDc3LjkxMjdMMjcuMjk5OCA3NS45MjE5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTM4LjY0NjcgNzcuOTEyM0wzMi4yNTM2IDkyLjgyOTZNMzguNzQ5NSA2NC45OTUxTDI3LjI5OTggNzUuOTIxNCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0zOC42NDY3IDc3LjkxMjJMMjcuMjk5OCA2Ny4yMDA5TTM4Ljc1ODkgNjQuOTk1MUwyOC45ODIyIDU4LjQ4MDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMjcuMjk5OCA2Ny4yMDA3TDM4Ljc0OTUgNjQuOTk0OUwzMi4yNDQyIDUwLjI4MzIiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNDEuNjgzNiA1MS4wMjE3TDMyLjIyNDcgNTAuMjgzM000MS42ODM2IDUxLjAyMTdMMjguOTgxNCA1OC40ODA0TTQxLjY4MzYgNTEuMDIxN0wzNy4xNzg1IDQzLjI0NTNNNDEuNjgzNiA1MS4wMjE3TDQzLjM2NiAzNi44NDI4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTUxLjQ2MSA0MC42MTkxTDM3LjE2OTkgNDMuMjQ1NiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik01NC41NjQ1IDc3LjA3MDJMNTQuNjM5MiA2Ni4wMjI0TDY1LjY4NyA2Ni4wOTcxTDY1LjYxMjMgNzcuMTQ0OUw1NC41NjQ1IDc3LjA3MDJaTTY2LjUxODkgNjQuOTEwMUw2Ni41OTM3IDUzLjg2MjNMNzcuNjQxNSA1My45MzcxTDc3LjU2NjcgNjQuOTg0OUw2Ni41MTg5IDY0LjkxMDFaTTY2LjUxODkgODkuMTI3NEw2Ni41OTM3IDc4LjA3OTZMNzcuNjQxNSA3OC4xNTQ0TDc3LjU2NjcgODkuMjAyMkw2Ni41MTg5IDg5LjEyNzRaTTc4LjU3NjEgNzYuOTY3M0w3OC42NTA5IDY1LjkxOTVMODkuNjk4NyA2NS45OTQzTDg5LjYyMzkgNzcuMDQyMUw3OC41NzYxIDc2Ljk2NzNaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNzcuOTQwNiA1Mi4yMzY2TDc3Ljk5NjYgNDQuNTcyM0w4NS42OTgzIDQ0LjYyODNMODUuNjQyMiA1Mi4yOTI2TDc3Ljk0MDYgNTIuMjM2NlpNNTguNjg2NCA1Mi4yMzY2TDU4Ljc0MjQgNDQuNTcyM0w2Ni40NDQxIDQ0LjYyODNMNjYuMzg4IDUyLjI5MjZMNTguNjg2NCA1Mi4yMzY2Wk00NS4zNTggNjUuODkyMUw0NS40MTQxIDU4LjIyNzhMNTMuMTE1NyA1OC4yODM5TDUzLjA1OTcgNjUuOTQ4Mkw0NS4zNTggNjUuODkyMVpNNDUuMzQ4NiA4NS4xNjVMNDUuNDMyOCA3Ny41MDA3TDUzLjEzNDQgNzcuNTg0OEw1My4wNTAzIDg1LjI0OTFMNDUuMzQ4NiA4NS4xNjVaTTkxLjI2OSA4NS4wMTU0TDkxLjMyNSA3Ny4zNTExTDk5LjAyNjcgNzcuNDA3Mkw5OC45NzA2IDg1LjA3MTVMOTEuMjY5IDg1LjAxNTRaTTkxLjQxODUgNjUuOTQ4Mkw5MS41MDI2IDU4LjI4MzlMOTkuMjA0MyA1OC4zNjhMOTkuMTIwMiA2Ni4wMzIzTDkxLjQxODUgNjUuOTQ4MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0zOS4xMTQzIDUzLjUyNjNMMzkuMTUxNyA0OC40NzkxTDQ0LjE4MDIgNDguNTE2NUw0NC4xNDI4IDUzLjU2MzdMMzkuMTE0MyA1My41MjYzWk00OC45NTYzIDQzLjI2MzdMNDguOTkzNyAzOC4yMTY0TDU0LjAyMjMgMzguMjUzOEw1My45ODQ5IDQzLjMwMUw0OC45NTYzIDQzLjI2MzdaTTYyLjQ5OTcgMzguMTg4NEw2Mi41MzcxIDMzLjE0MTJMNjcuNTY1NiAzMy4xNzg2TDY3LjUyODIgMzguMjI1OEw2Mi40OTk3IDM4LjE4ODRaTTM2LjE1MTQgNjcuNDkwM0wzNi4xODg4IDYyLjQ0MzFMNDEuMTg5MiA2Mi40ODA1TDQxLjE1MTkgNjcuNTI3N0wzNi4xNTE0IDY3LjQ5MDNaTTEwMC4wODMgNDguNTUzOUwxMDUuMTMgNDguNTE2NUwxMDUuMTY3IDUzLjU0NUwxMDAuMTIgNTMuNTgyNEwxMDAuMDgzIDQ4LjU1MzlaTTkwLjI0MDcgMzguMTEzNkw5NS4yODc5IDM4LjA3NjJMOTUuMzI1MyA0My4xMDQ4TDkwLjI3ODEgNDMuMTQyMUw5MC4yNDA3IDM4LjExMzZaTTc2LjY1MDYgMzMuMTY5Mkw4MS42OTc4IDMzLjEzMThMODEuNzM1MiAzOC4xNjA0TDc2LjY4OCAzOC4xOTc3TDc2LjY1MDYgMzMuMTY5MlpNMTAzLjAxOCA2Mi40OTkyTDEwOC4wNjUgNjIuNDYxOEwxMDguMTAyIDY3LjQ5MDNMMTAzLjA1NSA2Ny41Mjc3TDEwMy4wMTggNjIuNDk5MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik01OC41ODMgOTguMjQwNUw1OC42MzkxIDkwLjU3NjJMNjYuMzQwOCA5MC42MzIzTDY2LjI4NDcgOTguMjk2NUw1OC41ODMgOTguMjQwNVpNNzcuODM3MiA5OC4yNDA1TDc3Ljg5MzMgOTAuNTc2Mkw4NS41OTUgOTAuNjMyM0w4NS41Mzg5IDk4LjI5NjVMNzcuODM3MiA5OC4yNDA1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEwMC4wNDUgOTQuMzYxOUwxMDAuMDgyIDg5LjMxNDdMMTA1LjExMSA4OS4zNTIxTDEwNS4wNzQgOTQuMzk5M0wxMDAuMDQ1IDk0LjM2MTlaTTkwLjMxNTIgMTA0LjcyN0w5MC4zNTI2IDk5LjY4MDJMOTUuMzgxMSA5OS43MTc2TDk1LjM0MzcgMTA0Ljc2NUw5MC4zMTUyIDEwNC43MjdaTTc2Ljc3MTggMTA5LjdMNzYuODA5MiAxMDQuNjUzTDgxLjgzNzcgMTA0LjY5TDgxLjgwMDQgMTA5LjczN0w3Ni43NzE4IDEwOS43Wk0xMDMuMDA4IDgwLjM5NzlMMTAzLjA0NSA3NS4zNTA3TDEwOC4wNzQgNzUuMzg4MUwxMDguMDM3IDgwLjQzNTNMMTAzLjAwOCA4MC4zOTc5Wk0zOS4xMjMzIDg5LjMxNDdMNDQuMTcwNiA4OS4yNzczTDQ0LjIwNzkgOTQuMzA1OEwzOS4xNjA3IDk0LjM0MzJMMzkuMTIzMyA4OS4zMTQ3Wk00OC45NjU0IDk5LjY0MjhMNTQuMDEyNiA5OS42MDU0TDU0LjA1IDEwNC42MzRMNDkuMDAyOCAxMDQuNjcxTDQ4Ljk2NTQgOTkuNjQyOFpNNjIuNDQzMyAxMDQuNTk3TDY3LjQ5MDYgMTA0LjU1OUw2Ny41Mjc5IDEwOS41ODhMNjIuNDgwNyAxMDkuNjI1TDYyLjQ0MzMgMTA0LjU5N1pNMzYuMTg4NSA3NS4zNjk0TDQxLjIzNTcgNzUuMzMyTDQxLjI3MzEgODAuMzYwNkwzNi4yMjU5IDgwLjM5NzlMMzYuMTg4NSA3NS4zNjk0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExMC42MjUgNTEuNjM4NEwxMTAuNjQ0IDQ4LjkwOTJMMTEzLjQyOSA0OC45Mjc5TDExMy40MSA1MS42NTcxTDExMC42MjUgNTEuNjM4NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTQuMjI0IDU5Ljg5MTNMMTE0LjI0MiA1Ny4xNjIxTDExNy4wMjggNTcuMTgwOEwxMTcuMDA5IDU5LjkxTDExNC4yMjQgNTkuODkxM1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMDUuNzY3IDQ0LjMzNzZMMTA1Ljc4NSA0MS42MDg0TDEwOC41NzEgNDEuNjI3MUwxMDguNTUyIDQ0LjM1NjNMMTA1Ljc2NyA0NC4zMzc2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTQxLjk3MzYgMzguMDk0NUw0MS45OTIzIDM1LjM2NTJMNDQuNzc3NiAzNS4zODM5TDQ0Ljc1ODkgMzguMTEzMkw0MS45NzM2IDM4LjA5NDVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMjYgNjguNTU1NEwyNi4wMTg3IDY1LjgyNjJMMjguODA0IDY1Ljg0NDlMMjguNzg1MyA2OC41NzQxTDI2IDY4LjU1NTRaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOTkuNjI0IDM4LjA5NDVMOTkuNjQyNyAzNS4zNjUyTDEwMi40MjggMzUuMzgzOUwxMDIuNDA5IDM4LjExMzJMOTkuNjI0IDM4LjA5NDVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMjcuNTg5OCA1OS44ODE2TDI3LjYwODUgNTcuMTUyM0wzMC4zOTM5IDU3LjE3MUwzMC4zNzUyIDU5LjkwMDNMMjcuNTg5OCA1OS44ODE2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTU3LjYyOTkgMjkuNjM1NUw1Ny42NDg2IDI2LjkwNjJMNjAuNDMzOSAyNi45MjQ5TDYwLjQxNTIgMjkuNjU0Mkw1Ny42Mjk5IDI5LjYzNTVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzAuOTcyNyA1MS42Mzg0TDMwLjk5MTMgNDguOTA5MkwzMy43NzY3IDQ4LjkyNzlMMzMuNzU4IDUxLjY1NzFMMzAuOTcyNyA1MS42Mzg0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTM1Ljk0NTMgNDQuMjM2MUwzNS45NjQgNDEuNTA2OEwzOC43NDkzIDQxLjUyNTVMMzguNzMwNiA0NC4yNTQ4TDM1Ljk0NTMgNDQuMjM2MVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00OS40MjI5IDMwLjQyMDRMNTIuMTUyMSAzMC40MDE3TDUyLjE3MDggMzMuMTg3TDQ5LjQ0MTUgMzMuMjA1N0w0OS40MjI5IDMwLjQyMDRaTTY2LjMwMyAyNS4wNDZMNjkuMDMyMiAyNS4wMjczTDY5LjA1MDkgMjcuODEyN0w2Ni4zMjE3IDI3LjgzMTRMNjYuMzAzIDI1LjA0NloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4yMjI3IDMzLjIyNDRMOTIuMjQxNCAzMC40OTUxTDk1LjAyNjcgMzAuNTEzOEw5NS4wMDggMzMuMjQzTDkyLjIyMjcgMzMuMjI0NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTUuNTk4IDY4LjQ1MjlMMTE1LjYxNiA2NS43MjM2TDExOC40MDIgNjUuNzQyM0wxMTguMzgzIDY4LjQ3MTZMMTE1LjU5OCA2OC40NTI5WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTc1LjE5MTQgMjcuNzI5Mkw3NS4yMTAxIDI1TDc3Ljk5NTQgMjUuMDE4N0w3Ny45NzY3IDI3Ljc0NzlMNzUuMTkxNCAyNy43MjkyWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTgzLjg2NjIgMjkuNTIzMkw4My44ODQ5IDI2Ljc5MzlMODYuNjcwMiAyNi44MTI2TDg2LjY1MTUgMjkuNTQxOUw4My44NjYyIDI5LjUyMzJaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOTkuNjI0IDEwNy43TDk5LjY0MjcgMTA0Ljk3MUwxMDIuNDI4IDEwNC45ODlMMTAyLjQwOSAxMDcuNzE5TDk5LjYyNCAxMDcuN1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTUuNTk4IDc3LjIzOUwxMTUuNjE2IDc0LjUwOThMMTE4LjQwMiA3NC41Mjg1TDExOC4zODMgNzcuMjU3N0wxMTUuNTk4IDc3LjIzOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00MS45NzM2IDEwNy43TDQxLjk5MjMgMTA0Ljk3MUw0NC43Nzc2IDEwNC45ODlMNDQuNzU4OSAxMDcuNzE5TDQxLjk3MzYgMTA3LjdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMTE0LjIyNCA4Ni4wMzI5TDExNC4yNDIgODMuMzAzN0wxMTcuMDI4IDgzLjMyMjRMMTE3LjAwOSA4Ni4wNTE2TDExNC4yMjQgODYuMDMyOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik04My44NjYyIDExNi4yN0w4My44ODQ5IDExMy41NDFMODYuNjcwMiAxMTMuNTZMODYuNjUxNSAxMTYuMjg5TDgzLjg2NjIgMTE2LjI3WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExMC42MjUgOTQuMjY4M0wxMTAuNjQ0IDkxLjUzOTFMMTEzLjQyOSA5MS41NTc4TDExMy40MSA5NC4yODdMMTEwLjYyNSA5NC4yNjgzWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEwNS43NjcgMTAxLjY3MkwxMDUuNzg1IDk4Ljk0MjRMMTA4LjU3MSA5OC45NjExTDEwOC41NTIgMTAxLjY5TDEwNS43NjcgMTAxLjY3MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4xMDk0IDExMC4wNjVMOTQuODM4NiAxMTAuMDQ2TDk0Ljg1NzMgMTEyLjgzMUw5Mi4xMjggMTEyLjg1TDkyLjEwOTQgMTEwLjA2NVpNNzUuMzMyIDExNS4yMTVMNzguMDYxMyAxMTUuMTk2TDc4LjA4IDExNy45ODFMNzUuMzUwNyAxMThMNzUuMzMyIDExNS4yMTVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNDkuNDc4NSAxMTIuODg2TDQ5LjQ5NzIgMTEwLjE1N0w1Mi4yODI1IDExMC4xNzZMNTIuMjYzOCAxMTIuOTA1TDQ5LjQ3ODUgMTEyLjg4NloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0zMC44NTk0IDk0LjE2NThMMzAuODc4MSA5MS40MzY1TDMzLjY2MzQgOTEuNDU1MkwzMy42NDQ3IDk0LjE4NDVMMzAuODU5NCA5NC4xNjU4WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTI3LjU4MDEgODYuMDE0NEwyNy41OTg4IDgzLjI4NTJMMzAuMzg0MSA4My4zMDM5TDMwLjM2NTQgODYuMDMzMUwyNy41ODAxIDg2LjAxNDRaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzUuODMyIDEwMS42NzJMMzUuODUwNyA5OC45NDI0TDM4LjYzNiA5OC45NjExTDM4LjYxNzMgMTAxLjY5TDM1LjgzMiAxMDEuNjcyWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTI2IDc3LjIzOUwyNi4wMTg3IDc0LjUwOThMMjguODA0IDc0LjUyODVMMjguNzg1MyA3Ny4yNTc3TDI2IDc3LjIzOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik02Ni40MDUzIDExNy45NjJMNjYuNDI0IDExNS4yMzJMNjkuMjA5MyAxMTUuMjUxTDY5LjE5MDYgMTE3Ljk4TDY2LjQwNTMgMTE3Ljk2MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik01Ny41MTc2IDExNi4xNjhMNTcuNTM2MyAxMTMuNDM4TDYwLjMyMTYgMTEzLjQ1N0w2MC4zMDI5IDExNi4xODZMNTcuNTE3NiAxMTYuMTY4WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMjk4NSIgeDE9IjEwIiB5MT0iMTUuNSIgeDI9IjE0NCIgeTI9IjEzMS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEE4REEiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ5NSIgc3RvcC1jb2xvcj0iIzM1NzlCQyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyODZFQTUiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "external"], ["spec", "httpAndHttps"], ["spec", "httpAndHttps", "mode"], ["spec", "httpAndHttps", "targetPorts"], ["spec", "httpAndHttps", "targetPorts", "http"], ["spec", "httpAndHttps", "targetPorts", "https"], ["spec", "httpAndHttps", "endpoints"], ["spec", "whitelistHTTP"], ["spec", "whitelist"]] - secrets: - exclude: [] - include: [] diff --git a/packages/core/platform/psds/telepresence.yaml b/packages/core/platform/psds/telepresence.yaml index 55f62a03..ae52d918 100644 --- a/packages/core/platform/psds/telepresence.yaml +++ b/packages/core/platform/psds/telepresence.yaml @@ -16,7 +16,6 @@ spec: components: - name: telepresence path: system/telepresence - disabled: true install: namespace: cozy-telepresence releaseName: traffic-manager diff --git a/packages/core/platform/psds/tenant-application.yaml b/packages/core/platform/psds/tenant-application.yaml new file mode 100644 index 00000000..13f00978 --- /dev/null +++ b/packages/core/platform/psds/tenant-application.yaml @@ -0,0 +1,33 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.tenant-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.ingress-application + - cozystack.seaweedfs-application + - cozystack.info-application + - cozystack.monitoring-application + - cozystack.bootbox-application + - cozystack.etcd-application + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: tenant + path: apps/tenant + libraries: [cozy-lib] + - name: tenant-rd + path: system/tenant-rd + install: + namespace: cozy-system + releaseName: tenant-rd diff --git a/packages/core/platform/psds/tenant.yaml b/packages/core/platform/psds/tenant.yaml deleted file mode 100644 index fc0c77a2..00000000 --- a/packages/core/platform/psds/tenant.yaml +++ /dev/null @@ -1,52 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.tenant-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - - cozystack.ingress-application - - cozystack.seaweedfs-application - - cozystack.info-application - - cozystack.monitoring-application - - cozystack.bootbox-application - - cozystack.etcd-application - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: tenant - path: apps/tenant - libraries: - - cozy-lib - template: - spec: - application: - kind: Tenant - singular: tenant - plural: tenants - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"etcd":{"description":"Deploy own Etcd cluster.","type":"boolean","default":false},"host":{"description":"The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host).","type":"string","default":""},"ingress":{"description":"Deploy own Ingress Controller.","type":"boolean","default":false},"isolated":{"description":"Enforce tenant namespace with network policies (default: true).","type":"boolean","default":true},"monitoring":{"description":"Deploy own Monitoring Stack.","type":"boolean","default":false},"resourceQuotas":{"description":"Define resource quotas for the tenant.","type":"object","default":{},"additionalProperties":{"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}},"seaweedfs":{"description":"Deploy own SeaweedFS.","type":"boolean","default":false}}} - release: - prefix: tenant- - labels: - cozystack.io/ui: "true" - dashboard: - category: Administration - singular: Tenant - plural: Tenants - description: Separated tenant namespace - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQwMykiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDAzKSI+CjxwYXRoIGQ9Ik03MiAyOUM2Ni4zOTI2IDI5IDYxLjAxNDggMzEuMjM4OCA1Ny4wNDk3IDM1LjIyNEM1My4wODQ3IDM5LjIwOTEgNTAuODU3MSA0NC42MTQxIDUwLjg1NzEgNTAuMjVDNTAuODU3MSA1NS44ODU5IDUzLjA4NDcgNjEuMjkwOSA1Ny4wNDk3IDY1LjI3NkM2MS4wMTQ4IDY5LjI2MTIgNjYuMzkyNiA3MS41IDcyIDcxLjVDNzcuNjA3NCA3MS41IDgyLjk4NTIgNjkuMjYxMiA4Ni45NTAzIDY1LjI3NkM5MC45MTUzIDYxLjI5MDkgOTMuMTQyOSA1NS44ODU5IDkzLjE0MjkgNTAuMjVDOTMuMTQyOSA0NC42MTQxIDkwLjkxNTMgMzkuMjA5MSA4Ni45NTAzIDM1LjIyNEM4Mi45ODUyIDMxLjIzODggNzcuNjA3NCAyOSA3MiAyOVpNNjAuOTgyNiA4My4zMDM3QzYwLjQ1NCA4Mi41ODk4IDU5LjU5NTEgODIuMTkxNCA1OC43MTk2IDgyLjI3NDRDNDUuMzg5NyA4My43MzU0IDM1IDk1LjEwNzQgMzUgMTA4LjkwM0MzNSAxMTEuNzI2IDM3LjI3OTUgMTE0IDQwLjA3MSAxMTRIMTAzLjkyOUMxMDYuNzM3IDExNCAxMDkgMTExLjcwOSAxMDkgMTA4LjkwM0MxMDkgOTUuMTA3NCA5OC42MTAzIDgzLjc1MiA4NS4yNjM4IDgyLjI5MUM4NC4zODg0IDgyLjE5MTQgODMuNTI5NSA4Mi42MDY0IDgzLjAwMDkgODMuMzIwM0w3NC4wOTc4IDk1LjI0MDJDNzMuMDQwNiA5Ni42NTE0IDcwLjkyNjMgOTYuNjUxNCA2OS44NjkyIDk1LjI0MDJMNjAuOTY2MSA4My4zMjAzTDYwLjk4MjYgODMuMzAzN1oiIGZpbGw9ImJsYWNrIi8+CjwvZz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODdfMzQwMyIgeDE9IjcyIiB5MT0iMTQ0IiB4Mj0iLTEuMjgxN2UtMDUiIHkyPSI0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNDMEQ2RkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjMiIHN0b3AtY29sb3I9IiNDNERBRkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjY1IiBzdG9wLWNvbG9yPSIjRDNFOUZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0U5RkZGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zNDAzIj4KPHJlY3Qgd2lkdGg9Ijc0IiBoZWlnaHQ9Ijg1IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzUgMjkpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "etcd"], ["spec", "monitoring"], ["spec", "ingress"], ["spec", "seaweedfs"], ["spec", "isolated"], ["spec", "resourceQuotas"]] - secrets: - exclude: [] - include: [] diff --git a/packages/core/platform/psds/velero.yaml b/packages/core/platform/psds/velero.yaml index 37392e36..ac40db3a 100644 --- a/packages/core/platform/psds/velero.yaml +++ b/packages/core/platform/psds/velero.yaml @@ -17,7 +17,6 @@ spec: components: - name: velero path: system/velero - disabled: true install: privileged: true namespace: cozy-velero diff --git a/packages/core/platform/psds/virtual-machine-application.yaml b/packages/core/platform/psds/virtual-machine-application.yaml new file mode 100644 index 00000000..b2583e7e --- /dev/null +++ b/packages/core/platform/psds/virtual-machine-application.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.virtual-machine-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.kubevirt + - cozystack.kubevirt-cdi + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: virtual-machine + path: apps/virtual-machine + libraries: [cozy-lib] + - name: virtual-machine-rd + path: system/virtual-machine-rd + install: + namespace: cozy-system + releaseName: virtual-machine-rd diff --git a/packages/core/platform/psds/virtual-machine.yaml b/packages/core/platform/psds/virtual-machine.yaml deleted file mode 100644 index 6629311f..00000000 --- a/packages/core/platform/psds/virtual-machine.yaml +++ /dev/null @@ -1,56 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.virtual-machine-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: kubevirt - dependsOn: - - cozystack.networking - - cozystack.kubevirt - - cozystack.kubevirt-cdi - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: virtual-machine - path: apps/virtual-machine - libraries: - - cozy-lib - template: - spec: - application: - kind: VirtualMachine - plural: virtualmachines - singular: virtualmachine - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Whether the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"subnets":{"description":"Additional subnets","type":"array","default":[],"items":{"type":"object","properties":{"name":{"description":"Subnet name","type":"string"}}}},"systemDisk":{"description":"System disk configuration.","type":"object","default":{},"required":["image","storage"],"properties":{"image":{"description":"The base image for the virtual machine.","type":"string","default":"ubuntu","enum":["ubuntu","cirros","alpine","fedora","talos"]},"storage":{"description":"The size of the disk allocated for the virtual machine.","type":"string","default":"5Gi"},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}}} - release: - prefix: virtual-machine- - labels: - cozystack.io/ui: "true" - dashboard: - category: IaaS - singular: Virtual Machine - plural: Virtual Machines - description: Virtual Machine (simple) - weight: 10 - tags: - - compute - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQ1NCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDU0KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMDBCM0ZGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi41Mjc1IDUzLjgzNjdDNzIuNDQzMSA1My44MzUxIDcyLjM2MDUgNTMuODEyMiA3Mi4yODczIDUzLjc3MDFMNTYuNDY5OSA0NC43OTM0QzU2LjM5ODMgNDQuNzUxOSA1Ni4zMzg4IDQ0LjY5MjMgNTYuMjk3MyA0NC42MjA3QzU2LjI1NTkgNDQuNTQ5IDU2LjIzMzggNDQuNDY3OCA1Ni4yMzM0IDQ0LjM4NUM1Ni4yMzM0IDQ0LjIxNjkgNTYuMzI1OCA0NC4wNjE3IDU2LjQ2OTkgNDMuOTc4NUw3Mi4xOTEyIDM1LjA2MDlDNzIuMjYzNyAzNS4wMjEgNzIuMzQ1IDM1IDcyLjQyNzcgMzVDNzIuNTEwNSAzNSA3Mi41OTE4IDM1LjAyMSA3Mi42NjQzIDM1LjA2MDlMODguNDg3MiA0NC4wMzk1Qzg4LjU1OTEgNDQuMDgwMSA4OC42MTg4IDQ0LjEzOTIgODguNjYgNDQuMjEwN0M4OC43MDEzIDQ0LjI4MjIgODguNzIyNyA0NC4zNjM1IDg4LjcyMTkgNDQuNDQ2Qzg4LjcyMjUgNDQuNTI4NSA4OC43MDEgNDQuNjA5NyA4OC42NTk4IDQ0LjY4MTJDODguNjE4NSA0NC43NTI2IDg4LjU1ODkgNDQuODExOCA4OC40ODcyIDQ0Ljg1MjVMNzIuNzcxNCA1My43NjgzQzcyLjY5NzIgNTMuODExNCA3Mi42MTMzIDUzLjgzNDkgNzIuNTI3NSA1My44MzY3IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjciIGQ9Ik03MC4yNTUzIDc1LjY1MTdDNzAuMTcxIDc1LjY1MzUgNzAuMDg3OCA3NS42MzE3IDcwLjAxNTEgNzUuNTg4OEw1NC4yNDU4IDY2LjY0MTdDNTQuMTcxNSA2Ni42MDI0IDU0LjEwOTUgNjYuNTQzNiA1NC4wNjYxIDY2LjQ3MTZDNTQuMDIyOCA2Ni4zOTk3IDU0IDY2LjMxNzMgNTQgNjYuMjMzM1Y0OC4yNzhDNTQgNDguMTA4IDU0LjA5MjQgNDcuOTU0NiA1NC4yNDM5IDQ3Ljg2OTZDNTQuMzE3MiA0Ny44MjcxIDU0LjQwMDQgNDcuODA0NyA1NC40ODUxIDQ3LjgwNDdDNTQuNTY5NyA0Ny44MDQ3IDU0LjY1MjkgNDcuODI3MSA1NC43MjYyIDQ3Ljg2OTZMNzAuNDkzNyA1Ni44MTMxQzcwLjU2NDIgNTYuODU2NSA3MC42MjI1IDU2LjkxNyA3MC42NjMyIDU2Ljk4OTFDNzAuNzAzOSA1Ny4wNjEyIDcwLjcyNTcgNTcuMTQyNCA3MC43MjY1IDU3LjIyNTFWNzUuMTgwNUM3MC43MjU5IDc1LjI2MjggNzAuNzA0MiA3NS4zNDM2IDcwLjY2MzUgNzUuNDE1MUM3MC42MjI3IDc1LjQ4NjYgNzAuNTY0MiA3NS41NDY0IDcwLjQ5MzcgNzUuNTg4OEM3MC40MjA2IDc1LjYyOTEgNzAuMzM4NyA3NS42NTA3IDcwLjI1NTMgNzUuNjUxNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC40IiBkPSJNNzQuNzE5OCA3NS42NTExQzc0LjYzMzMgNzUuNjUxMiA3NC41NDgyIDc1LjYyOTYgNzQuNDcyMiA3NS41ODgzQzc0LjQwMTYgNzUuNTQ2MSA3NC4zNDMyIDc1LjQ4NjIgNzQuMzAyNyA3NS40MTQ3Qzc0LjI2MjMgNzUuMzQzMSA3NC4yNDExIDc1LjI2MjIgNzQuMjQxMiA3NS4xOFY1Ny4zMzczQzc0LjI0MTIgNTcuMTcxIDc0LjMzMzYgNTcuMDE1OCA3NC40NzIyIDU2LjkyOUw5MC4yMzk3IDQ3Ljk4NTVDOTAuMzExOSA0Ny45NDM4IDkwLjM5MzggNDcuOTIxOSA5MC40NzcxIDQ3LjkyMTlDOTAuNTYwNSA0Ny45MjE5IDkwLjY0MjQgNDcuOTQzOCA5MC43MTQ2IDQ3Ljk4NTVDOTAuNzg3NiA0OC4wMjU1IDkwLjg0ODUgNDguMDg0MiA5MC44OTExIDQ4LjE1NTdDOTAuOTMzNyA0OC4yMjcyIDkwLjk1NjMgNDguMzA4OCA5MC45NTY2IDQ4LjM5MlY2Ni4yMzI4QzkwLjk1NyA2Ni4zMTY0IDkwLjkzNDcgNjYuMzk4NSA5MC44OTIxIDY2LjQ3MDRDOTAuODQ5NSA2Ni41NDI0IDkwLjc4ODEgNjYuNjAxNCA5MC43MTQ2IDY2LjY0MTFMNzQuOTUyNiA3NS41ODgzQzc0Ljg4MjUgNzUuNjMwNyA3NC44MDE4IDc1LjY1MjUgNzQuNzE5OCA3NS42NTExIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zNDU0IiB4MT0iMTYxIiB5MT0iMTgwIiB4Mj0iMy41OTI4NGUtMDciIHkyPSI0Ljk5OTk4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTk1NjU2Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNjg3XzM0NTQiPgo8cmVjdCB3aWR0aD0iOTQiIGhlaWdodD0iOTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSAyNSkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "systemDisk"], ["spec", "systemDisk", "image"], ["spec", "systemDisk", "storage"], ["spec", "systemDisk", "storageClass"], ["spec", "subnets"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]] - secrets: - exclude: [] - include: [] - services: - exclude: [] - include: - - resourceNames: - - "{{`virtual-machine-{{ .name }}`}}" diff --git a/packages/core/platform/psds/virtualprivatecloud-application.yaml b/packages/core/platform/psds/virtualprivatecloud-application.yaml new file mode 100644 index 00000000..b6a8519b --- /dev/null +++ b/packages/core/platform/psds/virtualprivatecloud-application.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.virtualprivatecloud-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.multus + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: virtualprivatecloud + path: apps/vpc + libraries: [cozy-lib] + - name: virtualprivatecloud-rd + path: system/virtualprivatecloud-rd + install: + namespace: cozy-system + releaseName: virtualprivatecloud-rd diff --git a/packages/core/platform/psds/virtualprivatecloud.yaml b/packages/core/platform/psds/virtualprivatecloud.yaml deleted file mode 100644 index e32dfd14..00000000 --- a/packages/core/platform/psds/virtualprivatecloud.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.virtualprivatecloud-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: kubevirt - dependsOn: - - cozystack.networking - - cozystack.multus - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: virtualprivatecloud - path: apps/vpc - libraries: - - cozy-lib - template: - spec: - application: - kind: VirtualPrivateCloud - plural: virtualprivateclouds - singular: virtualprivatecloud - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"subnets":{"description":"Subnets of a VPC","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"cidr":{"description":"IP address range","type":"string"}}}}}} - release: - prefix: "virtualprivatecloud-" - labels: - cozystack.io/ui: "true" - dashboard: - category: IaaS - singular: VPC - plural: VPCs - description: "Isolated networks" - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8xMDI1XzMpIi8+CjxwYXRoIGQ9Ik0xMDkuNiA4Ni4xSDExNC4zQzExNi44ODUgODYuMSAxMTkgODguMjE1IDExOSA5MC44NDdWMTA0Ljg1M0MxMTkgMTA3LjQ4NSAxMTYuODg1IDEwOS42IDExNC4zIDEwOS42SDk1LjVDOTIuOTE1IDEwOS42IDkwLjggMTA3LjQ4NSA5MC44IDEwNC44NTNWOTAuODQ3QzkwLjggODguMjE1IDkyLjkxNSA4Ni4xIDk1LjUgODYuMUgxMDAuMlY3Ni43SDc2LjdWODYuMUg4MS40QzgzLjk4NSA4Ni4xIDg2LjEgODguMjE1IDg2LjEgOTAuODQ3VjEwNC44NTNDODYuMSAxMDcuNDg1IDgzLjk4NSAxMDkuNiA4MS40IDEwOS42SDYyLjZDNjAuMDE1IDEwOS42IDU3LjkgMTA3LjQ4NSA1Ny45IDEwNC44NTNWOTAuODQ3QzU3LjkgODguMjE1IDYwLjAxNSA4Ni4xIDYyLjYgODYuMUg2Ny4zVjc2LjdINDMuOFY4Ni4xSDQ4LjVDNTEuMDg1IDg2LjEgNTMuMiA4OC4yMTUgNTMuMiA5MC44NDdWMTA0Ljg1M0M1My4yIDEwNy40ODUgNTEuMDg1IDEwOS42IDQ4LjUgMTA5LjZIMjkuN0MyNy4xMTUgMTA5LjYgMjUgMTA3LjQ4NSAyNSAxMDQuODUzVjkwLjg0N0MyNSA4OC4yMTUgMjcuMTE1IDg2LjEgMjkuNyA4Ni4xSDM0LjRWNzYuN0MzNC40IDcxLjUzIDM4LjYzIDY3LjMgNDMuOCA2Ny4zSDY3LjNWNTcuOUg2Mi42QzYwLjAxNSA1Ny45IDU3LjkgNTUuNzg1IDU3LjkgNTMuMTUzVjM5LjE0N0M1Ny45IDM2LjUxNSA2MC4wMTUgMzQuNCA2Mi42IDM0LjRIODEuNEM4My45ODUgMzQuNCA4Ni4xIDM2LjUxNSA4Ni4xIDM5LjE0N1Y1My4xNTNDODYuMSA1NS43ODUgODMuOTg1IDU3LjkgODEuNCA1Ny45SDc2LjdWNjcuM0gxMDAuMkMxMDUuMzcgNjcuMyAxMDkuNiA3MS41MyAxMDkuNiA3Ni43Vjg2LjFaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzEwMjVfMyIgeDE9IjE0Mi41IiB5MT0iMTQzIiB4Mj0iMy45OTk5OSIgeTI9IjkuNDk5OTkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzAwMDgyRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyRTMwNjciLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "subnets"]] - secrets: - exclude: [] - include: [] - services: - exclude: [] - include: [] diff --git a/packages/core/platform/psds/vm-disk-application.yaml b/packages/core/platform/psds/vm-disk-application.yaml new file mode 100644 index 00000000..a4e98ca9 --- /dev/null +++ b/packages/core/platform/psds/vm-disk-application.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.vm-disk-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.kubevirt-cdi + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: vm-disk + path: apps/vm-disk + libraries: ["cozy-lib"] + - name: vm-disk-rd + path: system/vm-disk-rd + install: + namespace: cozy-system + releaseName: vm-disk-rd diff --git a/packages/core/platform/psds/vm-disk.yaml b/packages/core/platform/psds/vm-disk.yaml deleted file mode 100644 index 01797d29..00000000 --- a/packages/core/platform/psds/vm-disk.yaml +++ /dev/null @@ -1,50 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.vm-disk-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: kubevirt - dependsOn: - - cozystack.networking - - cozystack.kubevirt-cdi - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: vm-disk - path: apps/vm-disk - libraries: - - cozy-lib - template: - spec: - application: - kind: VMDisk - singular: vmdisk - plural: vmdisks - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"optical":{"description":"Defines if disk should be considered optical.","type":"boolean","default":false},"source":{"description":"The source image location used to create a disk.","type":"object","default":{},"properties":{"http":{"description":"Download image from an HTTP source.","type":"object","required":["url"],"properties":{"url":{"description":"URL to download the image.","type":"string"}}},"image":{"description":"Use image by name.","type":"object","required":["name"],"properties":{"name":{"description":"Name of the image to use (uploaded as \"golden image\" or from the list: `ubuntu`, `fedora`, `cirros`, `alpine`, `talos`).","type":"string"}}},"upload":{"description":"Upload local image."}}},"storage":{"description":"The size of the disk allocated for the virtual machine.","default":"5Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}} - release: - prefix: vm-disk- - labels: - cozystack.io/ui: "true" - dashboard: - category: IaaS - singular: VM Disk - plural: VM Disks - description: Virtual Machine disk - weight: 51 - tags: - - storage - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8zMzBfNDg5NjMpIi8+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2lfMzMwXzQ4OTYzKSI+CjxwYXRoIGQ9Ik03Mi4wMDAxIDI2LjYzNjdDNDYuODc3MiAyNi42MzY3IDI2LjUxMTIgNDcuMDAyNyAyNi41MTEyIDcyLjEyNTZDMjYuNTExMiA5Ny4yNDg0IDQ2Ljg3NzIgMTE3LjYxNCA3Mi4wMDAxIDExNy42MTRDOTcuMTIyOSAxMTcuNjE0IDExNy40ODkgOTcuMjQ4MiAxMTcuNDg5IDcyLjEyNTRDMTE3LjQ4OSA0Ny4wMDI1IDk3LjEyMjkgMjYuNjM2NyA3Mi4wMDAxIDI2LjYzNjdaTTcyLjAwMDEgODEuNjIxMkM2Ni43NTU3IDgxLjYyMTIgNjIuNTA0NCA3Ny4zNjk5IDYyLjUwNDQgNzIuMTI1NkM2Mi41MDQ0IDY2Ljg4MTIgNjYuNzU1NyA2Mi42Mjk5IDcyLjAwMDEgNjIuNjI5OUM3Ny4yNDQ0IDYyLjYyOTkgODEuNDk1NyA2Ni44ODEyIDgxLjQ5NTcgNzIuMTI1NkM4MS40OTU3IDc3LjM2OTkgNzcuMjQ0NCA4MS42MjEyIDcyLjAwMDEgODEuNjIxMloiIGZpbGw9IiNCQUQ5RkYiLz4KPC9nPgo8cGF0aCBkPSJNNTIuMDA3NSA2NS43MjA5TDMyLjI5NzYgNTkuMDQ5OEMzNi4yODQyIDQ3LjI3MTEgNDUuMzI4NSAzNy42MzE1IDU2LjQ5MSAzMy4yNjRMNjQuMDcyOCA1Mi42NDE5QzU4LjY0MiA1NC43NjY3IDU0LjAxOSA1OS43NzgzIDUyLjAwNzUgNjUuNzIwOVpNOTEuOTkyNiA3OC41M0wxMTEuNzAzIDg1LjIwMTFDMTA3LjcxNiA5Ni45Nzk5IDk4LjY3MTggMTA2LjYxOSA4Ny41MDkzIDExMC45ODdMNzkuOTI3NSA5MS42MDlDODUuMzU4MSA4OS40ODQyIDg5Ljk4MTMgODQuNDcyNiA5MS45OTI2IDc4LjUzWiIgZmlsbD0iI0VERjZGRiIvPgo8cGF0aCBkPSJNNTUuOTMyNCA1OC43MDI4QzU3LjY1MTQgNTYuNjE0IDU5LjcxOTQgNTQuODYzMiA2MS45ODk0IDUzLjYxODNDNjMuMTQ5IDUyLjk4MjQgNjQuMjYzMyA1My4xMjk2IDYzLjc4MTQgNTEuODk3OUw1Ny4yMDk1IDM1LjEwMDlDNTYuMjkwOSAzMi43NTI5IDU1LjI4MTQgMzMuNzI4NSA1My45MDYgMzQuMzg2OEM0OC45NzM0IDM2Ljc0NzYgNDQuNTM0OSA0MC4xNTkgNDAuODYwMSA0NC4zMTU0TDU1LjkzMjQgNTguNzAyOFpNODguMDY3NiA4NS41NDgxQzg1LjgzNTIgODguMjYwNSA4My4wMTQ4IDkwLjQwMjkgNzkuOTI2OSA5MS42MDhMODcuNTA4OSAxMTAuOTg2QzkzLjQ3ODUgMTA4LjY1NCA5OC44MzM2IDEwNC44MDYgMTAzLjE0IDk5LjkzNTVMODguMDY3NiA4NS41NDgxWiIgZmlsbD0iI0NERTNGRiIvPgo8cGF0aCBkPSJNNzIgODkuNDM4OEM2Mi40NTM0IDg5LjQzODggNTQuNjg2NSA4MS42NzIxIDU0LjY4NjUgNzIuMTI1NEM1NC42ODY1IDYyLjU3ODYgNjIuNDUzNCA1NC44MTE5IDcyIDU0LjgxMTlDODEuNTQ2OCA1NC44MTE5IDg5LjMxMzQgNjIuNTc4OCA4OS4zMTM0IDcyLjEyNTRDODkuMzEzNCA4MS42NzIgODEuNTQ2OCA4OS40Mzg4IDcyIDg5LjQzODhaTTcyIDU5LjExMDVDNjQuODIzNCA1OS4xMTA1IDU4Ljk4NDkgNjQuOTQ5IDU4Ljk4NDkgNzIuMTI1NkM1OC45ODQ5IDc5LjMwMjIgNjQuODIzNCA4NS4xNDA2IDcyIDg1LjE0MDZDNzkuMTc2NiA4NS4xNDA2IDg1LjAxNSA3OS4zMDIyIDg1LjAxNSA3Mi4xMjU2Qzg1LjAxNSA2NC45NDkgNzkuMTc2NiA1OS4xMTA1IDcyIDU5LjExMDVaIiBmaWxsPSIjMDBCNEZGIi8+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2lfMzMwXzQ4OTYzIiB4PSIyNi41MTEyIiB5PSIyNi42MzY3IiB3aWR0aD0iOTIuOTc3OCIgaGVpZ2h0PSI5Mi45Nzc1IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+CjxmZUNvbG9yTWF0cml4IGluPSJTb3VyY2VBbHBoYSIgdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIiByZXN1bHQ9ImhhcmRBbHBoYSIvPgo8ZmVPZmZzZXQgZHg9IjIiIGR5PSIyIi8+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIuNSIvPgo8ZmVDb21wb3NpdGUgaW4yPSJoYXJkQWxwaGEiIG9wZXJhdG9yPSJhcml0aG1ldGljIiBrMj0iLTEiIGszPSIxIi8+CjxmZUNvbG9yTWF0cml4IHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDEgMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwLjIxIDAiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbjI9InNoYXBlIiByZXN1bHQ9ImVmZmVjdDFfaW5uZXJTaGFkb3dfMzMwXzQ4OTYzIi8+CjwvZmlsdGVyPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMzMwXzQ4OTYzIiB4MT0iLTE1LjUiIHkxPSItMTIiIHgyPSIyMTYuNSIgeTI9IjE4NS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM2NUNDRkYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDQ0Mzc0Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "source"], ["spec", "optical"], ["spec", "storage"], ["spec", "storageClass"]] - secrets: - exclude: [] - include: [] diff --git a/packages/core/platform/psds/vm-instance-application.yaml b/packages/core/platform/psds/vm-instance-application.yaml new file mode 100644 index 00000000..eaa0c76e --- /dev/null +++ b/packages/core/platform/psds/vm-instance-application.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.vm-instance-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: kubevirt + dependsOn: + - cozystack.networking + - cozystack.kubevirt + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: vm-instance + path: apps/vm-instance + libraries: ["cozy-lib"] + - name: vm-instance-rd + path: system/vm-instance-rd + install: + namespace: cozy-system + releaseName: vm-instance-rd diff --git a/packages/core/platform/psds/vm-instance.yaml b/packages/core/platform/psds/vm-instance.yaml deleted file mode 100644 index aed6caa6..00000000 --- a/packages/core/platform/psds/vm-instance.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.vm-instance-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: kubevirt - dependsOn: - - cozystack.networking - - cozystack.kubevirt - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: vm-instance - path: apps/vm-instance - libraries: - - cozy-lib - template: - spec: - application: - kind: VMInstance - singular: vminstance - plural: vminstances - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"disks":{"description":"List of disks to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"bus":{"description":"Disk bus type (e.g. \"sata\").","type":"string"},"name":{"description":"Disk name.","type":"string"}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Determines if the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"subnets":{"description":"Additional subnets","type":"array","default":[],"items":{"type":"object","properties":{"name":{"description":"Subnet name","type":"string"}}}}}} - release: - prefix: vm-instance- - labels: - cozystack.io/ui: "true" - dashboard: - category: IaaS - singular: VM Instance - plural: VM Instances - description: Virtual machine instance - weight: 50 - tags: - - compute - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQ1NCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDU0KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMDBCM0ZGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi41Mjc1IDUzLjgzNjdDNzIuNDQzMSA1My44MzUxIDcyLjM2MDUgNTMuODEyMiA3Mi4yODczIDUzLjc3MDFMNTYuNDY5OSA0NC43OTM0QzU2LjM5ODMgNDQuNzUxOSA1Ni4zMzg4IDQ0LjY5MjMgNTYuMjk3MyA0NC42MjA3QzU2LjI1NTkgNDQuNTQ5IDU2LjIzMzggNDQuNDY3OCA1Ni4yMzM0IDQ0LjM4NUM1Ni4yMzM0IDQ0LjIxNjkgNTYuMzI1OCA0NC4wNjE3IDU2LjQ2OTkgNDMuOTc4NUw3Mi4xOTEyIDM1LjA2MDlDNzIuMjYzNyAzNS4wMjEgNzIuMzQ1IDM1IDcyLjQyNzcgMzVDNzIuNTEwNSAzNSA3Mi41OTE4IDM1LjAyMSA3Mi42NjQzIDM1LjA2MDlMODguNDg3MiA0NC4wMzk1Qzg4LjU1OTEgNDQuMDgwMSA4OC42MTg4IDQ0LjEzOTIgODguNjYgNDQuMjEwN0M4OC43MDEzIDQ0LjI4MjIgODguNzIyNyA0NC4zNjM1IDg4LjcyMTkgNDQuNDQ2Qzg4LjcyMjUgNDQuNTI4NSA4OC43MDEgNDQuNjA5NyA4OC42NTk4IDQ0LjY4MTJDODguNjE4NSA0NC43NTI2IDg4LjU1ODkgNDQuODExOCA4OC40ODcyIDQ0Ljg1MjVMNzIuNzcxNCA1My43NjgzQzcyLjY5NzIgNTMuODExNCA3Mi42MTMzIDUzLjgzNDkgNzIuNTI3NSA1My44MzY3IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjciIGQ9Ik03MC4yNTUzIDc1LjY1MTdDNzAuMTcxIDc1LjY1MzUgNzAuMDg3OCA3NS42MzE3IDcwLjAxNTEgNzUuNTg4OEw1NC4yNDU4IDY2LjY0MTdDNTQuMTcxNSA2Ni42MDI0IDU0LjEwOTUgNjYuNTQzNiA1NC4wNjYxIDY2LjQ3MTZDNTQuMDIyOCA2Ni4zOTk3IDU0IDY2LjMxNzMgNTQgNjYuMjMzM1Y0OC4yNzhDNTQgNDguMTA4IDU0LjA5MjQgNDcuOTU0NiA1NC4yNDM5IDQ3Ljg2OTZDNTQuMzE3MiA0Ny44MjcxIDU0LjQwMDQgNDcuODA0NyA1NC40ODUxIDQ3LjgwNDdDNTQuNTY5NyA0Ny44MDQ3IDU0LjY1MjkgNDcuODI3MSA1NC43MjYyIDQ3Ljg2OTZMNzAuNDkzNyA1Ni44MTMxQzcwLjU2NDIgNTYuODU2NSA3MC42MjI1IDU2LjkxNyA3MC42NjMyIDU2Ljk4OTFDNzAuNzAzOSA1Ny4wNjEyIDcwLjcyNTcgNTcuMTQyNCA3MC43MjY1IDU3LjIyNTFWNzUuMTgwNUM3MC43MjU5IDc1LjI2MjggNzAuNzA0MiA3NS4zNDM2IDcwLjY2MzUgNzUuNDE1MUM3MC42MjI3IDc1LjQ4NjYgNzAuNTY0MiA3NS41NDY0IDcwLjQ5MzcgNzUuNTg4OEM3MC40MjA2IDc1LjYyOTEgNzAuMzM4NyA3NS42NTA3IDcwLjI1NTMgNzUuNjUxNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC40IiBkPSJNNzQuNzE5OCA3NS42NTExQzc0LjYzMzMgNzUuNjUxMiA3NC41NDgyIDc1LjYyOTYgNzQuNDcyMiA3NS41ODgzQzc0LjQwMTYgNzUuNTQ2MSA3NC4zNDMyIDc1LjQ4NjIgNzQuMzAyNyA3NS40MTQ3Qzc0LjI2MjMgNzUuMzQzMSA3NC4yNDExIDc1LjI2MjIgNzQuMjQxMiA3NS4xOFY1Ny4zMzczQzc0LjI0MTIgNTcuMTcxIDc0LjMzMzYgNTcuMDE1OCA3NC40NzIyIDU2LjkyOUw5MC4yMzk3IDQ3Ljk4NTVDOTAuMzExOSA0Ny45NDM4IDkwLjM5MzggNDcuOTIxOSA5MC40NzcxIDQ3LjkyMTlDOTAuNTYwNSA0Ny45MjE5IDkwLjY0MjQgNDcuOTQzOCA5MC43MTQ2IDQ3Ljk4NTVDOTAuNzg3NiA0OC4wMjU1IDkwLjg0ODUgNDguMDg0MiA5MC44OTExIDQ4LjE1NTdDOTAuOTMzNyA0OC4yMjcyIDkwLjk1NjMgNDguMzA4OCA5MC45NTY2IDQ4LjM5MlY2Ni4yMzI4QzkwLjk1NyA2Ni4zMTY0IDkwLjkzNDcgNjYuMzk4NSA5MC44OTIxIDY2LjQ3MDRDOTAuODQ5NSA2Ni41NDI0IDkwLjc4ODEgNjYuNjAxNCA5MC43MTQ2IDY2LjY0MTFMNzQuOTUyNiA3NS41ODgzQzc0Ljg4MjUgNzUuNjMwNyA3NC44MDE4IDc1LjY1MjUgNzQuNzE5OCA3NS42NTExIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zNDU0IiB4MT0iMTYxIiB5MT0iMTgwIiB4Mj0iMy41OTI4NGUtMDciIHkyPSI0Ljk5OTk4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTk1NjU2Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNjg3XzM0NTQiPgo8cmVjdCB3aWR0aD0iOTQiIGhlaWdodD0iOTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSAyNSkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "disks"], ["spec", "subnets"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]] - secrets: - exclude: [] - include: [] - services: - exclude: [] - include: - - matchLabels: - apps.cozystack.io/user-service: "true" diff --git a/packages/core/platform/psds/vpn-application.yaml b/packages/core/platform/psds/vpn-application.yaml new file mode 100644 index 00000000..0200108f --- /dev/null +++ b/packages/core/platform/psds/vpn-application.yaml @@ -0,0 +1,27 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.vpn-application +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + libraries: + - name: cozy-lib + path: library/cozy-lib + components: + - name: vpn + path: apps/vpn + libraries: ["cozy-lib"] + - name: vpn-rd + path: system/vpn-rd + install: + namespace: cozy-system + releaseName: vpn-rd diff --git a/packages/core/platform/psds/vpn.yaml b/packages/core/platform/psds/vpn.yaml deleted file mode 100644 index 788562c2..00000000 --- a/packages/core/platform/psds/vpn.yaml +++ /dev/null @@ -1,55 +0,0 @@ ---- -apiVersion: cozystack.io/v1alpha1 -kind: PackageSource -metadata: - name: cozystack.vpn-application -spec: - sourceRef: - kind: OCIRepository - name: cozystack-packages - namespace: cozy-system - path: / - variants: - - name: default - dependsOn: - - cozystack.networking - libraries: - - name: cozy-lib - path: library/cozy-lib - components: [] - applications: - - name: vpn - path: apps/vpn - libraries: - - cozy-lib - template: - spec: - application: - kind: VPN - plural: vpns - singular: vpn - openAPISchema: |- - {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalIPs":{"description":"List of externalIPs for service. Optional. If not specified, will use LoadBalancer service by default.","type":"array","default":[],"items":{"type":"string"}},"host":{"description":"Host used to substitute into generated URLs.","type":"string","default":""},"replicas":{"description":"Number of VPN server replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each VPN server replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user (autogenerated if not provided).","type":"string"}}}}}} - release: - prefix: vpn- - labels: - cozystack.io/ui: "true" - dashboard: - category: NaaS - singular: VPN - plural: VPN - description: Managed VPN service - tags: - - network - icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xNDMuOTkyIDMwLjM2OTdDMTQzLjk5MiAyOS4yNTU2IDE0My45OTIgMjguMTUxNyAxNDMuOTkyIDI3LjA0NzdDMTQzLjk0NSAyNC42Mjg3IDE0My43MTcgMjIuMjE2NiAxNDMuMzA5IDE5LjgzMTZDMTQyLjkxMiAxNy40NDczIDE0Mi4xNTcgMTUuMTM2NSAxNDEuMDcyIDEyLjk3NjlDMTM5Ljk3IDEwLjgxOCAxMzguNTM0IDguODQ2NjUgMTM2LjgxNyA3LjEzNTc3TDEzMC45OTcgMi44OTA0NEMxMjguODM3IDEuODAyODkgMTI2LjUyNyAxLjA0MTg5IDEyNC4xNDQgMC42MzIyODNDMTIxLjc1NiAwLjIzNDgwOCAxMTkuMzQgMC4wMjM0MTEzIDExNi45MTkgMEMxMTUuODE1IDAgMjguMTQ2MSAwIDI3LjAzMjMgMEMyNC42MDQ3IDAuMDI0MjIxMSAyMi4xODI2IDAuMjM1NjA5IDE5Ljc4NzYgMC42MzIyODNDMTcuNDEyOCAxLjAzODUxIDE1LjExMjYgMS43OTk3NCAxMi45NjQzIDIuODkwNDRDMTAuODEzIDMuOTk1MTkgOC44NDYyNSA1LjQyNzM2IDcuMTM0MzYgNy4xMzU3N0M1LjQxNzY4IDguODQ0NCAzLjk4NDggMTAuODE2MyAyLjg4OTg3IDEyLjk3NjlDMS44MDA4NiAxNS4xMzYgMS4wNDMxMyAxNy40NDY4IDAuNjQyMTkzIDE5LjgzMTZDMC4yNDM0OTcgMjIuMjE2OSAwLjAyODc5OTggMjQuNjI5NCAwIDI3LjA0NzdDMCAyOC4xNTE3IDAgMTE1LjgzOCAwIDExNi45NTJDMC4wMjYxNzU1IDExOS4zODQgMC4yNDA4ODQgMTIxLjgxIDAuNjQyMTkzIDEyNC4yMDlDMS4wNDA0NCAxMjYuNTk0IDEuNzk4MjkgMTI4LjkwNSAyLjg4OTg3IDEzMS4wNjNDMy45ODUxNSAxMzMuMjE4IDUuNDE4MSAxMzUuMTgzIDcuMTM0MzYgMTM2Ljg4NEM4Ljg0MDk1IDEzOC41OTkgMTAuODA4NyAxNDAuMDMyIDEyLjk2NDMgMTQxLjEzQzE1LjExNDcgMTQyLjIwOSAxNy40MTQ2IDE0Mi45NiAxOS43ODc2IDE0My4zNThDMjIuMTczMSAxNDMuNzUxIDI0LjU4NDcgMTQzLjk2NiAyNy4wMDIyIDE0NEMyOC4xMTYgMTQ0IDExNS43ODUgMTQ0IDExNi44ODkgMTQ0QzExOS4zMDMgMTQzLjk2NyAxMjEuNzEyIDE0My43NTIgMTI0LjA5NCAxNDMuMzU4QzEyNi40ODUgMTQyLjk0NiAxMjguODAxIDE0Mi4xODIgMTMwLjk2NyAxNDEuMDg5QzEzMy4xMjEgMTM5Ljk5NCAxMzUuMDg2IDEzOC41NjEgMTM2Ljc4NyAxMzYuODQ0QzEzOC41MDMgMTM1LjE0IDEzOS45MzkgMTMzLjE3NiAxNDEuMDQyIDEzMS4wMjNDMTQyLjEzNyAxMjguODc5IDE0Mi45MDEgMTI2LjU4MSAxNDMuMzA5IDEyNC4yMDlDMTQzLjcxIDEyMS44MjMgMTQzLjkzMiAxMTkuNDExIDE0My45NzIgMTE2Ljk5MkMxNDMuOTkyIDExNS44MzggMTQ0LjAxMiAzMS42NzQ0IDE0My45OTIgMzAuMzY5N1oiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgxOCkiLz4KPHBhdGggZD0iTTExNS45NTUgNjcuNDIzMUMxMTQuOTQxIDU3LjgyMzQgMTEwLjcwMSA0OC44NTE4IDEwMy45MjggNDEuOTc1MkM5Ny4xNTQ5IDM1LjA5ODYgODguMjQ5NSAzMC43MjM5IDc4LjY2OCAyOS41NjY0VjQ2Ljc3ODZDODQuNDg4NyA0Ny45MTI3IDg5LjczMzggNTEuMDM2MiA5My41MDQ5IDU1LjYxMzdDOTcuMjc2IDYwLjE5MTIgOTkuMzM4MSA2NS45Mzc5IDk5LjMzODEgNzEuODY5MkM5OS4zMzgxIDc3LjgwMDQgOTcuMjc2IDgzLjU0NzEgOTMuNTA0OSA4OC4xMjQ2Qzg5LjczMzggOTIuNzAyMiA4NC40ODg3IDk1LjgyNTYgNzguNjY4IDk2Ljk1OThWMTE0LjIyMkM4OS43ODAxIDExMi44NzcgOTkuOTE3OCAxMDcuMjE1IDEwNi44OTQgOTguNDYwMUMxMTMuODY5IDg5LjcwNDggMTE3LjEyNCA3OC41NTczIDExNS45NTUgNjcuNDIzMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0yOC4wMTU1IDc2LjM2NTRDMjkuMDMxMSA4NS45NjQ0IDMzLjI3MTggOTQuOTM1MSA0MC4wNDQ3IDEwMS44MTFDNDYuODE3NSAxMDguNjg4IDU1LjcyMiAxMTMuMDYzIDY1LjMwMjggMTE0LjIyMlYyOS41NjY0QzU0LjE5MDcgMzAuOTExOSA0NC4wNTMgMzYuNTczMSAzNy4wNzcyIDQ1LjMyODRDMzAuMTAxMyA1NC4wODM3IDI2Ljg0NjcgNjUuMjMxMiAyOC4wMTU1IDc2LjM2NTRaIiBmaWxsPSIjNUJCMTkzIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgxXzI4MTgiIHgxPSIxMzIuNSIgeTE9IjEzMi41IiB4Mj0iLTI0IiB5Mj0iLTE5IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMxODM3MjkiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNDU5RDc1Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== - keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "external"], ["spec", "host"], ["spec", "users"], ["spec", "externalIPs"]] - secrets: - exclude: [] - include: - - resourceNames: - - "{{`vpn-{{ .name }}-urls`}}" - services: - exclude: [] - include: - - resourceNames: - - "{{`vpn-{{ .name }}-vpn`}}" diff --git a/packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml b/packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml index 2596175a..92a6335f 100644 --- a/packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml +++ b/packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml @@ -89,709 +89,6 @@ spec: items: description: Variant defines a single variant configuration properties: - applications: - description: Applications is a list of application releases - to be installed as part of this variant - items: - description: Application defines a single application release - within a package source - properties: - libraries: - description: |- - Libraries is a list of library names that this application depends on - These libraries must be defined at the variant level - items: - type: string - type: array - name: - description: Name is the unique identifier for this application - within the package source - type: string - path: - description: Path is the path to the Helm chart directory - type: string - template: - description: Template describes the applications that - will be created. - 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: - properties: - application: - description: Application configuration - properties: - kind: - description: Kind of the application, used - for UI and API - type: string - openAPISchema: - description: OpenAPI schema for the application, - used for API validation - type: string - plural: - description: Plural name of the application, - used for UI and API - type: string - singular: - description: Singular name of the application, - used for UI and API - type: string - required: - - kind - - openAPISchema - - plural - - singular - type: object - dashboard: - description: Dashboard configuration for this - resource - properties: - category: - description: Category used to group resources - in the UI (e.g., "Storage", "Networking") - type: string - description: - description: Short description shown in catalogs - or headers (e.g., "S3 compatible storage") - type: string - icon: - description: Icon encoded as a string (e.g., - inline SVG, base64, or data URI) - type: string - keysOrder: - description: Order of keys in the YAML view - items: - items: - type: string - type: array - type: array - module: - description: Whether this resource is a module - (tenant module) - type: boolean - name: - description: Hard-coded name used in the UI - (e.g., "bucket") - type: string - plural: - description: Plural human-readable name (e.g., - "Buckets") - type: string - singular: - description: Human-readable name shown in - the UI (e.g., "Bucket") - type: string - singularResource: - description: Whether this resource is singular - (not a collection) in the UI - type: boolean - tabs: - description: Which tabs to show for this resource - items: - description: DashboardTab enumerates allowed - UI tabs. - enum: - - workloads - - ingresses - - services - - secrets - - yaml - type: string - type: array - tags: - description: Free-form tags for search and - filtering - items: - type: string - type: array - weight: - description: Order weight for sorting resources - in the UI (lower first) - type: integer - required: - - category - - plural - - singular - type: object - ingresses: - description: Ingress selectors - properties: - exclude: - description: |- - Exclude contains an array of resource selectors that target resources. - If a resource matches the selector in any of the elements in the array, it is - hidden from the user, regardless of the matches in the include array. - items: - description: "CozystackResourceDefinitionResourceSelector - extends metav1.LabelSelector with resourceNames - support.\nA resource matches this selector - only if it satisfies ALL criteria:\n- - Label selector conditions (matchExpressions - and matchLabels)\n- AND has a name that - matches one of the names in resourceNames - (if specified)\n\nThe resourceNames field - supports Go templates with the following - variables available:\n- {{ .name }}: The - name of the managing application (from - apps.cozystack.io/application.name)\n- - {{ .kind }}: The lowercased kind of the - managing application (from apps.cozystack.io/application.kind)\n- - {{ .namespace }}: The namespace of the - resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t - \ include:\n\t - matchExpressions:\n\t - \ - key: badlabel\n\t operator: - DoesNotExist\n\t matchLabels:\n\t goodlabel: - goodvalue\n\t resourceNames:\n\t - - \"{{ .name }}-secret\"\n\t - \"{{ .kind - }}-{{ .name }}-tls\"\n\t - \"specificname\"" - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - resourceNames: - description: |- - ResourceNames is a list of resource names to match - If specified, the resource must have one of these exact names to match the selector - items: - type: string - type: array - type: object - x-kubernetes-map-type: atomic - type: array - include: - description: |- - Include contains an array of resource selectors that target resources. - If a resource matches the selector in any of the elements in the array, and - matches none of the selectors in the exclude array that resource is marked - as a tenant resource and is visible to users. - items: - description: "CozystackResourceDefinitionResourceSelector - extends metav1.LabelSelector with resourceNames - support.\nA resource matches this selector - only if it satisfies ALL criteria:\n- - Label selector conditions (matchExpressions - and matchLabels)\n- AND has a name that - matches one of the names in resourceNames - (if specified)\n\nThe resourceNames field - supports Go templates with the following - variables available:\n- {{ .name }}: The - name of the managing application (from - apps.cozystack.io/application.name)\n- - {{ .kind }}: The lowercased kind of the - managing application (from apps.cozystack.io/application.kind)\n- - {{ .namespace }}: The namespace of the - resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t - \ include:\n\t - matchExpressions:\n\t - \ - key: badlabel\n\t operator: - DoesNotExist\n\t matchLabels:\n\t goodlabel: - goodvalue\n\t resourceNames:\n\t - - \"{{ .name }}-secret\"\n\t - \"{{ .kind - }}-{{ .name }}-tls\"\n\t - \"specificname\"" - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - resourceNames: - description: |- - ResourceNames is a list of resource names to match - If specified, the resource must have one of these exact names to match the selector - items: - type: string - type: array - type: object - x-kubernetes-map-type: atomic - type: array - type: object - release: - description: Release configuration - properties: - chart: - description: Helm chart configuration - properties: - name: - description: Name of the Helm chart - type: string - sourceRef: - description: Source reference for the - Helm chart - properties: - kind: - default: HelmRepository - description: Kind of the source reference - type: string - name: - description: Name of the source reference - type: string - namespace: - default: cozy-public - description: Namespace of the source - reference - type: string - required: - - kind - - name - - namespace - type: object - required: - - name - - sourceRef - type: object - labels: - additionalProperties: - type: string - description: Labels for the release - type: object - prefix: - description: Prefix for the release name - type: string - required: - - prefix - type: object - secrets: - description: Secret selectors - properties: - exclude: - description: |- - Exclude contains an array of resource selectors that target resources. - If a resource matches the selector in any of the elements in the array, it is - hidden from the user, regardless of the matches in the include array. - items: - description: "CozystackResourceDefinitionResourceSelector - extends metav1.LabelSelector with resourceNames - support.\nA resource matches this selector - only if it satisfies ALL criteria:\n- - Label selector conditions (matchExpressions - and matchLabels)\n- AND has a name that - matches one of the names in resourceNames - (if specified)\n\nThe resourceNames field - supports Go templates with the following - variables available:\n- {{ .name }}: The - name of the managing application (from - apps.cozystack.io/application.name)\n- - {{ .kind }}: The lowercased kind of the - managing application (from apps.cozystack.io/application.kind)\n- - {{ .namespace }}: The namespace of the - resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t - \ include:\n\t - matchExpressions:\n\t - \ - key: badlabel\n\t operator: - DoesNotExist\n\t matchLabels:\n\t goodlabel: - goodvalue\n\t resourceNames:\n\t - - \"{{ .name }}-secret\"\n\t - \"{{ .kind - }}-{{ .name }}-tls\"\n\t - \"specificname\"" - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - resourceNames: - description: |- - ResourceNames is a list of resource names to match - If specified, the resource must have one of these exact names to match the selector - items: - type: string - type: array - type: object - x-kubernetes-map-type: atomic - type: array - include: - description: |- - Include contains an array of resource selectors that target resources. - If a resource matches the selector in any of the elements in the array, and - matches none of the selectors in the exclude array that resource is marked - as a tenant resource and is visible to users. - items: - description: "CozystackResourceDefinitionResourceSelector - extends metav1.LabelSelector with resourceNames - support.\nA resource matches this selector - only if it satisfies ALL criteria:\n- - Label selector conditions (matchExpressions - and matchLabels)\n- AND has a name that - matches one of the names in resourceNames - (if specified)\n\nThe resourceNames field - supports Go templates with the following - variables available:\n- {{ .name }}: The - name of the managing application (from - apps.cozystack.io/application.name)\n- - {{ .kind }}: The lowercased kind of the - managing application (from apps.cozystack.io/application.kind)\n- - {{ .namespace }}: The namespace of the - resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t - \ include:\n\t - matchExpressions:\n\t - \ - key: badlabel\n\t operator: - DoesNotExist\n\t matchLabels:\n\t goodlabel: - goodvalue\n\t resourceNames:\n\t - - \"{{ .name }}-secret\"\n\t - \"{{ .kind - }}-{{ .name }}-tls\"\n\t - \"specificname\"" - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - resourceNames: - description: |- - ResourceNames is a list of resource names to match - If specified, the resource must have one of these exact names to match the selector - items: - type: string - type: array - type: object - x-kubernetes-map-type: atomic - type: array - type: object - services: - description: Service selectors - properties: - exclude: - description: |- - Exclude contains an array of resource selectors that target resources. - If a resource matches the selector in any of the elements in the array, it is - hidden from the user, regardless of the matches in the include array. - items: - description: "CozystackResourceDefinitionResourceSelector - extends metav1.LabelSelector with resourceNames - support.\nA resource matches this selector - only if it satisfies ALL criteria:\n- - Label selector conditions (matchExpressions - and matchLabels)\n- AND has a name that - matches one of the names in resourceNames - (if specified)\n\nThe resourceNames field - supports Go templates with the following - variables available:\n- {{ .name }}: The - name of the managing application (from - apps.cozystack.io/application.name)\n- - {{ .kind }}: The lowercased kind of the - managing application (from apps.cozystack.io/application.kind)\n- - {{ .namespace }}: The namespace of the - resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t - \ include:\n\t - matchExpressions:\n\t - \ - key: badlabel\n\t operator: - DoesNotExist\n\t matchLabels:\n\t goodlabel: - goodvalue\n\t resourceNames:\n\t - - \"{{ .name }}-secret\"\n\t - \"{{ .kind - }}-{{ .name }}-tls\"\n\t - \"specificname\"" - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - resourceNames: - description: |- - ResourceNames is a list of resource names to match - If specified, the resource must have one of these exact names to match the selector - items: - type: string - type: array - type: object - x-kubernetes-map-type: atomic - type: array - include: - description: |- - Include contains an array of resource selectors that target resources. - If a resource matches the selector in any of the elements in the array, and - matches none of the selectors in the exclude array that resource is marked - as a tenant resource and is visible to users. - items: - description: "CozystackResourceDefinitionResourceSelector - extends metav1.LabelSelector with resourceNames - support.\nA resource matches this selector - only if it satisfies ALL criteria:\n- - Label selector conditions (matchExpressions - and matchLabels)\n- AND has a name that - matches one of the names in resourceNames - (if specified)\n\nThe resourceNames field - supports Go templates with the following - variables available:\n- {{ .name }}: The - name of the managing application (from - apps.cozystack.io/application.name)\n- - {{ .kind }}: The lowercased kind of the - managing application (from apps.cozystack.io/application.kind)\n- - {{ .namespace }}: The namespace of the - resource being processed\n\nExample YAML:\n\n\tsecrets:\n\t - \ include:\n\t - matchExpressions:\n\t - \ - key: badlabel\n\t operator: - DoesNotExist\n\t matchLabels:\n\t goodlabel: - goodvalue\n\t resourceNames:\n\t - - \"{{ .name }}-secret\"\n\t - \"{{ .kind - }}-{{ .name }}-tls\"\n\t - \"specificname\"" - properties: - matchExpressions: - description: matchExpressions is a list - of label selector requirements. The - requirements are ANDed. - items: - description: |- - A label selector requirement is a selector that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label - key that the selector applies - to. - type: string - operator: - description: |- - operator represents a key's relationship to a set of values. - Valid operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: |- - values is an array of string values. If the operator is In or NotIn, - the values array must be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - x-kubernetes-list-type: atomic - required: - - key - - operator - type: object - type: array - x-kubernetes-list-type: atomic - matchLabels: - additionalProperties: - type: string - description: |- - matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, whose key field is "key", the - operator is "In", and the values array contains only "value". The requirements are ANDed. - type: object - resourceNames: - description: |- - ResourceNames is a list of resource names to match - If specified, the resource must have one of these exact names to match the selector - items: - type: string - type: array - type: object - x-kubernetes-map-type: atomic - type: array - type: object - required: - - application - - release - type: object - type: object - required: - - name - - path - - template - type: object - type: array components: description: Components is a list of Helm releases to be installed as part of this variant @@ -799,10 +96,6 @@ spec: description: Component defines a single Helm release component within a package source properties: - disabled: - description: Disabled indicates whether this component - is disabled (should not be installed) - type: boolean install: description: Install defines installation parameters for this component diff --git a/pkg/generated/openapi/zz_generated.openapi.go b/pkg/generated/openapi/zz_generated.openapi.go index 4202bbac..ba5ab71b 100644 --- a/pkg/generated/openapi/zz_generated.openapi.go +++ b/pkg/generated/openapi/zz_generated.openapi.go @@ -2714,6 +2714,13 @@ func schema_pkg_apis_meta_v1_DeleteOptions(ref common.ReferenceCallback) common. }, }, }, + "ignoreStoreReadErrorWithClusterBreakingPotential": { + SchemaProps: spec.SchemaProps{ + Description: "if set to true, it will trigger an unsafe deletion of the resource in case the normal deletion flow fails with a corrupt object error. A resource is considered corrupt if it can not be retrieved from the underlying storage successfully because of a) its data can not be transformed e.g. decryption failure, or b) it fails to decode into an object. NOTE: unsafe deletion ignores finalizer constraints, skips precondition checks, and removes the object from the storage. WARNING: This may potentially break the cluster if the workload associated with the resource being unsafe-deleted relies on normal deletion flow. Use only if you REALLY know what you are doing. The default value is false, and the user must opt in to enable it", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, @@ -4601,16 +4608,46 @@ func schema_k8sio_apimachinery_pkg_version_Info(ref common.ReferenceCallback) co Properties: map[string]spec.Schema{ "major": { SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Description: "Major is the major version of the binary version", + Default: "", + Type: []string{"string"}, + Format: "", }, }, "minor": { SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", + Description: "Minor is the minor version of the binary version", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "emulationMajor": { + SchemaProps: spec.SchemaProps{ + Description: "EmulationMajor is the major version of the emulation version", + Type: []string{"string"}, + Format: "", + }, + }, + "emulationMinor": { + SchemaProps: spec.SchemaProps{ + Description: "EmulationMinor is the minor version of the emulation version", + Type: []string{"string"}, + Format: "", + }, + }, + "minCompatibilityMajor": { + SchemaProps: spec.SchemaProps{ + Description: "MinCompatibilityMajor is the major version of the minimum compatibility version", + Type: []string{"string"}, + Format: "", + }, + }, + "minCompatibilityMinor": { + SchemaProps: spec.SchemaProps{ + Description: "MinCompatibilityMinor is the minor version of the minimum compatibility version", + Type: []string{"string"}, + Format: "", }, }, "gitVersion": { From 0f2fc0d9915027208a2fbf3ae9186d8746bcd9fd Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Fri, 19 Dec 2025 13:06:28 +0100 Subject: [PATCH 10/15] Sourcec reconciled Signed-off-by: Andrei Kvapil --- cmd/cozystack-operator/main.go | 22 +- cmd/psds-graph/main.go | 293 +++++++++++ internal/operator/packagesource_reconciler.go | 468 ++++++++++++++++++ .../templates/cozystack-operator.yaml | 10 +- packages/core/installer/values.yaml | 4 +- .../platform/psds/bootbox-application.yaml | 8 +- .../core/platform/psds/cozystack-engine.yaml | 5 + .../platform/psds/kubernetes-application.yaml | 2 +- packages/core/platform/psds/networking.yaml | 5 + packages/system/bootbox-rd/Chart.yaml | 3 + packages/system/bootbox-rd/Makefile | 4 + .../system/bootbox-rd/cozyrds/bootbox.yaml | 43 ++ .../system/bootbox-rd/templates/cozyrd.yaml | 4 + packages/system/bootbox-rd/values.yaml | 1 + packages/system/bucket-rd/Chart.yaml | 3 + packages/system/bucket-rd/Makefile | 4 + packages/system/bucket-rd/cozyrds/bucket.yaml | 42 ++ .../system/bucket-rd/templates/cozyrd.yaml | 4 + packages/system/bucket-rd/values.yaml | 1 + packages/system/clickhouse-rd/Chart.yaml | 3 + packages/system/clickhouse-rd/Makefile | 4 + .../clickhouse-rd/cozyrds/clickhouse.yaml | 39 ++ .../clickhouse-rd/templates/cozyrd.yaml | 4 + packages/system/clickhouse-rd/values.yaml | 1 + packages/system/etcd-rd/Chart.yaml | 3 + packages/system/etcd-rd/Makefile | 4 + packages/system/etcd-rd/cozyrds/etcd.yaml | 39 ++ packages/system/etcd-rd/templates/cozyrd.yaml | 4 + packages/system/etcd-rd/values.yaml | 1 + packages/system/ferretdb-rd/Chart.yaml | 3 + packages/system/ferretdb-rd/Makefile | 4 + .../system/ferretdb-rd/cozyrds/ferretdb.yaml | 40 ++ .../system/ferretdb-rd/templates/cozyrd.yaml | 4 + packages/system/ferretdb-rd/values.yaml | 1 + packages/system/foundationdb-rd/Chart.yaml | 3 + packages/system/foundationdb-rd/Makefile | 4 + .../foundationdb-rd/cozyrds/foundationdb.yaml | 30 ++ .../foundationdb-rd/templates/cozyrd.yaml | 4 + packages/system/foundationdb-rd/values.yaml | 1 + packages/system/http-cache-rd/Chart.yaml | 3 + packages/system/http-cache-rd/Makefile | 4 + .../http-cache-rd/cozyrds/http-cache.yaml | 34 ++ .../http-cache-rd/templates/cozyrd.yaml | 4 + packages/system/http-cache-rd/values.yaml | 1 + packages/system/info-rd/Chart.yaml | 3 + packages/system/info-rd/Makefile | 4 + packages/system/info-rd/cozyrds/info.yaml | 37 ++ packages/system/info-rd/templates/cozyrd.yaml | 4 + packages/system/info-rd/values.yaml | 1 + packages/system/ingress-rd/Chart.yaml | 3 + packages/system/ingress-rd/Makefile | 4 + .../system/ingress-rd/cozyrds/ingress.yaml | 39 ++ .../system/ingress-rd/templates/cozyrd.yaml | 4 + packages/system/ingress-rd/values.yaml | 1 + packages/system/kafka-rd/Chart.yaml | 3 + packages/system/kafka-rd/Makefile | 4 + packages/system/kafka-rd/cozyrds/kafka.yaml | 40 ++ .../system/kafka-rd/templates/cozyrd.yaml | 4 + packages/system/kafka-rd/values.yaml | 1 + packages/system/kubernetes-rd/Chart.yaml | 3 + packages/system/kubernetes-rd/Makefile | 4 + .../kubernetes-rd/cozyrds/kubernetes.yaml | 46 ++ .../kubernetes-rd/templates/cozyrd.yaml | 4 + packages/system/kubernetes-rd/values.yaml | 1 + packages/system/monitoring-rd/Chart.yaml | 3 + packages/system/monitoring-rd/Makefile | 4 + .../monitoring-rd/cozyrds/monitoring.yaml | 48 ++ .../monitoring-rd/templates/cozyrd.yaml | 4 + packages/system/monitoring-rd/values.yaml | 1 + packages/system/mysql-rd/Chart.yaml | 3 + packages/system/mysql-rd/Makefile | 4 + packages/system/mysql-rd/cozyrds/mysql.yaml | 41 ++ .../system/mysql-rd/templates/cozyrd.yaml | 4 + packages/system/mysql-rd/values.yaml | 1 + packages/system/nats-rd/Chart.yaml | 3 + packages/system/nats-rd/Makefile | 4 + packages/system/nats-rd/cozyrds/nats.yaml | 40 ++ packages/system/nats-rd/templates/cozyrd.yaml | 4 + packages/system/nats-rd/values.yaml | 1 + packages/system/postgres-rd/Chart.yaml | 3 + packages/system/postgres-rd/Makefile | 4 + .../system/postgres-rd/cozyrds/postgres.yaml | 51 ++ .../system/postgres-rd/templates/cozyrd.yaml | 4 + packages/system/postgres-rd/values.yaml | 1 + packages/system/rabbitmq-rd/Chart.yaml | 3 + packages/system/rabbitmq-rd/Makefile | 4 + .../system/rabbitmq-rd/cozyrds/rabbitmq.yaml | 42 ++ .../system/rabbitmq-rd/templates/cozyrd.yaml | 4 + packages/system/rabbitmq-rd/values.yaml | 1 + packages/system/redis-rd/Chart.yaml | 3 + packages/system/redis-rd/Makefile | 4 + packages/system/redis-rd/cozyrds/redis.yaml | 43 ++ .../system/redis-rd/templates/cozyrd.yaml | 4 + packages/system/redis-rd/values.yaml | 1 + packages/system/seaweedfs-rd/Chart.yaml | 3 + packages/system/seaweedfs-rd/Makefile | 4 + .../seaweedfs-rd/cozyrds/seaweedfs.yaml | 44 ++ .../system/seaweedfs-rd/templates/cozyrd.yaml | 4 + packages/system/seaweedfs-rd/values.yaml | 1 + packages/system/tcp-balancer-rd/Chart.yaml | 3 + packages/system/tcp-balancer-rd/Makefile | 4 + .../tcp-balancer-rd/cozyrds/tcp-balancer.yaml | 33 ++ .../tcp-balancer-rd/templates/cozyrd.yaml | 4 + packages/system/tcp-balancer-rd/values.yaml | 1 + packages/system/tenant-rd/Chart.yaml | 3 + packages/system/tenant-rd/Makefile | 4 + packages/system/tenant-rd/cozyrds/tenant.yaml | 31 ++ .../system/tenant-rd/templates/cozyrd.yaml | 4 + packages/system/tenant-rd/values.yaml | 1 + packages/system/virtual-machine-rd/Chart.yaml | 3 + packages/system/virtual-machine-rd/Makefile | 4 + .../cozyrds/virtual-machine.yaml | 39 ++ .../virtual-machine-rd/templates/cozyrd.yaml | 4 + .../system/virtual-machine-rd/values.yaml | 1 + .../system/virtualprivatecloud-rd/Chart.yaml | 3 + .../system/virtualprivatecloud-rd/Makefile | 4 + .../cozyrds/virtualprivatecloud.yaml | 34 ++ .../templates/cozyrd.yaml | 4 + .../system/virtualprivatecloud-rd/values.yaml | 1 + packages/system/vm-disk-rd/Chart.yaml | 3 + packages/system/vm-disk-rd/Makefile | 4 + .../system/vm-disk-rd/cozyrds/vm-disk.yaml | 34 ++ .../system/vm-disk-rd/templates/cozyrd.yaml | 4 + packages/system/vm-disk-rd/values.yaml | 1 + packages/system/vm-instance-rd/Chart.yaml | 3 + packages/system/vm-instance-rd/Makefile | 4 + .../vm-instance-rd/cozyrds/vm-instance.yaml | 39 ++ .../vm-instance-rd/templates/cozyrd.yaml | 4 + packages/system/vm-instance-rd/values.yaml | 1 + packages/system/vpn-rd/Chart.yaml | 3 + packages/system/vpn-rd/Makefile | 4 + packages/system/vpn-rd/cozyrds/vpn.yaml | 40 ++ packages/system/vpn-rd/templates/cozyrd.yaml | 4 + packages/system/vpn-rd/values.yaml | 1 + 134 files changed, 2087 insertions(+), 18 deletions(-) create mode 100644 cmd/psds-graph/main.go create mode 100644 internal/operator/packagesource_reconciler.go create mode 100644 packages/system/bootbox-rd/Chart.yaml create mode 100644 packages/system/bootbox-rd/Makefile create mode 100644 packages/system/bootbox-rd/cozyrds/bootbox.yaml create mode 100644 packages/system/bootbox-rd/templates/cozyrd.yaml create mode 100644 packages/system/bootbox-rd/values.yaml create mode 100644 packages/system/bucket-rd/Chart.yaml create mode 100644 packages/system/bucket-rd/Makefile create mode 100644 packages/system/bucket-rd/cozyrds/bucket.yaml create mode 100644 packages/system/bucket-rd/templates/cozyrd.yaml create mode 100644 packages/system/bucket-rd/values.yaml create mode 100644 packages/system/clickhouse-rd/Chart.yaml create mode 100644 packages/system/clickhouse-rd/Makefile create mode 100644 packages/system/clickhouse-rd/cozyrds/clickhouse.yaml create mode 100644 packages/system/clickhouse-rd/templates/cozyrd.yaml create mode 100644 packages/system/clickhouse-rd/values.yaml create mode 100644 packages/system/etcd-rd/Chart.yaml create mode 100644 packages/system/etcd-rd/Makefile create mode 100644 packages/system/etcd-rd/cozyrds/etcd.yaml create mode 100644 packages/system/etcd-rd/templates/cozyrd.yaml create mode 100644 packages/system/etcd-rd/values.yaml create mode 100644 packages/system/ferretdb-rd/Chart.yaml create mode 100644 packages/system/ferretdb-rd/Makefile create mode 100644 packages/system/ferretdb-rd/cozyrds/ferretdb.yaml create mode 100644 packages/system/ferretdb-rd/templates/cozyrd.yaml create mode 100644 packages/system/ferretdb-rd/values.yaml create mode 100644 packages/system/foundationdb-rd/Chart.yaml create mode 100644 packages/system/foundationdb-rd/Makefile create mode 100644 packages/system/foundationdb-rd/cozyrds/foundationdb.yaml create mode 100644 packages/system/foundationdb-rd/templates/cozyrd.yaml create mode 100644 packages/system/foundationdb-rd/values.yaml create mode 100644 packages/system/http-cache-rd/Chart.yaml create mode 100644 packages/system/http-cache-rd/Makefile create mode 100644 packages/system/http-cache-rd/cozyrds/http-cache.yaml create mode 100644 packages/system/http-cache-rd/templates/cozyrd.yaml create mode 100644 packages/system/http-cache-rd/values.yaml create mode 100644 packages/system/info-rd/Chart.yaml create mode 100644 packages/system/info-rd/Makefile create mode 100644 packages/system/info-rd/cozyrds/info.yaml create mode 100644 packages/system/info-rd/templates/cozyrd.yaml create mode 100644 packages/system/info-rd/values.yaml create mode 100644 packages/system/ingress-rd/Chart.yaml create mode 100644 packages/system/ingress-rd/Makefile create mode 100644 packages/system/ingress-rd/cozyrds/ingress.yaml create mode 100644 packages/system/ingress-rd/templates/cozyrd.yaml create mode 100644 packages/system/ingress-rd/values.yaml create mode 100644 packages/system/kafka-rd/Chart.yaml create mode 100644 packages/system/kafka-rd/Makefile create mode 100644 packages/system/kafka-rd/cozyrds/kafka.yaml create mode 100644 packages/system/kafka-rd/templates/cozyrd.yaml create mode 100644 packages/system/kafka-rd/values.yaml create mode 100644 packages/system/kubernetes-rd/Chart.yaml create mode 100644 packages/system/kubernetes-rd/Makefile create mode 100644 packages/system/kubernetes-rd/cozyrds/kubernetes.yaml create mode 100644 packages/system/kubernetes-rd/templates/cozyrd.yaml create mode 100644 packages/system/kubernetes-rd/values.yaml create mode 100644 packages/system/monitoring-rd/Chart.yaml create mode 100644 packages/system/monitoring-rd/Makefile create mode 100644 packages/system/monitoring-rd/cozyrds/monitoring.yaml create mode 100644 packages/system/monitoring-rd/templates/cozyrd.yaml create mode 100644 packages/system/monitoring-rd/values.yaml create mode 100644 packages/system/mysql-rd/Chart.yaml create mode 100644 packages/system/mysql-rd/Makefile create mode 100644 packages/system/mysql-rd/cozyrds/mysql.yaml create mode 100644 packages/system/mysql-rd/templates/cozyrd.yaml create mode 100644 packages/system/mysql-rd/values.yaml create mode 100644 packages/system/nats-rd/Chart.yaml create mode 100644 packages/system/nats-rd/Makefile create mode 100644 packages/system/nats-rd/cozyrds/nats.yaml create mode 100644 packages/system/nats-rd/templates/cozyrd.yaml create mode 100644 packages/system/nats-rd/values.yaml create mode 100644 packages/system/postgres-rd/Chart.yaml create mode 100644 packages/system/postgres-rd/Makefile create mode 100644 packages/system/postgres-rd/cozyrds/postgres.yaml create mode 100644 packages/system/postgres-rd/templates/cozyrd.yaml create mode 100644 packages/system/postgres-rd/values.yaml create mode 100644 packages/system/rabbitmq-rd/Chart.yaml create mode 100644 packages/system/rabbitmq-rd/Makefile create mode 100644 packages/system/rabbitmq-rd/cozyrds/rabbitmq.yaml create mode 100644 packages/system/rabbitmq-rd/templates/cozyrd.yaml create mode 100644 packages/system/rabbitmq-rd/values.yaml create mode 100644 packages/system/redis-rd/Chart.yaml create mode 100644 packages/system/redis-rd/Makefile create mode 100644 packages/system/redis-rd/cozyrds/redis.yaml create mode 100644 packages/system/redis-rd/templates/cozyrd.yaml create mode 100644 packages/system/redis-rd/values.yaml create mode 100644 packages/system/seaweedfs-rd/Chart.yaml create mode 100644 packages/system/seaweedfs-rd/Makefile create mode 100644 packages/system/seaweedfs-rd/cozyrds/seaweedfs.yaml create mode 100644 packages/system/seaweedfs-rd/templates/cozyrd.yaml create mode 100644 packages/system/seaweedfs-rd/values.yaml create mode 100644 packages/system/tcp-balancer-rd/Chart.yaml create mode 100644 packages/system/tcp-balancer-rd/Makefile create mode 100644 packages/system/tcp-balancer-rd/cozyrds/tcp-balancer.yaml create mode 100644 packages/system/tcp-balancer-rd/templates/cozyrd.yaml create mode 100644 packages/system/tcp-balancer-rd/values.yaml create mode 100644 packages/system/tenant-rd/Chart.yaml create mode 100644 packages/system/tenant-rd/Makefile create mode 100644 packages/system/tenant-rd/cozyrds/tenant.yaml create mode 100644 packages/system/tenant-rd/templates/cozyrd.yaml create mode 100644 packages/system/tenant-rd/values.yaml create mode 100644 packages/system/virtual-machine-rd/Chart.yaml create mode 100644 packages/system/virtual-machine-rd/Makefile create mode 100644 packages/system/virtual-machine-rd/cozyrds/virtual-machine.yaml create mode 100644 packages/system/virtual-machine-rd/templates/cozyrd.yaml create mode 100644 packages/system/virtual-machine-rd/values.yaml create mode 100644 packages/system/virtualprivatecloud-rd/Chart.yaml create mode 100644 packages/system/virtualprivatecloud-rd/Makefile create mode 100644 packages/system/virtualprivatecloud-rd/cozyrds/virtualprivatecloud.yaml create mode 100644 packages/system/virtualprivatecloud-rd/templates/cozyrd.yaml create mode 100644 packages/system/virtualprivatecloud-rd/values.yaml create mode 100644 packages/system/vm-disk-rd/Chart.yaml create mode 100644 packages/system/vm-disk-rd/Makefile create mode 100644 packages/system/vm-disk-rd/cozyrds/vm-disk.yaml create mode 100644 packages/system/vm-disk-rd/templates/cozyrd.yaml create mode 100644 packages/system/vm-disk-rd/values.yaml create mode 100644 packages/system/vm-instance-rd/Chart.yaml create mode 100644 packages/system/vm-instance-rd/Makefile create mode 100644 packages/system/vm-instance-rd/cozyrds/vm-instance.yaml create mode 100644 packages/system/vm-instance-rd/templates/cozyrd.yaml create mode 100644 packages/system/vm-instance-rd/values.yaml create mode 100644 packages/system/vpn-rd/Chart.yaml create mode 100644 packages/system/vpn-rd/Makefile create mode 100644 packages/system/vpn-rd/cozyrds/vpn.yaml create mode 100644 packages/system/vpn-rd/templates/cozyrd.yaml create mode 100644 packages/system/vpn-rd/values.yaml diff --git a/cmd/cozystack-operator/main.go b/cmd/cozystack-operator/main.go index 9ffba5d6..6cabbd5d 100644 --- a/cmd/cozystack-operator/main.go +++ b/cmd/cozystack-operator/main.go @@ -48,6 +48,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/webhook" "github.com/cozystack/cozystack/internal/fluxinstall" + "github.com/cozystack/cozystack/internal/operator" // +kubebuilder:scaffold:imports ) @@ -88,7 +89,7 @@ func main() { var cozystackVersion string var installFluxResources stringSliceFlag var platformSource string - var platformName string + var platformSourceName string flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") @@ -104,7 +105,7 @@ func main() { flag.StringVar(&cozystackVersion, "cozystack-version", "unknown", "Version of Cozystack") flag.StringVar(&platformSource, "platform-source", "", "Platform source URL (oci:// or git://). If specified, generates OCIRepository or GitRepository resource.") - flag.StringVar(&platformName, "platform-name", "cozystack-packages", "Name for the generated platform source resource (default: cozystack-packages)") + flag.StringVar(&platformSourceName, "platform-source-name", "cozystack-packages", "Name for the generated platform source resource (default: cozystack-packages)") opts := zap.Options{ Development: true, @@ -178,11 +179,11 @@ func main() { // Generate and install platform source resource if specified if platformSource != "" { - setupLog.Info("Generating platform source resource", "source", platformSource, "name", platformName) + setupLog.Info("Generating platform source resource", "source", platformSource, "name", platformSourceName) installCtx, installCancel := context.WithTimeout(context.Background(), 2*time.Minute) defer installCancel() - if err := installPlatformSourceResource(installCtx, mgr.GetClient(), platformSource, platformName); err != nil { + if err := installPlatformSourceResource(installCtx, mgr.GetClient(), platformSource, platformSourceName); err != nil { setupLog.Error(err, "failed to install platform source resource") os.Exit(1) } else { @@ -190,6 +191,15 @@ func main() { } } + // Setup PackageSource reconciler + if err := (&operator.PackageSourceReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "PackageSource") + os.Exit(1) + } + // +kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { @@ -348,12 +358,12 @@ func installPlatformSourceResource(ctx context.Context, k8sClient client.Client, func parsePlatformSource(sourceURL string) (sourceType, repoURL, ref string, err error) { // Normalize the URL by trimming whitespace sourceURL = strings.TrimSpace(sourceURL) - + // Check for oci:// prefix if strings.HasPrefix(sourceURL, "oci://") { // Remove oci:// prefix rest := strings.TrimPrefix(sourceURL, "oci://") - + // Check for @sha256: digest (look for @ followed by sha256:) // We need to find the last @ before sha256: to handle paths with @ symbols sha256Idx := strings.Index(rest, "@sha256:") diff --git a/cmd/psds-graph/main.go b/cmd/psds-graph/main.go new file mode 100644 index 00000000..6b3e58e0 --- /dev/null +++ b/cmd/psds-graph/main.go @@ -0,0 +1,293 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 main + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/emicklei/dot" + "github.com/spf13/cobra" + "gopkg.in/yaml.v3" +) + +var ( + psdsDir string + outputFile string + packagesOnly bool + format string +) + +func main() { + rootCmd := &cobra.Command{ + Use: "psds-graph", + Short: "Generate dependency graph for PackageSource files", + Long: `Generate a dependency graph visualization for PackageSource files. + +The command scans all YAML files in the specified directory, extracts dependencies, +and generates a graph in DOT format (compatible with graphviz). + +Examples: + # Generate SVG graph + psds-graph --psds-dir packages/core/platform/psds --output dependencies.svg + + # Generate PNG (requires graphviz) + psds-graph --psds-dir packages/core/platform/psds --output dependencies.png --format png + + # Show only package-level dependencies + psds-graph --psds-dir packages/core/platform/psds --output dependencies.svg --packages-only`, + RunE: run, + } + + rootCmd.Flags().StringVar(&psdsDir, "psds-dir", "packages/core/platform/psds", "Directory containing PackageSource YAML files") + rootCmd.Flags().StringVar(&outputFile, "output", "dependencies.dot", "Output file path") + rootCmd.Flags().BoolVar(&packagesOnly, "packages-only", false, "Show only package-level dependencies, hide component dependencies") + rootCmd.Flags().StringVar(&format, "format", "dot", "Output format: dot, svg, png, pdf (requires graphviz for non-dot formats)") + + if err := rootCmd.Execute(); err != nil { + fmt.Fprintf(os.Stderr, "Error: %v\n", err) + os.Exit(1) + } +} + +func run(cmd *cobra.Command, args []string) error { + if psdsDir == "" { + return fmt.Errorf("--psds-dir is required") + } + + fmt.Fprintf(os.Stderr, "Scanning %s...\n", psdsDir) + + graph, allNodes, err := buildGraph(psdsDir, packagesOnly) + if err != nil { + return fmt.Errorf("failed to build graph: %w", err) + } + + fmt.Fprintf(os.Stderr, "Found %d nodes and %d edges\n", len(allNodes), countEdges(graph)) + + // Generate DOT graph + dotGraph := generateDOTGraph(graph, allNodes, packagesOnly) + + // Write DOT file first + dotFile := outputFile + if format != "dot" { + dotFile = strings.TrimSuffix(outputFile, filepath.Ext(outputFile)) + ".dot" + } + + if err := writeDOT(dotGraph, dotFile); err != nil { + return err + } + + // If format is not dot, try to render using graphviz + if format != "dot" { + return renderWithGraphviz(dotFile, outputFile, format) + } + + return nil +} + +type PackageSource struct { + APIVersion string `yaml:"apiVersion"` + Kind string `yaml:"kind"` + Metadata map[string]interface{} `yaml:"metadata"` + Spec Spec `yaml:"spec"` +} + +type Spec struct { + Variants []Variant `yaml:"variants"` +} + +type Variant struct { + Name string `yaml:"name"` + DependsOn []string `yaml:"dependsOn"` + Components []Component `yaml:"components"` +} + +type Component struct { + Name string `yaml:"name"` + Install Install `yaml:"install"` +} + +type Install struct { + DependsOn []string `yaml:"dependsOn"` +} + +func buildGraph(psdsDir string, packagesOnly bool) (map[string][]string, map[string]bool, error) { + graph := make(map[string][]string) + allNodes := make(map[string]bool) + + err := filepath.Walk(psdsDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + if !strings.HasSuffix(path, ".yaml") { + return nil + } + + data, err := os.ReadFile(path) + if err != nil { + fmt.Fprintf(os.Stderr, "Warning: failed to read %s: %v\n", path, err) + return nil + } + + var ps PackageSource + if err := yaml.Unmarshal(data, &ps); err != nil { + fmt.Fprintf(os.Stderr, "Warning: failed to parse %s: %v\n", path, err) + return nil + } + + packageName, ok := ps.Metadata["name"].(string) + if !ok || packageName == "" { + fmt.Fprintf(os.Stderr, "Warning: %s has no package name, skipping\n", path) + return nil + } + + allNodes[packageName] = true + + // Extract dependencies + for _, variant := range ps.Spec.Variants { + // Variant-level dependencies + for _, dep := range variant.DependsOn { + graph[packageName] = append(graph[packageName], dep) + allNodes[dep] = true + } + + // Component-level dependencies + if !packagesOnly { + for _, component := range variant.Components { + componentName := fmt.Sprintf("%s.%s", packageName, component.Name) + allNodes[componentName] = true + + for _, dep := range component.Install.DependsOn { + // Check if it's a local component dependency or external + if strings.Contains(dep, ".") { + graph[componentName] = append(graph[componentName], dep) + allNodes[dep] = true + } else { + // Local component dependency + localDep := fmt.Sprintf("%s.%s", packageName, dep) + graph[componentName] = append(graph[componentName], localDep) + allNodes[localDep] = true + } + } + } + } + } + + return nil + }) + + return graph, allNodes, err +} + +func countEdges(graph map[string][]string) int { + count := 0 + for _, deps := range graph { + count += len(deps) + } + return count +} + +func generateDOTGraph(graph map[string][]string, allNodes map[string]bool, packagesOnly bool) *dot.Graph { + g := dot.NewGraph(dot.Directed) + g.Attr("rankdir", "LR") + g.Attr("nodesep", "0.5") + g.Attr("ranksep", "1.0") + + // Add nodes + for node := range allNodes { + if packagesOnly && strings.Contains(node, ".") && !strings.HasPrefix(node, "cozystack.") { + // Skip component nodes when packages-only is enabled + continue + } + + n := g.Node(node) + + // Style nodes based on type + if strings.Contains(node, ".") && !strings.HasPrefix(node, "cozystack.") { + // Component node + n.Attr("shape", "box") + n.Attr("style", "rounded,filled") + n.Attr("fillcolor", "lightyellow") + n.Attr("label", strings.Split(node, ".")[len(strings.Split(node, "."))-1]) + } else { + // Package node + n.Attr("shape", "box") + n.Attr("style", "rounded,filled") + n.Attr("fillcolor", "lightblue") + label := node + if strings.HasPrefix(node, "cozystack.") { + label = strings.TrimPrefix(node, "cozystack.") + } + n.Attr("label", label) + } + } + + // Add edges + for source, targets := range graph { + if packagesOnly && strings.Contains(source, ".") && !strings.HasPrefix(source, "cozystack.") { + // Skip component edges when packages-only is enabled + continue + } + + for _, target := range targets { + if packagesOnly && strings.Contains(target, ".") && !strings.HasPrefix(target, "cozystack.") { + // Skip component edges when packages-only is enabled + continue + } + + // Only add edge if both nodes exist + if allNodes[source] && allNodes[target] { + g.Edge(g.Node(source), g.Node(target)) + } + } + } + + return g +} + +func writeDOT(g *dot.Graph, outputFile string) error { + file, err := os.Create(outputFile) + if err != nil { + return fmt.Errorf("failed to create output file: %w", err) + } + defer file.Close() + + g.Write(file) + + return nil +} + +func renderWithGraphviz(dotFile, outputFile, format string) error { + // Check if dot is available + dotPath, err := exec.LookPath("dot") + if err != nil { + return fmt.Errorf("graphviz 'dot' command not found. Install with: brew install graphviz\nGenerated DOT file: %s", dotFile) + } + + cmd := exec.Command(dotPath, "-T"+format, dotFile, "-o", outputFile) + if err := cmd.Run(); err != nil { + return fmt.Errorf("failed to render graph: %w\nGenerated DOT file: %s", err, dotFile) + } + + fmt.Fprintf(os.Stderr, "Generated %s\n", outputFile) + return nil +} + diff --git a/internal/operator/packagesource_reconciler.go b/internal/operator/packagesource_reconciler.go new file mode 100644 index 00000000..d0b5db85 --- /dev/null +++ b/internal/operator/packagesource_reconciler.go @@ -0,0 +1,468 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 operator + +import ( + "context" + "fmt" + "strings" + + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + sourcewatcherv1beta1 "github.com/fluxcd/source-watcher/api/v2/v1beta1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// PackageSourceReconciler reconciles PackageSource resources +type PackageSourceReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +// +kubebuilder:rbac:groups=cozystack.io,resources=packagesources,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=cozystack.io,resources=packagesources/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=source.extensions.fluxcd.io,resources=artifactgenerators,verbs=get;list;watch;create;update;patch;delete + +// Reconcile is part of the main kubernetes reconciliation loop +func (r *PackageSourceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + logger := log.FromContext(ctx) + + packageSource := &cozyv1alpha1.PackageSource{} + if err := r.Get(ctx, req.NamespacedName, packageSource); err != nil { + if apierrors.IsNotFound(err) { + // Resource not found, return (ownerReference will handle cleanup) + return ctrl.Result{}, nil + } + return ctrl.Result{}, err + } + + // Generate ArtifactGenerator for package source + if err := r.reconcileArtifactGenerators(ctx, packageSource); err != nil { + logger.Error(err, "failed to reconcile ArtifactGenerator") + return ctrl.Result{}, err + } + + // Update PackageSource status (variants and conditions from ArtifactGenerator) + if err := r.updateStatus(ctx, packageSource); err != nil { + logger.Error(err, "failed to update status") + // Don't return error, status update is not critical + } + + return ctrl.Result{}, nil +} + +// reconcileArtifactGenerators generates a single ArtifactGenerator for the package source +// Creates one ArtifactGenerator per package source with all OutputArtifacts from components +func (r *PackageSourceReconciler) reconcileArtifactGenerators(ctx context.Context, packageSource *cozyv1alpha1.PackageSource) error { + logger := log.FromContext(ctx) + + // Check if SourceRef is set + if packageSource.Spec.SourceRef == nil { + logger.Info("skipping ArtifactGenerator creation, SourceRef not set", "packageSource", packageSource.Name) + return nil + } + + // Build library map from all variants + // Map key is the library name (from lib.Name or extracted from path) + // This allows components to reference libraries by name + libraryMap := make(map[string]cozyv1alpha1.Library) + for _, variant := range packageSource.Spec.Variants { + for _, lib := range variant.Libraries { + libName := lib.Name + if libName == "" { + // If library name is not set, extract from path + libName = r.getPackageNameFromPath(lib.Path) + } + if libName != "" { + // Store library with the resolved name + libraryMap[libName] = lib + } + } + } + + // Namespace is always cozy-system + namespace := "cozy-system" + // ArtifactGenerator name is the package source name + agName := packageSource.Name + + // Collect all OutputArtifacts + outputArtifacts := []sourcewatcherv1beta1.OutputArtifact{} + + // Process all variants and their components + for _, variant := range packageSource.Spec.Variants { + for _, component := range variant.Components { + // Skip components without path + if component.Path == "" { + logger.V(1).Info("skipping component without path", "packageSource", packageSource.Name, "variant", variant.Name, "component", component.Name) + continue + } + + logger.V(1).Info("processing component", "packageSource", packageSource.Name, "variant", variant.Name, "component", component.Name, "path", component.Path) + + // Extract component name from path (last component) + componentPathName := r.getPackageNameFromPath(component.Path) + if componentPathName == "" { + logger.Info("skipping component with invalid path", "packageSource", packageSource.Name, "variant", variant.Name, "component", component.Name, "path", component.Path) + continue + } + + // Get basePath with default values + basePath := r.getBasePath(packageSource) + + // Build copy operations + copyOps := []sourcewatcherv1beta1.CopyOperation{ + { + From: r.buildSourcePath(packageSource.Spec.SourceRef.Name, basePath, component.Path), + To: fmt.Sprintf("@artifact/%s/", componentPathName), + }, + } + + // Add libraries if specified + for _, libName := range component.Libraries { + if lib, ok := libraryMap[libName]; ok { + copyOps = append(copyOps, sourcewatcherv1beta1.CopyOperation{ + From: r.buildSourcePath(packageSource.Spec.SourceRef.Name, basePath, lib.Path), + To: fmt.Sprintf("@artifact/%s/charts/%s/", componentPathName, libName), + }) + } + } + + // Add valuesFiles if specified + for i, valuesFile := range component.ValuesFiles { + strategy := "Merge" + if i == 0 { + strategy = "Overwrite" + } + copyOps = append(copyOps, sourcewatcherv1beta1.CopyOperation{ + From: r.buildSourceFilePath(packageSource.Spec.SourceRef.Name, basePath, fmt.Sprintf("%s/%s", component.Path, valuesFile)), + To: fmt.Sprintf("@artifact/%s/values.yaml", componentPathName), + Strategy: strategy, + }) + } + + // Artifact name: -- + // Replace dots with dashes to comply with Kubernetes naming requirements + artifactName := fmt.Sprintf("%s-%s-%s", + strings.ReplaceAll(packageSource.Name, ".", "-"), + strings.ReplaceAll(variant.Name, ".", "-"), + strings.ReplaceAll(component.Name, ".", "-")) + + outputArtifacts = append(outputArtifacts, sourcewatcherv1beta1.OutputArtifact{ + Name: artifactName, + Copy: copyOps, + }) + + logger.Info("added OutputArtifact for component", "packageSource", packageSource.Name, "variant", variant.Name, "component", component.Name, "artifactName", artifactName) + } + } + + // If there are no OutputArtifacts, return (ownerReference will handle cleanup if needed) + if len(outputArtifacts) == 0 { + logger.Info("no OutputArtifacts to generate, skipping ArtifactGenerator creation", "packageSource", packageSource.Name) + return nil + } + + // Build labels + labels := make(map[string]string) + labels["cozystack.io/packagesource"] = packageSource.Name + + // Create single ArtifactGenerator for the package source + ag := &sourcewatcherv1beta1.ArtifactGenerator{ + ObjectMeta: metav1.ObjectMeta{ + Name: agName, + Namespace: namespace, + Labels: labels, + }, + Spec: sourcewatcherv1beta1.ArtifactGeneratorSpec{ + Sources: []sourcewatcherv1beta1.SourceReference{ + { + Alias: packageSource.Spec.SourceRef.Name, + Kind: packageSource.Spec.SourceRef.Kind, + Name: packageSource.Spec.SourceRef.Name, + Namespace: packageSource.Spec.SourceRef.Namespace, + }, + }, + OutputArtifacts: outputArtifacts, + }, + } + + // Set ownerReference + ag.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: packageSource.APIVersion, + Kind: packageSource.Kind, + Name: packageSource.Name, + UID: packageSource.UID, + Controller: func() *bool { b := true; return &b }(), + }, + } + + logger.Info("creating ArtifactGenerator for package source", "packageSource", packageSource.Name, "agName", agName, "namespace", namespace, "outputArtifactCount", len(outputArtifacts)) + + if err := r.createOrUpdate(ctx, ag); err != nil { + return fmt.Errorf("failed to reconcile ArtifactGenerator %s: %w", agName, err) + } + + logger.Info("reconciled ArtifactGenerator for package source", "name", agName, "namespace", namespace, "outputArtifactCount", len(outputArtifacts)) + + return nil +} + +// Helper functions +func (r *PackageSourceReconciler) getPackageNameFromPath(path string) string { + parts := strings.Split(path, "/") + if len(parts) > 0 { + return parts[len(parts)-1] + } + return "" +} + +// getBasePath returns the basePath with default values based on source kind +func (r *PackageSourceReconciler) getBasePath(packageSource *cozyv1alpha1.PackageSource) string { + // If path is explicitly set in SourceRef, use it (but normalize "/" to empty) + if packageSource.Spec.SourceRef.Path != "" { + path := strings.Trim(packageSource.Spec.SourceRef.Path, "/") + // If path is "/" or empty after trim, return empty string + if path == "" { + return "" + } + return path + } + // Default values based on kind + if packageSource.Spec.SourceRef.Kind == "OCIRepository" { + return "" // Root for OCI + } + // Default for GitRepository + return "packages" +} + +// buildSourcePath builds the full source path using basePath with glob pattern +func (r *PackageSourceReconciler) buildSourcePath(sourceName, basePath, path string) string { + // Remove leading/trailing slashes and combine + parts := []string{} + if basePath != "" { + trimmed := strings.Trim(basePath, "/") + if trimmed != "" { + parts = append(parts, trimmed) + } + } + if path != "" { + trimmed := strings.Trim(path, "/") + if trimmed != "" { + parts = append(parts, trimmed) + } + } + + fullPath := strings.Join(parts, "/") + if fullPath == "" { + return fmt.Sprintf("@%s/**", sourceName) + } + return fmt.Sprintf("@%s/%s/**", sourceName, fullPath) +} + +// buildSourceFilePath builds the full source path for a specific file (without glob pattern) +func (r *PackageSourceReconciler) buildSourceFilePath(sourceName, basePath, path string) string { + // Remove leading/trailing slashes and combine + parts := []string{} + if basePath != "" { + trimmed := strings.Trim(basePath, "/") + if trimmed != "" { + parts = append(parts, trimmed) + } + } + if path != "" { + trimmed := strings.Trim(path, "/") + if trimmed != "" { + parts = append(parts, trimmed) + } + } + + fullPath := strings.Join(parts, "/") + if fullPath == "" { + return fmt.Sprintf("@%s", sourceName) + } + return fmt.Sprintf("@%s/%s", sourceName, fullPath) +} + +// createOrUpdate creates or updates a resource +func (r *PackageSourceReconciler) createOrUpdate(ctx context.Context, obj client.Object) error { + existing := obj.DeepCopyObject().(client.Object) + key := client.ObjectKeyFromObject(obj) + + err := r.Get(ctx, key, existing) + if apierrors.IsNotFound(err) { + return r.Create(ctx, obj) + } else if err != nil { + return err + } + + // Preserve resource version + obj.SetResourceVersion(existing.GetResourceVersion()) + // Merge labels and annotations + labels := obj.GetLabels() + if labels == nil { + labels = make(map[string]string) + } + for k, v := range existing.GetLabels() { + if _, ok := labels[k]; !ok { + labels[k] = v + } + } + obj.SetLabels(labels) + + annotations := obj.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + for k, v := range existing.GetAnnotations() { + if _, ok := annotations[k]; !ok { + annotations[k] = v + } + } + obj.SetAnnotations(annotations) + + // For ArtifactGenerator, explicitly update Spec (OutputArtifacts and Sources) + if ag, ok := obj.(*sourcewatcherv1beta1.ArtifactGenerator); ok { + if existingAG, ok := existing.(*sourcewatcherv1beta1.ArtifactGenerator); ok { + logger := log.FromContext(ctx) + logger.V(1).Info("updating ArtifactGenerator Spec", "name", ag.Name, "namespace", ag.Namespace, + "outputArtifactCount", len(ag.Spec.OutputArtifacts)) + // Update Spec from obj (which contains the desired state with all OutputArtifacts) + existingAG.Spec = ag.Spec + // Preserve metadata updates we made above + existingAG.SetLabels(ag.GetLabels()) + existingAG.SetAnnotations(ag.GetAnnotations()) + existingAG.SetOwnerReferences(ag.GetOwnerReferences()) + // Use existingAG for Update + obj = existingAG + } + } + + return r.Update(ctx, obj) +} + +// updateStatus updates PackageSource status (variants and conditions from ArtifactGenerator) +func (r *PackageSourceReconciler) updateStatus(ctx context.Context, packageSource *cozyv1alpha1.PackageSource) error { + logger := log.FromContext(ctx) + + // Update variants in status from spec + variantNames := make([]string, 0, len(packageSource.Spec.Variants)) + for _, variant := range packageSource.Spec.Variants { + variantNames = append(variantNames, variant.Name) + } + packageSource.Status.Variants = strings.Join(variantNames, ",") + + // Check if SourceRef is set + if packageSource.Spec.SourceRef == nil { + // Set status to unknown if SourceRef is not set + meta.SetStatusCondition(&packageSource.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionUnknown, + Reason: "SourceRefNotSet", + Message: "SourceRef is not configured", + }) + return r.Status().Update(ctx, packageSource) + } + + // Get ArtifactGenerator + ag := &sourcewatcherv1beta1.ArtifactGenerator{} + agKey := types.NamespacedName{ + Name: packageSource.Name, + Namespace: "cozy-system", + } + + if err := r.Get(ctx, agKey, ag); err != nil { + if apierrors.IsNotFound(err) { + // ArtifactGenerator not found, set status to unknown + meta.SetStatusCondition(&packageSource.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionUnknown, + Reason: "ArtifactGeneratorNotFound", + Message: "ArtifactGenerator not found", + }) + return r.Status().Update(ctx, packageSource) + } + return fmt.Errorf("failed to get ArtifactGenerator: %w", err) + } + + // Find Ready condition in ArtifactGenerator + readyCondition := meta.FindStatusCondition(ag.Status.Conditions, "Ready") + if readyCondition == nil { + // No Ready condition in ArtifactGenerator, set status to unknown + meta.SetStatusCondition(&packageSource.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionUnknown, + Reason: "ArtifactGeneratorNotReady", + Message: "ArtifactGenerator Ready condition not found", + }) + return r.Status().Update(ctx, packageSource) + } + + // Copy Ready condition from ArtifactGenerator to PackageSource + meta.SetStatusCondition(&packageSource.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: readyCondition.Status, + Reason: readyCondition.Reason, + Message: readyCondition.Message, + ObservedGeneration: packageSource.Generation, + LastTransitionTime: readyCondition.LastTransitionTime, + }) + + logger.V(1).Info("updated PackageSource status from ArtifactGenerator", + "packageSource", packageSource.Name, + "status", readyCondition.Status, + "reason", readyCondition.Reason) + + return r.Status().Update(ctx, packageSource) +} + +// SetupWithManager sets up the controller with the Manager. +func (r *PackageSourceReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + Named("cozystack-packagesource"). + For(&cozyv1alpha1.PackageSource{}). + Watches( + &sourcewatcherv1beta1.ArtifactGenerator{}, + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { + ag, ok := obj.(*sourcewatcherv1beta1.ArtifactGenerator) + if !ok { + return nil + } + // Find the PackageSource that owns this ArtifactGenerator by ownerReference + for _, ownerRef := range ag.OwnerReferences { + if ownerRef.Kind == "PackageSource" { + return []reconcile.Request{{ + NamespacedName: types.NamespacedName{ + Name: ownerRef.Name, + }, + }} + } + } + return nil + }), + ). + Complete(r) +} + diff --git a/packages/core/installer/templates/cozystack-operator.yaml b/packages/core/installer/templates/cozystack-operator.yaml index 19153827..4372bd4c 100644 --- a/packages/core/installer/templates/cozystack-operator.yaml +++ b/packages/core/installer/templates/cozystack-operator.yaml @@ -59,7 +59,7 @@ spec: {{- if .Values.cozystackOperator.disableTelemetry }} - --disable-telemetry {{- end }} - - --platform-name=cozystack-platform + - --platform-source-name=cozystack-packages - --platform-source={{ .Values.cozystackOperator.platformSource }} env: - name: KUBERNETES_SERVICE_HOST @@ -100,8 +100,8 @@ spec: releaseName: cozystack-platform name: cozystack-platform path: core/platform - valuesFiles: - - paas-full.yaml + #valuesFiles: + #- paas-full.yaml - name: paas-hosted components: - install: @@ -109,5 +109,5 @@ spec: releaseName: cozystack-platform name: cozystack-platform path: core/platform - valuesFiles: - - paas-hosted.yaml + #valuesFiles: + #- paas-hosted.yaml diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index 7c33fca4..13a3e1b4 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,6 +1,6 @@ cozystack: image: ghcr.io/cozystack/cozystack/installer:v0.38.2@sha256:9ff92b655de6f9bea3cba4cd42dcffabd9aace6966dcfb1cc02dda2420ea4a15 cozystackOperator: - image: ghcr.io/cozystack/cozystack/cozystack-operator:latest@sha256:873a52d9f69932a93f7fa99c3ccac418c80bab409ca3cba781492cba00276c84 - platformSource: 'oci://ghcr.io/cozystack/cozystack/platform-packages@sha256:3edff5f9feb4bd66e4b46df9e07e5db3eb6ead051edac74cbda3b222eb940a70' + image: ghcr.io/cozystack/cozystack/cozystack-operator:latest@sha256:63ff14a08eb20c16100e063b7387655c9f7ff239c50bc987b207e6e768a6725d + platformSource: 'oci://ghcr.io/cozystack/cozystack/platform-packages@sha256:bc1039d7d7dd4d204e03c35c38c1a68b34e38ca1b8f980258efeac8448ae5c77' cozystackVersion: latest diff --git a/packages/core/platform/psds/bootbox-application.yaml b/packages/core/platform/psds/bootbox-application.yaml index 8f8e8ae9..86f1fa6e 100644 --- a/packages/core/platform/psds/bootbox-application.yaml +++ b/packages/core/platform/psds/bootbox-application.yaml @@ -17,13 +17,13 @@ spec: - name: cozy-lib path: library/cozy-lib components: - - name: bootbox-application - path: system/bootbox-application + - name: bootbox + path: system/bootbox install: releaseName: bootbox-application namespace: cozy-system - - name: bootbox - path: apps/bootbox + - name: bootbox-app + path: extra/bootbox libraries: ["cozy-lib"] - name: bootbox-rd path: system/bootbox-rd diff --git a/packages/core/platform/psds/cozystack-engine.yaml b/packages/core/platform/psds/cozystack-engine.yaml index bd1bf76e..710b4350 100644 --- a/packages/core/platform/psds/cozystack-engine.yaml +++ b/packages/core/platform/psds/cozystack-engine.yaml @@ -4,6 +4,11 @@ kind: PackageSource metadata: name: cozystack.cozystack-engine spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / variants: - name: default dependsOn: diff --git a/packages/core/platform/psds/kubernetes-application.yaml b/packages/core/platform/psds/kubernetes-application.yaml index 719672bc..93e4d68b 100644 --- a/packages/core/platform/psds/kubernetes-application.yaml +++ b/packages/core/platform/psds/kubernetes-application.yaml @@ -10,7 +10,7 @@ spec: namespace: cozy-system path: / variants: - - name: default + - name: kubevirt dependsOn: - cozystack.networking - cozystack.capi-operator diff --git a/packages/core/platform/psds/networking.yaml b/packages/core/platform/psds/networking.yaml index 5518de0e..5a443e25 100644 --- a/packages/core/platform/psds/networking.yaml +++ b/packages/core/platform/psds/networking.yaml @@ -4,6 +4,11 @@ kind: PackageSource metadata: name: cozystack.networking spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / variants: - name: noop components: [] diff --git a/packages/system/bootbox-rd/Chart.yaml b/packages/system/bootbox-rd/Chart.yaml new file mode 100644 index 00000000..0a35867d --- /dev/null +++ b/packages/system/bootbox-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: bootbox-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/bootbox-rd/Makefile b/packages/system/bootbox-rd/Makefile new file mode 100644 index 00000000..b570a84f --- /dev/null +++ b/packages/system/bootbox-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=bootbox-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/bootbox-rd/cozyrds/bootbox.yaml b/packages/system/bootbox-rd/cozyrds/bootbox.yaml new file mode 100644 index 00000000..f47bf8f6 --- /dev/null +++ b/packages/system/bootbox-rd/cozyrds/bootbox.yaml @@ -0,0 +1,43 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: bootbox +spec: + application: + kind: BootBox + plural: bootboxes + singular: bootbox + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"machines":{"description":"Configuration of physical machine instances.","type":"array","default":[],"items":{"type":"object","required":["arch","hostname","ip","leaseTime","uefi"],"properties":{"arch":{"description":"Architecture.","type":"string"},"hostname":{"description":"Hostname.","type":"string"},"ip":{"description":"IP address configuration.","type":"object","required":["address","gateway","netmask"],"properties":{"address":{"description":"IP address.","type":"string"},"gateway":{"description":"IP gateway.","type":"string"},"netmask":{"description":"Netmask.","type":"string"}}},"leaseTime":{"description":"Lease time.","type":"integer"},"mac":{"description":"MAC addresses.","type":"array","items":{"type":"string"}},"nameServers":{"description":"Name servers.","type":"array","items":{"type":"string"}},"timeServers":{"description":"Time servers.","type":"array","items":{"type":"string"}},"uefi":{"description":"UEFI.","type":"boolean"}}}},"whitelist":{"description":"List of client networks.","type":"array","default":[],"items":{"type":"string"}},"whitelistHTTP":{"description":"Secure HTTP by enabling client networks whitelisting.","type":"boolean","default":true}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + chart: + name: bootbox + sourceRef: + kind: HelmRepository + name: cozystack-extra + namespace: cozy-public + dashboard: + category: Administration + singular: BootBox + plural: BootBox + name: bootbox + description: PXE hardware provisioning + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNzEuNTY5OCA3Ni41MzM2QzcxLjIzNzQgNzYuNTMzNiA3MC45MDM2IDc2LjQ4NDcgNzAuNTgyOSA3Ni4zODkyTDM2LjIwNzkgNjYuMDc2N0MzNC4zODg1IDY1LjUzMTEgMzMuMzU2MiA2My42MTQ0IDMzLjkwMTcgNjEuNzk2NkMzNC40NDg5IDU5Ljk3NTUgMzYuMzY1NyA1OC45NDgzIDM4LjE4MTcgNTkuNDkwNEw3MS41Njk4IDY5LjUwNzZMMTA0Ljk1OCA1OS40OTA0QzEwNi43NzYgNTguOTYgMTA4LjY5MSA1OS45NzcyIDEwOS4yMzggNjEuNzk2NkMxMDkuNzgzIDYzLjYxNDQgMTA4Ljc1MSA2NS41MzExIDEwNi45MzIgNjYuMDc2N0w3Mi41NTY3IDc2LjM4OTJDNzIuMjM2IDc2LjQ4NDcgNzEuOTAyMiA3Ni41MzM2IDcxLjU2OTggNzYuNTMzNloiIGZpbGw9IiMyMzFGMjAiLz4KPHBhdGggZD0iTTc0Ljk3MyA1My4wMjE0Qzc0Ljc2NjggNTQuMzI3NiA3My44MDQzIDU1LjM5MzMgNzIuNTY2OCA1NS43NzE0TDM4LjE5MTggNjYuMDgzOUMzNy44NDggNjYuMTg3IDM3LjUzODcgNjYuMjIxNCAzNy4xOTQ5IDY2LjIyMTRDMzYuMzY5OSA2Ni4yMjE0IDM1LjU3OTMgNjUuOTEyIDM0LjkyNjIgNjUuMzYyTDIxLjE3NjIgNTMuMzMwOEMyMC4yNDggNTIuNTQwMSAxOS44MzU1IDUxLjI2ODMgMjAuMDc2MiA1MC4wNjUxQzIwLjMxNjggNDguODYyIDIxLjE3NjIgNDcuODY1MSAyMi4zNDQ5IDQ3LjQ4N0w1My4yODI0IDM3LjE3NDVDNTQuMzEzNyAzNi44MzA4IDU1LjQ0OCAzNy4wMDI2IDU2LjM0MTggMzcuNjIxNEw3My41MjkzIDQ5LjY1MjZDNzQuNjI5MyA1MC40MDg5IDc1LjE3OTMgNTEuNzE1MSA3NC45NzMgNTMuMDIxNFoiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEyMS45NjQgNTMuMzMwOEwxMDguMjE0IDY1LjM2MkMxMDcuNTYgNjUuOTEyIDEwNi43NyA2Ni4yMjE0IDEwNS45NDUgNjYuMjIxNEMxMDUuNjAxIDY2LjIyMTQgMTA1LjI5MiA2Ni4xODcgMTA0Ljk0OCA2Ni4wODM5TDcwLjU3MyA1NS43NzE0QzY5LjMzNTUgNTUuMzkzMyA2OC4zNzMgNTQuMzI3NiA2OC4xNjY3IDUzLjAyMTRDNjcuOTYwNSA1MS43MTUxIDY4LjUxMDUgNTAuNDA4OSA2OS42MTA1IDQ5LjY1MjZMODYuNzk4IDM3LjYyMTRDODcuNjkxNyAzNy4wMDI2IDg4LjgyNjEgMzYuODMwOCA4OS44NTc0IDM3LjE3NDVMMTIwLjc5NSA0Ny40ODdDMTIxLjk2NCA0Ny44NjUxIDEyMi44MjMgNDguODYyIDEyMy4wNjQgNTAuMDY1MUMxMjMuMzA0IDUxLjI2ODMgMTIyLjg5MiA1Mi41NDAxIDEyMS45NjQgNTMuMzMwOFoiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEwOS4zODIgNjMuNjQyNlYxMDcuNDcxQzEwOS4zODIgMTA4Ljg4IDEwOC41MjIgMTEwLjE1MiAxMDcuMjE2IDExMC42NjhMNzIuODQxMiAxMjQuNDE4QzcyLjQyODcgMTI0LjU4OSA3Mi4wMTYyIDEyNC42NTggNzEuNTY5MyAxMjQuNjU4QzcxLjEyMjUgMTI0LjY1OCA3MC43MSAxMjQuNTg5IDcwLjI5NzUgMTI0LjQxOEwzNS45MjI1IDExMC42NjhDMzQuNjE2MiAxMTAuMTUyIDMzLjc1NjggMTA4Ljg4IDMzLjc1NjggMTA3LjQ3MVY2My42NDI2QzMzLjc1NjggNjEuNzUyIDM1LjMwMzcgNjAuMjA1MSAzNy4xOTQzIDYwLjIwNTFIMTA1Ljk0NEMxMDcuODM1IDYwLjIwNTEgMTA5LjM4MiA2MS43NTIgMTA5LjM4MiA2My42NDI2WiIgZmlsbD0iI0VBQkQ0QyIvPgo8cGF0aCBkPSJNMTA3Ljk5OSA2MS40OTU4QzEwNy45OTkgNjIuOTgxMiAxMDcuMDM3IDY0LjI5NzkgMTA1LjY0MyA2NC43MzY4TDcyLjQ2MTMgNzQuODY1QzcyLjEyOTUgNzQuOTY2MiA3MS44MzA4IDc1IDcxLjQ5OSA3NUM3MS4xNjcyIDc1IDcwLjg2ODYgNzQuOTY2MiA3MC41MzY4IDc0Ljg2NUwzNy4zNTQ5IDY0LjczNjhDMzUuOTYxMyA2NC4yOTc5IDM0Ljk5OSA2Mi45ODEyIDM0Ljk5OSA2MS40OTU4QzM0Ljk5OSA2MC4wMTAzIDM1Ljk2MTMgNTguNjkzNyAzNy4zNTQ5IDU4LjI1NDhMNzAuNTM2OCA0OC4xMjY2QzcxLjE2NzIgNDcuOTU3OCA3MS44MzA4IDQ3Ljk1NzggNzIuNDYxMyA0OC4xMjY2TDEwNS42NDMgNTguMjU0OEMxMDcuMDM3IDU4LjY5MzcgMTA3Ljk5OSA2MC4wMTAzIDEwNy45OTkgNjEuNDk1OFoiIGZpbGw9IiM0QzM4MjUiLz4KPHBhdGggZD0iTTc0LjUxMTggNzdDNzUuMzUgNzcgNzYuMTc5NCA3Ni45NjI4IDc3IDc2LjkxMzNWMjEuMDg2N0M3Ni4xNzY1IDIxLjAzNDcgNzUuMzQ3MSAyMSA3NC41MDU5IDIxQzczLjY2NDcgMjEgNzIuODI5NCAyMS4wMzQ3IDcyIDIxLjA4NjdWNzYuOTEwOEM3Mi44MjY1IDc2Ljk2MjggNzMuNjU4OCA3Ni45OTc1IDc0LjUgNzdINzQuNTExOFoiIGZpbGw9InVybCgjcGFpbnQxX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNDQuMDI4MiAzOC4xMTI5TDQzLjIwNzggMzcuMjk1OUM0Mi4wNzczIDM4LjkxMjEgNDEuMDc0NiA0MC42MTQgNDAuMjA4OCA0Mi4zODYxQzUwLjEwMDEgNTIuNDM1NCA1MS4xNDI0IDU3LjI4MzUgNTEuMTI4OSA1OC45MDc0QzUxLjA5MTkgNjMuMDI2IDQ2LjA1MjIgNjkuNDg0NSA0MC4xNDE2IDc1LjQ2NTdDNDAuOTk5NiA3Ny4yMzc1IDQxLjk5MzMgNzguOTQwNSA0My4xMTM3IDgwLjU1OTJDNDMuNDQ5OSA4MC4yMjMgNDMuNzY5MyA3OS45MTM3IDQ0LjA5NTQgNzkuNTg0MkM1Mi42MjUgNzAuOTk3NSA1Ni43OTQgNjQuMjQ5OCA1Ni44NDQ1IDU4Ljk0NzdDNTYuODk0OSA1My42NDU3IDUyLjcwMjQgNDYuODg3OSA0NC4wMjgyIDM4LjExMjlaIiBmaWxsPSJ1cmwoI3BhaW50Ml9saW5lYXJfOTc5Xzc5MikiLz4KPHBhdGggZD0iTTEwNC42OTUgNzkuNTk3NUwxMDUuNjc2IDgwLjU3MjVDMTA2Ljc5NSA3OC45NDkyIDEwNy43ODcgNzcuMjQxNyAxMDguNjQyIDc1LjQ2NTVDMTAyLjczNSA2OS40NzA5IDk3LjY5NDggNjIuOTk1NSA5Ny42NTQ1IDU4Ljg5MzdDOTcuNjE3NSA1NC44OTI4IDEwMi42MjcgNDguNDIwOCAxMDguNTY4IDQyLjM1OUMxMDcuNzAzIDQwLjU5MTcgMTA2LjcwMyAzOC44OTQ0IDEwNS41NzYgMzcuMjgyMkwxMDQuNzU1IDM4LjA5OTJDOTYuMDgxIDQ2Ljg1NzUgOTEuODg4NSA1My42NzkxIDkxLjkzODkgNTguOTQ0MkM5MS45ODk0IDY0LjIwOTIgOTYuMTU4MyA3MS4wMTA3IDEwNC42OTUgNzkuNTk3NVoiIGZpbGw9InVybCgjcGFpbnQzX2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNODcuNDM5NiA1OC45MzQ0Qzg3LjQzOTYgNTEuNTM3OCA5MC43Mzc4IDM5LjIzOTMgOTUuODE3OSAyNy42MTY1Qzk0LjE5NzkgMjYuNTEzOSA5Mi40OTUgMjUuNTM4MiA5MC43MjQ0IDI0LjY5ODJDODUuMTYzNSAzNy4yMjg3IDgxLjcyMDcgNTAuNTU2MSA4MS43MjA3IDU4Ljk0NzhDODEuNzIwNyA2Ny4wNjczIDg1LjQ0OTMgODAuNTQyNSA5MS4xMTEgOTMuMTQwM0M5Mi44NDY4IDkyLjI4NTkgOTQuNTE0NyA5MS4zMDAyIDk2LjEwMDQgOTAuMTkxN0M5MC44NTg5IDc4LjQwMDkgODcuNDM5NiA2Ni4wNzU1IDg3LjQzOTYgNTguOTM0NFoiIGZpbGw9InVybCgjcGFpbnQ0X2xpbmVhcl85NzlfNzkyKSIvPgo8cGF0aCBkPSJNNjcuMDM4NCA1OC45MzUzQzY3LjAzODQgNTAuNDk5OCA2My40NTc4IDM3LjA5ODUgNTcuOTYwOCAyNC43MjI3QzU2LjIxNTggMjUuNTYxMyA1NC41Mzc3IDI2LjUzMjUgNTIuOTQxMiAyNy42Mjc1QzU4LjAzMTQgMzkuMjQzNSA2MS4zMjI4IDUxLjU0NTQgNjEuMzIyOCA1OC45MzUzQzYxLjMyMjggNjYuMDczIDU3LjkwMzYgNzguMzk1IDUyLjY2MjEgOTAuMTcyNEM1NC4yNDgyIDkxLjI4MDIgNTUuOTE2MSA5Mi4yNjU4IDU3LjY1MTQgOTMuMTIxQzYzLjMxOTkgODAuNTI2NiA2Ny4wMzg0IDY3LjA2MTQgNjcuMDM4NCA1OC45MzUzWiIgZmlsbD0idXJsKCNwYWludDVfbGluZWFyXzk3OV83OTIpIi8+CjxwYXRoIGQ9Ik03NC40MjI5IDc0Ljk4N0w2MC42NzI5IDk1LjYxMkM2MC4wMTk3IDk2LjYwODkgNTguOTU0MSA5Ny4xNTg5IDU3LjgxOTcgOTcuMTU4OUM1Ny40MDcyIDk3LjE1ODkgNTYuOTYwNCA5Ny4wOTAxIDU2LjU0NzkgOTYuOTE4M0wyMi4xNzI5IDgzLjE2ODNDMjEuMTQxNiA4Mi43NTU4IDIwLjM4NTQgODEuODk2NCAyMC4xMTA0IDgwLjg2NTFDMTkuODM1NCA3OS43OTk1IDIwLjA3NiA3OC42NjUxIDIwLjc2MzUgNzcuODQwMUwzNC41MTM1IDYwLjY1MjZDMzUuMzcyOSA1OS41NTI2IDMyLjczOTEgNTcuODQwNCAzNC4wNzk3IDU4LjIxODVMNzIuNTY2NiA2OS43OTY0QzczLjU5NzkgNzAuMTA1OCA3NC40MjI5IDcwLjg5NjQgNzQuODAxIDcxLjkyNzZDNzUuMTc5MSA3Mi45NTg5IDc1LjA0MTYgNzQuMDkzMyA3NC40MjI5IDc0Ljk4N1oiIGZpbGw9IiNGRkRDODMiLz4KPHBhdGggZD0iTTEyMy4wMjkgODAuNjI0MkMxMjIuNzU0IDgxLjY1NTUgMTIxLjk5OCA4Mi41NDkyIDEyMS4wMDEgODIuOTI3NEw4Ni42MjYxIDk2LjkxOEM4Ni4xNzkyIDk3LjA4OTkgODUuNzY2NyA5Ny4xNTg2IDg1LjMxOTkgOTcuMTU4NkM4NC4xODU1IDk3LjE1ODYgODMuMTE5OSA5Ni42MDg2IDgyLjQ2NjcgOTUuNjExN0w2OC43MTY3IDc0Ljk4NjdDNjguMDk4IDc0LjA5MyA2Ny45NjA1IDcyLjk1ODYgNjguMzM4NiA3MS45Mjc0QzY4LjcxNjcgNzAuODk2MSA2OS41NDE3IDcwLjEwNTUgNzAuNTczIDY5Ljc5NjFMMTA4LjQ2OSA1OC40MzMxQzEwOS44MSA1OC4wMjA2IDEwNy43MzIgNTkuNTUyNCAxMDguNjI2IDYwLjYxOEwxMjIuMzc2IDc3LjU5OTJDMTIzLjA2NCA3OC40MjQyIDEyMy4zMDQgNzkuNTU4NiAxMjMuMDI5IDgwLjYyNDJaIiBmaWxsPSIjRkZEQzgzIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfOTc5Xzc5MiIgeDE9IjI0IiB5MT0iMy41IiB4Mj0iMTgxIiB5Mj0iMTQ3IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM0ODAwMDAiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjQUUyMzAwIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQxX2xpbmVhcl85NzlfNzkyIiB4MT0iNzQuNSIgeTE9IjE3LjIzNjkiIHgyPSI3NC41IiB5Mj0iNzkuOTEzMyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDJfbGluZWFyXzk3OV83OTIiIHgxPSI0OC40OTMiIHkxPSIxNS44OTI4IiB4Mj0iNDguNDkzIiB5Mj0iMTAwLjk1NCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDNfbGluZWFyXzk3OV83OTIiIHgxPSIxMDAuMjkiIHkxPSIxNS44OTI2IiB4Mj0iMTAwLjI5IiB5Mj0iMTAwLjk1MyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkZEMjAwIi8+CjxzdG9wIG9mZnNldD0iMC4wNiIgc3RvcC1jb2xvcj0iI0ZGQjUwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMTQiIHN0b3AtY29sb3I9IiNGRjhDMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjIxIiBzdG9wLWNvbG9yPSIjRkY3MzAwIi8+CjxzdG9wIG9mZnNldD0iMC4yNiIgc3RvcC1jb2xvcj0iI0ZGNkEwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMzMiIHN0b3AtY29sb3I9IiNGQzRGMEUiLz4KPHN0b3Agb2Zmc2V0PSIwLjQzIiBzdG9wLWNvbG9yPSIjRjkyRjFFIi8+CjxzdG9wIG9mZnNldD0iMC41MSIgc3RvcC1jb2xvcj0iI0Y4MUIyNyIvPgo8c3RvcCBvZmZzZXQ9IjAuNTciIHN0b3AtY29sb3I9IiNGNzE0MkIiLz4KPHN0b3Agb2Zmc2V0PSIwLjY4IiBzdG9wLWNvbG9yPSIjREYxNjJFIi8+CjxzdG9wIG9mZnNldD0iMC43OSIgc3RvcC1jb2xvcj0iI0FGMUEzOCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM0QjIxNEMiLz4KPC9saW5lYXJHcmFkaWVudD4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDRfbGluZWFyXzk3OV83OTIiIHgxPSI4OC45MTIyIiB5MT0iMTUuODkyOSIgeDI9Ijg4LjkxMjIiIHkyPSIxMDAuOTU0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkQyMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjA2IiBzdG9wLWNvbG9yPSIjRkZCNTAwIi8+CjxzdG9wIG9mZnNldD0iMC4xNCIgc3RvcC1jb2xvcj0iI0ZGOEMwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMjEiIHN0b3AtY29sb3I9IiNGRjczMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjI2IiBzdG9wLWNvbG9yPSIjRkY2QTAwIi8+CjxzdG9wIG9mZnNldD0iMC4zMyIgc3RvcC1jb2xvcj0iI0ZDNEYwRSIvPgo8c3RvcCBvZmZzZXQ9IjAuNDMiIHN0b3AtY29sb3I9IiNGOTJGMUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUxIiBzdG9wLWNvbG9yPSIjRjgxQjI3Ii8+CjxzdG9wIG9mZnNldD0iMC41NyIgc3RvcC1jb2xvcj0iI0Y3MTQyQiIvPgo8c3RvcCBvZmZzZXQ9IjAuNjgiIHN0b3AtY29sb3I9IiNERjE2MkUiLz4KPHN0b3Agb2Zmc2V0PSIwLjc5IiBzdG9wLWNvbG9yPSIjQUYxQTM4Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzRCMjE0QyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50NV9saW5lYXJfOTc5Xzc5MiIgeDE9IjU5Ljg1NyIgeTE9IjE1Ljg5MzgiIHgyPSI1OS44NTciIHkyPSIxMDAuOTU1IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkQyMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjA2IiBzdG9wLWNvbG9yPSIjRkZCNTAwIi8+CjxzdG9wIG9mZnNldD0iMC4xNCIgc3RvcC1jb2xvcj0iI0ZGOEMwMCIvPgo8c3RvcCBvZmZzZXQ9IjAuMjEiIHN0b3AtY29sb3I9IiNGRjczMDAiLz4KPHN0b3Agb2Zmc2V0PSIwLjI2IiBzdG9wLWNvbG9yPSIjRkY2QTAwIi8+CjxzdG9wIG9mZnNldD0iMC4zMyIgc3RvcC1jb2xvcj0iI0ZDNEYwRSIvPgo8c3RvcCBvZmZzZXQ9IjAuNDMiIHN0b3AtY29sb3I9IiNGOTJGMUUiLz4KPHN0b3Agb2Zmc2V0PSIwLjUxIiBzdG9wLWNvbG9yPSIjRjgxQjI3Ii8+CjxzdG9wIG9mZnNldD0iMC41NyIgc3RvcC1jb2xvcj0iI0Y3MTQyQiIvPgo8c3RvcCBvZmZzZXQ9IjAuNjgiIHN0b3AtY29sb3I9IiNERjE2MkUiLz4KPHN0b3Agb2Zmc2V0PSIwLjc5IiBzdG9wLWNvbG9yPSIjQUYxQTM4Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzRCMjE0QyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "whitelistHTTP"], ["spec", "whitelist"], ["spec", "machines"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - bootbox + ingresses: + exclude: [] + include: + - resourceNames: + - bootbox diff --git a/packages/system/bootbox-rd/templates/cozyrd.yaml b/packages/system/bootbox-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/bootbox-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/bootbox-rd/values.yaml b/packages/system/bootbox-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/bootbox-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/bucket-rd/Chart.yaml b/packages/system/bucket-rd/Chart.yaml new file mode 100644 index 00000000..352a949c --- /dev/null +++ b/packages/system/bucket-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: bucket-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/bucket-rd/Makefile b/packages/system/bucket-rd/Makefile new file mode 100644 index 00000000..53e89367 --- /dev/null +++ b/packages/system/bucket-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=bucket-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/bucket-rd/cozyrds/bucket.yaml b/packages/system/bucket-rd/cozyrds/bucket.yaml new file mode 100644 index 00000000..889a36b5 --- /dev/null +++ b/packages/system/bucket-rd/cozyrds/bucket.yaml @@ -0,0 +1,42 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: bucket +spec: + application: + kind: Bucket + plural: buckets + singular: bucket + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{}} + release: + prefix: bucket- + labels: + cozystack.io/ui: "true" + chart: + name: bucket + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + singular: Bucket + plural: Buckets + category: IaaS + weight: 80 + description: S3 compatible storage + tags: + - storage + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzA5MSkiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03MiAzMC4xNjQxTDExNy45ODMgMzYuNzc4OVY0MC42NzM5QzExNy45ODMgNDYuNDY1MyA5Ny4zODYyIDUxLjEzMzIgNzEuOTgyNyA1MS4xMzMyQzQ2LjU3OTIgNTEuMTMzMiAyNiA0Ni40NjUzIDI2IDQwLjY3MzlWMzYuNDQzMUw3MiAzMC4xNjQxWk03MiA1OC4yNjc4QzkxLjIwODQgNTguMjY3OCAxMDcuNjU4IDU1LjU5ODYgMTE0LjU0NyA1MS44MDQ4TDExNi44MDMgNDguMTExTDExNy43MjMgNDQuNzUzVjQ4LjkxNzFMMTAyLjY3OSAxMTEuMDMzQzEwMi42NzkgMTE0Ljg5NSA4OC45NTMzIDExOCA3Mi4wMTcyIDExOEM1NS4wODEyIDExOCA0MS4zNzQzIDExNC44OTUgNDEuMzc0MyAxMTEuMDMzTDI2LjMzIDQ4LjkxNzFWNDQuODM2OUwyOS44MDA3IDUxLjkzODJDMzYuNzA2NSA1NS42NjUzIDUyLjk5OTcgNTguMjY3OCA3MiA1OC4yNjc4WiIgZmlsbD0iIzhDMzEyMyIvPgo8cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTcyLjAwMDMgMjZDOTcuNDAzOCAyNiAxMTggMzAuNjgzOSAxMTggMzYuNDQyQzExOCA0Mi4yIDk3LjM4NjYgNDYuODUwNyA3Mi4wMDAzIDQ2Ljg1MDdDNDYuNjE0MSA0Ni44NTA3IDI2LjAxNzYgNDIuMjM0NSAyNi4wMTc2IDM2LjQ0MkMyNi4wMTc2IDMwLjY0OTQgNDYuNTk2OCAyNiA3Mi4wMDAzIDI2Wk03Mi4wMDAzIDU0LjEwMzdDOTUuNjg1NyA1NC4xMDM3IDExNS4xNzIgNTAuMDU4IDExNy43MDYgNDQuODE5N0wxMDIuNjYyIDEwNi45MzdDMTAyLjY2MiAxMTAuNzk5IDg4LjkzNjQgMTEzLjkwNSA3Mi4wMDAzIDExMy45MDVDNTUuMDY0MyAxMTMuOTA1IDQxLjMzOSAxMTAuODE2IDQxLjMzOSAxMDYuOTU0TDI2LjI5NTkgNDQuODM3QzI4Ljg0NjYgNTAuMDU4IDQ4LjMzMzMgNTQuMTAzNyA3Mi4wMDAzIDU0LjEwMzdaIiBmaWxsPSIjRTA1MjQzIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNjEuMTcyNSA2MC4wMjkzSDgxLjA5MjhWNzkuMTY3Nkg2MS4xNzI1VjYwLjAyOTNaTTQ1LjMzMDEgOTUuMzY4OEM0NS4zMzAxIDkwLjE0MiA0OS43MTA0IDg1LjkzNDIgNTUuMTUxMSA4NS45MzQyQzYwLjU5MTcgODUuOTM0MiA2NC45NzIxIDkwLjE0MiA2NC45NzIxIDk1LjM2ODhDNjQuOTcyMSAxMDAuNTk2IDYwLjU5MTcgMTA0LjgwMyA1NS4xNTExIDEwNC44MDNDNDkuNzEwNCAxMDQuODAzIDQ1LjMzMDEgMTAwLjU5NiA0NS4zMzAxIDk1LjM2ODhaTTk2LjQ0ODcgMTA0LjM2OEg3Ni43NzIyTDg2LjYxMDUgODYuNzczN0w5Ni40NDg3IDEwNC4zNjhaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18zMDkxIiB4MT0iMCIgeTE9IjAiIHgyPSIxNTEiIHkyPSIxODAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0ZGRjBFRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNFQzg4N0QiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"]] + secrets: + exclude: [] + include: + - resourceNames: + - bucket-{{ .name }} + - bucket-{{ .name }}-credentials + ingresses: + exclude: [] + include: + - resourceNames: + - bucket-{{ .name }}-ui diff --git a/packages/system/bucket-rd/templates/cozyrd.yaml b/packages/system/bucket-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/bucket-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/bucket-rd/values.yaml b/packages/system/bucket-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/bucket-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/clickhouse-rd/Chart.yaml b/packages/system/clickhouse-rd/Chart.yaml new file mode 100644 index 00000000..583d39a6 --- /dev/null +++ b/packages/system/clickhouse-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: clickhouse-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/clickhouse-rd/Makefile b/packages/system/clickhouse-rd/Makefile new file mode 100644 index 00000000..4ac0738a --- /dev/null +++ b/packages/system/clickhouse-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=clickhouse-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/clickhouse-rd/cozyrds/clickhouse.yaml b/packages/system/clickhouse-rd/cozyrds/clickhouse.yaml new file mode 100644 index 00000000..6948fce0 --- /dev/null +++ b/packages/system/clickhouse-rd/cozyrds/clickhouse.yaml @@ -0,0 +1,39 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: clickhouse +spec: + application: + kind: ClickHouse + singular: clickhouse + plural: clickhouses + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["cleanupStrategy","enabled","resticPassword","s3AccessKey","s3Bucket","s3Region","s3SecretKey","schedule"],"properties":{"cleanupStrategy":{"description":"Retention strategy for cleaning up old backups.","type":"string","default":"--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"resticPassword":{"description":"Password for Restic backup encryption.","type":"string","default":""},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3Bucket":{"description":"S3 bucket used for storing backups.","type":"string","default":"s3.example.org/clickhouse-backups"},"s3Region":{"description":"AWS S3 region where backups are stored.","type":"string","default":"us-east-1"},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * *"}}},"clickhouseKeeper":{"description":"ClickHouse Keeper configuration.","type":"object","default":{},"properties":{"enabled":{"description":"Deploy ClickHouse Keeper for cluster coordination.","type":"boolean","default":true},"replicas":{"description":"Number of Keeper replicas.","type":"integer","default":3},"resourcesPreset":{"description":"Default sizing preset.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"logStorageSize":{"description":"Size of Persistent Volume for logs.","default":"2Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"logTTL":{"description":"TTL (expiration time) for `query_log` and `query_thread_log`.","type":"integer","default":15},"replicas":{"description":"Number of ClickHouse replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each ClickHouse replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"shards":{"description":"Number of ClickHouse shards.","type":"integer","default":1},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"},"readonly":{"description":"User is readonly (default: false).","type":"boolean"}}}}}} + release: + prefix: clickhouse- + labels: + cozystack.io/ui: "true" + chart: + name: clickhouse + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: ClickHouse + plural: ClickHouse + description: Managed ClickHouse service + tags: [] + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzIwMikiLz4KPHBhdGggZD0iTTIzIDEwNUgzNFYxMTZIMjNWMTA1WiIgZmlsbD0iI0ZGMDAwMCIvPgo8cGF0aCBkPSJNMjMgMjhIMzRWMTA1SDIzVjI4Wk00NSAyOEg1NS45OTk5VjExNkg0NVYyOFpNNjYuOTk5OSAyOEg3Ny45OTk5VjExNkg2Ni45OTk5VjI4Wk04OC45OTk5IDI4SDk5Ljk5OTlWMTE2SDg4Ljk5OTlWMjhaTTExMSA2My43NDk5SDEyMlY4MC4yNDk5SDExMVY2My43NDk5WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMzIwMiIgeDE9Ii0wLjQ5OTk5OCIgeTE9IjEuNSIgeDI9IjE1My41IiB5Mj0iMTYyIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNGRkNDMDAiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjRkY3QTAwIi8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "shards"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "logStorageSize"], ["spec", "logTTL"], ["spec", "users"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "s3Region"], ["spec", "backup", "s3Bucket"], ["spec", "backup", "schedule"], ["spec", "backup", "cleanupStrategy"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "backup", "resticPassword"], ["spec", "clickhouseKeeper"], ["spec", "clickhouseKeeper", "enabled"], ["spec", "clickhouseKeeper", "size"], ["spec", "clickhouseKeeper", "resourcesPreset"], ["spec", "clickhouseKeeper", "replicas"]] + secrets: + exclude: [] + include: + - resourceNames: + - clickhouse-{{ .name }}-credentials + services: + exclude: [] + include: + - resourceNames: + - chendpoint-clickhouse-{{ .name }} diff --git a/packages/system/clickhouse-rd/templates/cozyrd.yaml b/packages/system/clickhouse-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/clickhouse-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/clickhouse-rd/values.yaml b/packages/system/clickhouse-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/clickhouse-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/etcd-rd/Chart.yaml b/packages/system/etcd-rd/Chart.yaml new file mode 100644 index 00000000..8aa00f9b --- /dev/null +++ b/packages/system/etcd-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: etcd-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/etcd-rd/Makefile b/packages/system/etcd-rd/Makefile new file mode 100644 index 00000000..ad91bad9 --- /dev/null +++ b/packages/system/etcd-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=etcd-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/etcd-rd/cozyrds/etcd.yaml b/packages/system/etcd-rd/cozyrds/etcd.yaml new file mode 100644 index 00000000..7381469d --- /dev/null +++ b/packages/system/etcd-rd/cozyrds/etcd.yaml @@ -0,0 +1,39 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: etcd +spec: + application: + kind: Etcd + plural: etcds + singular: etcd + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"replicas":{"description":"Number of etcd replicas.","type":"integer","default":3},"resources":{"description":"Resource configuration for etcd.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","default":"1000m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","default":"512Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"size":{"description":"Persistent Volume size.","default":"4Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + chart: + name: etcd + sourceRef: + kind: HelmRepository + name: cozystack-extra + namespace: cozy-public + dashboard: + category: Administration + singular: Etcd + plural: Etcd + name: etcd + description: Storage for Kubernetes clusters + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NjMpIi8+CjxwYXRoIGQ9Ik0xMjIuNDQyIDczLjQ3MjlDMTIxLjk1OSA3My41MTM0IDEyMS40NzQgNzMuNTMyMiAxMjAuOTU4IDczLjUzMjJDMTE3Ljk2NSA3My41MzIyIDExNS4wNjEgNzIuODMwNCAxMTIuNDQyIDcxLjU0NTFDMTEzLjMxNCA2Ni41NDIxIDExMy42ODUgNjEuNTAxOSAxMTMuNTg4IDU2LjQ4MDJDMTEwLjc0OCA1Mi4zNzIzIDEwNy41MDIgNDguNDk2NSAxMDMuODM4IDQ0LjkyNTdDMTA1LjQyOCA0MS45NDU0IDEwNy43NzggMzkuMzgxMSAxMTAuNzExIDM3LjU2MjhMMTExLjk3MSAzNi43ODQyTDExMC45ODkgMzUuNjc3NEMxMDUuOTMyIDI5Ljk4MzIgOTkuODk3MSAyNS41ODA5IDkzLjA1NDcgMjIuNTkzN0w5MS42OTAyIDIyTDkxLjM0MzcgMjMuNDQyM0M5MC41Mjc3IDI2LjgwMzYgODguODIyMiAyOS44MzYgODYuNDgwNyAzMi4yNjk1QzgxLjk4MDMgMjkuODc3NCA3Ny4yNzg4IDI3Ljk0NCA3Mi40MzA1IDI2LjQ3OTdDNjcuNTkzNyAyNy45NDA4IDYyLjkwMDUgMjkuODY4NiA1OC40MDIgMzIuMjU3MUM1Ni4wNzAxIDI5LjgyNjggNTQuMzY4OCAyNi44MDE4IDUzLjU1NiAyMy40NTAxTDUzLjIwNzIgMjIuMDA4M0w1MS44NDc3IDIyLjU5OTJDNDUuMDkxNCAyNS41NDMxIDM4Ljg5MDEgMzAuMDY0NyAzMy45MTYyIDM1LjY3NDJMMzIuOTMxOCAzNi43ODMzTDM0LjE5IDM3LjU2MTlDMzcuMTE0MiAzOS4zNzMzIDM5LjQ1NzYgNDEuOTIyNCA0MS4wNDQ0IDQ0Ljg4NjZDMzcuMzkxNyA0OC40NDM1IDM0LjE0OTUgNTIuMzA3IDMxLjMxMTkgNTYuMzk1OUMzMS4yMDE0IDYxLjQxNTQgMzEuNTUzNSA2Ni40OTI0IDMyLjQyOTcgNzEuNTY0NEMyOS44MjMxIDcyLjgzNzggMjYuOTM1OCA3My41MzE4IDIzLjk2MjggNzMuNTMxOEMyMy40NDA5IDczLjUzMTggMjIuOTUyNyA3My41MTI5IDIyLjQ3ODIgNzMuNDczM0wyMSA3My4zNjA2TDIxLjEzODUgNzQuODM2NUMyMS44NjI5IDgyLjMwMzMgMjQuMTgxNCA4OS40MDUzIDI4LjAzMzQgOTUuOTQ3MUwyOC43ODUzIDk3LjIyMzdMMjkuOTE0MiA5Ni4yNjU2QzMyLjUzMDUgOTQuMDQ2NSAzNS42OTE3IDkyLjU3NyAzOS4wNTMgOTEuOTg0N0M0MS4yNjg5IDk2LjUxNTUgNDMuODk1MyAxMDAuNzcyIDQ2Ljg3NDcgMTA0LjcyNUM1MS42Mjg3IDEwNi4zODcgNTYuNTgxOSAxMDcuNjI5IDYxLjY5NzEgMTA4LjM2N0M2Mi4xODc3IDExMS43NSA2MS43OTcgMTE1LjI0OSA2MC40NjI0IDExOC40ODRMNTkuODk5NSAxMTkuODU1TDYxLjM0NjkgMTIwLjE3NEM2NS4wNTI5IDEyMC45ODkgNjguNzkxNyAxMjEuNDA0IDcyLjQ1MjYgMTIxLjQwNEw4My41NTUxIDEyMC4xNzRMODUuMDAzOSAxMTkuODU1TDg0LjQzOTcgMTE4LjQ4MkM4My4xMDg3IDExNS4yNDYgODIuNzE4IDExMS43NDMgODMuMjA4NiAxMDguMzZDODguMzAzNiAxMDcuNjIxIDkzLjIzODQgMTA2LjM4MiA5Ny45NzQ4IDEwNC43MjVDMTAwLjk1NyAxMDAuNzY5IDEwMy41ODYgOTYuNTA5NSAxMDUuODA1IDkxLjk3MjhDMTA5LjE3NyA5Mi41NjE0IDExMi4zNTYgOTQuMDMxNyAxMTQuOTg5IDk2LjI1NzNMMTE2LjExOCA5Ny4yMTQxTDExNi44NjYgOTUuOTQwN0MxMjAuNzI1IDg5LjM5MDUgMTIzLjA0MyA4Mi4yODkxIDEyMy43NTYgNzQuODM0MkwxMjMuODk1IDczLjM2MUwxMjIuNDQyIDczLjQ3MjlaTTg4LjMxOTcgOTEuNTE4MUM4My4wNjczIDkyLjk0NjYgNzcuNzMzIDkzLjY2NzcgNzIuNDMwNSA5My42Njc3QzY3LjExMzcgOTMuNjY3NyA2MS43ODU5IDkyLjk0NyA1Ni41MjkgOTEuNTE4MUM1My42NDQ4IDg3LjAzNjYgNTEuMzY0NSA4Mi4yMzU3IDQ5LjcyMzQgNzcuMTgxMkM0OC4wODkyIDcyLjE1MDIgNDcuMTMyOSA2Ni44Nzk1IDQ2Ljg1NTQgNjEuNDUyMkM1MC4yNTA0IDU3LjI1NDcgNTQuMTExIDUzLjU3NzYgNTguMzc2NyA1MC40ODIzQzYyLjcxMTQgNDcuMzI5NCA2Ny40MjcxIDQ0Ljc2NzkgNzIuNDMwNSA0Mi44NDFDNzcuNDI1NiA0NC43NjgzIDgyLjEzMjYgNDcuMzI2MiA4Ni40NTcyIDUwLjQ2NTdDOTAuNzM5NCA1My41Nzc2IDk0LjYxNzEgNTcuMjgzMiA5OC4wMjg3IDYxLjUwN0M5Ny43Mzc4IDY2LjkwMzQgOTYuNzcgNzIuMTQzOCA5NS4xMzMgNzcuMTY2NUM5My40OTYxIDgyLjIyIDkxLjIwODQgODcuMDM2MSA4OC4zMTk3IDkxLjUxODFaTTc2Ljc2ODQgNjYuMTk3NEM3Ni43Njg0IDY5LjkwODEgNzkuNzc1NCA3Mi45MDk2IDgzLjQ4MSA3Mi45MDk2Qzg3LjE4NTcgNzIuOTA5NiA5MC4xODk1IDY5LjkwODYgOTAuMTg5NSA2Ni4xOTc0QzkwLjE4OTUgNjIuNTAxIDg3LjE4NTcgNTkuNDg4MSA4My40ODEgNTkuNDg4MUM3OS43NzU0IDU5LjQ4ODEgNzYuNzY4NCA2Mi41MDEgNzYuNzY4NCA2Ni4xOTc0Wk02OC4wOTU0IDY2LjE5NzRDNjguMDk1NCA2OS45MDgxIDY1LjA4ODggNzIuOTA5NiA2MS4zODMyIDcyLjkwOTZDNTcuNjc0OSA3Mi45MDk2IDU0LjY3NjYgNjkuOTA4NiA1NC42NzY2IDY2LjE5NzRDNTQuNjc2NiA2Mi41MDI0IDU3LjY3NTMgNTkuNDg5NCA2MS4zODMyIDU5LjQ4OTRDNjUuMDg4OCA1OS40ODk0IDY4LjA5NTQgNjIuNTAyNCA2OC4wOTU0IDY2LjE5NzRaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yOTYzIiB4MT0iNS41IiB5MT0iMTEiIHgyPSIxNDEiIHkyPSIxMjQuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNTNCMkYwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzQxOUVEQSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "size"], ["spec", "storageClass"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resources", "cpu"], ["spec", "resources", "memory"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - etcd diff --git a/packages/system/etcd-rd/templates/cozyrd.yaml b/packages/system/etcd-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/etcd-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/etcd-rd/values.yaml b/packages/system/etcd-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/etcd-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/ferretdb-rd/Chart.yaml b/packages/system/ferretdb-rd/Chart.yaml new file mode 100644 index 00000000..6e2730f1 --- /dev/null +++ b/packages/system/ferretdb-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: ferretdb-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/ferretdb-rd/Makefile b/packages/system/ferretdb-rd/Makefile new file mode 100644 index 00000000..f6814169 --- /dev/null +++ b/packages/system/ferretdb-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=ferretdb-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/ferretdb-rd/cozyrds/ferretdb.yaml b/packages/system/ferretdb-rd/cozyrds/ferretdb.yaml new file mode 100644 index 00000000..f7bdeb82 --- /dev/null +++ b/packages/system/ferretdb-rd/cozyrds/ferretdb.yaml @@ -0,0 +1,40 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: ferretdb +spec: + application: + kind: FerretDB + plural: ferretdbs + singular: ferretdb + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["destinationPath","enabled","endpointURL","retentionPolicy","s3AccessKey","s3SecretKey","schedule"],"properties":{"destinationPath":{"description":"Path to store the backup (e.g. s3://bucket/path/to/folder/).","type":"string","default":"s3://bucket/path/to/folder/"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"endpointURL":{"description":"S3 endpoint URL for uploads.","type":"string","default":"http://minio-gateway-service:9000"},"retentionPolicy":{"description":"Retention policy.","type":"string","default":"30d"},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * * *"}}},"bootstrap":{"description":"Bootstrap configuration.","type":"object","default":{},"properties":{"enabled":{"description":"Restore database cluster from a backup.","type":"boolean","default":false},"oldName":{"description":"Name of database cluster before deletion.","type":"string","default":""},"recoveryTime":{"description":"Timestamp (RFC3339) for point-in-time recovery; empty means latest.","type":"string","default":""}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"quorum":{"description":"Configuration for quorum-based synchronous replication.","type":"object","default":{},"required":["maxSyncReplicas","minSyncReplicas"],"properties":{"maxSyncReplicas":{"description":"Maximum number of synchronous replicas allowed (must be less than total replicas).","type":"integer","default":0},"minSyncReplicas":{"description":"Minimum number of synchronous replicas required for commit.","type":"integer","default":0}}},"replicas":{"description":"Number of replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each FerretDB replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}}}} + release: + prefix: ferretdb- + labels: + cozystack.io/ui: "true" + chart: + name: ferretdb + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: FerretDB + plural: FerretDB + description: Managed FerretDB service + tags: + - database + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NTIpIi8+CjxwYXRoIGQ9Ik02OS41OTIzIDIyLjEzMUM1OC4yNjYyIDIzLjY3ODcgNDYuOTAzNyAzMC44NzE0IDQwLjMzMDIgNDAuNjY3OUMzOS4yNzQgNDIuMjUyMSAzNy40NTMxIDQ1LjU0OCAzNy40NTMxIDQ1Ljg3NTdDMzcuNDUzMSA0NS45MTIyIDM4LjMyNzIgNDUuMzg0MSAzOS4zODMzIDQ0LjY5MjFDNTIuMzg0NyAzNi4xMTU2IDY3Ljg5ODkgMzQuNTMxNCA4MC41MTc4IDQwLjQ4NThDODMuMjY3NCA0MS43Nzg3IDg0Ljk5NzMgNDMuMDM1MSA4Ny40NTU1IDQ1LjQ5MzNDOTEuNTg5IDQ5LjY0NSA5NC42MTE3IDU1LjE5ODggOTYuNzA1OCA2Mi41MDA3Qzk3Ljc5ODMgNjYuMjUxOCA5OC43MDg4IDcxLjM2ODYgOTguOTQ1NSA3NC44NDY1Qzk5LjAwMDEgNzUuNzkzNCA5OS4xNDU4IDc2LjYzMSA5OS4yMzY5IDc2LjY4NTZDOTkuNzQ2NyA3Ni45OTUyIDEwMi4wNDEgNzMuNjYyOSAxMDMuNjYyIDcwLjI3NkMxMDYuMjI5IDY0Ljg4NjEgMTA3LjQzMSA1OS41ODcyIDEwNy40MTMgNTMuNzA1N0MxMDcuMzk1IDQ1LjM4NDEgMTA0LjUxOCAzOC4zOTE3IDk4LjcyNyAzMi41NjQ4QzkzLjU5MiAyNy4zOTM0IDg3LjEwOTUgMjMuODQyNiA4MC4zMTc1IDIyLjQ1ODdDNzguNzMzMyAyMi4xNDkyIDc3LjU2NzkgMjIuMDU4MSA3NC41OTk5IDIyLjAwMzVDNzIuNTQyMiAyMS45ODUzIDcwLjMwMjUgMjIuMDM5OSA2OS41OTIzIDIyLjEzMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00NS41MiA0Ni40NDAyQzQ0LjMzNjQgNDcuMDIyOSA0Mi4zNTE2IDQ4Ljg0MzggNDAuNjAzNSA1MC45Mzc5QzM5LjgyMDUgNTEuODY2NiAzOC42MzY5IDUzLjAxMzcgMzcuNzYyOSA1My42NjkzQzM1LjcyMzQgNTUuMTk4OSAzMi4yNDU1IDU4LjYwNCAzMC40NzkyIDYwLjgwNzNDMjEuMjY1NCA3Mi4yMjQ0IDE4LjY5NzkgODUuMjQ0IDIzLjA4NjMgOTguMzE4MkMyNi42OTE3IDEwOS4wMjUgMzUuMDMxNSAxMTYuMTI3IDQ3Ljg1MDggMTE5LjM1QzUyLjg0MDEgMTIwLjYyNCA2MC4zMjQgMTIxLjMzNSA2My40NTYgMTIwLjg0M0w2NC4yNTcyIDEyMC43MTVMNjMuMDE5IDExOS45ODdDNTYuMTkwNiAxMTYuMDE4IDUxLjQxOTggMTA5LjMxNyA1MC4wOTA1IDEwMS44NjlDNDkuNjg5OSA5OS42MTEgNDkuNjcxNyA5NS42MDUgNTAuMDcyMyA5My40MDE3QzUwLjk2NDUgODguNDQ4OCA1My40NTkyIDgzLjg5NjUgNTYuODQ2MSA4MS4wNTU5QzU4LjQzMDMgNzkuNzI2NiA2MS4xOTgxIDc4LjM2MDkgNjMuNDAxNCA3Ny44MzI5QzY2LjcxNTUgNzcuMDMxNyA2OC43MzY3IDc2LjEyMTIgNzAuODMwNyA3NC40NjQyQzcyLjE3ODIgNzMuNDA4IDczLjM2MTggNzEuODA1NiA3NC4zNDUxIDY5LjcyOThDNzUuMTgyNyA2Ny45NjM1IDc2Ljk2NzIgNjIuMzU1MSA3Ni45NjcyIDYxLjQ2MjhDNzYuOTY3MiA2MC44NDM3IDc2LjMyOTkgNjAuMDA2MSA3NS40MTk1IDU5LjQ0MTZDNzQuOTQ2IDU5LjE1MDIgNzQuMTk5NCA1OC45ODY0IDcyLjI4NzUgNTguNzg2MUM2NC4wNTY5IDU3LjkzMDIgNTkuOTU5OSA1Ni40MzcxIDU1LjAwNyA1Mi41MjIxQzU0LjI5NjggNTEuOTU3NiA1My40NDEgNTEuMzIwMyA1My4wOTUgNTEuMTAxOEM1Mi43NDkgNTAuOTAxNSA1Mi4wNTcxIDUwLjEzNjcgNTEuNTgzNiA0OS40MjY1QzUwLjE0NTEgNDcuMzMyNSA0OC4zNjA2IDQ1Ljk4NSA0Ni45OTQ5IDQ1Ljk2NjhDNDYuNzAzNiA0NS45NjY4IDQ2LjAyOTggNDYuMTg1MyA0NS41MiA0Ni40NDAyWk01NC40NjA3IDU0Ljg3MTFDNTUuMDc5OCA1NS4xODA2IDU1Ljc1MzUgNTUuNTgxMiA1NS45NzIgNTUuNzQ1MUw1Ni4zNzI3IDU2LjA3MjlMNTUuNzM1MyA1OC42MjIyQzU1LjE4OTEgNjAuODQzNyA1NS4wOTggNjEuNDA4MiA1NS4xNTI2IDYyLjk5MjRDNTUuMjA3MyA2NC41NTg0IDU1LjI2MTkgNjQuOTA0MyA1NS42MjYxIDY1LjQxNDJDNTYuMjI3IDY2LjIzMzYgNTcuMjY0OSA2Ni43MjUzIDU4LjQzMDMgNjYuNzI1M0M2MC4wODczIDY2LjcyNTMgNjEuMzgwMiA2NS43Nzg0IDYzLjUyODkgNjIuOTU2QzY0LjE0OCA2Mi4xNTQ4IDY0LjYzOTYgNjEuNzE3NyA2NS4zNjggNjEuMzcxOEM2Ni40OTcgNjAuODA3MyA2Ny4yOTgyIDYwLjc1MjcgNjkuODExIDYwLjk3MTJMNzEuNDg2MyA2MS4xMzVWNjIuMTE4M0M3MS40ODYzIDYzLjY2NjEgNzIuMzA1NyA2NC41NTg0IDczLjk4MDkgNjQuODEzM0w3NC43ODIxIDY0LjkyMjZMNzQuNDkwOCA2NS41OTYzQzczLjIxNjEgNjguNjczNiA2OS45Mzg1IDcyLjE1MTYgNjYuODYxMSA3My42OTk0QzY2LjM2OTUgNzMuOTM2MSA2NS4yNTg3IDc0LjM3MzEgNjQuNDAyOSA3NC42NjQ1QzYzLjAwMDggNzUuMTE5NyA2Mi42MTg0IDc1LjE3NDMgNjAuMjE0OCA3NS4xNzQzQzU3LjgyOTQgNzUuMTc0MyA1Ny40Mjg4IDc1LjExOTcgNTYuMTE3NyA3NC42ODI3QzUyLjE2NjMgNzMuMzcxNiA0OS4yMzQ3IDcwLjQ1ODEgNDcuOTA1NCA2Ni41NDMyQzQ3LjQzMTkgNjUuMTU5MyA0Ny40MTM3IDYxLjEzNSA0Ny44ODcyIDU5LjQ1OThDNDguNTI0NSA1Ny4xNDcyIDQ5LjY1MzUgNTUuMjM1MyA1MC44MzcxIDU0LjQ4ODdDNTEuNjAxOCA1My45OTcgNTMuMDIyMiA1NC4xNjA5IDU0LjQ2MDcgNTQuODcxMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTMuMDIyIDYxLjczNjFDMTEzLjAyMiA2Mi41NTU1IDExMi4xMTEgNjYuMzQzMSAxMTEuMzQ3IDY4LjcxMDJDMTA4LjQ3IDc3LjU3ODEgMTAzLjI2MiA4NS41MzU1IDk2LjQ2OTcgOTEuMzQ0M0M5MS42OTg5IDk1LjQ0MTMgODguMzExOSA5Ny4yNDQgODIuOTQwMiA5OC41NzMzQzc5LjQ4MDUgOTkuNDI5MSA3Ny4yMjI2IDk5LjcwMjMgNzIuODM0MSA5OS44MTE1QzY3LjM1MzIgOTkuOTU3MiA2MS45NDUxIDk5LjQ2NTUgNTcuMTAxNCA5OC40MDk0QzU2LjE3MjcgOTguMjA5MSA1NS4zODk4IDk4LjA4MTYgNTUuMzM1MSA5OC4xMzYzQzU1LjExNjYgOTguMzM2NiA1NS45NTQyIDEwMS4xMjMgNTYuNjgyNiAxMDIuNTk4QzU4LjAxMTkgMTA1LjMyOSA1OS41MjMyIDEwNy4zNjggNjIuMjE4MiAxMTAuMDYzQzY1LjA1ODggMTEyLjkwNCA2Ny4xNzExIDExNC40NyA3MC40NDg3IDExNi4xNjNDNzguNTcgMTIwLjM1MSA4Ny44OTMxIDEyMC45MTYgOTcuNDUzIDExNy43NjZDMTA3LjU0MSAxMTQuNDcgMTE0Ljk1MiAxMDguNTE2IDExOC45NCAxMDAuNTAzQzEyMS41OTggOTUuMTg2NCAxMjIuNjkxIDg5LjUwNTEgMTIyLjI5IDgzLjAyMjdDMTIxLjc5OSA3NS4wMjg4IDExOC44NDkgNjcuMTk4OSAxMTQuNTcgNjIuNTczOEMxMTMuODk2IDYxLjg0NTQgMTEzLjI3NyA2MS4yNjI3IDExMy4xODYgNjEuMjYyN0MxMTMuMDk1IDYxLjI2MjcgMTEzLjAyMiA2MS40ODEyIDExMy4wMjIgNjEuNzM2MVoiIGZpbGw9IndoaXRlIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgzXzI5NTIiIHgxPSI1LjUiIHkxPSIxMSIgeDI9IjE0MSIgeTI9IjEyNC41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM0NUFEQzYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMjE2Nzc4Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "quorum"], ["spec", "quorum", "minSyncReplicas"], ["spec", "quorum", "maxSyncReplicas"], ["spec", "users"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "schedule"], ["spec", "backup", "retentionPolicy"], ["spec", "backup", "endpointURL"], ["spec", "backup", "destinationPath"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "bootstrap"], ["spec", "bootstrap", "enabled"], ["spec", "bootstrap", "recoveryTime"], ["spec", "bootstrap", "oldName"]] + secrets: + exclude: [] + include: + - resourceNames: + - ferretdb-{{ .name }}-credentials + services: + exclude: [] + include: + - resourceNames: + - ferretdb-{{ .name }} diff --git a/packages/system/ferretdb-rd/templates/cozyrd.yaml b/packages/system/ferretdb-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/ferretdb-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/ferretdb-rd/values.yaml b/packages/system/ferretdb-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/ferretdb-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/foundationdb-rd/Chart.yaml b/packages/system/foundationdb-rd/Chart.yaml new file mode 100644 index 00000000..1c8afe3a --- /dev/null +++ b/packages/system/foundationdb-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: foundationdb-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/foundationdb-rd/Makefile b/packages/system/foundationdb-rd/Makefile new file mode 100644 index 00000000..b6e6d41a --- /dev/null +++ b/packages/system/foundationdb-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=foundationdb-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/foundationdb-rd/cozyrds/foundationdb.yaml b/packages/system/foundationdb-rd/cozyrds/foundationdb.yaml new file mode 100644 index 00000000..e7759380 --- /dev/null +++ b/packages/system/foundationdb-rd/cozyrds/foundationdb.yaml @@ -0,0 +1,30 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: foundationdb +spec: + application: + kind: FoundationDB + singular: foundationdb + plural: foundationdbs + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"automaticReplacements":{"description":"Enable automatic pod replacements","type":"boolean","default":true},"backup":{"description":"Backup configuration","type":"object","default":{"enabled":false,"retentionPolicy":"7d","s3":{"bucket":"","credentials":{"accessKeyId":"","secretAccessKey":""},"endpoint":"","region":"us-east-1"}},"required":["enabled","retentionPolicy","s3"],"properties":{"enabled":{"description":"Enable backups","type":"boolean","default":false},"retentionPolicy":{"description":"Retention policy for backups","type":"string","default":"7d"},"s3":{"description":"S3 configuration for backups","type":"object","default":{"bucket":"","credentials":{"accessKeyId":"","secretAccessKey":""},"endpoint":"","region":"us-east-1"},"required":["bucket","credentials","endpoint","region"],"properties":{"bucket":{"description":"S3 bucket name","type":"string"},"credentials":{"description":"S3 credentials","type":"object","default":{"accessKeyId":"","secretAccessKey":""},"required":["accessKeyId","secretAccessKey"],"properties":{"accessKeyId":{"description":"S3 access key ID","type":"string"},"secretAccessKey":{"description":"S3 secret access key","type":"string"}}},"endpoint":{"description":"S3 endpoint URL","type":"string"},"region":{"description":"S3 region","type":"string","default":"us-east-1"}}}}},"cluster":{"description":"Cluster configuration","type":"object","default":{"faultDomain":{"key":"kubernetes.io/hostname","valueFrom":"spec.nodeName"},"processCounts":{"cluster_controller":1,"stateless":-1,"storage":3},"redundancyMode":"double","storageEngine":"ssd-2","version":"7.3.63"},"required":["faultDomain","processCounts","redundancyMode","storageEngine","version"],"properties":{"faultDomain":{"description":"Fault domain configuration","type":"object","default":{"key":"kubernetes.io/hostname","valueFrom":"spec.nodeName"},"required":["key","valueFrom"],"properties":{"key":{"description":"Fault domain key","type":"string","default":"kubernetes.io/hostname"},"valueFrom":{"description":"Fault domain value source","type":"string","default":"spec.nodeName"}}},"processCounts":{"description":"Process counts for different roles","type":"object","default":{"cluster_controller":1,"stateless":-1,"storage":3},"required":["cluster_controller","stateless","storage"],"properties":{"cluster_controller":{"description":"Number of cluster controller processes","type":"integer","default":1},"stateless":{"description":"Number of stateless processes (-1 for automatic)","type":"integer","default":-1},"storage":{"description":"Number of storage processes (determines cluster size)","type":"integer","default":3}}},"redundancyMode":{"description":"Database redundancy mode (single, double, triple, three_datacenter, three_datacenter_fallback)","type":"string","default":"double"},"storageEngine":{"description":"Storage engine (ssd-2, ssd-redwood-v1, ssd-rocksdb-v1, memory)","type":"string","default":"ssd-2"},"version":{"description":"Version of FoundationDB to use","type":"string","default":"7.3.63"}}},"customParameters":{"description":"Custom parameters to pass to FoundationDB","type":"array","default":[],"items":{"type":"string"}},"imageType":{"description":"Container image deployment type","type":"string","default":"unified","enum":["unified","split"]},"monitoring":{"description":"Monitoring configuration","type":"object","default":{"enabled":true},"required":["enabled"],"properties":{"enabled":{"description":"Enable WorkloadMonitor integration","type":"boolean","default":true}}},"resources":{"description":"Explicit CPU and memory configuration for each FoundationDB instance. When left empty, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each instance","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each instance","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted. Allowed values: `small`, `medium`, `large`, `xlarge`, `2xlarge`.","type":"string","default":"medium","enum":["small","medium","large","xlarge","2xlarge"]},"securityContext":{"description":"Security context for containers","type":"object","default":{"runAsGroup":4059,"runAsUser":4059},"required":["runAsGroup","runAsUser"],"properties":{"runAsGroup":{"description":"Group ID to run the container","type":"integer","default":4059},"runAsUser":{"description":"User ID to run the container","type":"integer","default":4059}}},"storage":{"description":"Storage configuration","type":"object","default":{"size":"16Gi","storageClass":""},"required":["size","storageClass"],"properties":{"size":{"description":"Size of persistent volumes for each instance","default":"16Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"Storage class (if not set, uses cluster default)","type":"string"}}}}} + release: + prefix: foundationdb- + labels: + cozystack.io/ui: "true" + chart: + name: foundationdb + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: FoundationDB + plural: FoundationDB + description: Managed FoundationDB service + tags: + - database + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF84NThfMzA3MikiLz4KPHBhdGggZD0iTTEzNS43ODQgNzUuNjQ0NkwxMzUuOTM5IDg3Ljc2MzhMODkuNjg0NiA4MS41MzYyTDYyLjA4NjggODQuNTA3OUwzNS4zNDE3IDgxLjQzMjlMOC43NTE2NyA4NC41ODU0TDguNzI1ODMgODEuNTEwNEwzNS4zNjc2IDc3LjU4MjZWNjQuMTcxM0w2Mi4yOTM1IDcwLjczNDhMNjIuMzQ1MiA4MS4yNzc4TDg5LjQ3NzkgNzcuNjg2TDg5LjQwMDQgNjQuMTk3MkwxMzUuNzg0IDc1LjY0NDZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNODkuNDc3OCA4Ni4wMzI1TDEzNS44ODggOTAuODM4OFYxMDIuNzI2SDguNjQ4MjVMOC41MTkwNCA5OS41NzNIMzUuMjY0MUMzNS4yNjQxIDk5LjU3MyAzNS4yNjQxIDkwLjczNTUgMzUuMjY0MSA4Ni4wNTgzQzQ0LjI1NjcgODYuOTM2OSA2Mi4wODY3IDg4LjY5NDEgNjIuMDg2NyA4OC42OTQxVjk5LjI2MjlIODkuNDc3OFY4Ni4wMzI1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTYyLjI5MzQgNjYuODg0Nkw2Mi4yMTU4IDYzLjYyODZDNjIuMjE1OCA2My42Mjg2IDc5LjgxMzMgNTguMzU3MSA4OC45MDkyIDU1LjY2OTdDODguOTA5MiA1MS4zMDI2IDg4LjkwOTIgNDcuMDkwNiA4OC45MDkyIDQyQzEwNC44NzkgNDguNDA4NSAxMjAuMjI4IDU0LjYxMDIgMTM1LjczMyA2MC44Mzc4QzEzNS43MzMgNjQuNzEzOSAxMzUuNzMzIDY4LjQzNSAxMzUuNzMzIDcyLjU2OTVDMTE5Ljg0MSA2OC4yMDI0IDEwNC4yODQgNjMuOTEyOSA4OS4xNjc2IDU5Ljc1MjVDNzkuOTY4NCA2Mi4yMDc0IDYyLjI5MzQgNjYuODg0NiA2Mi4yOTM0IDY2Ljg4NDZaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzUuMzk2MiA4MS43MDczTDguODA2MTIgODQuODU5OEw4Ljc4MDI3IDgxLjc4NDhMMzUuNDIyIDc3Ljg1N1Y2NC40NDU3TDYyLjM0OCA3MS4wMDkzTDYyLjM5OTYgODEuNTUyMkw4OS41MzIzIDc3Ljk2MDRMODkuNDU0OCA2NC40NzE2TDEzNS44MzkgNzUuOTE5TDEzNS45OTQgODguMDM4Mkw4OS43MzkxIDgxLjgxMDZMNjIuMTQxMiA4NC43ODIzTDM1LjM5NjIgODEuNzA3M1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik04OS41MzIzIDg2LjMwNjlMMTM1Ljk0MiA5MS4xMTMzVjEwM0g4LjcwMjdMOC41NzM0OSA5OS44NDc0SDM1LjMxODZDMzUuMzE4NiA5OS44NDc0IDM1LjMxODYgOTEuMDA5OSAzNS4zMTg2IDg2LjMzMjhDNDQuMzExMSA4Ny4yMTE0IDYyLjE0MTIgODguOTY4NSA2Mi4xNDEyIDg4Ljk2ODVWOTkuNTM3M0g4OS41MzIzVjg2LjMwNjlaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNjIuMzQ4MyA2Ny4xNTlMNjIuMjcwOCA2My45MDMxQzYyLjI3MDggNjMuOTAzMSA3OS44NjgyIDU4LjYzMTYgODguOTY0MiA1NS45NDQyQzg4Ljk2NDIgNTEuNTc3MSA4OC45NjQyIDQ3LjM2NTEgODguOTY0MiA0Mi4yNzQ0QzEwNC45MzQgNDguNjgyOSAxMjAuMjgzIDU0Ljg4NDcgMTM1Ljc4NyA2MS4xMTIzQzEzNS43ODcgNjQuOTg4NCAxMzUuNzg3IDY4LjcwOTQgMTM1Ljc4NyA3Mi44NDM5QzExOS44OTUgNjguNDc2OSAxMDQuMzM5IDY0LjE4NzMgODkuMjIyNiA2MC4wMjdDODAuMDIzMyA2Mi40ODE4IDYyLjM0ODMgNjcuMTU5IDYyLjM0ODMgNjcuMTU5WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQwX3JhZGlhbF84NThfMzA3MiIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgtMjkuNSAtMTgpIHJvdGF0ZSgzOS42OTYzKSBzY2FsZSgzMDIuMTY4IDI3NS4yNzEpIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0JFRERGRiIvPgo8c3RvcCBvZmZzZXQ9IjAuMjU5NjE1IiBzdG9wLWNvbG9yPSIjOUVDQ0ZEIi8+CjxzdG9wIG9mZnNldD0iMC41OTEzNDYiIHN0b3AtY29sb3I9IiMzRjlBRkIiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMEI3MEUwIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + # keysOrder: [] diff --git a/packages/system/foundationdb-rd/templates/cozyrd.yaml b/packages/system/foundationdb-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/foundationdb-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/foundationdb-rd/values.yaml b/packages/system/foundationdb-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/foundationdb-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/http-cache-rd/Chart.yaml b/packages/system/http-cache-rd/Chart.yaml new file mode 100644 index 00000000..c82ad1aa --- /dev/null +++ b/packages/system/http-cache-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: http-cache-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/http-cache-rd/Makefile b/packages/system/http-cache-rd/Makefile new file mode 100644 index 00000000..cf367cf4 --- /dev/null +++ b/packages/system/http-cache-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=http-cache-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/http-cache-rd/cozyrds/http-cache.yaml b/packages/system/http-cache-rd/cozyrds/http-cache.yaml new file mode 100644 index 00000000..70de0418 --- /dev/null +++ b/packages/system/http-cache-rd/cozyrds/http-cache.yaml @@ -0,0 +1,34 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: http-cache +spec: + application: + kind: HTTPCache + plural: httpcaches + singular: httpcache + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"endpoints":{"description":"Endpoints configuration, as a list of .","type":"array","default":[],"items":{"type":"string"}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"haproxy":{"description":"HAProxy configuration.","type":"object","default":{},"required":["replicas","resourcesPreset"],"properties":{"replicas":{"description":"Number of HAProxy replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"nginx":{"description":"Nginx configuration.","type":"object","default":{},"required":["replicas","resourcesPreset"],"properties":{"replicas":{"description":"Number of Nginx replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}} + release: + prefix: http-cache- + labels: + cozystack.io/ui: "true" + chart: + name: http-cache + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: NaaS + singular: HTTP Cache + plural: HTTP Cache + description: Layer7 load balancer and caching service + tags: + - cache + - network + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyNSkiLz4KPHBhdGggZD0iTTI2LjAwMjYgMzcuODU4OEMyNi4wMDI2IDYwLjkxOSAyNi4wMDI2IDgzLjk4MTQgMjYuMDAyNiAxMDcuMDQ2QzI1Ljk3MyAxMDguMzIzIDI2LjE5OTYgMTA5LjU5MyAyNi42NjkyIDExMC43ODNDMjcuMTM4NyAxMTEuOTcyIDI3Ljg0MTggMTEzLjA1NiAyOC43Mzc0IDExMy45NzJDMzAuNDUzOSAxMTUuNjU5IDMyLjcgMTE2LjcwOSAzNS4xMDA5IDExNi45NDhDMzcuNTAxOSAxMTcuMTg3IDM5LjkxMjYgMTE2LjYgNDEuOTMxIDExNS4yODRDNDMuMjgyIDExNC4zNzEgNDQuMzg4MSAxMTMuMTQzIDQ1LjE1MjcgMTExLjcwN0M0NS45MTc0IDExMC4yNzEgNDYuMzE3NSAxMDguNjcxIDQ2LjMxODEgMTA3LjA0NkM0Ni4zMTgxIDkwLjM1MjggNDYuMjg2MSA3My42NTk3IDQ2LjMxODEgNTYuOTY2NkM2MS42MTY4IDc1LjE4ODkgNzYuOTQ3NCA5My4zODU2IDkyLjMxIDExMS41NTdDOTQuNDQ0NCAxMTMuNzA4IDk3LjA4NzUgMTE1LjI5MSA5OS45OTcgMTE2LjE2MkMxMDIuOTA2IDExNy4wMzIgMTA1Ljk4OSAxMTcuMTYyIDEwOC45NjIgMTE2LjUzOUMxMTEuMDYxIDExNi4xMjggMTEyLjk3MyAxMTUuMDU3IDExNC40MTUgMTEzLjQ4NUMxMTUuODU3IDExMS45MTMgMTE2Ljc1NCAxMDkuOTIxIDExNi45NzQgMTA3LjgwNEMxMTcuMDA5IDg0LjI2ODEgMTE3LjAwOSA2MC43MzQzIDExNi45NzQgMzcuMjAyNUMxMTYuNzU0IDM0LjY5MDcgMTE1LjU5NSAzMi4zNTIyIDExMy43MjYgMzAuNjQ4NkMxMTEuODU4IDI4Ljk0NSAxMDkuNDE1IDI4IDEwNi44ODEgMjhDMTA0LjM0NiAyOCAxMDEuOTAzIDI4Ljk0NSAxMDAuMDM1IDMwLjY0ODZDOTguMTY2MyAzMi4zNTIyIDk3LjAwNzQgMzQuNjkwNyA5Ni43ODY5IDM3LjIwMjVDOTYuNzg2OSA1NC4xNjMyIDk2LjY4NDQgNzEuMTA0OCA5Ni43ODY5IDg4LjA1OTFDODEuNzYxNiA3MC40MzU4IDY2LjkyMTkgNTIuNjU5NiA1MS45NTQzIDM0Ljk3MjVDNDkuOTgxIDMyLjQ1NTQgNDcuMzY4NSAzMC41MDczIDQ0LjM4NjMgMjkuMzI5MUM0MS40MDQxIDI4LjE1MDkgMzguMTU5OSAyNy43ODUyIDM0Ljk4ODMgMjguMjY5OEMzMi41ODU3IDI4LjUzNTkgMzAuMzU4MyAyOS42NDkzIDI4LjcwOTkgMzEuNDA4NEMyNy4wNjE1IDMzLjE2NzUgMjYuMTAxIDM1LjQ1NTkgMjYuMDAyNiAzNy44NTg4WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODFfMjgyNSIgeDE9IjEwIiB5MT0iMTUuNSIgeDI9IjE0NCIgeTI9IjEzMS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEM1NEEiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDE5NjM5Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "endpoints"], ["spec", "haproxy"], ["spec", "haproxy", "replicas"], ["spec", "haproxy", "resources"], ["spec", "haproxy", "resourcesPreset"], ["spec", "nginx"], ["spec", "nginx", "replicas"], ["spec", "nginx", "resources"], ["spec", "nginx", "resourcesPreset"]] + secrets: + exclude: [] + include: [] diff --git a/packages/system/http-cache-rd/templates/cozyrd.yaml b/packages/system/http-cache-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/http-cache-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/http-cache-rd/values.yaml b/packages/system/http-cache-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/http-cache-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/info-rd/Chart.yaml b/packages/system/info-rd/Chart.yaml new file mode 100644 index 00000000..2f354177 --- /dev/null +++ b/packages/system/info-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: info-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/info-rd/Makefile b/packages/system/info-rd/Makefile new file mode 100644 index 00000000..7cfed08d --- /dev/null +++ b/packages/system/info-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=info-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/info-rd/cozyrds/info.yaml b/packages/system/info-rd/cozyrds/info.yaml new file mode 100644 index 00000000..43cda091 --- /dev/null +++ b/packages/system/info-rd/cozyrds/info.yaml @@ -0,0 +1,37 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: info +spec: + application: + kind: Info + plural: infos + singular: info + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + chart: + name: info + sourceRef: + kind: HelmRepository + name: cozystack-extra + namespace: cozy-public + dashboard: + name: info + category: Administration + singular: Info + plural: Info + description: Info + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX3JhZGlhbF8xNDRfMykiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzE0NF8zKSI+CjxwYXRoIGQ9Ik03Ny42NDA3IDk3LjA4NDRMODIuODMzIDk3LjM2MDRWMTA0LjYzN0g2MS4xNzI4Vjk3LjcxOTdMNjQuMTc3MSA5Ny40NDk1QzY1LjgxMDEgOTcuMjY4NCA2Ni44MTA2IDk2LjcxOTMgNjYuODEwNiA5NC41MzQzVjY5LjIzMTRDNjYuODEwNiA2Ny4yMjE3IDY2LjI3MDEgNjYuNTg2NCA2NC41MzY1IDY2LjU4NjRMNjEuMzU2OCA2Ni40MDgxVjU4Ljg1ODRINzcuNjQ2NUw3Ny42NDA3IDk3LjA4NDRaTTcxLjI3MjYgMzkuMzYzQzc1LjI4MDQgMzkuMzYzIDc4LjE4NyA0Mi4zNzMxIDc4LjE4NyA0Ni4xODgzQzc4LjE4NyA1MC4wMTQ5IDc1LjI3MTggNTIuODM4MSA3MS4xNzc4IDUyLjgzODFDNjYuOTk3NSA1Mi44MzgxIDY0LjI2NjMgNTAuMDE0OSA2NC4yNjYzIDQ2LjE4ODNDNjQuMjY2MyA0Mi4zNzMxIDY2Ljk5NzUgMzkuMzYzIDcxLjI3MjYgMzkuMzYzWk03MiAxMThDNDYuNjM2OCAxMTggMjYgOTcuMzYzMiAyNiA3MkMyNiA0Ni42MzY4IDQ2LjYzNjggMjYgNzIgMjZDOTcuMzU3NSAyNiAxMTggNDYuNjM2OCAxMTggNzJDMTE4IDk3LjM2MzIgOTcuMzU3NSAxMTggNzIgMTE4Wk03MiAzNC42MjVDNTEuMzkyIDM0LjYyNSAzNC42MjUgNTEuMzkyIDM0LjYyNSA3MkMzNC42MjUgOTIuNjA4IDUxLjM5MiAxMDkuMzc1IDcyIDEwOS4zNzVDOTIuNjA4IDEwOS4zNzUgMTA5LjM3NSA5Mi42MDggMTA5LjM3NSA3MkMxMDkuMzc1IDUxLjM5MiA5Mi42MDggMzQuNjI1IDcyIDM0LjYyNVoiIGZpbGw9IndoaXRlIi8+CjwvZz4KPGRlZnM+CjxyYWRpYWxHcmFkaWVudCBpZD0icGFpbnQwX3JhZGlhbF8xNDRfMyIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSgxLjMyMjk4ZS0wNSAtNy41MDAwMSkgcm90YXRlKDQ0LjcxNzgpIHNjYWxlKDIxNS4zMTcgMzEyLjQ1NSkiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDBCNUU3Ii8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwMzk4NCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzE0NF8zIj4KPHJlY3Qgd2lkdGg9IjkyIiBoZWlnaHQ9IjkyIiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjYgMjYpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"]] + secrets: + exclude: [] + include: + - resourceNames: + - kubeconfig-{{ .namespace }} + - "{{ .namespace }}" diff --git a/packages/system/info-rd/templates/cozyrd.yaml b/packages/system/info-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/info-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/info-rd/values.yaml b/packages/system/info-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/info-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/ingress-rd/Chart.yaml b/packages/system/ingress-rd/Chart.yaml new file mode 100644 index 00000000..2e1b77d7 --- /dev/null +++ b/packages/system/ingress-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: ingress-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/ingress-rd/Makefile b/packages/system/ingress-rd/Makefile new file mode 100644 index 00000000..82976cc6 --- /dev/null +++ b/packages/system/ingress-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=ingress-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/ingress-rd/cozyrds/ingress.yaml b/packages/system/ingress-rd/cozyrds/ingress.yaml new file mode 100644 index 00000000..2e00f6ed --- /dev/null +++ b/packages/system/ingress-rd/cozyrds/ingress.yaml @@ -0,0 +1,39 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: ingress +spec: + application: + kind: Ingress + plural: ingresses + singular: ingress + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"cloudflareProxy":{"description":"Restoring original visitor IPs when Cloudflare proxied is enabled.","type":"boolean","default":false},"replicas":{"description":"Number of ingress-nginx replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each ingress-nginx replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"List of client networks.","type":"array","default":[],"items":{"type":"string"}}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + chart: + name: ingress + sourceRef: + kind: HelmRepository + name: cozystack-extra + namespace: cozy-public + dashboard: + category: Administration + singular: Ingress + plural: Ingress + name: ingress + description: NGINX Ingress Controller + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODRfMzIyOSkiLz4KPHBhdGggZD0iTTg2LjkyNzQgMzcuMTA3NEgxN1YxMDcuMDM1SDg2LjkyNzRWMzcuMTA3NFoiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTEyNy42NDMgMjlIMTA3LjQ1NVY0OS4xODgzSDEyNy42NDNWMjlaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik0xMjcuNjQzIDYxLjcyNjZIMTA3LjQ1NVY4MS45MTQ5SDEyNy42NDNWNjEuNzI2NloiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTEyNy42NDMgOTQuNDUyMUgxMDcuNDU1VjExNC42NEgxMjcuNjQzVjk0LjQ1MjFaIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik04OC41MTM3IDcyLjA3MTNIMTA2LjI3IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik04Ny41Njc0IDgwLjQyNDhMMTA3LjczIDk1Ljc4MDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTg3LjU2NzQgNjMuNzE4MUwxMDcuNzMgNDguMzYyMyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4NF8zMjI5IiB4MT0iMTAiIHkxPSIxNS41IiB4Mj0iMTQ0IiB5Mj0iMTMxLjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzAwREE1MyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMwMDk2MzkiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "whitelist"], ["spec", "cloudflareProxy"], ["spec", "resources"], ["spec", "resourcesPreset"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - "{{ slice .namespace 7 }}-ingress-controller" diff --git a/packages/system/ingress-rd/templates/cozyrd.yaml b/packages/system/ingress-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/ingress-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/ingress-rd/values.yaml b/packages/system/ingress-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/ingress-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/kafka-rd/Chart.yaml b/packages/system/kafka-rd/Chart.yaml new file mode 100644 index 00000000..87b84e32 --- /dev/null +++ b/packages/system/kafka-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: kafka-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/kafka-rd/Makefile b/packages/system/kafka-rd/Makefile new file mode 100644 index 00000000..3c333dcf --- /dev/null +++ b/packages/system/kafka-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=kafka-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/kafka-rd/cozyrds/kafka.yaml b/packages/system/kafka-rd/cozyrds/kafka.yaml new file mode 100644 index 00000000..7009d241 --- /dev/null +++ b/packages/system/kafka-rd/cozyrds/kafka.yaml @@ -0,0 +1,40 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: kafka +spec: + application: + kind: Kafka + plural: kafkas + singular: kafka + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"kafka":{"description":"Kafka configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of Kafka replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size for Kafka.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the Kafka data.","type":"string","default":""}}},"topics":{"description":"Topics configuration.","type":"array","default":[],"items":{"type":"object","required":["config","name","partitions","replicas"],"properties":{"config":{"description":"Topic configuration.","type":"object","x-kubernetes-preserve-unknown-fields":true},"name":{"description":"Topic name.","type":"string"},"partitions":{"description":"Number of partitions.","type":"integer"},"replicas":{"description":"Number of replicas.","type":"integer"}}}},"zookeeper":{"description":"ZooKeeper configuration.","type":"object","default":{},"required":["replicas","resourcesPreset","size","storageClass"],"properties":{"replicas":{"description":"Number of ZooKeeper replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size for ZooKeeper.","default":"5Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the ZooKeeper data.","type":"string","default":""}}}}} + release: + prefix: kafka- + labels: + cozystack.io/ui: "true" + chart: + name: kafka + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: Kafka + plural: Kafka + description: Managed Kafka service + tags: + - messaging + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyMCkiLz4KPHBhdGggZD0iTTkxLjAzMDcgNzcuODE4NUM4Ni44NTc3IDc3LjgxODUgODMuMTE2NiA3OS42ODE4IDgwLjU1NDcgODIuNjE1NEw3My45OTAxIDc3LjkzMTVDNzQuNjg2OSA3NS45OTc4IDc1LjA4NyA3My45MjE1IDc1LjA4NyA3MS43NDgyQzc1LjA4NyA2OS42MTI2IDc0LjcwMDggNjcuNTcxMSA3NC4wMjY5IDY1LjY2Nkw4MC41NzY5IDYxLjAzMThDODMuMTM4NSA2My45NTA1IDg2Ljg2OTkgNjUuODAzNyA5MS4wMzA3IDY1LjgwMzdDOTguNzMyOCA2NS44MDM3IDEwNSA1OS40ODg0IDEwNSA1MS43MjQ3QzEwNSA0My45NjEgOTguNzMyOCAzNy42NDU3IDkxLjAzMDcgMzcuNjQ1N0M4My4zMjg1IDM3LjY0NTcgNzcuMDYxNCA0My45NjEgNzcuMDYxNCA1MS43MjQ3Qzc3LjA2MTQgNTMuMTE0MyA3Ny4yNjk3IDU0LjQ1NDMgNzcuNjQzNSA1NS43MjMzTDcxLjA4OTEgNjAuMzU5OEM2OC4zNTEyIDU2LjkzNjUgNjQuNDA5IDU0LjU0NjMgNTkuOTE3NCA1My44MTY2VjQ1Ljg1NTNDNjYuMjQ1MSA0NC41MTU4IDcxLjAxMjggMzguODQ5NSA3MS4wMTI4IDMyLjA3OUM3MS4wMTI4IDI0LjMxNTMgNjQuNzQ1NyAxOCA1Ny4wNDM1IDE4QzQ5LjM0MTQgMTggNDMuMDc0MiAyNC4zMTUzIDQzLjA3NDIgMzIuMDc5QzQzLjA3NDIgMzguNzU4OSA0Ny43MTg0IDQ0LjM1NTIgNTMuOTE5NiA0NS43OTAzVjUzLjg1NTFDNDUuNDU2NyA1NS4zNTIzIDM5IDYyLjc5NjEgMzkgNzEuNzQ4MkMzOSA4MC43NDQgNDUuNTIwNiA4OC4yMTUxIDU0LjA0NDYgODkuNjYxM1Y5OC4xNzcyQzQ3Ljc4MDEgOTkuNTY1IDQzLjA3NDIgMTA1LjE5NiA0My4wNzQyIDExMS45MjFDNDMuMDc0MiAxMTkuNjg1IDQ5LjM0MTQgMTI2IDU3LjA0MzUgMTI2QzY0Ljc0NTcgMTI2IDcxLjAxMjggMTE5LjY4NSA3MS4wMTI4IDExMS45MjFDNzEuMDEyOCAxMDUuMTk2IDY2LjMwNyA5OS41NjUgNjAuMDQyNCA5OC4xNzcyVjg5LjY2MTFDNjQuMzU2OSA4OC45Mjg2IDY4LjI2MDEgODYuNjQwNyA3MS4wMjUyIDgzLjIyMzRMNzcuNjMzNyA4Ny45Mzc2Qzc3LjI2NjkgODkuMTk1MiA3Ny4wNjE0IDkwLjUyMTkgNzcuMDYxNCA5MS44OTc1Qzc3LjA2MTQgOTkuNjYxMiA4My4zMjg1IDEwNS45NzYgOTEuMDMwNyAxMDUuOTc2Qzk4LjczMjggMTA1Ljk3NiAxMDUgOTkuNjYxMiAxMDUgOTEuODk3NUMxMDUgODQuMTMzOCA5OC43MzI4IDc3LjgxODUgOTEuMDMwNyA3Ny44MTg1Wk05MS4wMzA3IDQ0Ljg5ODVDOTQuNzY1NiA0NC44OTg1IDk3LjgwMzQgNDcuOTYxNSA5Ny44MDM0IDUxLjcyNDdDOTcuODAzNCA1NS40ODc5IDk0Ljc2NTYgNTguNTUwNiA5MS4wMzA3IDU4LjU1MDZDODcuMjk1OCA1OC41NTA2IDg0LjI1OCA1NS40ODc5IDg0LjI1OCA1MS43MjQ3Qzg0LjI1OCA0Ny45NjE1IDg3LjI5NTggNDQuODk4NSA5MS4wMzA3IDQ0Ljg5ODVaTTUwLjI3MDUgMzIuMDc5QzUwLjI3MDUgMjguMzE1OCA1My4zMDg2IDI1LjI1MzEgNTcuMDQzNSAyNS4yNTMxQzYwLjc3ODUgMjUuMjUzMSA2My44MTYzIDI4LjMxNTggNjMuODE2MyAzMi4wNzlDNjMuODE2MyAzNS44NDIyIDYwLjc3ODUgMzguOTA0OSA1Ny4wNDM1IDM4LjkwNDlDNTMuMzA4NiAzOC45MDQ5IDUwLjI3MDUgMzUuODQyMiA1MC4yNzA1IDMyLjA3OVpNNjMuODE2MyAxMTEuOTIxQzYzLjgxNjMgMTE1LjY4NCA2MC43Nzg1IDExOC43NDcgNTcuMDQzNSAxMTguNzQ3QzUzLjMwODYgMTE4Ljc0NyA1MC4yNzA1IDExNS42ODQgNTAuMjcwNSAxMTEuOTIxQzUwLjI3MDUgMTA4LjE1OCA1My4zMDg2IDEwNS4wOTUgNTcuMDQzNSAxMDUuMDk1QzYwLjc3ODUgMTA1LjA5NSA2My44MTYzIDEwOC4xNTggNjMuODE2MyAxMTEuOTIxWk01Ny4wNDMgODEuMjY4MUM1MS44MzM5IDgxLjI2ODEgNDcuNTk2MiA3Ni45OTggNDcuNTk2MiA3MS43NDgyQzQ3LjU5NjIgNjYuNDk4MiA1MS44MzM5IDYyLjIyNzMgNTcuMDQzIDYyLjIyNzNDNjIuMjUxOSA2Mi4yMjczIDY2LjQ4OTUgNjYuNDk4MiA2Ni40ODk1IDcxLjc0ODJDNjYuNDg5NSA3Ni45OTggNjIuMjUxOSA4MS4yNjgxIDU3LjA0MyA4MS4yNjgxWk05MS4wMzA3IDk4LjcyMzdDODcuMjk1OCA5OC43MjM3IDg0LjI1OCA5NS42NjA3IDg0LjI1OCA5MS44OTc1Qzg0LjI1OCA4OC4xMzQzIDg3LjI5NTggODUuMDcxNiA5MS4wMzA3IDg1LjA3MTZDOTQuNzY1NiA4NS4wNzE2IDk3LjgwMzQgODguMTM0MyA5Ny44MDM0IDkxLjg5NzVDOTcuODAzNCA5NS42NjA3IDk0Ljc2NTYgOTguNzIzNyA5MS4wMzA3IDk4LjcyMzdaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4MV8yODIwIiB4MT0iMTQwIiB5MT0iMTMwLjUiIHgyPSI0IiB5Mj0iOS40OTk5OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcC8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzQzNDE0MSIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "topics"], ["spec", "kafka"], ["spec", "kafka", "replicas"], ["spec", "kafka", "resources"], ["spec", "kafka", "resourcesPreset"], ["spec", "kafka", "size"], ["spec", "kafka", "storageClass"], ["spec", "zookeeper"], ["spec", "zookeeper", "replicas"], ["spec", "zookeeper", "resources"], ["spec", "zookeeper", "resourcesPreset"], ["spec", "zookeeper", "size"], ["spec", "zookeeper", "storageClass"]] + secrets: + exclude: [] + include: + - resourceNames: + - kafka-{{ .name }}-clients-ca + services: + exclude: [] + include: + - resourceNames: + - kafka-{{ .name }}-kafka-bootstrap diff --git a/packages/system/kafka-rd/templates/cozyrd.yaml b/packages/system/kafka-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/kafka-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/kafka-rd/values.yaml b/packages/system/kafka-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/kafka-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/kubernetes-rd/Chart.yaml b/packages/system/kubernetes-rd/Chart.yaml new file mode 100644 index 00000000..8fad1a45 --- /dev/null +++ b/packages/system/kubernetes-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: kubernetes-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/kubernetes-rd/Makefile b/packages/system/kubernetes-rd/Makefile new file mode 100644 index 00000000..45969603 --- /dev/null +++ b/packages/system/kubernetes-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=kubernetes-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/kubernetes-rd/cozyrds/kubernetes.yaml b/packages/system/kubernetes-rd/cozyrds/kubernetes.yaml new file mode 100644 index 00000000..05ed110f --- /dev/null +++ b/packages/system/kubernetes-rd/cozyrds/kubernetes.yaml @@ -0,0 +1,46 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: kubernetes +spec: + application: + kind: Kubernetes + singular: kubernetes + plural: kuberneteses + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"addons":{"description":"Cluster addons configuration.","type":"object","default":{},"required":["certManager","cilium","coredns","fluxcd","gatewayAPI","gpuOperator","ingressNginx","monitoringAgents","velero","verticalPodAutoscaler"],"properties":{"certManager":{"description":"Cert-manager addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable cert-manager.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"cilium":{"description":"Cilium CNI plugin.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"coredns":{"description":"CoreDNS addon.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"fluxcd":{"description":"FluxCD GitOps operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable FluxCD.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"gatewayAPI":{"description":"Gateway API addon.","type":"object","default":{},"required":["enabled"],"properties":{"enabled":{"description":"Enable Gateway API.","type":"boolean","default":false}}},"gpuOperator":{"description":"NVIDIA GPU Operator.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable GPU Operator.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"ingressNginx":{"description":"Ingress-NGINX controller.","type":"object","default":{},"required":["enabled","exposeMethod","valuesOverride"],"properties":{"enabled":{"description":"Enable the controller (requires nodes labeled `ingress-nginx`).","type":"boolean","default":false},"exposeMethod":{"description":"Method to expose the controller. Allowed values: `Proxied`, `LoadBalancer`.","type":"string","default":"Proxied"},"hosts":{"description":"Domains routed to this tenant cluster when `exposeMethod` is `Proxied`.","type":"array","default":[],"items":{"type":"string"}},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"monitoringAgents":{"description":"Monitoring agents.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable monitoring agents.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"velero":{"description":"Velero backup/restore addon.","type":"object","default":{},"required":["enabled","valuesOverride"],"properties":{"enabled":{"description":"Enable Velero.","type":"boolean","default":false},"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"verticalPodAutoscaler":{"description":"Vertical Pod Autoscaler.","type":"object","default":{},"required":["valuesOverride"],"properties":{"valuesOverride":{"description":"Custom Helm values overrides.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}}}},"controlPlane":{"description":"Kubernetes control-plane configuration.","type":"object","default":{},"required":["apiServer","controllerManager","konnectivity","replicas","scheduler"],"properties":{"apiServer":{"description":"API Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for API Server.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"medium","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"controllerManager":{"description":"Controller Manager configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Controller Manager.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"konnectivity":{"description":"Konnectivity configuration.","type":"object","default":{},"required":["server"],"properties":{"server":{"description":"Konnectivity Server configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Konnectivity.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"replicas":{"description":"Number of control-plane replicas.","type":"integer","default":2},"scheduler":{"description":"Scheduler configuration.","type":"object","default":{},"required":["resources","resourcesPreset"],"properties":{"resources":{"description":"CPU and memory resources for Scheduler.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Preset if `resources` omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}}}},"host":{"description":"External hostname for Kubernetes cluster. Defaults to `.` if empty.","type":"string","default":""},"nodeGroups":{"description":"Worker nodes configuration map.","type":"object","default":{"md0":{"ephemeralStorage":"20Gi","gpus":[],"instanceType":"u1.medium","maxReplicas":10,"minReplicas":0,"resources":{},"roles":["ingress-nginx"]}},"additionalProperties":{"type":"object","required":["ephemeralStorage","instanceType","maxReplicas","minReplicas","resources"],"properties":{"ephemeralStorage":{"description":"Ephemeral storage size.","default":"20Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","items":{"type":"object","required":["name"],"properties":{"name":{"description":"Name of GPU, such as \"nvidia.com/AD102GL_L40S\".","type":"string"}}}},"instanceType":{"description":"Virtual machine instance type.","type":"string","default":"u1.medium"},"maxReplicas":{"description":"Maximum number of replicas.","type":"integer","default":10},"minReplicas":{"description":"Minimum number of replicas.","type":"integer","default":0},"resources":{"description":"CPU and memory resources for each worker node.","type":"object","properties":{"cpu":{"description":"CPU available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"roles":{"description":"List of node roles.","type":"array","items":{"type":"string"}}}}},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"},"version":{"description":"Kubernetes major.minor version to deploy","type":"string","default":"v1.33","enum":["v1.33","v1.32","v1.31","v1.30","v1.29","v1.28"]}}} + release: + prefix: kubernetes- + labels: + cozystack.io/ui: "true" + chart: + name: kubernetes + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: IaaS + singular: Kubernetes + plural: Kubernetes + weight: 40 + description: Managed Kubernetes service + tags: + - compute + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjg0NSkiLz4KPHBhdGggZD0iTTcxLjk5NjggMTlDNzAuMzAzOSAxOS4wMDAyIDY4LjkzMTIgMjAuNTMyMiA2OC45MzE0IDIyLjQyMjFDNjguOTMxNCAyMi40NTExIDY4LjkzNzMgMjIuNDc4OCA2OC45Mzc5IDIyLjUwNzZDNjguOTM1NCAyMi43NjQ0IDY4LjkyMzEgMjMuMDczNyA2OC45MzE0IDIzLjI5NzNDNjguOTcxNyAyNC4zODczIDY5LjIwODIgMjUuMjIxNiA2OS4zNTA2IDI2LjIyNThDNjkuNjA4NCAyOC4zNzUyIDY5LjgyNDUgMzAuMTU2OSA2OS42OTEyIDMxLjgxM0M2OS41NjE1IDMyLjQzNzUgNjkuMTAzNyAzMy4wMDg2IDY4LjY5NTYgMzMuNDA1Nkw2OC42MjM1IDM0LjcwODZDNjYuNzgzOSAzNC44NjE3IDY0LjkzMTkgMzUuMTQyMSA2My4wODIxIDM1LjU2NDFDNTUuMTIyNiAzNy4zNzk4IDQ4LjI2OTUgNDEuNDk5MSA0My4wNTIgNDcuMDYwOUM0Mi43MTM0IDQ2LjgyODggNDIuMTIxMSA0Ni40MDE5IDQxLjk0NSA0Ni4yNzEyQzQxLjM5NzcgNDYuMzQ1NCA0MC44NDQ1IDQ2LjUxNTEgNDAuMTI0MSA0Ni4wOTM1QzM4Ljc1MjIgNDUuMTY1NyAzNy41MDI4IDQzLjg4NTEgMzUuOTkxIDQyLjM0MjRDMzUuMjk4MiA0MS42MDQ0IDM0Ljc5NjYgNDAuOTAxOCAzMy45NzM1IDQwLjE5MDRDMzMuNzg2NiA0MC4wMjg5IDMzLjUwMTQgMzkuODEwNCAzMy4yOTIzIDM5LjY0NDJDMzIuNjQ4OSAzOS4xMjg4IDMxLjg5IDM4Ljg2IDMxLjE1NyAzOC44MzQ4QzMwLjIxNDcgMzguODAyNCAyOS4zMDc1IDM5LjE3MjUgMjguNzEzOCAzOS45MjA2QzI3LjY1ODQgNDEuMjUwNiAyNy45OTYzIDQzLjI4MzMgMjkuNDY3MSA0NC40NjE0QzI5LjQ4MiA0NC40NzM0IDI5LjQ5NzkgNDQuNDgyNyAyOS41MTI5IDQ0LjQ5NDNDMjkuNzE1IDQ0LjY1ODkgMjkuOTYyNSA0NC44Njk4IDMwLjE0ODMgNDUuMDA3NkMzMS4wMjE3IDQ1LjY1NTUgMzEuODE5NSA0NS45ODcyIDMyLjY4OTcgNDYuNTAxNUMzNC41MjMxIDQ3LjYzOTEgMzYuMDQzIDQ4LjU4MjMgMzcuMjQ4NiA0OS43MTk2QzM3LjcxOTQgNTAuMjIzNyAzNy44MDE2IDUxLjExMjIgMzcuODY0MyA1MS40OTY0TDM4Ljg0NjggNTIuMzc4MkMzMy41ODcyIDYwLjMzMDggMzEuMTUzIDcwLjE1MzkgMzIuNTkxNSA4MC4xNjI3TDMxLjMwNzcgODAuNTM3OEMzMC45NjkzIDgwLjk3NjggMzAuNDkxMiA4MS42Njc2IDI5Ljk5MTEgODEuODczOEMyOC40MTM4IDgyLjM3MjkgMjYuNjM4NyA4Mi41NTYyIDI0LjQ5NTYgODIuNzgxOUMyMy40ODk0IDgyLjg2NiAyMi42MjEzIDgyLjgxNTggMjEuNTU0NiA4My4wMTg4QzIxLjMxOTggODMuMDYzNSAyMC45OTI3IDgzLjE0OTEgMjAuNzM1OCA4My4yMDk3QzIwLjcyNjkgODMuMjExNiAyMC43MTg2IDgzLjIxNDIgMjAuNzA5NiA4My4yMTYyQzIwLjY5NTYgODMuMjE5NSAyMC42NzcyIDgzLjIyNjMgMjAuNjYzOCA4My4yMjk0QzE4Ljg1NyA4My42NjggMTcuNjk2MyA4NS4zMzY1IDE4LjA2OTkgODYuOTgwNUMxOC40NDM3IDg4LjYyNDggMjAuMjA4NiA4OS42MjQ4IDIyLjAyNjIgODkuMjMxMkMyMi4wMzkzIDg5LjIyODIgMjIuMDU4NCA4OS4yMjc3IDIyLjA3MiA4OS4yMjQ2QzIyLjA5MjYgODkuMjE5OSAyMi4xMTA2IDg5LjIwOTkgMjIuMTMxIDg5LjIwNDlDMjIuMzg0NCA4OS4xNDkgMjIuNzAxOSA4OS4wODY4IDIyLjkyMzYgODkuMDI3MkMyMy45NzIzIDg4Ljc0NTEgMjQuNzMxOCA4OC4zMzA2IDI1LjY3NDYgODcuOTY3N0MyNy43MDI5IDg3LjIzNjggMjkuMzgyOCA4Ni42MjYyIDMxLjAxOTUgODYuMzg4M0MzMS43MDMgODYuMzM0NSAzMi40MjMyIDg2LjgxMiAzMi43ODE0IDg3LjAxMzRMMzQuMTE3NyA4Ni43ODMxQzM3LjE5MjYgOTYuMzYxMyA0My42MzY2IDEwNC4xMDMgNTEuNzk2MyAxMDguOTYxTDUxLjIzOTYgMTEwLjMwM0M1MS40NDAzIDExMC44MjQgNTEuNjYxNiAxMTEuNTMgNTEuNTEyMSAxMTIuMDQ1QzUwLjkxNzEgMTEzLjU5NSA0OS44OTggMTE1LjIzMSA0OC43Mzc0IDExNy4wNTVDNDguMTc1NSAxMTcuODk4IDQ3LjYwMDQgMTE4LjU1MiA0Ny4wOTM0IDExOS41MTZDNDYuOTcyIDExOS43NDcgNDYuODE3NSAxMjAuMTAyIDQ2LjcwMDQgMTIwLjM0NkM0NS45MTI1IDEyMi4wMzkgNDYuNDkwNCAxMjMuOTkgNDguMDAzOCAxMjQuNzIyQzQ5LjUyNjggMTI1LjQ1OSA1MS40MTcxIDEyNC42ODIgNTIuMjM1MiAxMjIuOTg1QzUyLjIzNjQgMTIyLjk4MiA1Mi4yNDA2IDEyMi45OCA1Mi4yNDE3IDEyMi45NzhDNTIuMjQyNiAxMjIuOTc2IDUyLjI0MDkgMTIyLjk3MyA1Mi4yNDE3IDEyMi45NzFDNTIuMzU4MiAxMjIuNzMxIDUyLjUyMzMgMTIyLjQxNSA1Mi42MjE2IDEyMi4xODhDNTMuMDU2IDEyMS4xODkgNTMuMjAwNSAxMjAuMzMyIDUzLjUwNTkgMTE5LjM2NUM1NC4zMTcgMTE3LjMxOCA1NC43NjI2IDExNS4xNyA1NS44NzkxIDExMy44MzJDNTYuMTg0OSAxMTMuNDY2IDU2LjY4MzMgMTEzLjMyNSA1Ny4yMDAxIDExMy4xODZMNTcuODk0NCAxMTEuOTIyQzY1LjAwOCAxMTQuNjY1IDcyLjk3MDUgMTE1LjQwMiA4MC45MjQ1IDExMy41ODdDODIuNzM5MSAxMTMuMTczIDg0LjQ5MDggMTEyLjYzNyA4Ni4xODQzIDExMS45OTRDODYuMzc5NCAxMTIuMzQyIDg2Ljc0MiAxMTMuMDExIDg2LjgzOTMgMTEzLjE3OUM4Ny4zNjQ0IDExMy4zNTEgODcuOTM3NyAxMTMuNDM5IDg4LjQwNDcgMTE0LjEzM0M4OS4yNDAxIDExNS41NjcgODkuODExNCAxMTcuMjYzIDkwLjUwNzMgMTE5LjMxMkM5MC44MTI4IDEyMC4yNzkgOTAuOTYzOCAxMjEuMTM2IDkxLjM5ODEgMTIyLjEzNkM5MS40OTcxIDEyMi4zNjMgOTEuNjYxNCAxMjIuNjg0IDkxLjc3OCAxMjIuOTI1QzkyLjU5NDQgMTI0LjYyOCA5NC40OTA3IDEyNS40MDcgOTYuMDE1OSAxMjQuNjY5Qzk3LjUyOTIgMTIzLjkzNyA5OC4xMDc3IDEyMS45ODYgOTcuMzE5NCAxMjAuMjkzQzk3LjIwMjMgMTIwLjA0OSA5Ny4wNDEyIDExOS42OTUgOTYuOTE5OCAxMTkuNDY0Qzk2LjQxMjcgMTE4LjQ5OSA5NS44Mzc3IDExNy44NTIgOTUuMjc1OCAxMTcuMDA5Qzk0LjExNTIgMTE1LjE4NSA5My4xNTI2IDExMy42NyA5Mi41NTc1IDExMi4xMkM5Mi4zMDg3IDExMS4zMiA5Mi41OTk1IDExMC44MjMgOTIuNzkzMyAxMTAuMzAzQzkyLjY3NzIgMTEwLjE3IDkyLjQyODggMTA5LjQxNCA5Mi4yODI0IDEwOS4wNTlDMTAwLjc2MiAxMDQuMDI5IDEwNy4wMTcgOTUuOTk4NSAxMDkuOTU1IDg2LjcyMzlDMTEwLjM1MSA4Ni43ODY1IDExMS4wNDEgODYuOTA5MSAxMTEuMjY1IDg2Ljk1NDJDMTExLjcyNiA4Ni42NDg3IDExMi4xNDkgODYuMjUwMSAxMTIuOTgxIDg2LjMxNTlDMTE0LjYxNyA4Ni41NTM3IDExNi4yOTcgODcuMTY0NSAxMTguMzI2IDg3Ljg5NTNDMTE5LjI2OCA4OC4yNTgxIDEyMC4wMjggODguNjc5MyAxMjEuMDc3IDg4Ljk2MTRDMTIxLjI5OCA4OS4wMjEgMTIxLjYxNiA4OS4wNzY2IDEyMS44NjkgODkuMTMyNUMxMjEuODg5IDg5LjEzNzUgMTIxLjkwOCA4OS4xNDc1IDEyMS45MjggODkuMTUyMkMxMjEuOTQyIDg5LjE1NTMgMTIxLjk2MSA4OS4xNTU4IDEyMS45NzQgODkuMTU4OEMxMjMuNzkyIDg5LjU1MiAxMjUuNTU3IDg4LjU1MjYgMTI1LjkzIDg2LjkwODFDMTI2LjMwMyA4NS4yNjQxIDEyNS4xNDMgODMuNTk1MiAxMjMuMzM2IDgzLjE1N0MxMjMuMDc0IDgzLjA5NyAxMjIuNzAxIDgyLjk5NSAxMjIuNDQ2IDgyLjk0NjVDMTIxLjM3OSA4Mi43NDM1IDEyMC41MTEgODIuNzkzNSAxMTkuNTA1IDgyLjcwOTVDMTE3LjM2MSA4Mi40ODM5IDExNS41ODYgODIuMzAwNCAxMTQuMDA5IDgxLjgwMTRDMTEzLjM2NiA4MS41NTA3IDExMi45MDggODAuNzgxOSAxMTIuNjg2IDgwLjQ2NTVMMTExLjQ0OCA4MC4xMDM1QzExMi4wOSA3NS40MzggMTExLjkxNyA3MC41ODI1IDExMC44MDYgNjUuNzI0M0MxMDkuNjg1IDYwLjgyMDggMTA3LjcwNCA1Ni4zMzYxIDEwNS4wNjIgNTIuMzg0OEMxMDUuMzc5IDUyLjA5NDggMTA1Ljk3OSA1MS41NjEyIDEwNi4xNDkgNTEuNDA0M0MxMDYuMTk5IDUwLjg1MTcgMTA2LjE1NiA1MC4yNzIyIDEwNi43MjUgNDkuNjYwM0MxMDcuOTMxIDQ4LjUyMyAxMDkuNDUxIDQ3LjU3OTkgMTExLjI4NCA0Ni40NDIzQzExMi4xNTQgNDUuOTI3OSAxMTIuOTU5IDQ1LjU5NjQgMTEzLjgzMiA0NC45NDg0QzExNC4wMyA0NC44MDE5IDExNC4yOTkgNDQuNTY5OSAxMTQuNTA3IDQ0LjQwMjJDMTE1Ljk3NyA0My4yMjM3IDExNi4zMTYgNDEuMTkxMSAxMTUuMjYgMzkuODYxNEMxMTQuMjA0IDM4LjUzMTcgMTEyLjE1OSAzOC40MDY1IDExMC42ODggMzkuNTg1QzExMC40NzkgMzkuNzUxNiAxMTAuMTk1IDM5Ljk2ODggMTEwLjAwNyA0MC4xMzEyQzEwOS4xODQgNDAuODQyNiAxMDguNjc2IDQxLjU0NTIgMTA3Ljk4MyA0Mi4yODMyQzEwNi40NzEgNDMuODI1OSAxMDUuMjIyIDQ1LjExMyAxMDMuODUgNDYuMDQwOUMxMDMuMjU1IDQ2LjM4ODUgMTAyLjM4NSA0Ni4yNjgyIDEwMS45OSA0Ni4yNDQ5TDEwMC44MjQgNDcuMDgwNkM5NC4xNzUzIDQwLjA3NjMgODUuMTIzNSAzNS41OTgyIDc1LjM3NjYgMzQuNzI4M0M3NS4zNDk0IDM0LjMxNzkgNzUuMzEzNyAzMy41NzYxIDc1LjMwNDYgMzMuMzUyOUM3NC45MDU2IDMyLjk2OTMgNzQuNDIzNSAzMi42NDE4IDc0LjMwMjQgMzEuODEzQzc0LjE2OTEgMzAuMTU2OSA3NC4zOTE3IDI4LjM3NTIgNzQuNjQ5NiAyNi4yMjU4Qzc0Ljc5MTkgMjUuMjIxNiA3NS4wMjg0IDI0LjM4NzMgNzUuMDY4OCAyMy4yOTczQzc1LjA3OCAyMy4wNDk1IDc1LjA2MzIgMjIuNjkgNzUuMDYyMiAyMi40MjIxQzc1LjA2MiAyMC41MzIyIDczLjY4OTggMTguOTk5OCA3MS45OTY4IDE5Wk02OC4xNTg1IDQyLjg4ODZMNjcuMjQ4IDU5LjA0NDdMNjcuMTgyNSA1OS4wNzc2QzY3LjEyMTQgNjAuNTIyOSA2NS45Mzc1IDYxLjY3NyA2NC40ODM5IDYxLjY3N0M2My44ODg0IDYxLjY3NyA2My4zMzg4IDYxLjQ4NDkgNjIuODkyMiA2MS4xNTcxTDYyLjg2NiA2MS4xNzAzTDQ5LjY4MDcgNTEuNzc5NEM1My43MzMxIDQ3Ljc3NTkgNTguOTE2NCA0NC44MTcyIDY0Ljg5IDQzLjQ1NDZDNjUuOTgxMiA0My4yMDU2IDY3LjA3MTkgNDMuMDIwOSA2OC4xNTg1IDQyLjg4ODZaTTc1Ljg0MTcgNDIuODg4NkM4Mi44MTU5IDQzLjc1MDQgODkuMjY1NyA0Ni45MjMyIDk0LjIwODEgNTEuNzg2TDgxLjEwOCA2MS4xMTc2TDgxLjA2MjEgNjEuMDk3OUM3OS44OTk0IDYxLjk1MTIgNzguMjYxMSA2MS43Mzk0IDc3LjM1NDggNjAuNTk3OEM3Ni45ODM1IDYwLjEzMDEgNzYuNzg4NyA1OS41ODAxIDc2Ljc2NTMgNTkuMDI0OUw3Ni43NTIyIDU5LjAxODRMNzUuODQxNyA0Mi44ODg2Wk00NC44OTkxIDU3LjgxNEw1Ni45MzgyIDY4LjYzM0w1Ni45MjUxIDY4LjY5ODhDNTguMDExNyA2OS42NDc5IDU4LjE3MiA3MS4yOTQ5IDU3LjI2NTcgNzIuNDM2OEM1Ni44OTQ0IDcyLjkwNDUgNTYuMzk3NSA3My4yMTgyIDU1Ljg2MzkgNzMuMzY0N0w1NS44NTA4IDczLjQxNzNMNDAuNDE4OCA3Ny44OTIzQzM5LjYzMzQgNzAuNjc2NSA0MS4zMjYxIDYzLjY2MjEgNDQuODk5MSA1Ny44MTRaTTk5LjAwOTQgNTcuODIwNkMxMDAuNzk4IDYwLjczMzYgMTAyLjE1MyA2My45ODcxIDEwMi45NTkgNjcuNTE0M0MxMDMuNzU2IDcwLjk5OTEgMTAzLjk1NiA3NC40Nzc4IDEwMy42MjcgNzcuODM5N0w4OC4xMTY2IDczLjM1MTVMODguMTAzNSA3My4yODU3Qzg2LjcxNDUgNzIuOTA0MyA4NS44NjA5IDcxLjQ4NDggODYuMTg0MyA3MC4wNjExQzg2LjMxNjggNjkuNDc3OCA4Ni42MjQ5IDY4Ljk4NDQgODcuMDQyMyA2OC42MTk4TDg3LjAzNTggNjguNTg2OUw5OS4wMDk0IDU3LjgyMDZaTTY5LjUyNzQgNjkuNDY4OEg3NC40NTk2TDc3LjUyNTEgNzMuMzE4Nkw3Ni40MjQ3IDc4LjEyMjZMNzEuOTk2OCA4MC4yNjE0TDY3LjU1NTggNzguMTE2MUw2Ni40NTU0IDczLjMxMkw2OS41Mjc0IDY5LjQ2ODhaTTg1LjMzOTMgODIuNjQzN0M4NS41NDg5IDgyLjYzMzEgODUuNzU3NiA4Mi42NTIgODUuOTYxNiA4Mi42ODk4TDg1Ljk4NzggODIuNjU2OUwxMDEuOTUgODUuMzY4MkM5OS42MTQyIDkxLjk2MjQgOTUuMTQ0IDk3LjY3NSA4OS4xNzExIDEwMS40OThMODIuOTc0NyA4Ni40NjA2TDgyLjk5NDQgODYuNDM0M0M4Mi40MjUyIDg1LjEwNTUgODIuOTk0OCA4My41NDcyIDg0LjMwNDQgODIuOTEzNUM4NC42Mzk3IDgyLjc1MTMgODQuOTkgODIuNjYxNCA4NS4zMzkzIDgyLjY0MzdaTTU4LjUyOTggODIuNzA5NUM1OS43NDggODIuNzI2NyA2MC44NDA2IDgzLjU3NjEgNjEuMTIzNyA4NC44MjJDNjEuMjU2MiA4NS40MDUyIDYxLjE5MTcgODUuOTgzMSA2MC45NzMgODYuNDkzNUw2MS4wMTg5IDg2LjU1MjdMNTQuODg4IDEwMS40MzlDNDkuMTU1OSA5Ny43NDMyIDQ0LjU5MDQgOTIuMjA5OSA0Mi4xNDgxIDg1LjQyMDhMNTcuOTczMSA4Mi43MjI3TDU3Ljk5OTMgODIuNzU1NkM1OC4xNzYzIDgyLjcyMjkgNTguMzU1OCA4Mi43MDcxIDU4LjUyOTggODIuNzA5NVpNNzEuODk4NiA4OS4yMzEyQzcyLjMyMjkgODkuMjE1NSA3Mi43NTM0IDg5LjMwMyA3My4xNjI3IDg5LjUwMUM3My42OTkyIDg5Ljc2MDYgNzQuMTEzNiA5MC4xNjkyIDc0LjM3NDUgOTAuNjU5Mkg3NC40MzM0TDgyLjIzNDYgMTA0LjgyMUM4MS4yMjIxIDEwNS4xNjIgODAuMTgxMyAxMDUuNDU0IDc5LjExNjcgMTA1LjY5N0M3My4xNTA1IDEwNy4wNTggNjcuMjAzMiAxMDYuNjQ1IDYxLjgxOCAxMDQuODAyTDY5LjU5OTUgOTAuNjY1OEg2OS42MTI2QzcwLjA3OTUgODkuNzg4OCA3MC45NjUgODkuMjY1NiA3MS44OTg2IDg5LjIzMTJaIiBmaWxsPSJ3aGl0ZSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjI1Ii8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgxXzI4NDUiIHgxPSIxMCIgeTE9IjE1LjUiIHgyPSIxNDQiIHkyPSIxMzEuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNEQ4N0ZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzA1NDdEMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "storageClass"], ["spec", "nodeGroups"], ["spec", "nodeGroups", "md0"], ["spec", "nodeGroups", "md0", "minReplicas"], ["spec", "nodeGroups", "md0", "maxReplicas"], ["spec", "nodeGroups", "md0", "instanceType"], ["spec", "nodeGroups", "md0", "ephemeralStorage"], ["spec", "nodeGroups", "md0", "roles"], ["spec", "nodeGroups", "md0", "resources"], ["spec", "nodeGroups", "md0", "gpus"], ["spec", "version"], ["spec", "host"], ["spec", "addons"], ["spec", "addons", "certManager"], ["spec", "addons", "certManager", "enabled"], ["spec", "addons", "certManager", "valuesOverride"], ["spec", "addons", "cilium"], ["spec", "addons", "cilium", "valuesOverride"], ["spec", "addons", "gatewayAPI"], ["spec", "addons", "gatewayAPI", "enabled"], ["spec", "addons", "ingressNginx"], ["spec", "addons", "ingressNginx", "enabled"], ["spec", "addons", "ingressNginx", "exposeMethod"], ["spec", "addons", "ingressNginx", "hosts"], ["spec", "addons", "ingressNginx", "valuesOverride"], ["spec", "addons", "gpuOperator"], ["spec", "addons", "gpuOperator", "enabled"], ["spec", "addons", "gpuOperator", "valuesOverride"], ["spec", "addons", "fluxcd"], ["spec", "addons", "fluxcd", "enabled"], ["spec", "addons", "fluxcd", "valuesOverride"], ["spec", "addons", "monitoringAgents"], ["spec", "addons", "monitoringAgents", "enabled"], ["spec", "addons", "monitoringAgents", "valuesOverride"], ["spec", "addons", "verticalPodAutoscaler"], ["spec", "addons", "verticalPodAutoscaler", "valuesOverride"], ["spec", "addons", "velero"], ["spec", "addons", "velero", "enabled"], ["spec", "addons", "velero", "valuesOverride"], ["spec", "addons", "coredns"], ["spec", "addons", "coredns", "valuesOverride"], ["spec", "controlPlane"], ["spec", "controlPlane", "replicas"], ["spec", "controlPlane", "apiServer"], ["spec", "controlPlane", "apiServer", "resources"], ["spec", "controlPlane", "apiServer", "resourcesPreset"], ["spec", "controlPlane", "controllerManager"], ["spec", "controlPlane", "controllerManager", "resources"], ["spec", "controlPlane", "controllerManager", "resourcesPreset"], ["spec", "controlPlane", "scheduler"], ["spec", "controlPlane", "scheduler", "resources"], ["spec", "controlPlane", "scheduler", "resourcesPreset"], ["spec", "controlPlane", "konnectivity"], ["spec", "controlPlane", "konnectivity", "server"], ["spec", "controlPlane", "konnectivity", "server", "resources"], ["spec", "controlPlane", "konnectivity", "server", "resourcesPreset"]] + secrets: + exclude: [] + include: + - resourceNames: + - kubernetes-{{ .name }}-admin-kubeconfig + services: + exclude: [] + include: + - resourceNames: + - kubernetes-{{ .name }} + ingresses: + exclude: [] + include: + - resourceNames: + - kubernetes-{{ .name }} diff --git a/packages/system/kubernetes-rd/templates/cozyrd.yaml b/packages/system/kubernetes-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/kubernetes-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/kubernetes-rd/values.yaml b/packages/system/kubernetes-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/kubernetes-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/monitoring-rd/Chart.yaml b/packages/system/monitoring-rd/Chart.yaml new file mode 100644 index 00000000..cac8a99d --- /dev/null +++ b/packages/system/monitoring-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: monitoring-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/monitoring-rd/Makefile b/packages/system/monitoring-rd/Makefile new file mode 100644 index 00000000..ecce61e3 --- /dev/null +++ b/packages/system/monitoring-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=monitoring-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/monitoring-rd/cozyrds/monitoring.yaml b/packages/system/monitoring-rd/cozyrds/monitoring.yaml new file mode 100644 index 00000000..720dc161 --- /dev/null +++ b/packages/system/monitoring-rd/cozyrds/monitoring.yaml @@ -0,0 +1,48 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: monitoring +spec: + application: + kind: Monitoring + singular: monitoring + plural: monitorings + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"alerta":{"description":"Configuration for the Alerta service.","type":"object","default":{},"properties":{"alerts":{"description":"Alert routing configuration.","type":"object","default":{},"properties":{"slack":{"description":"Configuration for Slack alerts.","type":"object","default":{},"required":["url"],"properties":{"url":{"description":"Configuration uri for Slack alerts.","type":"string","default":""}}},"telegram":{"description":"Configuration for Telegram alerts.","type":"object","default":{},"required":["chatID","token"],"properties":{"chatID":{"description":"Telegram chat ID(s), separated by commas.","type":"string","default":""},"disabledSeverity":{"description":"List of severities without alerts (e.g. \"informational,warning\").","type":"string","default":""},"token":{"description":"Telegram bot token.","type":"string","default":""}}}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"storage":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the database.","type":"string","default":""}}},"grafana":{"description":"Configuration for Grafana.","type":"object","default":{},"properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"size":{"description":"Persistent volume size for the database.","type":"string","default":"10Gi"}}},"resources":{"description":"Resource configuration.","type":"object","default":{},"properties":{"limits":{"description":"Resource limits.","type":"object","default":{},"properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"requests":{"description":"Resource requests.","type":"object","default":{},"properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}},"host":{"description":"The hostname used to access Grafana externally (defaults to 'grafana' subdomain for the tenant host).","type":"string","default":""},"logsStorages":{"description":"Configuration of logs storage instances.","type":"array","default":[{"name":"generic","retentionPeriod":"1","storage":"10Gi","storageClassName":"replicated"}],"items":{"type":"object","required":["name","retentionPeriod","storage","storageClassName"],"properties":{"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for logs.","type":"string","default":"1"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}},"metricsStorages":{"description":"Configuration of metrics storage instances.","type":"array","default":[{"deduplicationInterval":"15s","name":"shortterm","retentionPeriod":"3d","storage":"10Gi","storageClassName":""},{"deduplicationInterval":"5m","name":"longterm","retentionPeriod":"14d","storage":"10Gi","storageClassName":""}],"items":{"type":"object","required":["deduplicationInterval","name","retentionPeriod","storage"],"properties":{"deduplicationInterval":{"description":"Deduplication interval for metrics.","type":"string"},"name":{"description":"Name of the storage instance.","type":"string"},"retentionPeriod":{"description":"Retention period for metrics.","type":"string"},"storage":{"description":"Persistent volume size.","type":"string","default":"10Gi"},"storageClassName":{"description":"StorageClass used for the data.","type":"string"},"vminsert":{"description":"Configuration for vminsert.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmselect":{"description":"Configuration for vmselect.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}},"vmstorage":{"description":"Configuration for vmstorage.","type":"object","properties":{"maxAllowed":{"description":"Maximum allowed resources.","type":"object","properties":{"cpu":{"description":"CPU limit.","default":1,"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory limit.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"minAllowed":{"description":"Minimum guaranteed resources.","type":"object","properties":{"cpu":{"description":"CPU request.","default":"100m","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory request.","default":"256Mi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}}},"vmagent":{"description":"Configuration for VictoriaMetrics Agent.","type":"object","default":{},"properties":{"externalLabels":{"description":"External labels applied to all metrics.","default":{"cluster":"cozystack"}},"remoteWrite":{"description":"Remote write configuration.","default":{"urls":["http://vminsert-shortterm:8480/insert/0/prometheus","http://vminsert-longterm:8480/insert/0/prometheus"]}}}}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + chart: + name: monitoring + sourceRef: + kind: HelmRepository + name: cozystack-extra + namespace: cozy-public + dashboard: + category: Administration + singular: Monitoring + plural: Monitoring + name: monitoring + description: Monitoring and observability stack + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzI2OCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zMjY4KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMzg0NTRGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNNTQuMTcyMiAzOC43NzU3SDMzLjEwMzJDMzIuMTMwNyAzOC43NzU3IDMxLjQ4MjQgMzguMTI3NCAzMS40ODI0IDM3LjE1NDlDMzEuNDgyNCAzNi4xODI0IDMyLjEzMDcgMzUuNTM0MiAzMy4xMDMyIDM1LjUzNDJINTQuMTcyMkM1NS4xNDQ3IDM1LjUzNDIgNTUuNzkzIDM2LjE4MjQgNTUuNzkzIDM3LjE1NDlDNTUuNzkyOCAzOC4xMjc0IDU1LjE0NDUgMzguNzc1NyA1NC4xNzIyIDM4Ljc3NTdaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik02My44OTYzIDQ1LjI1OTFINDEuMjA2N0M0MC4yMzQyIDQ1LjI1OTEgMzkuNTg1OSA0NC42MTA4IDM5LjU4NTkgNDMuNjM4M0MzOS41ODU5IDQyLjY2NTggNDAuMjM0MiA0Mi4wMTc2IDQxLjIwNjcgNDIuMDE3Nkg2My44OTYzQzY0Ljg2ODggNDIuMDE3NiA2NS41MTcxIDQyLjY2NTggNjUuNTE3MSA0My42MzgzQzY1LjUxNzEgNDQuNjEwOCA2NC44Njg4IDQ1LjI1OTEgNjMuODk2MyA0NS4yNTkxWiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMzQuNzI0IDQ1LjI1OTFIMzMuMTAzMkMzMi4xMzA3IDQ1LjI1OTEgMzEuNDgyNCA0NC42MTA4IDMxLjQ4MjQgNDMuNjM4M0MzMS40ODI0IDQyLjY2NTggMzIuMTMwNyA0Mi4wMTc2IDMzLjEwMzIgNDIuMDE3NkgzNC43MjRDMzUuNjk2NCA0Mi4wMTc2IDM2LjM0NDcgNDIuNjY1OCAzNi4zNDQ3IDQzLjYzODNDMzYuMzQ0NyA0NC42MTA4IDM1LjY5NjMgNDUuMjU5MSAzNC43MjQgNDUuMjU5MVoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgMzguNzc1N0g2MC42NTQ5QzU5LjY4MjQgMzguNzc1NyA1OS4wMzQyIDM4LjEyNzQgNTkuMDM0MiAzNy4xNTQ5QzU5LjAzNDIgMzYuMTgyNCA1OS42ODI0IDM1LjUzNDIgNjAuNjU0OSAzNS41MzQySDYzLjg5NjNDNjQuODY4OCAzNS41MzQyIDY1LjUxNzEgMzYuMTgyNCA2NS41MTcxIDM3LjE1NDlDNjUuNTE3MSAzOC4xMjc0IDY0Ljg2ODggMzguNzc1NyA2My44OTYzIDM4Ljc3NTdaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik00Ny42ODkzIDUxLjc0MTNIMzMuMTAzMkMzMi4xMzA3IDUxLjc0MTMgMzEuNDgyNCA1MS4wOTMxIDMxLjQ4MjQgNTAuMTIwNkMzMS40ODI0IDQ5LjE0ODEgMzIuMTMwNyA0OC41IDMzLjEwMzIgNDguNUg0Ny42ODkzQzQ4LjY2MTggNDguNSA0OS4zMTAxIDQ5LjE0ODMgNDkuMzEwMSA1MC4xMjA4QzQ5LjMxMDEgNTEuMDkzMyA0OC42NjE4IDUxLjc0MTMgNDcuNjg5MyA1MS43NDEzWiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNjMuODk2OCA1MS43NDEzSDU0LjE3MjVDNTMuMiA1MS43NDEzIDUyLjU1MTggNTEuMDkzMSA1Mi41NTE4IDUwLjEyMDZDNTIuNTUxOCA0OS4xNDgxIDUzLjIwMDIgNDguNSA1NC4xNzI3IDQ4LjVINjMuODk2OUM2NC44Njk0IDQ4LjUgNjUuNTE3NyA0OS4xNDgzIDY1LjUxNzcgNTAuMTIwOEM2NS41MTc3IDUxLjA5MzMgNjQuODY5MiA1MS43NDEzIDYzLjg5NjggNTEuNzQxM1oiIGZpbGw9IiNFQ0JBMTYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNTguMjI0SDMzLjEwMzJDMzIuMTMwNyA1OC4yMjQgMzEuNDgyNCA1Ny41NzU3IDMxLjQ4MjQgNTYuNjAzMkMzMS40ODI0IDU1LjYzMDcgMzIuMTMwNyA1NC45ODI0IDMzLjEwMzIgNTQuOTgyNEg1NC4xNzIyQzU1LjE0NDcgNTQuOTgyNCA1NS43OTMgNTUuNjMwNyA1NS43OTMgNTYuNjAzMkM1NS43OTMgNTcuNTc1NyA1NS4xNDQ1IDU4LjIyNCA1NC4xNzIyIDU4LjIyNFoiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTYzLjg5NjMgNjQuNzA3NEg0MS4yMDY3QzQwLjIzNDIgNjQuNzA3NCAzOS41ODU5IDY0LjA1OTEgMzkuNTg1OSA2My4wODY2QzM5LjU4NTkgNjIuMTE0MSA0MC4yMzQyIDYxLjQ2NTggNDEuMjA2NyA2MS40NjU4SDYzLjg5NjNDNjQuODY4OCA2MS40NjU4IDY1LjUxNzEgNjIuMTE0MSA2NS41MTcxIDYzLjA4NjZDNjUuNTE3MSA2NC4wNTkxIDY0Ljg2ODggNjQuNzA3NCA2My44OTYzIDY0LjcwNzRaIiBmaWxsPSIjRUNCQTE2Ii8+CjxwYXRoIGQ9Ik0zNC43MjQgNjQuNzA3NEgzMy4xMDMyQzMyLjEzMDcgNjQuNzA3NCAzMS40ODI0IDY0LjA1OTEgMzEuNDgyNCA2My4wODY2QzMxLjQ4MjQgNjIuMTE0MSAzMi4xMzA3IDYxLjQ2NTggMzMuMTAzMiA2MS40NjU4SDM0LjcyNEMzNS42OTY0IDYxLjQ2NTggMzYuMzQ0NyA2Mi4xMTQxIDM2LjM0NDcgNjMuMDg2NkMzNi4zNDQ3IDY0LjA1OTEgMzUuNjk2MyA2NC43MDc0IDM0LjcyNCA2NC43MDc0WiIgZmlsbD0iI0REMzQyRSIvPgo8cGF0aCBkPSJNNDcuNjg5MyA3MS4xODk4SDMzLjEwMzJDMzIuMTMwNyA3MS4xODk4IDMxLjQ4MjQgNzAuNTQxNSAzMS40ODI0IDY5LjU2OUMzMS40ODI0IDY4LjU5NjUgMzIuMTMwNyA2Ny45NDgyIDMzLjEwMzIgNjcuOTQ4Mkg0Ny42ODkzQzQ4LjY2MTggNjcuOTQ4MiA0OS4zMTAxIDY4LjU5NjUgNDkuMzEwMSA2OS41NjlDNDkuMzEwMSA3MC41NDE1IDQ4LjY2MTggNzEuMTg5OCA0Ny42ODkzIDcxLjE4OThaIiBmaWxsPSIjNDJCMDVDIi8+CjxwYXRoIGQ9Ik02My44OTY4IDcxLjE4OThINTQuMTcyNUM1My4yIDcxLjE4OTggNTIuNTUxOCA3MC41NDE1IDUyLjU1MTggNjkuNTY5QzUyLjU1MTggNjguNTk2NSA1My4yIDY3Ljk0ODIgNTQuMTcyNSA2Ny45NDgySDYzLjg5NjhDNjQuODY5MiA2Ny45NDgyIDY1LjUxNzUgNjguNTk2NSA2NS41MTc1IDY5LjU2OUM2NS41MTc1IDcwLjU0MTUgNjQuODY5MiA3MS4xODk4IDYzLjg5NjggNzEuMTg5OFoiIGZpbGw9IiM3MzgzQkYiLz4KPHBhdGggZD0iTTU0LjE3MjIgNzcuNjcyMkgzMy4xMDMyQzMyLjEzMDcgNzcuNjcyMiAzMS40ODI0IDc3LjAyMzkgMzEuNDgyNCA3Ni4wNTE0QzMxLjQ4MjQgNzUuMDc4OSAzMi4xMzA3IDc0LjQzMDcgMzMuMTAzMiA3NC40MzA3SDU0LjE3MjJDNTUuMTQ0NyA3NC40MzA3IDU1Ljc5MyA3NS4wNzg5IDU1Ljc5MyA3Ni4wNTE0QzU1Ljc5MjggNzcuMDIzOSA1NS4xNDQ1IDc3LjY3MjIgNTQuMTcyMiA3Ny42NzIyWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNNjMuODk2MyA3Ny42NzIySDYwLjY1NDlDNTkuNjgyNCA3Ny42NzIyIDU5LjAzNDIgNzcuMDIzOSA1OS4wMzQyIDc2LjA1MTRDNTkuMDM0MiA3NS4wNzg5IDU5LjY4MjQgNzQuNDMwNyA2MC42NTQ5IDc0LjQzMDdINjMuODk2M0M2NC44Njg4IDc0LjQzMDcgNjUuNTE3MSA3NS4wNzg5IDY1LjUxNzEgNzYuMDUxNEM2NS41MTcxIDc3LjAyMzkgNjQuODY4OCA3Ny42NzIyIDYzLjg5NjMgNzcuNjcyMloiIGZpbGw9IiM0MkIwNUMiLz4KPHBhdGggZD0iTTEwMS4xNzIgNzcuNjcyMkg4MC4xMDMyQzc5LjEzMDcgNzcuNjcyMiA3OC40ODI0IDc3LjAyMzkgNzguNDgyNCA3Ni4wNTE0Qzc4LjQ4MjQgNzUuMDc4OSA3OS4xMzA3IDc0LjQzMDcgODAuMTAzMiA3NC40MzA3SDEwMS4xNzJDMTAyLjE0NSA3NC40MzA3IDEwMi43OTMgNzUuMDc4OSAxMDIuNzkzIDc2LjA1MTRDMTAyLjc5MyA3Ny4wMjM5IDEwMi4xNDUgNzcuNjcyMiAxMDEuMTcyIDc3LjY3MjJaIiBmaWxsPSIjREQzNDJFIi8+CjxwYXRoIGQ9Ik0xMTAuODk2IDc3LjY3MjJIMTA3LjY1NUMxMDYuNjgyIDc3LjY3MjIgMTA2LjAzNCA3Ny4wMjM5IDEwNi4wMzQgNzYuMDUxNEMxMDYuMDM0IDc1LjA3ODkgMTA2LjY4MiA3NC40MzA3IDEwNy42NTUgNzQuNDMwN0gxMTAuODk2QzExMS44NjkgNzQuNDMwNyAxMTIuNTE3IDc1LjA3ODkgMTEyLjUxNyA3Ni4wNTE0QzExMi41MTcgNzcuMDIzOSAxMTEuODY5IDc3LjY3MjIgMTEwLjg5NiA3Ny42NzIyWiIgZmlsbD0iIzQyQjA1QyIvPgo8cGF0aCBkPSJNNjMuODk2MyA1OC4yMjRINjAuNjU0OUM1OS42ODI0IDU4LjIyNCA1OS4wMzQyIDU3LjU3NTcgNTkuMDM0MiA1Ni42MDMyQzU5LjAzNDIgNTUuNjMwNyA1OS42ODI0IDU0Ljk4MjQgNjAuNjU0OSA1NC45ODI0SDYzLjg5NjNDNjQuODY4OCA1NC45ODI0IDY1LjUxNzEgNTUuNjMwNyA2NS41MTcxIDU2LjYwMzJDNjUuNTE3MSA1Ny41NzU3IDY0Ljg2ODggNTguMjI0IDYzLjg5NjMgNTguMjI0WiIgZmlsbD0iIzczODNCRiIvPgo8cGF0aCBkPSJNMTEyLjUxNyA1MS43NDExQzExMi41MTcgNjAuNjU0OSAxMDUuMjI0IDY3Ljk0OCA5Ni4zMTA0IDY3Ljk0OEM4Ny4zOTY2IDY3Ljk0OCA4MC4xMDM1IDYwLjY1NDkgODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNDIuODI3MyA4Ny4zOTY2IDM1LjUzNDIgOTYuMzEwNCAzNS41MzQyQzEwNS4yMjQgMzUuNTM0MiAxMTIuNTE3IDQyLjgyNzMgMTEyLjUxNyA1MS43NDExWiIgZmlsbD0iI0VDQkExNiIvPgo8cGF0aCBkPSJNODAuMTAzNSA1MS43NDExQzgwLjEwMzUgNTIuMjI3MyA4MC4xMDM1IDUyLjg3NTUgODAuMTAzNSA1My4zNjE5SDk2LjMxMDRWMzUuNTM0MkM4Ny4zOTY2IDM1LjUzNDIgODAuMTAzNSA0Mi44MjczIDgwLjEwMzUgNTEuNzQxMVoiIGZpbGw9IiM0MkIwNUMiLz4KPC9nPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zMjY4IiB4MT0iMS4yMzIzOWUtMDYiIHkxPSItOS41MDAwMSIgeDI9IjE2OCIgeTI9IjE2MiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjOEZEREZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNzVGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zMjY4Ij4KPHJlY3Qgd2lkdGg9Ijk0IiBoZWlnaHQ9Ijk0IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjUgMjUpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "metricsStorages"], ["spec", "logsStorages"], ["spec", "alerta"], ["spec", "alerta", "storage"], ["spec", "alerta", "storageClassName"], ["spec", "alerta", "resources"], ["spec", "alerta", "resources", "limits"], ["spec", "alerta", "resources", "limits", "cpu"], ["spec", "alerta", "resources", "limits", "memory"], ["spec", "alerta", "resources", "requests"], ["spec", "alerta", "resources", "requests", "cpu"], ["spec", "alerta", "resources", "requests", "memory"], ["spec", "alerta", "alerts"], ["spec", "alerta", "alerts", "telegram"], ["spec", "alerta", "alerts", "telegram", "token"], ["spec", "alerta", "alerts", "telegram", "chatID"], ["spec", "alerta", "alerts", "telegram", "disabledSeverity"], ["spec", "alerta", "alerts", "slack"], ["spec", "alerta", "alerts", "slack", "url"], ["spec", "grafana"], ["spec", "grafana", "db"], ["spec", "grafana", "db", "size"], ["spec", "grafana", "resources"], ["spec", "grafana", "resources", "limits"], ["spec", "grafana", "resources", "limits", "cpu"], ["spec", "grafana", "resources", "limits", "memory"], ["spec", "grafana", "resources", "requests"], ["spec", "grafana", "resources", "requests", "cpu"], ["spec", "grafana", "resources", "requests", "memory"], ["spec", "vmagent"], ["spec", "vmagent", "externalLabels"], ["spec", "vmagent", "externalLabels", "cluster"], ["spec", "vmagent", "remoteWrite"], ["spec", "vmagent", "remoteWrite", "urls"]] + secrets: + exclude: [] + include: + - resourceNames: + - grafana-admin-password + services: + exclude: [] + include: + - resourceNames: + - grafana-service + - alerta + ingresses: + exclude: [] + include: + - resourceNames: + - grafana-ingress + - alerta diff --git a/packages/system/monitoring-rd/templates/cozyrd.yaml b/packages/system/monitoring-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/monitoring-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/monitoring-rd/values.yaml b/packages/system/monitoring-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/monitoring-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/mysql-rd/Chart.yaml b/packages/system/mysql-rd/Chart.yaml new file mode 100644 index 00000000..d3c6b081 --- /dev/null +++ b/packages/system/mysql-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: mysql-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/mysql-rd/Makefile b/packages/system/mysql-rd/Makefile new file mode 100644 index 00000000..a2d28923 --- /dev/null +++ b/packages/system/mysql-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=mysql-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/mysql-rd/cozyrds/mysql.yaml b/packages/system/mysql-rd/cozyrds/mysql.yaml new file mode 100644 index 00000000..ba8251b8 --- /dev/null +++ b/packages/system/mysql-rd/cozyrds/mysql.yaml @@ -0,0 +1,41 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: mysql +spec: + application: + kind: MySQL + plural: mysqls + singular: mysql + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["cleanupStrategy","enabled","resticPassword","s3AccessKey","s3Bucket","s3Region","s3SecretKey","schedule"],"properties":{"cleanupStrategy":{"description":"Retention strategy for cleaning up old backups.","type":"string","default":"--keep-last=3 --keep-daily=3 --keep-within-weekly=1m"},"enabled":{"description":"Enable regular backups (default: false).","type":"boolean","default":false},"resticPassword":{"description":"Password for Restic backup encryption.","type":"string","default":""},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3Bucket":{"description":"S3 bucket used for storing backups.","type":"string","default":"s3.example.org/mysql-backups"},"s3Region":{"description":"AWS S3 region where backups are stored.","type":"string","default":"us-east-1"},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * *"}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of MariaDB replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each MariaDB replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","required":["maxUserConnections","password"],"properties":{"maxUserConnections":{"description":"Maximum number of connections.","type":"integer"},"password":{"description":"Password for the user.","type":"string"}}}},"version":{"description":"MariaDB major.minor version to deploy","type":"string","default":"v11.8","enum":["v11.8","v11.4","v10.11","v10.6"]}}} + release: + prefix: mysql- + labels: + cozystack.io/ui: "true" + chart: + name: mysql + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: MySQL + plural: MySQL + description: Managed MariaDB service + tags: + - database + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5MzApIi8+CjxwYXRoIGQ9Ik0xMzMuMTkxIDI5LjAwMjJDMTMxLjIxMyAyOS4wNjU0IDEzMS44MzkgMjkuNjM1NCAxMjcuNTY0IDMwLjY4NzNDMTIzLjI0OCAzMS43NDk2IDExNy45NzUgMzEuNDIzOSAxMTMuMzI3IDMzLjM3MzNDOTkuNDUxNiAzOS4xOTI0IDk2LjY2NzYgNTkuMDgxMyA4NC4wNTM1IDY2LjIwNTlDNzQuNjI0NyA3MS41MzE4IDY1LjExMiA3MS45NTY1IDU2LjU1OTQgNzQuNjM2NUM1MC45Mzg5IDc2LjM5OSA0NC43OTA2IDgwLjAxMzUgMzkuNjk4MiA4NC40MDE4QzM1Ljc0NTUgODcuODA5MyAzNS42NDIzIDkwLjgwNTQgMzEuNTEyMyA5NS4wNzkxQzI3LjA5NDcgOTkuNjUwNCAxMy45NTUxIDk1LjE1NjQgOCAxMDIuMTUzQzkuOTE4MzUgMTA0LjA5MyAxMC43NTk0IDEwNC42MzYgMTQuNTM5OCAxMDQuMTMzQzEzLjc1NzEgMTA1LjYxNiA5LjE0MzMyIDEwNi44NjYgMTAuMDQ2NSAxMDkuMDQ5QzEwLjk5NjggMTExLjM0NSAyMi4xNTExIDExMi45MDEgMzIuMjkwOCAxMDYuNzhDMzcuMDEzMSAxMDMuOTI5IDQwLjc3NDMgOTkuODE5MyA0OC4xMjg4IDk4LjgzODRDNTcuNjQ1OSA5Ny41Njk5IDY4LjYwOTMgOTkuNjUyIDc5LjYyNjggMTAxLjI0MUM3Ny45OTMyIDEwNi4xMTIgNzQuNzEzMyAxMDkuMzUxIDcyLjA4NiAxMTMuMjMxQzcxLjI3MjQgMTE0LjEwNyA3My43MjAyIDExNC4yMDUgNzYuNTEyNiAxMTMuNjc1QzgxLjUzNTkgMTEyLjQzMyA4NS4xNTYxIDExMS40MzMgODguOTQ3MiAxMDkuMjI3QzkzLjYwNDcgMTA2LjUxNSA5NC4zMTA0IDk5LjU2MzkgMTAwLjAyNSA5OC4wNTk5QzEwMy4yMDkgMTAyLjk1NCAxMTEuODY5IDEwNC4xMSAxMTcuMjQyIDEwMC4xOTVDMTEyLjUyNyA5OC44NjA3IDExMS4yMjQgODguODI0NCAxMTIuODE1IDg0LjQwMThDMTE0LjMyMyA4MC4yMTU2IDExNS44MTMgNzMuNTE5MiAxMTcuMzMxIDY3Ljk4NTVDMTE4Ljk2MSA2Mi4wNDI1IDExOS41NjIgNTQuNTUxOSAxMjEuNTM1IDUxLjUyNDdDMTI0LjUwMyA0Ni45NzAxIDEyNy43ODMgNDUuNDA2IDEzMC42MyA0Mi44Mzc3QzEzMy40NzcgNDAuMjY5NSAxMzYuMDgzIDM3Ljc2OTQgMTM1Ljk5OCAzMS44OTI3QzEzNS45NyAyOS45OTk4IDEzNC45OTIgMjguOTQ0NyAxMzMuMTkxIDI5LjAwMjJaIiBmaWxsPSIjMDQyNDRFIi8+CjxwYXRoIGQ9Ik0xMjguOTUzIDMyLjQ4NDRDMTI5LjQyNyAzNC4xMDA0IDEzMC4xNjggMzQuODQyMSAxMzMuMzc1IDM1LjEzODdDMTMyLjkwNiAzOS4yMDQxIDEzMC4xOTUgNDEuNDI3NiAxMjcuMTU0IDQzLjU2MTFDMTI0LjQ3OSA0NS40Mzc2IDEyMS41NDcgNDcuMjQ0NSAxMTkuNjY0IDUwLjE3NTdDMTE3LjczNCA1My4xNzg1IDExNi41MDkgNjMuNDU1NCAxMTMuNTE3IDczLjYwNDRDMTEwLjkzMSA4Mi4zNzM4IDEwNy4wMjUgOTEuMDQ0NSAxMDAuMjA0IDk0Ljg0MzdDOTkuNDkxOSA5My4wNTAyIDEwMC4yOTUgODkuNzQgOTguODc4IDg4LjY1MkM5Ny45NjExIDkxLjI2NzQgOTYuOTI0MiA5My43NjI3IDk1LjcwOTggOTYuMDgyMUM5MS43MDc3IDEwMy43MzIgODUuNzgyMiAxMDkuNDU5IDc1Ljg4MDEgMTExLjIwOEM4MC41Nzg1IDEwNC44NSA4NS4wNzEgOTguMjg0NCA4NS4xNjgzIDg3LjMyNjJDODEuODYxNyA4OC4wNDE3IDgxLjkzMTkgOTUuODUyMiA3OC41MzQ1IDk3Ljk0MDJDNzYuMzU2MyA5OC4xNzcyIDc0LjE0OTggOTguMTc1OCA3MS45MjkxIDk4LjA0MjRDNjIuODA5MSA5Ny40OTU5IDUzLjQ1MzUgOTQuNzU0OSA0NC45MjE5IDk3LjQ5MjNDMzkuMTEyOCA5OS4zNTY4IDM0LjM2MTkgMTAzLjc1NSAyOS40NDI4IDEwNS44ODhDMjMuNjYxNCAxMDguMzk2IDE5LjI4MzEgMTA5LjQyNyAxMi4wODM2IDEwOC4zOTZDMTEuMTY5NSAxMDcuMTY0IDE3LjM1MjYgMTA1LjU3NSAxNi45ODI5IDEwMi45MDJDMTQuMTY1MyAxMDIuNTkgMTIuNTI5MyAxMDMuMjczIDEwLjA4MDEgMTAyLjE2QzEwLjM1MDUgMTAxLjY2MiAxMC43NDc5IDEwMS4yNDcgMTEuMjQ4MyAxMDAuOTAxQzE1LjczNzMgOTcuNzk0IDI4LjQ4ODIgMTAwLjE2NyAzMS45MDA2IDk2LjgxNjdDMzQuMDA3IDk0Ljc1IDM1LjM4ODkgOTIuNTg2NyAzNi44MTk3IDkwLjQ4MzhDMzguMjA3MiA4OC40NDM0IDM5LjY0MTUgODYuNDU5NyA0MS44MjY4IDg0LjY3MTlDNDIuNjMzNyA4NC4wMTE4IDQzLjUxMSA4My4zNTk2IDQ0LjQ0MjEgODIuNzIzQzQ4LjE2NiA4MC4xNzQzIDUyLjc3MjkgNzcuODYyOCA1Ny4zMDY2IDc2LjI2OTRDNjMuNDgyNiA3NC4wOTg0IDY5Ljc0MSA3My45MTk1IDc2LjMyMzcgNzEuNDA0M0M4MC4zOTA0IDY5Ljg1IDg0LjgxMjcgNjcuOTMwMiA4OC40MTc0IDY1LjI0MzlDODkuMjczMyA2NC42MDUxIDkwLjA4MzEgNjMuOTI0NSA5MC44MzE5IDYzLjE5NDlDMTAxLjEyNSA1My4xNjA4IDEwMy4xNjUgMzUuNDYxIDExOS4yMjQgMzMuODExNkMxMjEuMTY2IDMzLjYxMjEgMTIyLjc1NiAzMy42NzY3IDEyNC4yMDMgMzMuNjMyN0MxMjUuODcxIDMzLjU4MyAxMjcuMzQ3IDMzLjM4OTMgMTI4Ljk1MyAzMi40ODQ0Wk0xMDkuMzc1IDg5LjEzMzlDMTA5LjU2NyA5Mi4yMDEzIDExMS4zNDggOTguMjg3MiAxMTIuOTIgOTkuNzY2M0MxMDkuODQxIDEwMC41MTUgMTA0LjUzNyA5OS4yNzggMTAzLjE3NyA5Ny4xMDYyQzEwMy44NzYgOTMuOTcwNyAxMDcuNTE0IDkxLjEwNDEgMTA5LjM3NSA4OS4xMzM5WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEzMC4xMDkgMzUuOTE4N0MxMjkuNDkgMzcuMjE2OSAxMjguMzA1IDM4Ljg5MDggMTI4LjMwNSA0Mi4xOTU2QzEyOC4zIDQyLjc2MyAxMjcuODc1IDQzLjE1MTcgMTI3Ljg2NyA0Mi4yNzdDMTI3Ljg5OSAzOS4wNDcgMTI4Ljc1NCAzNy42NTA3IDEyOS42NjIgMzUuODE1NUMxMzAuMDg1IDM1LjA2MzYgMTMwLjMzOSAzNS4zNzM4IDEzMC4xMDkgMzUuOTE4N1pNMTI5LjQ4NiAzNS40Mjk3QzEyOC43NTYgMzYuNjY4NCAxMjYuOTk4IDM4LjkyNzggMTI2LjcwNyA0Mi4yMjAzQzEyNi42NTMgNDIuNzg0OCAxMjYuMTk0IDQzLjEzNDMgMTI2LjI2NCA0Mi4yNjE4QzEyNi41ODEgMzkuMDQ3NyAxMjcuOTg2IDM3LjAzNiAxMjkuMDUyIDM1LjI4NzNDMTI5LjUzNiAzNC41NzYxIDEyOS43NjMgMzQuOTA3NCAxMjkuNDg2IDM1LjQyOTdaTTEyOC45MTggMzQuNzgxN0MxMjguMDg2IDM1Ljk1NDMgMTI1LjM4IDM4LjY2NzggMTI0LjgxNCA0MS45MjQ3QzEyNC43MTIgNDIuNDgxOSAxMjQuMjI1IDQyLjc5MjggMTI0LjM2OCA0MS45MjlDMTI0Ljk1NCAzOC43NTIgMTI3LjI4NyAzNi4yNTUgMTI4LjQ5NiAzNC42MDM3QzEyOS4wMzggMzMuOTM0NiAxMjkuMjM3IDM0LjI4NCAxMjguOTE4IDM0Ljc4MTdaTTEyOC40MTEgMzQuMDU4OEwxMjguMTM3IDM0LjM0OTlDMTI2LjkyNyAzNS42NDcyIDEyNC4xMTYgMzguODExNCAxMjMuMTc5IDQxLjcwNzRDMTIyLjk5OSA0Mi4yNDUgMTIyLjQ3NCA0Mi40ODQ4IDEyMi43MzcgNDEuNjQ5M0MxMjMuNzYzIDM4LjU4NjQgMTI2LjU4OSAzNS4yODczIDEyOC4wMTggMzMuODIyN0MxMjguNjUgMzMuMjM2NCAxMjguNzk2IDMzLjYxMDYgMTI4LjQxMSAzNC4wNTg4Wk0xMTMuODg2IDQwLjYxNjJDMTE0LjUxMyAzNy45MjMxIDExNi42MDcgMzYuNjk2IDEyMC4yMjMgMzYuOTk1M0MxMjEuMDk2IDQxLjAxNTEgMTE2LjIxMyA0Mi42MzY2IDExMy44ODYgNDAuNjE2MloiIGZpbGw9IiMwNDI0NEUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMjkzMCIgeDE9IjE0MC41IiB5MT0iMTQxIiB4Mj0iNS45OTk5OSIgeTI9Ii01LjUwMjI4ZS0wNiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjQzQ5QTZDIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0U3QkY5MyIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "version"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "s3Region"], ["spec", "backup", "s3Bucket"], ["spec", "backup", "schedule"], ["spec", "backup", "cleanupStrategy"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "backup", "resticPassword"]] + secrets: + exclude: [] + include: + - resourceNames: + - mysql-{{ .name }}-credentials + services: + exclude: [] + include: + - resourceNames: + - mysql-{{ .name }}-primary + - mysql-{{ .name }}-secondary diff --git a/packages/system/mysql-rd/templates/cozyrd.yaml b/packages/system/mysql-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/mysql-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/mysql-rd/values.yaml b/packages/system/mysql-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/mysql-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/nats-rd/Chart.yaml b/packages/system/nats-rd/Chart.yaml new file mode 100644 index 00000000..9be57a87 --- /dev/null +++ b/packages/system/nats-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: nats-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/nats-rd/Makefile b/packages/system/nats-rd/Makefile new file mode 100644 index 00000000..2b5b232e --- /dev/null +++ b/packages/system/nats-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=nats-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/nats-rd/cozyrds/nats.yaml b/packages/system/nats-rd/cozyrds/nats.yaml new file mode 100644 index 00000000..258f8f40 --- /dev/null +++ b/packages/system/nats-rd/cozyrds/nats.yaml @@ -0,0 +1,40 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: nats +spec: + application: + kind: NATS + plural: natses + singular: nats + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"config":{"description":"NATS configuration.","type":"object","default":{},"properties":{"merge":{"description":"Additional configuration to merge into NATS config.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true},"resolver":{"description":"Additional resolver configuration to merge into NATS config.","type":"object","default":{},"x-kubernetes-preserve-unknown-fields":true}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"jetstream":{"description":"Jetstream configuration.","type":"object","default":{},"required":["enabled","size"],"properties":{"enabled":{"description":"Enable or disable Jetstream for persistent messaging in NATS.","type":"boolean","default":true},"size":{"description":"Jetstream persistent storage size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"replicas":{"description":"Number of replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each NATS replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}}}} + release: + prefix: nats- + labels: + cozystack.io/ui: "true" + chart: + name: nats + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: NATS + plural: NATS + description: Managed NATS service + tags: + - messaging + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgyMSkiLz4KPHJlY3Qgd2lkdGg9IjE0NCIgaGVpZ2h0PSIxNDQiIHJ4PSIyNCIgZmlsbD0iYmxhY2siIGZpbGwtb3BhY2l0eT0iMC4zIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTE3LjQ4IDI1SDI3Vjk4Ljk2OTNINjYuMDY4OUw4Ny43MDc1IDExOVY5OC45NjkzSDExNy40OFYyNVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4xMzUyIDcyLjQ1NTJWNDIuNjI1SDEwMi43NzNWODEuMTk5OUg4Ni42NTE5TDU0LjExNCA1MC44NDE0VjgxLjIzMjJINDMuNDQ0M1Y0Mi42MjVINjAuMTI2Mkw5Mi4xMzUyIDcyLjQ1NTJaIiBmaWxsPSJibGFjayIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4MV8yODIxIiB4MT0iMTAiIHkxPSIxNS41IiB4Mj0iMTQ0IiB5Mj0iMTMxLjUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzM4NUM5MyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMzMkE1NzQiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "jetstream"], ["spec", "jetstream", "enabled"], ["spec", "jetstream", "size"], ["spec", "config"], ["spec", "config", "merge"], ["spec", "config", "resolver"]] + secrets: + exclude: [] + include: + - resourceNames: + - nats-{{ .name }}-credentials + services: + exclude: [] + include: + - resourceNames: + - nats-{{ .name }} diff --git a/packages/system/nats-rd/templates/cozyrd.yaml b/packages/system/nats-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/nats-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/nats-rd/values.yaml b/packages/system/nats-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/nats-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/postgres-rd/Chart.yaml b/packages/system/postgres-rd/Chart.yaml new file mode 100644 index 00000000..ca2e2d2a --- /dev/null +++ b/packages/system/postgres-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: postgres-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/postgres-rd/Makefile b/packages/system/postgres-rd/Makefile new file mode 100644 index 00000000..0c8b1cb0 --- /dev/null +++ b/packages/system/postgres-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=postgres-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/postgres-rd/cozyrds/postgres.yaml b/packages/system/postgres-rd/cozyrds/postgres.yaml new file mode 100644 index 00000000..c3d16cb7 --- /dev/null +++ b/packages/system/postgres-rd/cozyrds/postgres.yaml @@ -0,0 +1,51 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: postgres +spec: + application: + kind: Postgres + singular: postgres + plural: postgreses + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"backup":{"description":"Backup configuration.","type":"object","default":{},"required":["enabled"],"properties":{"destinationPath":{"description":"Destination path for backups (e.g. s3://bucket/path/).","type":"string","default":"s3://bucket/path/to/folder/"},"enabled":{"description":"Enable regular backups.","type":"boolean","default":false},"endpointURL":{"description":"S3 endpoint URL for uploads.","type":"string","default":"http://minio-gateway-service:9000"},"retentionPolicy":{"description":"Retention policy (e.g. \"30d\").","type":"string","default":"30d"},"s3AccessKey":{"description":"Access key for S3 authentication.","type":"string","default":""},"s3SecretKey":{"description":"Secret key for S3 authentication.","type":"string","default":""},"schedule":{"description":"Cron schedule for automated backups.","type":"string","default":"0 2 * * * *"}}},"bootstrap":{"description":"Bootstrap configuration.","type":"object","default":{},"required":["enabled","oldName"],"properties":{"enabled":{"description":"Whether to restore from a backup.","type":"boolean","default":false},"oldName":{"description":"Previous cluster name before deletion.","type":"string","default":""},"recoveryTime":{"description":"Timestamp (RFC3339) for point-in-time recovery; empty means latest.","type":"string","default":""}}},"databases":{"description":"Databases configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"extensions":{"description":"List of enabled PostgreSQL extensions.","type":"array","items":{"type":"string"}},"roles":{"description":"Roles assigned to users.","type":"object","properties":{"admin":{"description":"List of users with admin privileges.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of users with read-only privileges.","type":"array","items":{"type":"string"}}}}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"postgresql":{"description":"PostgreSQL server configuration.","type":"object","default":{},"properties":{"parameters":{"description":"PostgreSQL server parameters.","type":"object","default":{},"properties":{"max_connections":{"description":"Maximum number of concurrent connections to the database server.","type":"integer","default":100}}}}},"quorum":{"description":"Quorum configuration for synchronous replication.","type":"object","default":{},"required":["maxSyncReplicas","minSyncReplicas"],"properties":{"maxSyncReplicas":{"description":"Maximum number of synchronous replicas allowed (must be less than total replicas).","type":"integer","default":0},"minSyncReplicas":{"description":"Minimum number of synchronous replicas required for commit.","type":"integer","default":0}}},"replicas":{"description":"Number of Postgres replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each PostgreSQL replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"micro","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"},"replication":{"description":"Whether the user has replication privileges.","type":"boolean"}}}},"version":{"description":"PostgreSQL major version to deploy","type":"string","default":"v18","enum":["v18","v17","v16","v15","v14","v13"]}}} + release: + prefix: postgres- + labels: + cozystack.io/ui: "true" + chart: + name: postgres + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: PostgreSQL + plural: PostgreSQL + description: Managed PostgreSQL service + tags: + - database + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMjg0OSkiLz4KPHBhdGggZD0iTTk0LjQ4MSA5My4zMDQ5Qzk1LjA3MTggODguMzQ3NyA5NC44OTQ4IDg3LjYyMDggOTguNTYxMiA4OC40MjM4TDk5LjQ5MiA4OC41MDYxQzEwMi4zMTEgODguNjM1MyAxMDUuOTk5IDg4LjA0OTUgMTA4LjE2NiA4Ny4wMzU4QzExMi44MyA4NC44NTY0IDExNS41OTUgODEuMjE3NiAxMTAuOTk2IDgyLjE3MzhDMTAwLjUwNiA4NC4zNTMyIDk5Ljc4NDkgODAuNzc1OSA5OS43ODQ5IDgwLjc3NTlDMTEwLjg2MiA2NC4yMjQgMTE1LjQ5MyA0My4yMTI4IDExMS40OTYgMzguMDY5N0MxMDAuNTk0IDI0LjA0MTIgODEuNzIzMSAzMC42NzUgODEuNDA3MyAzMC44NDcyTDgxLjMwNjggMzAuODY1OUM3OS4yMzQgMzAuNDMyOCA3Ni45MTQzIDMwLjE3NCA3NC4zMDg1IDMwLjEzMTZDNjkuNTYxMyAzMC4wNTMgNjUuOTU5MSAzMS4zODQ5IDYzLjIyNjYgMzMuNDcyMUM2My4yMjY2IDMzLjQ3MjEgMjkuNTYyMSAxOS41MDQ3IDMxLjEyODIgNTEuMDM3NUMzMS40NjEzIDU3Ljc0NTQgNDAuNjc1OCAxMDEuNzk1IDUxLjY2NTkgODguNDkwMUM1NS42ODI3IDgzLjYyNDkgNTkuNTY0NiA3OS41MTEzIDU5LjU2NDYgNzkuNTExM0M2MS40OTIyIDgwLjgwMDkgNjMuOCA4MS40NTg4IDY2LjIyMDQgODEuMjIyNUw2Ni40MDc1IDgxLjA2MThDNjYuMzQ4OSA4MS42NjU5IDY2LjM3NDcgODIuMjU2NyA2Ni40ODI0IDgyLjk1NjJDNjMuNjUxNyA4Ni4xNDE5IDY0LjQ4MzUgODYuNzAxMiA1OC44MjMxIDg3Ljg3NDVDNTMuMDk2NSA4OS4wNjMxIDU2LjQ2MDkgOTEuMTc5MyA1OC42NTY5IDkxLjczMjRDNjEuMzE5OSA5Mi40MDMgNjcuNDgwNCA5My4zNTMgNzEuNjQ0IDg3LjQ4NDVMNzEuNDc4MiA4OC4xNTQxQzcyLjU4ODggODkuMDQ4OSA3Mi41MTM3IDk0LjU4NTQgNzIuNjcxMiA5OC41NDExQzcyLjgyODkgMTAyLjQ5NyA3My4wOTE5IDEwNi4xODkgNzMuODkyNiAxMDguMzY1Qzc0LjY5MzMgMTEwLjU0MSA3NS42MzgxIDExNi4xNDcgODMuMDc3MSAxMTQuNTQxQzg5LjI5NDMgMTEzLjIgOTQuMDQ3OCAxMTEuMjY5IDk0LjQ4MSA5My4zMDQ5WiIgZmlsbD0iYmxhY2siIHN0cm9rZT0iYmxhY2siIHN0cm9rZS13aWR0aD0iNiIvPgo8cGF0aCBkPSJNMTEwLjk5OCA4Mi4xNzI3QzEwMC41MDYgODQuMzUyMSA5OS43ODQ5IDgwLjc3NDggOTkuNzg0OSA4MC43NzQ4QzExMC44NjIgNjQuMjIxOCAxMTUuNDkzIDQzLjIxMDIgMTExLjQ5NyAzOC4wNjc4QzEwMC41OTUgMjQuMDQwMSA4MS43MjMxIDMwLjY3NDMgODEuNDA4MiAzMC44NDY1TDgxLjMwNjggMzAuODY0OEM3OS4yMzQxIDMwLjQzMTUgNzYuOTE0NCAzMC4xNzMzIDc0LjMwNzMgMzAuMTMwNUM2OS41NiAzMC4wNTIxIDY1Ljk1OTEgMzEuMzgzOCA2My4yMjY3IDMzLjQ3MDZDNjMuMjI2NyAzMy40NzA2IDI5LjU2MTUgMTkuNTAzOCAzMS4xMjcyIDUxLjAzNjRDMzEuNDYwMyA1Ny43NDQ3IDQwLjY3NDYgMTAxLjc5NSA1MS42NjUxIDg4LjQ4OTVDNTUuNjgyMSA4My42MjQzIDU5LjU2MzQgNzkuNTEwNiA1OS41NjM0IDc5LjUxMDZDNjEuNDkxMiA4MC44MDAyIDYzLjc5OSA4MS40NTgxIDY2LjIxODQgODEuMjIxOEw2Ni40MDYzIDgxLjA2MTFDNjYuMzQ3OSA4MS42NjUyIDY2LjM3NDYgODIuMjU2IDY2LjQ4MTYgODIuOTU1NUM2My42NTAzIDg2LjE0MTIgNjQuNDgyMiA4Ni43MDA1IDU4LjgyMjMgODcuODczOEM1My4wOTUzIDg5LjA2MjUgNTYuNDU5NyA5MS4xNzg2IDU4LjY1NjMgOTEuNzMxN0M2MS4zMTkzIDkyLjQwMjMgNjcuNDgwMiA5My4zNTI0IDcxLjY0MyA4Ny40ODM4TDcxLjQ3NyA4OC4xNTM0QzcyLjU4NjQgODkuMDQ4MiA3My4zNjU0IDkzLjk3MzkgNzMuMjM0OCA5OC40MzlDNzMuMTA0MiAxMDIuOTA0IDczLjAxNzEgMTA1Ljk3IDczLjg5MTIgMTA4LjM2NEM3NC43NjUzIDExMC43NTkgNzUuNjM2NSAxMTYuMTQ2IDgzLjA3NjkgMTE0LjU0MUM4OS4yOTQxIDExMy4xOTkgOTIuNTE1OSAxMDkuNzIyIDkyLjk2NDEgMTAzLjkyMkM5My4yODIyIDk5Ljc5ODggOTQuMDAxOSAxMDAuNDA4IDk0LjA0NzQgOTYuNzIxOUw5NC42MjQ3IDk0Ljk3NjZDOTUuMjkwNSA4OS4zODcyIDk0LjczMDUgODcuNTg0IDk4LjU2MDggODguNDIyN0w5OS40OTE3IDg4LjUwNUMxMDIuMzExIDg4LjYzNDIgMTA2LjAwMSA4OC4wNDg0IDEwOC4xNjYgODcuMDM0N0MxMTIuODI5IDg0Ljg1NTMgMTE1LjU5NSA4MS4yMTY2IDExMC45OTcgODIuMTcyN0gxMTAuOTk4WiIgZmlsbD0iIzMzNjc5MSIvPgo8cGF0aCBkPSJNNzIuMDkzMyA4NS4zNzdDNzEuODA0NSA5NS43Nzc0IDcyLjE2NTkgMTA2LjI1IDczLjE3NjQgMTA4Ljc5NkM3NC4xODc2IDExMS4zNDEgNzYuMzUxNCAxMTYuMjkyIDgzLjc5MjUgMTE0LjY4NkM5MC4wMDkxIDExMy4zNDQgOTIuMjcxIDExMC43NDcgOTMuMjUyNiAxMDUuMDE0QzkzLjk3NTUgMTAwLjc5NiA5NS4zNjkxIDg5LjA4MSA5NS41NDc5IDg2LjY4MDkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik02My4xNzUgMzMuMjM5M0M2My4xNzUgMzMuMjM5MyAyOS40ODY4IDE5LjM3MzIgMzEuMDUzIDUwLjkwNThDMzEuMzg2IDU3LjYxNDEgNDAuNjAxIDEwMS42NjUgNTEuNTkxMyA4OC4zNTk3QzU1LjYwNzUgODMuNDkzOCA1OS4yMzk3IDc5LjY3NzYgNTkuMjM5NyA3OS42Nzc2IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNODEuMzcxMyAzMC43MDc4QzgwLjIwNTIgMzEuMDc2IDEwMC4xMTEgMjMuMzc5NiAxMTEuNDIzIDM3LjkzNjhDMTE1LjQxOSA0My4wNzk1IDExMC43ODkgNjQuMDkxMSA5OS43MTE1IDgwLjY0NDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIi8+CjxwYXRoIGQ9Ik05OS43MTEgODAuNjQ0OEM5OS43MTEgODAuNjQ0OCAxMDAuNDMzIDg0LjIyMyAxMTAuOTI0IDgyLjA0MjJDMTE1LjUyMSA4MS4wODYxIDExMi43NTUgODQuNzI1MiAxMDguMDkzIDg2LjkwNTdDMTA0LjI2NyA4OC42OTQgOTUuNjg4MyA4OS4xNTIzIDk1LjU0ODIgODYuNjgxMkM5NS4xODc2IDgwLjMwNTMgMTAwLjA2MyA4Mi4yNDIzIDk5LjcxMSA4MC42NDQ4Wk05OS43MTEgODAuNjQ0OEM5OS4zOTI5IDc5LjIwNiA5Ny4yMTI4IDc3Ljc5MzkgOTUuNzcwNSA3NC4yNzI1Qzk0LjUxMTQgNzEuMTk5IDc4LjUwMTkgNDcuNjI4OSAxMDAuMjEgNTEuMTI5NEMxMDEuMDA2IDUwLjk2MzcgOTQuNTQ4NSAzMC4zMzQ4IDc0LjIzMjUgMjkuOTk5NEM1My45MjExIDI5LjY2MzkgNTQuNTg3NSA1NS4xNTQ1IDU0LjU4NzUgNTUuMTU0NSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiLz4KPHBhdGggZD0iTTY2LjQwNzcgODIuODI1M0M2My41NzYgODYuMDEwOCA2NC40MDg4IDg2LjU3MDIgNTguNzQ4NSA4Ny43NDM5QzUzLjAyMTQgODguOTMyNyA1Ni4zODYyIDkxLjA0ODUgNTguNTgyMiA5MS42MDEzQzYxLjI0NTIgOTIuMjcyNCA2Ny40MDYxIDkzLjIyMjQgNzEuNTY4OSA4Ny4zNTI0QzcyLjgzNjYgODUuNTY1MSA3MS41NjE0IDgyLjcxMzQgNjkuODIwMSA4MS45ODY0QzY4Ljk3ODcgODEuNjM1NCA2Ny44NTM3IDgxLjE5NTYgNjYuNDA3NyA4Mi44MjUzWiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPHBhdGggZD0iTTY2LjIyMjUgODIuNzY5MUM2NS45MzcyIDgwLjg5NjEgNjYuODMzNiA3OC42Njc0IDY3Ljc5NDMgNzYuMDU5OUM2OS4yMzggNzIuMTQ3NyA3Mi41NjkgNjguMjM0OCA2OS45MDQ0IDU1LjgyNDZDNjcuOTE4MiA0Ni41NzY3IDU0LjU5NjMgNTMuOSA1NC41ODggNTUuMTU0QzU0LjU3OTggNTYuNDA3NSA1NS4xOTA1IDYxLjUwOTkgNTQuMzY1NCA2Ny40NTE1QzUzLjI4ODggNzUuMjA0OCA1OS4yNjQzIDgxLjc2MjEgNjYuMTQ1MSA4MS4wOTEzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8cGF0aCBkPSJNNjMuMDUyOCA1NC45NjY1QzYyLjk5MjggNTUuMzk0OCA2My44MzE0IDU2LjUzNzcgNjQuOTI0OSA1Ni42OTA0QzY2LjAxNjYgNTYuODQzNyA2Ni45NTEgNTUuOTUwNiA2Ny4wMTAyIDU1LjUyMjdDNjcuMDY5NCA1NS4wOTQ1IDY2LjIzMTggNTQuNjIyNyA2NS4xMzc5IDU0LjQ2OTRDNjQuMDQ1NiA1NC4zMTU4IDYzLjExMDggNTQuNTM5MyA2My4wNTMxIDU0Ljk2NjVINjMuMDUyOFoiIGZpbGw9IndoaXRlIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz4KPHBhdGggZD0iTTk2LjMwMzQgNTQuMDkyNEM5Ni4zNjI3IDU0LjUyMDcgOTUuNTI1MSA1NS42NjM1IDk0LjQzMTMgNTUuODE2MkM5My4zMzg5IDU1Ljk2OTYgOTIuNDA0NSA1NS4wNzY1IDkyLjM0NDYgNTQuNjQ4NkM5Mi4yODY4IDU0LjIyMDMgOTMuMTI0NyA1My43NDg2IDk0LjIxNzMgNTMuNTk1M0M5NS4zMSA1My40NDE5IDk2LjI0NDIgNTMuNjY1MiA5Ni4zMDM0IDU0LjA5MjZWNTQuMDkyNFoiIGZpbGw9IndoaXRlIiBzdHJva2U9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMDAuMjEgNTEuMTI4OUMxMDAuMzkgNTQuNDg4MyA5OS40OTIgNTYuNzc2NSA5OS4zNzg3IDYwLjM1MjdDOTkuMjExIDY1LjU1MDggMTAxLjg0IDcxLjUwMDUgOTcuODc4OSA3Ny40NTc1IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yODQ5IiB4MT0iMTQwIiB5MT0iMTMwLjUiIHgyPSI0IiB5Mj0iOS40OTk5OSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMDAyQzRDIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNDc3QiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + #tabs: + # services: + # labelSelector: + # cnpg.io/cluster: "{reqs[0]['metadata','name']}" + # workloadMonitors: + # labelSelector: + # helm.toolkit.fluxcd.io/name: "{reqs[0]['metadata','name']}" + + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "version"], ["spec", "postgresql"], ["spec", "postgresql", "parameters"], ["spec", "postgresql", "parameters", "max_connections"], ["spec", "quorum"], ["spec", "quorum", "minSyncReplicas"], ["spec", "quorum", "maxSyncReplicas"], ["spec", "users"], ["spec", "databases"], ["spec", "backup"], ["spec", "backup", "enabled"], ["spec", "backup", "retentionPolicy"], ["spec", "backup", "destinationPath"], ["spec", "backup", "endpointURL"], ["spec", "backup", "schedule"], ["spec", "backup", "s3AccessKey"], ["spec", "backup", "s3SecretKey"], ["spec", "bootstrap"], ["spec", "bootstrap", "enabled"], ["spec", "bootstrap", "recoveryTime"], ["spec", "bootstrap", "oldName"]] + secrets: + exclude: [] + include: + - resourceNames: + - postgres-{{ .name }}-credentials + services: + exclude: [] + include: + - resourceNames: + - postgres-{{ .name }}-r + - postgres-{{ .name }}-ro + - postgres-{{ .name }}-rw + - postgres-{{ .name }}-external-write diff --git a/packages/system/postgres-rd/templates/cozyrd.yaml b/packages/system/postgres-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/postgres-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/postgres-rd/values.yaml b/packages/system/postgres-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/postgres-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/rabbitmq-rd/Chart.yaml b/packages/system/rabbitmq-rd/Chart.yaml new file mode 100644 index 00000000..9fa858de --- /dev/null +++ b/packages/system/rabbitmq-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: rabbitmq-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/rabbitmq-rd/Makefile b/packages/system/rabbitmq-rd/Makefile new file mode 100644 index 00000000..9c5be0d5 --- /dev/null +++ b/packages/system/rabbitmq-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=rabbitmq-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/rabbitmq-rd/cozyrds/rabbitmq.yaml b/packages/system/rabbitmq-rd/cozyrds/rabbitmq.yaml new file mode 100644 index 00000000..092142ac --- /dev/null +++ b/packages/system/rabbitmq-rd/cozyrds/rabbitmq.yaml @@ -0,0 +1,42 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: rabbitmq +spec: + application: + kind: RabbitMQ + plural: rabbitmqs + singular: rabbitmq + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of RabbitMQ replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration for each RabbitMQ replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user.","type":"string"}}}},"vhosts":{"description":"Virtual hosts configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","required":["roles"],"properties":{"roles":{"description":"Virtual host roles list.","type":"object","properties":{"admin":{"description":"List of admin users.","type":"array","items":{"type":"string"}},"readonly":{"description":"List of readonly users.","type":"array","items":{"type":"string"}}}}}}}}} + release: + prefix: rabbitmq- + labels: + cozystack.io/ui: "true" + chart: + name: rabbitmq + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: RabbitMQ + plural: RabbitMQ + description: Managed RabbitMQ service + tags: + - messaging + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHg9Ii0wLjAwMTk1MzEyIiB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgcng9IjI0IiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNjgzXzI5NzIpIi8+CjxwYXRoIGQ9Ik0xMTEuNDExIDYyLjhIODIuNDkzOUM4MS43OTY5IDYyLjc5OTcgODEuMTI4NSA2Mi41MjI4IDgwLjYzNTYgNjIuMDMwMUM4MC4xNDI3IDYxLjUzNzMgNzkuODY1NiA2MC44NjkxIDc5Ljg2NTMgNjAuMTcyMlYzMC4wNDEyQzc5Ljg2NTMgMjcuODEgNzguMDU1NiAyNiA3NS44MjQ5IDI2SDY1LjUwMjFDNjMuMjcgMjYgNjEuNDYxNCAyNy44MSA2MS40NjE0IDMwLjA0MTJWNTkuOTg5OEM2MS40NjE0IDYxLjU0MzUgNjAuMjA1IDYyLjgwNjUgNTguNjUwOCA2Mi44MTMzTDQ5LjE3NDMgNjIuODU4NEM0Ny42MDY5IDYyLjg2NjkgNDYuMzMzNiA2MS41OTU1IDQ2LjMzNjYgNjAuMDI5OEw0Ni4zOTU0IDMwLjA0OEM0Ni40MDA1IDI3LjgxMzQgNDQuNTkwMiAyNiA0Mi4zNTUgMjZIMzIuMDQwN0MyOS44MDgzIDI2IDI4IDI3LjgxIDI4IDMwLjA0MTJWMTE0LjQxMkMyOCAxMTYuMzk0IDI5LjYwNjEgMTE4IDMxLjU4NzEgMTE4SDExMS40MTFDMTEzLjM5NCAxMTggMTE1IDExNi4zOTQgMTE1IDExNC40MTJWNjYuMzg4QzExNSA2NC40MDU4IDExMy4zOTQgNjIuOCAxMTEuNDExIDYyLjhaTTk3Ljg1MDggOTQuNDc3OUM5Ny44NTA4IDk3LjA3NTUgOTUuNzQ0NSA5OS4xODE3IDkzLjE0NjQgOTkuMTgxN0g4NC45ODg0QzgyLjM5IDk5LjE4MTcgODAuMjgzNiA5Ny4wNzU1IDgwLjI4MzYgOTQuNDc3OVY4Ni4zMjE3QzgwLjI4MzYgODMuNzIzOCA4Mi4zOSA4MS42MTc5IDg0Ljk4ODQgODEuNjE3OUg5My4xNDY0Qzk1Ljc0NDUgODEuNjE3OSA5Ny44NTA4IDgzLjcyMzggOTcuODUwOCA4Ni4zMjE3Vjk0LjQ3NzlaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4M18yOTcyIiB4MT0iNSIgeTE9Ii03LjUiIHgyPSIxNDEiIHkyPSIxMjQuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRkY4MjJGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0ZGNjYwMCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8L2RlZnM+Cjwvc3ZnPgo= + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "users"], ["spec", "vhosts"]] + secrets: + exclude: [] + include: + - resourceNames: + - rabbitmq-{{ .name }}-default-user + - matchLabels: + apps.cozystack.io/user-secret: "true" + services: + exclude: [] + include: + - resourceNames: + - rabbitmq-{{ .name }} diff --git a/packages/system/rabbitmq-rd/templates/cozyrd.yaml b/packages/system/rabbitmq-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/rabbitmq-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/rabbitmq-rd/values.yaml b/packages/system/rabbitmq-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/rabbitmq-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/redis-rd/Chart.yaml b/packages/system/redis-rd/Chart.yaml new file mode 100644 index 00000000..4ccfa4fd --- /dev/null +++ b/packages/system/redis-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: redis-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/redis-rd/Makefile b/packages/system/redis-rd/Makefile new file mode 100644 index 00000000..bed18877 --- /dev/null +++ b/packages/system/redis-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=redis-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/redis-rd/cozyrds/redis.yaml b/packages/system/redis-rd/cozyrds/redis.yaml new file mode 100644 index 00000000..d23f8d2c --- /dev/null +++ b/packages/system/redis-rd/cozyrds/redis.yaml @@ -0,0 +1,43 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: redis +spec: + application: + kind: Redis + plural: redises + singular: redis + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"authEnabled":{"description":"Enable password generation.","type":"boolean","default":true},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"replicas":{"description":"Number of Redis replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each Redis replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume Claim size available for application data.","default":"1Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"version":{"description":"Redis major version to deploy","type":"string","default":"v8","enum":["v8","v7"]}}} + release: + prefix: redis- + labels: + cozystack.io/ui: "true" + chart: + name: redis + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: PaaS + singular: Redis + plural: Redis + description: Managed Redis service + tags: + - cache + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMzIxMykiLz4KPHBhdGggZD0iTTEyMC4xNDkgOTUuNTQ5MUMxMTQuNTg2IDk4LjQ0ODUgODUuNzcwOSAxMTAuMjk2IDc5LjYzNjMgMTEzLjQ5NUM3My41MDE2IDExNi42OTMgNzAuMDkzNyAxMTYuNjYyIDY1LjI0NzIgMTE0LjM0NkM2MC40MDEyIDExMi4wMjkgMjkuNzM2NCA5OS42NDIzIDI0LjIxMjUgOTcuMDAxOUMyMS40NTE5IDk1LjY4MjcgMjAgOTQuNTY4NyAyMCA5My41MTY2VjgyLjk4MDlDMjAgODIuOTgwOSA1OS45MjIgNzQuMjkwMSA2Ni4zNjY5IDcxLjk3NzhDNzIuODExNSA2OS42NjU2IDc1LjA0NzYgNjkuNTgyMSA4MC41MzIgNzEuNTkxQzg2LjAxNzMgNzMuNjAwOCAxMTguODEyIDc5LjUxNzYgMTI0LjIzMyA4MS41MDI5TDEyNC4yMyA5MS44ODk2QzEyNC4yMzEgOTIuOTMxMSAxMjIuOTggOTQuMDczNiAxMjAuMTQ5IDk1LjU0OTFaIiBmaWxsPSIjOTEyNjI2Ii8+CjxwYXRoIGQ9Ik0xMjAuMTQ3IDg1LjA3NTJDMTE0LjU4NSA4Ny45NzM0IDg1Ljc3IDk5LjgyMTggNzkuNjM1NCAxMDMuMDJDNzMuNTAxMSAxMDYuMjE5IDcwLjA5MzIgMTA2LjE4NyA2NS4yNDcyIDEwMy44NzFDNjAuNDAwNyAxMDEuNTU1IDI5LjczNzEgODkuMTY2OCAyNC4yMTM2IDg2LjUyOEMxOC42OTAxIDgzLjg4NzYgMTguNTc0NCA4Mi4wNzA0IDI0LjAwMDMgNzkuOTQ1OEMyOS40MjYxIDc3LjgyMDUgNTkuOTIxNSA2NS44NTYxIDY2LjM2NzIgNjMuNTQzOEM3Mi44MTE4IDYxLjIzMjQgNzUuMDQ3NSA2MS4xNDgxIDgwLjUzMTkgNjMuMTU3OEM4Ni4wMTY4IDY1LjE2NjggMTE0LjY2IDc2LjU2NzYgMTIwLjA3OSA3OC41NTI1QzEyNS41MDEgODAuNTM5OSAxMjUuNzA5IDgyLjE3NjMgMTIwLjE0NyA4NS4wNzUyWiIgZmlsbD0iI0M2MzAyQiIvPgo8cGF0aCBkPSJNMTIwLjE0OSA3OC41MDJDMTE0LjU4NiA4MS40MDE4IDg1Ljc3MDkgOTMuMjQ5MyA3OS42MzYzIDk2LjQ0ODhDNzMuNTAxNiA5OS42NDYyIDcwLjA5MzcgOTkuNjE1MiA2NS4yNDcyIDk3LjI5ODVDNjAuNDAwOCA5NC45ODMgMjkuNzM2NCA4Mi41OTUyIDI0LjIxMjUgNzkuOTU0N0MyMS40NTE5IDc4LjYzNTUgMjAgNzcuNTIzMiAyMCA3Ni40NzA3VjY1LjkzMzhDMjAgNjUuOTMzOCA1OS45MjIgNTcuMjQzNCA2Ni4zNjY5IDU0LjkzMTFDNzIuODExNSA1Mi42MTg5IDc1LjA0NzYgNTIuNTM1IDgwLjUzMiA1NC41NDQzQzg2LjAxNzcgNTYuNTUzNiAxMTguODEzIDYyLjQ2OTMgMTI0LjIzMyA2NC40NTVMMTI0LjIzIDc0Ljg0MjhDMTI0LjIzMSA3NS44ODQgMTIyLjk4IDc3LjAyNjQgMTIwLjE0OSA3OC41MDJaIiBmaWxsPSIjOTEyNjI2Ii8+CjxwYXRoIGQ9Ik0xMjAuMTQ3IDY4LjAyODJDMTE0LjU4NSA3MC45MjcxIDg1Ljc3IDgyLjc3NDcgNzkuNjM1NCA4NS45NzM3QzczLjUwMTEgODkuMTcxNiA3MC4wOTMyIDg5LjE0MDIgNjUuMjQ3MiA4Ni44MjM1QzYwLjQwMDcgODQuNTA4NCAyOS43MzcxIDcyLjEyMDEgMjQuMjEzNiA2OS40ODA5QzE4LjY5MDEgNjYuODQxMyAxOC41NzQ0IDY1LjAyMzcgMjQuMDAwMyA2Mi44OTg0QzI5LjQyNjEgNjAuNzc0MiA1OS45MjE5IDQ4LjgwOSA2Ni4zNjcyIDQ2LjQ5NzJDNzIuODExOCA0NC4xODUzIDc1LjA0NzUgNDQuMTAxNCA4MC41MzE5IDQ2LjExMDhDODYuMDE2OCA0OC4xMTk3IDExNC42NiA1OS41MTk3IDEyMC4wNzkgNjEuNTA1NUMxMjUuNTAxIDYzLjQ5MjQgMTI1LjcwOSA2NS4xMjkyIDEyMC4xNDcgNjguMDI4MloiIGZpbGw9IiNDNjMwMkIiLz4KPHBhdGggZD0iTTEyMC4xNDkgNjAuODIyNEMxMTQuNTg2IDYzLjcyMTQgODUuNzcwOSA3NS41Njk4IDc5LjYzNjMgNzguNzY5MkM3My41MDE2IDgxLjk2NzEgNzAuMDkzNyA4MS45MzU3IDY1LjI0NzIgNzkuNjE5QzYwLjQwMDggNzcuMzAzNSAyOS43MzY0IDY0LjkxNTIgMjQuMjEyNSA2Mi4yNzZDMjEuNDUxOSA2MC45NTU2IDIwIDU5Ljg0MjggMjAgNTguNzkxNVY0OC4yNTQyQzIwIDQ4LjI1NDIgNTkuOTIyIDM5LjU2NDIgNjYuMzY2OSAzNy4yNTI0QzcyLjgxMTUgMzQuOTM5NyA3NS4wNDc2IDM0Ljg1NjcgODAuNTMyIDM2Ljg2NTZDODYuMDE3NyAzOC44NzQ5IDExOC44MTMgNDQuNzkwNSAxMjQuMjMzIDQ2Ljc3NjNMMTI0LjIzIDU3LjE2MzdDMTI0LjIzMSA1OC4yMDQgMTIyLjk4IDU5LjM0NjUgMTIwLjE0OSA2MC44MjI0WiIgZmlsbD0iIzkxMjYyNiIvPgo8cGF0aCBkPSJNMTIwLjE0NyA1MC4zNDlDMTE0LjU4NSA1My4yNDc5IDg1Ljc2OTggNjUuMDk2MyA3OS42MzUyIDY4LjI5NDFDNzMuNTAwOSA3MS40OTIgNzAuMDkzIDcxLjQ2MDYgNjUuMjQ2OSA2OS4xNDUxQzYwLjQwMDkgNjYuODI4MyAyOS43MzY5IDU0LjQ0MDkgMjQuMjEzOCA1MS44MDEzQzE4LjY4OTkgNDkuMTYyMSAxOC41NzQ2IDQ3LjM0NDEgMjQgNDUuMjE5MkMyOS40MjU5IDQzLjA5NDYgNTkuOTIxNyAzMS4xMzEgNjYuMzY3IDI4LjgxODRDNzIuODExNiAyNi41MDYxIDc1LjA0NzMgMjYuNDIzIDgwLjUzMTcgMjguNDMyNEM4Ni4wMTY2IDMwLjQ0MTcgMTE0LjY1OSA0MS44NDE4IDEyMC4wNzkgNDMuODI3NUMxMjUuNTAxIDQ1LjgxMjggMTI1LjcwOSA0Ny40NSAxMjAuMTQ3IDUwLjM0OVoiIGZpbGw9IiNDNjMwMkIiLz4KPHBhdGggZD0iTTg0Ljg1NDEgNDAuMDk5NEw3NS44OTI2IDQxLjAyOThMNzMuODg2NSA0NS44NTdMNzAuNjQ2MyA0MC40NzAzTDYwLjI5ODMgMzkuNTQwNEw2OC4wMTk3IDM2Ljc1NThMNjUuNzAzIDMyLjQ4MTRMNzIuOTMyMSAzNS4zMDg4TDc5Ljc0NzEgMzMuMDc3NUw3Ny45MDUyIDM3LjQ5NzJMODQuODU0MSA0MC4wOTk0Wk03My4zNTE1IDYzLjUxODRMNTYuNjI2NiA1Ni41ODE2TDgwLjU5MiA1Mi45MDI5TDczLjM1MTUgNjMuNTE4NFpNNTAuMTYzNyA0Mi43ODI2QzU3LjIzODEgNDIuNzgyNiA2Mi45NzMgNDUuMDA1NyA2Mi45NzMgNDcuNzQ3NUM2Mi45NzMgNTAuNDkwMSA1Ny4yMzgxIDUyLjcxMjggNTAuMTYzNyA1Mi43MTI4QzQzLjA4OTMgNTIuNzEyOCAzNy4zNTQ1IDUwLjQ4OTcgMzcuMzU0NSA0Ny43NDc1QzM3LjM1NDUgNDUuMDA1NyA0My4wODkzIDQyLjc4MjYgNTAuMTYzNyA0Mi43ODI2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTk1LjQ0MzQgNDEuNDE3NEwxMDkuNjI3IDQ3LjAyMjRMOTUuNDU1NiA1Mi42MjJMOTUuNDQzNCA0MS40MTc0WiIgZmlsbD0iIzYyMUIxQyIvPgo8cGF0aCBkPSJNNzkuNzUyOSA0Ny42MjYxTDk1LjQ0NDkgNDEuNDE4OUw5NS40NTcxIDUyLjYyMzZMOTMuOTE4NCA1My4yMjU0TDc5Ljc1MjkgNDcuNjI2MVoiIGZpbGw9IiM5QTI5MjgiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMzIxMyIgeDE9IjE4OSIgeTE9IjIxMC41IiB4Mj0iMCIgeTI9IjAiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iI0E4MDAwMCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNGRkNGQ0YiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "size"], ["spec", "storageClass"], ["spec", "external"], ["spec", "version"], ["spec", "authEnabled"]] + secrets: + exclude: [] + include: + - resourceNames: + - redis-{{ .name }}-auth + services: + exclude: [] + include: + - resourceNames: + - rfs-redis-{{ .name }} + - rfrm-redis-{{ .name }} + - rfrs-redis-{{ .name }} + - redis-{{ .name }}-external-lb diff --git a/packages/system/redis-rd/templates/cozyrd.yaml b/packages/system/redis-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/redis-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/redis-rd/values.yaml b/packages/system/redis-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/redis-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/seaweedfs-rd/Chart.yaml b/packages/system/seaweedfs-rd/Chart.yaml new file mode 100644 index 00000000..5799783b --- /dev/null +++ b/packages/system/seaweedfs-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: seaweedfs-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/seaweedfs-rd/Makefile b/packages/system/seaweedfs-rd/Makefile new file mode 100644 index 00000000..5be03dbb --- /dev/null +++ b/packages/system/seaweedfs-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=seaweedfs-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/seaweedfs-rd/cozyrds/seaweedfs.yaml b/packages/system/seaweedfs-rd/cozyrds/seaweedfs.yaml new file mode 100644 index 00000000..787b5448 --- /dev/null +++ b/packages/system/seaweedfs-rd/cozyrds/seaweedfs.yaml @@ -0,0 +1,44 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: seaweedfs +spec: + application: + kind: SeaweedFS + singular: seaweedfs + plural: seaweedfses + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"db":{"description":"Database configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of database replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""}}},"filer":{"description":"Filer service configuration.","type":"object","default":{},"properties":{"grpcHost":{"description":"The hostname used to expose or access the filer service externally.","type":"string","default":""},"grpcPort":{"description":"The port used to access the filer service externally.","type":"integer","default":443},"replicas":{"description":"Number of filer replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"A list of IP addresses or CIDR ranges that are allowed to access the filer service.","type":"array","default":[],"items":{"type":"string"}}}},"host":{"description":"The hostname used to access SeaweedFS externally (defaults to 's3' subdomain for the tenant host).","type":"string","default":""},"master":{"description":"Master service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of master replicas.","type":"integer","default":3},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"replicationFactor":{"description":"Replication factor: number of replicas for each volume in the SeaweedFS cluster.","type":"integer","default":2},"s3":{"description":"S3 service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of S3 replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]}}},"topology":{"description":"The topology of the SeaweedFS cluster.","type":"string","default":"Simple","enum":["Simple","MultiZone","Client"]},"volume":{"description":"Volume service configuration.","type":"object","default":{},"properties":{"replicas":{"description":"Number of volume replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"small","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"size":{"description":"Persistent Volume size.","default":"10Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":""},"zones":{"description":"A map of zones for MultiZone topology. Each zone can have its own number of replicas and size.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"replicas":{"description":"Number of replicas in the zone.","type":"integer"},"size":{"description":"Zone storage size.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}}}}}}} + release: + prefix: "" + labels: + cozystack.io/ui: "true" + internal.cozystack.io/tenantmodule: "true" + chart: + name: seaweedfs + sourceRef: + kind: HelmRepository + name: cozystack-extra + namespace: cozy-public + dashboard: + category: Administration + singular: SeaweedFS + plural: SeaweedFS + name: seaweedfs + description: Seaweedfs + module: true + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTEzOC42ODUgMTIxLjA1N0MxMzguNjg1IDEyNi42NTIgMTM2LjQ2MiAxMzIuMDE3IDEzMi41MDQgMTM1Ljk3M0MxMjguNTQ3IDEzOS45MjkgMTIzLjE3OSAxNDIuMTUxIDExNy41ODIgMTQyLjE1MUMxMTEuOTg1IDE0Mi4xNTEgMTA2LjYxOCAxMzkuOTI5IDEwMi42NiAxMzUuOTczQzk4LjcwMjggMTMyLjAxNyA5Ni40Nzk1IDEyNi42NTIgOTYuNDc5NSAxMjEuMDU3Qzk2LjQ3OTUgMTE4LjI4NyA5Ny4wMjUzIDExNS41NDQgOTguMDg1OCAxMTIuOTg1Qzk5LjE0NjMgMTEwLjQyNSAxMDAuNzAxIDEwOC4xIDEwMi42NiAxMDYuMTQxQzEwNC42MiAxMDQuMTgyIDEwNi45NDYgMTAyLjYyOSAxMDkuNTA3IDEwMS41NjlDMTEyLjA2NyAxMDAuNTA5IDExNC44MTEgOTkuOTYyOSAxMTcuNTgyIDk5Ljk2MjlDMTIwLjM1MyA5OS45NjI5IDEyMy4wOTggMTAwLjUwOSAxMjUuNjU4IDEwMS41NjlDMTI4LjIxOCAxMDIuNjI5IDEzMC41NDQgMTA0LjE4MiAxMzIuNTA0IDEwNi4xNDFDMTM0LjQ2NCAxMDguMSAxMzYuMDE4IDExMC40MjUgMTM3LjA3OSAxMTIuOTg1QzEzOC4xMzkgMTE1LjU0NCAxMzguNjg1IDExOC4yODcgMTM4LjY4NSAxMjEuMDU3WiIgZmlsbD0idXJsKCNwYWludDFfcmFkaWFsXzY3OV8xOTEwKSIvPgo8cGF0aCBkPSJNMTEwLjMzNiAxMjYuMTQ3SDEyMy42OFYxMzYuODIzSDExMC4zMzZWMTI2LjE0N1oiIGZpbGw9IiMwRjVFOUMiLz4KPHBhdGggZD0iTTExOS4yNyAxMTIuMjk0QzExOS4yNyAxMTIuNzE0IDExOS4xNzggMTEzLjEzMSAxMTkgMTEzLjUxOUMxMTguODIxIDExMy45MDggMTE4LjU2IDExNC4yNjEgMTE4LjIzIDExNC41NThDMTE3LjkwMSAxMTQuODU1IDExNy41MDkgMTE1LjA5MSAxMTcuMDc5IDExNS4yNTJDMTE2LjY0OCAxMTUuNDEzIDExNi4xODYgMTE1LjQ5NiAxMTUuNzIgMTE1LjQ5NkMxMTQuNzc4IDExNS40OTYgMTEzLjg3NSAxMTUuMTU4IDExMy4yMSAxMTQuNTU4QzExMi41NDQgMTEzLjk1NyAxMTIuMTcgMTEzLjE0MyAxMTIuMTcgMTEyLjI5NEMxMTIuMTcgMTExLjQ0NSAxMTIuNTQ0IDExMC42MyAxMTMuMjEgMTEwLjAzQzExMy44NzUgMTA5LjQyOSAxMTQuNzc4IDEwOS4wOTIgMTE1LjcyIDEwOS4wOTJDMTE2LjE4NiAxMDkuMDkyIDExNi42NDggMTA5LjE3NSAxMTcuMDc5IDEwOS4zMzZDMTE3LjUwOSAxMDkuNDk2IDExNy45MDEgMTA5LjczMiAxMTguMjMgMTEwLjAzQzExOC41NiAxMTAuMzI3IDExOC44MjEgMTEwLjY4IDExOSAxMTEuMDY4QzExOS4xNzggMTExLjQ1NyAxMTkuMjcgMTExLjg3MyAxMTkuMjcgMTEyLjI5NFoiIGZpbGw9IiM1OTY4NkYiLz4KPHBhdGggZD0iTTEyOC4xMSAxMTQuMTAzQzEyOC4xMSAxMTQuOTUzIDEyNy43MzYgMTE1Ljc2NyAxMjcuMDcgMTE2LjM2OEMxMjYuNDA0IDExNi45NjggMTI1LjUwMSAxMTcuMzA1IDEyNC41NiAxMTcuMzA1QzEyNC4wOTQgMTE3LjMwNSAxMjMuNjMyIDExNy4yMjMgMTIzLjIwMSAxMTcuMDYyQzEyMi43NzEgMTE2LjkwMSAxMjIuMzc5IDExNi42NjUgMTIyLjA1IDExNi4zNjhDMTIxLjcyIDExNi4wNyAxMjEuNDU4IDExNS43MTcgMTIxLjI4IDExNS4zMjlDMTIxLjEwMiAxMTQuOTQgMTIxLjAxIDExNC41MjQgMTIxLjAxIDExNC4xMDNDMTIxLjAxIDExMy42ODMgMTIxLjEwMiAxMTMuMjY2IDEyMS4yOCAxMTIuODc4QzEyMS40NTggMTEyLjQ5IDEyMS43MiAxMTIuMTM3IDEyMi4wNSAxMTEuODM5QzEyMi4zNzkgMTExLjU0MiAxMjIuNzcxIDExMS4zMDYgMTIzLjIwMSAxMTEuMTQ1QzEyMy42MzIgMTEwLjk4NCAxMjQuMDk0IDExMC45MDEgMTI0LjU2IDExMC45MDFDMTI1LjUwMSAxMTAuOTAxIDEyNi40MDQgMTExLjIzOSAxMjcuMDcgMTExLjgzOUMxMjcuNzM2IDExMi40NCAxMjguMTEgMTEzLjI1NCAxMjguMTEgMTE0LjEwM1oiIGZpbGw9IiM1OTY4NkYiLz4KPHBhdGggZD0iTTEyMi4zMzMgMTE4Ljk3NkMxMjIuMzMzIDExOS44MjYgMTIxLjk1OCAxMjAuNjQgMTIxLjI5MyAxMjEuMjQxQzEyMC42MjcgMTIxLjg0MSAxMTkuNzI0IDEyMi4xNzggMTE4Ljc4MiAxMjIuMTc4QzExOC4zMTYgMTIyLjE3OCAxMTcuODU1IDEyMi4wOTYgMTE3LjQyNCAxMjEuOTM1QzExNi45OTMgMTIxLjc3NCAxMTYuNjAyIDEyMS41MzggMTE2LjI3MiAxMjEuMjQxQzExNS45NDMgMTIwLjk0MyAxMTUuNjgxIDEyMC41OSAxMTUuNTAzIDEyMC4yMDJDMTE1LjMyNCAxMTkuODEzIDExNS4yMzIgMTE5LjM5NyAxMTUuMjMyIDExOC45NzZDMTE1LjIzMiAxMTguNTU2IDExNS4zMjQgMTE4LjE0IDExNS41MDMgMTE3Ljc1MUMxMTUuNjgxIDExNy4zNjMgMTE1Ljk0MyAxMTcuMDEgMTE2LjI3MiAxMTYuNzEyQzExNi42MDIgMTE2LjQxNSAxMTYuOTkzIDExNi4xNzkgMTE3LjQyNCAxMTYuMDE4QzExNy44NTUgMTE1Ljg1NyAxMTguMzE2IDExNS43NzQgMTE4Ljc4MiAxMTUuNzc0QzExOS43MjQgMTE1Ljc3NCAxMjAuNjI3IDExNi4xMTIgMTIxLjI5MyAxMTYuNzEyQzEyMS45NTggMTE3LjMxMyAxMjIuMzMzIDExOC4xMjcgMTIyLjMzMyAxMTguOTc2WiIgZmlsbD0iIzU5Njg2RiIvPgo8cGF0aCBkPSJNMTE1LjMwOCAxMjEuOTA1QzExMy43MzUgMTIxLjQyNiAxMTUuNzA3IDEyMC42OCAxMTUuNDI5IDEyMC41NzNDMTE0LjY1MyAxMjAuMjc2IDExNS43MyAxMTkuMzMzIDExNi43NCAxMTguNTM5QzExNy42MjggMTE3Ljg0MSAxMTcuNjU5IDExNy44MzkgMTE3Ljg5MiAxMTguNDY4QzExOC4wMjQgMTE4LjgyMyAxMTguMzcxIDExOS4yMDYgMTE4LjY2NSAxMTkuMzE5QzExOS4yODkgMTE5LjU1OCAxMjAuOTUxIDExOS4yNjkgMTIwLjk1MSAxMTguODM1QzEyMC45NTEgMTE4LjIyMyAxMjEuNDE1IDExOC42OTkgMTIxLjc5NCAxMTkuNTMxQzEyMi40NTcgMTIwLjk4NyAxMjIuNDM3IDEyMi40NzIgMTIxLjQ1IDEyMi40NzJDMTIwLjg1OSAxMjIuNDcyIDEyMC4zMSAxMjIuNjkxIDEyMC4xOSAxMjMuMTQ3QzExNS4wNDYgMTI0LjYgMTE2LjQ3MSAxMjMuMjg0IDExNS4zMDggMTIxLjkwNVpNMTIzLjA5NCAxMTguMDU0QzEyMS42MDkgMTE3LjQ2NiAxMjAuNTQ3IDExNC44MzggMTIwLjU0NyAxMTMuMzA5QzEyMC41NDcgMTExLjMyMyAxMjIuNTQxIDEwOS4wOTUgMTI0LjMxNyAxMDkuMDk1QzEyOC4zMTUgMTA5LjA5NSAxMzAuNjg0IDExMi4yNjEgMTI4LjgzOCAxMTguNDA5QzEyOC4zODUgMTE5LjkxOSAxMjMuOTMzIDExOC4zODcgMTIzLjA5NCAxMTguMDU0Wk0xMjUuODY2IDExNS42NDlDMTI3LjU0NCAxMTQuNDc0IDEyNS44NTcgMTExLjc1NSAxMjMuOTgxIDExMi42MUMxMjIuNDc5IDExMy4yOTQgMTIzLjExOSAxMTYuMTE1IDEyNC43NyAxMTYuMTY0QzEyNC45NjEgMTE2LjE2OSAxMjUuNDU0IDExNS45MzggMTI1Ljg2NiAxMTUuNjQ5Wk0xMjQuMzM5IDExNC41NzlDMTIzLjc3MSAxMTQuMzgxIDEyMy44MDMgMTEzLjI1NiAxMjQuMzgzIDExMy4wMzRDMTI0LjkwMiAxMTIuODM1IDEyNS42MDQgMTEzLjM5OCAxMjUuNjA0IDExNC4wMTRDMTI1LjYwNCAxMTQuNDg5IDEyNC45MzYgMTE0Ljc4NyAxMjQuMzM5IDExNC41NzlaTTExMi4zMTkgMTE2Ljk4QzEwOS45NiAxMTUuNjcgMTEwLjI4NiAxMTEuMDA2IDExMi40MTcgMTA4Ljk2NUMxMTQuMzk2IDEwNy4wNjkgMTE4Ljc3OCAxMDcuMTAzIDExOS43NjQgMTA5LjQ2MkMxMjAuNDE1IDExMS4wMjEgMTIwLjIyOCAxMTIuNiAxMTkuMzk4IDExNC4wNzdDMTE4LjE5NCAxMTYuMjE5IDExNC4yNDIgMTE4LjA0OSAxMTIuMzE5IDExNi45OFpNMTE2LjU2IDExMy41OTNDMTE3LjMyNSAxMTIuOTAxIDExNy4yOTcgMTEyLjA2IDExNi41NzIgMTExLjI1OUMxMTUuNzc3IDExMC4zNzkgMTE0LjY5MiAxMTAuMzQ1IDExNC4wMzUgMTExLjM0N0MxMTMuNTI0IDExMi4xMjcgMTEzLjQzMSAxMTIuNTI4IDExMy45NDMgMTEzLjMwOUMxMTQuNTggMTE0LjI4IDExNS42NyAxMTQuMzk5IDExNi41NiAxMTMuNTkzWk0xMTQuMzc0IDExMi4zNEMxMTQuMTI4IDExMS42OTggMTE0Ljk4NSAxMTAuOTgxIDExNS42OCAxMTEuMjQ3QzExNS45NzQgMTExLjM2IDExNi4xNjQgMTExLjcxOCAxMTYuMTAyIDExMi4wNDRDMTE1Ljk2MSAxMTIuNzg1IDExNC42MzIgMTEzLjAxMiAxMTQuMzc0IDExMi4zNFoiIGZpbGw9IiNEM0Q2REEiLz4KPHBhdGggZD0iTTExOC40NjMgMTIxLjAwOEwxMTcuOTQ1IDEyMC43OEMxMTcuNTEgMTIwLjY4NSAxMTcuMjMxIDEyMS4xMDcgMTE3LjEzNiAxMjEuNTQzTDExNi44ODEgMTIyLjcwOUMxMTYuNzg2IDEyMy4xNDUgMTE3LjA2MSAxMjMuNTcxIDExNy40OTYgMTIzLjY2NkwxMTguNDQ3IDEyMy44NzRDMTE4Ljg4MiAxMjMuOTY5IDExOS4zMTEgMTIzLjY5NCAxMTkuNDA2IDEyMy4yNTlMMTE5LjY4NSAxMjEuNTU2QzExOS43OCAxMjEuMTIgMTE5LjQ3OSAxMjEuMjI4IDExOS4wNDMgMTIxLjEzM0wxMTguNjI4IDEyMS4wNDNDMTE4LjU3MyAxMjEuMzIxIDExOC41MTYgMTIxLjYxMyAxMTguNDcxIDEyMS44MzNDMTE4LjQzOCAxMjEuOTk4IDExOC40MDcgMTIyLjE0OCAxMTguMzc5IDEyMi4yODJDMTE4LjM1MSAxMjIuNDE1IDExOC4zMjcgMTIyLjUzMyAxMTguMzA1IDEyMi42MzVDMTE4LjI4MiAxMjIuNzM4IDExOC4yNjIgMTIyLjgyNSAxMTguMjQ1IDEyMi44OTdDMTE4LjIyOCAxMjIuOTY5IDExOC4yMTQgMTIzLjAyNSAxMTguMjAyIDEyMy4wNjhDMTE4LjE5NiAxMjMuMDg5IDExOC4xOTMgMTIzLjEwNyAxMTguMTg4IDEyMy4xMjFDMTE4LjE4MyAxMjMuMTM1IDExOC4xNzggMTIzLjE0NSAxMTguMTc1IDEyMy4xNTJDMTE4LjE3MyAxMjMuMTU1IDExOC4xNzIgMTIzLjE1NiAxMTguMTcxIDEyMy4xNThDMTE4LjE3IDEyMy4xNTkgMTE4LjE2OCAxMjMuMTYgMTE4LjE2NyAxMjMuMTZMMTE4LjE2NSAxMjMuMTU4QzExOC4xNjQgMTIzLjE1NiAxMTguMTYzIDEyMy4xNTIgMTE4LjE2MyAxMjMuMTQ4QzExOC4xNjIgMTIzLjE0IDExOC4xNjIgMTIzLjEyOSAxMTguMTYzIDEyMy4xMTVDMTE4LjE2MyAxMjMuMSAxMTguMTYzIDEyMy4wODMgMTE4LjE2NSAxMjMuMDYxQzExOC4xNjggMTIzLjAxOCAxMTguMTc1IDEyMi45NjEgMTE4LjE4MyAxMjIuODkxQzExOC4xOTIgMTIyLjgyIDExOC4yMDMgMTIyLjczNiAxMTguMjE2IDEyMi42NEMxMTguMjI5IDEyMi41NDMgMTE4LjI0NiAxMjIuNDMxIDExOC4yNjQgMTIyLjMwOEMxMTguMjgxIDEyMi4xODUgMTE4LjMwMSAxMjIuMDUxIDExOC4zMjMgMTIxLjkwM0MxMTguMzQ2IDEyMS43NTUgMTE4LjM3IDEyMS41OTIgMTE4LjM5NyAxMjEuNDE5QzExOC40MTYgMTIxLjI5OSAxMTguNDQyIDEyMS4xNCAxMTguNDYzIDEyMS4wMDhaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDMuNTgxIDExNi4zNjdDMTAzLjQ3OSAxMTYuMTAzIDEwMy42MjIgMTE1LjY5OSAxMDMuODk4IDExNS40NjlDMTA0LjMwMyAxMTUuMTMzIDEwNC41MDQgMTE1LjE1NSAxMDQuOTMgMTE1LjU4MUMxMDUuMjIgMTE1Ljg3MSAxMDUuMzU1IDExNi4yNzYgMTA1LjIzIDExNi40NzlDMTA0LjkwMiAxMTcuMDA5IDEwMy43OTggMTE2LjkzNCAxMDMuNTgxIDExNi4zNjdaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDYuMDM4IDExMi4yODFDMTA1LjY4IDExMS44NDkgMTA1LjcwMiAxMTEuNjYgMTA2LjE2NSAxMTEuMTk3QzEwNi42ODkgMTEwLjY3NCAxMDYuNzY0IDExMC42NzQgMTA3LjI4NyAxMTEuMTk3QzEwNy43NTEgMTExLjY2IDEwNy43NzMgMTExLjg0OSAxMDcuNDE1IDExMi4yODFDMTA3LjE3NiAxMTIuNTY4IDEwNi44NjYgMTEyLjgwMyAxMDYuNzI2IDExMi44MDNDMTA2LjU4NiAxMTIuODAzIDEwNi4yNzcgMTEyLjU2OCAxMDYuMDM4IDExMi4yODFaIiBmaWxsPSIjOThDNkQ4Ii8+CjxwYXRoIGQ9Ik0xMDYuMDM4IDEwNy4yMjRDMTA1LjY4MiAxMDYuNzk1IDEwNS42OTQgMTA2LjYxMiAxMDYuMTA2IDEwNi4yMDFDMTA2LjY1IDEwNS42NTcgMTA3LjczOCAxMDUuODggMTA3LjczOCAxMDYuNTM2QzEwNy43MzggMTA2Ljk3IDEwNy4wNzIgMTA3Ljc0NyAxMDYuNyAxMDcuNzQ3QzEwNi41NzUgMTA3Ljc0NyAxMDYuMjc3IDEwNy41MTIgMTA2LjAzOCAxMDcuMjI0WiIgZmlsbD0iIzk4QzZEOCIvPgo8cGF0aCBkPSJNMTE3Ljk1NSAxMzYuNTQxQzExNC41NzggMTM2LjExMSAxMTAuMDg3IDEzNC44ODEgMTA5LjQxIDEzNC4yNzRDMTA4LjEyMyAxMzMuMTE5IDEwOC45NDIgMTI3Ljg3OSAxMTAuNDY2IDEyNi41NEMxMTEuMzg3IDEyNS43MzEgMTE1LjAzOSAxMjQuNjYzIDExNy4xODIgMTI1LjE2OUMxMTkuNjQyIDEyNS43NDkgMTIzLjkzMiAxMjguNjQ4IDEyNC4yNSAxMjkuNTA4QzEyNC42MjUgMTMwLjUyMiAxMjQuMDQ4IDEzNC41NDEgMTIzLjMyMyAxMzUuNTM2QzEyMi42OTQgMTM2LjM5OSAxMjAuMzI1IDEzNi44NDMgMTE3Ljk1NSAxMzYuNTQxWk0xMjAuNTQgMTM0LjA4NEMxMjEuMjk3IDEzMy4zOTkgMTIxLjM0MiAxMzEuODQyIDEyMC42MjcgMTMxLjEyNkMxMTkuNDkgMTI5Ljk4OSAxMTcuMTEyIDEzMC44NjkgMTE3LjExMiAxMzIuNDI4QzExNy4xMTIgMTM0LjMwNCAxMTkuMTg5IDEzNS4zMDcgMTIwLjU0IDEzNC4wODRaTTExOC41ODIgMTMzLjEyNUMxMTguMzExIDEzMi40MTkgMTE4LjY4IDEzMS42MDggMTE5LjI3MiAxMzEuNjA4QzEyMCAxMzEuNjA4IDEyMC4yMjggMTMyLjE3MyAxMTkuODEyIDEzMi45NDlDMTE5LjM4MSAxMzMuNzU1IDExOC44NTMgMTMzLjgzIDExOC41ODIgMTMzLjEyNVpNMTE2LjQyMiAxMzMuMTQzQzExNy4wOTQgMTMyLjMzMyAxMTYuNzExIDEzMS4xNzYgMTE1LjY4MSAxMzAuOTAyQzExNC41ODEgMTMwLjYxIDExNC4wNTIgMTMxLjE4MyAxMTQuODY5IDEzMS43OEMxMTUuNjgzIDEzMi4zNzUgMTE1LjU1MSAxMzIuNjc5IDExNC41MzMgMTMyLjU1N0MxMTMuMzI3IDEzMi40MTMgMTEyLjgzMyAxMzEuNTY2IDExMy4yNTQgMTMwLjM2MkMxMTMuNjgxIDEyOS4xNDIgMTE1LjE5NyAxMjguODYzIDExNS43NTMgMTI5LjkwMkMxMTYuMTkzIDEzMC43MjUgMTE2LjYyNyAxMzAuNzkzIDExNi45IDEzMC4wODNDMTE3LjIyOSAxMjkuMjI0IDExNS45MTQgMTI4LjIzNyAxMTQuNDQgMTI4LjIzN0MxMTEuOTkzIDEyOC4yMzcgMTEwLjgxNiAxMzEuMDc0IDExMi41NDYgMTMyLjgwM0MxMTMuNSAxMzMuNzU4IDExNS43NDkgMTMzLjk1NSAxMTYuNDIyIDEzMy4xNDNaIiBmaWxsPSIjN0JBOUI5Ii8+CjxwYXRoIGQ9Ik0xMjAuMTE4IDEzOC41OTJDMTE4Ljc1MSAxMzcuMjk3IDEyMS45MTYgMTM2LjA5NiAxMjMuNjA2IDEzOC4yODNDMTI0LjQ2OSAxMzkuMzIyIDEyMi44NTMgMTM5Ljk3NiAxMjAuMTE4IDEzOC41OTJaTTEwNi4xMiAxMzUuNjU4QzEwNC43NTEgMTM0LjI4OSAxMDYuOTYzIDEzMy45MDQgMTA4LjU4MSAxMzUuMjNMMTA5Ljk0MSAxMzUuOTJMMTA4LjA1OSAxMzYuMDYxQzEwNy4yMTUgMTM2LjA2MiAxMDYuMzQzIDEzNS44ODEgMTA2LjEyIDEzNS42NThWMTM1LjY1OFpNMTI1LjM2MyAxMjcuODY2QzEyNS4wODIgMTI3LjQxIDEyOC4zMzMgMTI2LjI2NyAxMjguNjg4IDEyNi40ODZDMTI4Ljg0NiAxMjYuNTg0IDEyOC45NzUgMTI3LjMzNyAxMjguOTc1IDEyOC4xNjFDMTI4Ljk3NSAxMjkuMjM5IDEyOC44NCAxMjkuNjU4IDEyOC40OSAxMjkuNjU4QzEyOC4yMjIgMTI5LjY1OCAxMjUuNDc2IDEyOC4wNDcgMTI1LjM2MyAxMjcuODY2Wk0xMTguNjQxIDEyMS4wOTVDMTE0Ljg3MSAxMjAuNzUzIDExNS4zNzggMTE5LjMyNyAxMTYuMzYxIDExOC40OTlDMTE2LjkyOCAxMTguMDIxIDExNy4zNCAxMTcuNzc5IDExNy45MTMgMTE3LjY2N0MxMTcuOTEzIDExNy42NjcgMTE3Ljg3MiAxMTkuMDQ2IDExOC42NjYgMTE5LjMxOUMxMTkuMjk3IDExOS41MzYgMTIwLjI3OCAxMTkuMDY0IDEyMC40NzEgMTE4LjY3NUMxMjIuMTg4IDExNS4yMDEgMTIxLjQxNSAxMTguNjk5IDEyMS43OTQgMTE5LjUzMkMxMjMuMjM4IDEyNC4wMDcgMTIwLjE4OCAxMjEuNzMgMTE4LjY0MSAxMjEuMDk1Wk0xMDQuOTEyIDEyMS4yM0MxMDQuMjQyIDEyMC40ODcgMTAzLjY5MyAxMTkuNzI5IDEwMy42OTMgMTE5LjU0NEMxMDMuNjkzIDExOS4xMTYgMTA0Ljc0NiAxMTkuMTEyIDEwNS44NjMgMTE5LjUzN0MxMDYuNTkzIDExOS44MTQgMTEwLjM0NyAxMjAuMDA2IDExMC4zNDcgMTIxLjE1M0MxMTAuMzQ3IDEyMS44OTkgMTA4Ljg5IDEyMy43NjIgMTA4LjcyNiAxMjMuNzYyQzEwOC41NjMgMTIzLjc2MiAxMDUuNTgzIDEyMS45NzIgMTA0LjkxMiAxMjEuMjNaIiBmaWxsPSIjQTZCM0MyIi8+CjxwYXRoIGQ9Ik0xMTguNDYzIDEyMS4wMDhDMTE4LjQ0MiAxMjEuMTQgMTE4LjQxNiAxMjEuMjk5IDExOC4zOTcgMTIxLjQxOUMxMTguMzcgMTIxLjU5MiAxMTguMzQ1IDEyMS43NTUgMTE4LjMyMyAxMjEuOTAzQzExOC4zIDEyMi4wNTEgMTE4LjI4MSAxMjIuMTg1IDExOC4yNjMgMTIyLjMwOEMxMTguMjQ1IDEyMi40MzEgMTE4LjIyOSAxMjIuNTQyIDExOC4yMTYgMTIyLjYzOUMxMTguMjAzIDEyMi43MzYgMTE4LjE5MSAxMjIuODIgMTE4LjE4MyAxMjIuODlDMTE4LjE3NSAxMjIuOTYxIDExOC4xNjggMTIzLjAxOCAxMTguMTY1IDEyMy4wNjFDMTE4LjE2MyAxMjMuMDgzIDExOC4xNjQgMTIzLjEgMTE4LjE2MyAxMjMuMTE1QzExOC4xNjIgMTIzLjEyOSAxMTguMTYyIDEyMy4xNCAxMTguMTYzIDEyMy4xNDhDMTE4LjE2MyAxMjMuMTUyIDExOC4xNjQgMTIzLjE1NiAxMTguMTY1IDEyMy4xNThMMTE4LjE2NyAxMjMuMTZDMTE4LjE2OCAxMjMuMTYgMTE4LjE3IDEyMy4xNTkgMTE4LjE3MSAxMjMuMTU4QzExOC4xNzIgMTIzLjE1NyAxMTguMTczIDEyMy4xNTUgMTE4LjE3NSAxMjMuMTUyQzExOC4xNzggMTIzLjE0NSAxMTguMTgyIDEyMy4xMzUgMTE4LjE4NyAxMjMuMTIxQzExOC4xOTIgMTIzLjEwNyAxMTguMTk2IDEyMy4wODkgMTE4LjIwMiAxMjMuMDY3QzExOC4yMTMgMTIzLjAyNSAxMTguMjI4IDEyMi45NjkgMTE4LjI0NSAxMjIuODk3QzExOC4yNjIgMTIyLjgyNSAxMTguMjgyIDEyMi43MzggMTE4LjMwNSAxMjIuNjM1QzExOC4zMjcgMTIyLjUzMyAxMTguMzUxIDEyMi40MTUgMTE4LjM3OSAxMjIuMjgxQzExOC40MDYgMTIyLjE0OCAxMTguNDM4IDEyMS45OTggMTE4LjQ3MSAxMjEuODMzQzExOC41MTYgMTIxLjYxMyAxMTguNTczIDEyMS4zMjEgMTE4LjYyOCAxMjEuMDQzTDExOC40NjMgMTIxLjAwOFoiIGZpbGw9IiM0QzlDQkIiLz4KPHBhdGggZD0iTTMwLjk5ODYgMTQyLjY3M0MyNi40NDg5IDE0MC45MTYgMjEuNDY2NCAxMzYuODA1IDE4Ljc5MjEgMTMyLjYwM0MxNS40MDUzIDEyNy4yODEgMTQuNDA1MiAxMjMuNDE5IDE1LjA2MzYgMTE4LjIwM0MxNS42ODA2IDExMy4zMTUgMTcuMzU1OCAxMTAuNTU3IDIyLjIyMzIgMTA2LjQxM0MyOS4wNDE3IDEwMC42MDggMzQuNDg0NiA5Ny45Nzk5IDQwLjU5NDcgOTcuNTQxNUM0OS44MjEyIDk2Ljg3OTQgNTUuMDk3OCA5OS44MTA5IDU3LjY0NjUgMTA3LjAxNUM1OC41MDQzIDEwOS40MzkgNTguNjg1NiAxMTUuNTcgNTguMDU0NCAxMjAuODA5QzU3LjgzMTEgMTIyLjY2MyA1Ny40Nzg5IDEyNi4wNTUgNTcuMjcxOCAxMjguMzQ4QzU2LjU0NjcgMTM2LjM3NSA1NC40MTQ3IDE0MC40MTcgNDkuNjI1MyAxNDIuODQzQzQ4LjI5NzkgMTQzLjUxNiA0Ny43MTk5IDE0My41NjEgNDAuNjkyNCAxNDMuNTM5QzMzLjUxNTEgMTQzLjUxNiAzMy4wODEgMTQzLjQ3OCAzMC45OTg2IDE0Mi42NzNaTTAuMDc5NTc2NSAxMDQuOTY1QzAuMDgxNTcyMyAxMDMuODUzIDAuMTQ0NDAzIDEwMy40MzggMC4yMTk0MjcgMTA0LjA0NEMwLjI5NDQ1MSAxMDQuNjUgMC4yOTI4OTkgMTA1LjU2IDAuMjE1OTk2IDEwNi4wNjdDMC4xMzkwNzkgMTA2LjU3MyAwLjA3NzY4MzggMTA2LjA3OCAwLjA3OTU3NjUgMTA0Ljk2NVpNMC4wMDE3MzM1MSAxMDIuMjRDMC4wMTc4OTkyIDEwMS44NDggMC4wOTc3ODk3IDEwMS43NjggMC4yMDUzOTggMTAyLjAzN0MwLjMwMjc3MiAxMDIuMjggMC4yOTA3OTcgMTAyLjU3MSAwLjE3ODc4NyAxMDIuNjgzQzAuMDY2Nzc0OCAxMDIuNzk1IC0wLjAxMjkwMjEgMTAyLjU5NiAwLjAwMTczMzUxIDEwMi4yNFpNMC4wMjgzNDQ0IDc1LjEzMjZDMC4wMjgzNDQ0IDc0LjY2OTEgMC4xMDQ4NTcgNzQuNDc5NSAwLjE5ODM2OSA3NC43MTEyQzAuMjkxODg0IDc0Ljk0MyAwLjI5MTg4NCA3NS4zMjIyIDAuMTk4MzY5IDc1LjU1MzlDMC4xMDQ4NTcgNzUuNzg1NyAwLjAyODM0NDQgNzUuNTk2MSAwLjAyODM0NDQgNzUuMTMyNloiIGZpbGw9InVybCgjcGFpbnQyX3JhZGlhbF82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTM1LjMxMzMgMTEyLjU0NEwzNy45IDExMS4wOTFMMzkuMzUxNyAxMjEuNDZMMzkuMjQ4IDEyOC45MjZMMzUuMzcwMyAxMzAuODUxTDMyLjkyMjkgMTI2LjQzN0wzNS4zMTMzIDExMi41NDRaIiBmaWxsPSIjMzA2MEFEIi8+CjxwYXRoIGQ9Ik0zOC43Mjk1IDExNi42OUwzOS4zNTE2IDEyNC41NzFMNDMuMjkxOSAxMjUuOTE5TDQzLjM5NTYgMTA5LjIyNUw0MC4xODEyIDExMC4wNTRMMzguNzI5NSAxMTYuNjlaIiBmaWxsPSIjNjA2MzY4Ii8+CjxwYXRoIGQ9Ik0zNS4zNjk5IDEzMC44NTFDMzMuMDMyNCAxMjkuNzMgMjkuNzMwMSAxMjYuNDA4IDI4LjY2MjEgMTI0LjEwM0MyOC4wMzMyIDEyMi43NDUgMjcuNjM5NyAxMjIuMzEgMjYuODkyMyAxMjIuMTQ2QzI1Ljc4NzkgMTIxLjkwMyAyNS44MDg0IDEyMS45NzEgMjYuMzIxOCAxMjAuMjU4QzI2LjU5MzYgMTE5LjM1IDI2LjkwMzIgMTE4Ljk1NCAyNy4zNDA2IDExOC45NTRDMjcuNjg2MiAxMTguOTU0IDI5LjE1OTcgMTE3Ljg0MSAzMC42MTQ5IDExNi40OEMzMi4wNzAyIDExNS4xMTkgMzMuNzIyNiAxMTMuNjc3IDM0LjI4NjkgMTEzLjI3NUwzNS4zMTI5IDExMi41NDRMMzUuNjc2NyAxMTQuMjQxQzM3LjA0NDMgMTIwLjYxOCAzNy4wMjcgMTI0LjI2NiAzNS42MTk4IDEyNi4yNDNDMzQuNTUyMSAxMjcuNzQ0IDM0Ljg0MTcgMTI4LjM5MyAzNi41NzkxIDEyOC4zOTNDMzcuMzk3IDEyOC4zOTMgMzcuODIyMiAxMjguMTg1IDM4LjEzMDUgMTI3LjYzNEMzOC42NzQ4IDEyNi42NjMgMzguNjMxNSAxMjAuOTY4IDM4LjA0NTQgMTE2LjQyNkMzNy4zNDQ2IDExMC45OTUgMzcuMzEyNyAxMTEuMTY3IDM5LjE1NzggMTEwLjM5OEM0MC4wMzYgMTEwLjAzMSA0MC44MTggMTA5Ljc5NyA0MC44OTU1IDEwOS44NzdDNDAuOTczMSAxMDkuOTU2IDQwLjgxOTEgMTExLjIzNSA0MC41NTM0IDExMi43MThDMzkuNjA2NyAxMTguMDAzIDM5LjkzMTUgMTIzLjIzOCA0MS4yNzUyIDEyNC4zNTNDNDEuNjg1MSAxMjQuNjkzIDQxLjcyMzMgMTIzLjk2OSA0MS41NDUyIDExOS4yMzJDNDEuMzE1NiAxMTMuMTIzIDQxLjUxNzQgMTEwLjkxOSA0Mi40MDc1IDEwOS44MkM0Mi45MTk4IDEwOS4xODggNDMuMjEzIDEwOS4xMTYgNDQuNDk1OSAxMDkuMzFDNDYuOTU2NiAxMDkuNjgyIDQ2Ljk1MDYgMTA5LjY2OCA0Ni4yMDk5IDExMy4yNTRDNDUuODQ5NiAxMTQuOTk5IDQ1LjQ0ODMgMTE3LjIyNCA0NS4zMTggMTE4LjJMNDUuMDgxMiAxMTkuOTczTDQ1Ljk0NDYgMTE5LjY0NUM0Ni40MTk1IDExOS40NjUgNDcuNDQxMyAxMTguOTk0IDQ4LjIxNTMgMTE4LjU5OUw0OS42MjI2IDExNy44ODFMNDkuMzg5MyAxMTguNjdDNDkuMjYxIDExOS4xMDUgNDkuMDY3MiAxMjAuNzAxIDQ4Ljk1ODcgMTIyLjIxOEw0OC43NjE0IDEyNC45NzZMNDcuMTA5NSAxMjQuMzI1QzQ2LjIwMSAxMjMuOTY3IDQ1LjMxMTYgMTIzLjY3NCA0NS4xMzMxIDEyMy42NzRDNDQuOTQxIDEyMy42NzQgNDQuODA4NSAxMjUuNTMyIDQ0LjgwODUgMTI4LjIyNEM0NC44MDg1IDEzMS44OTEgNDQuNzE3MSAxMzIuNzc1IDQ0LjMzODYgMTMyLjc3NUM0MS4wMTk4IDEzMi4yOTUgMzguNzg0MiAxMzIuNDU4IDM1LjM2OTkgMTMwLjg1MVoiIGZpbGw9IiNFRUMyM0IiLz4KPHBhdGggZD0iTTQxLjE2MzkgMTMyLjQxOEM0MS4xNjM5IDEzMi4yODMgNDEuMzQwOCAxMzAuNTE1IDQxLjY2OTIgMTI4LjE0NUM0MS45OTc3IDEyNS43NzUgNDIuMzU3NyAxMjIuOTYxIDQyLjQ2OTIgMTIxLjg5M0M0Mi41ODA4IDEyMC44MjQgNDIuNzk2OSAxMjAuMDI3IDQyLjk0OTUgMTIwLjEyMUM0My42NDQzIDEyMC41NTEgNDQuMjkzOCAxMjkuMzc1IDQ0LjA0NzQgMTMxLjQyQzQzLjg5MDkgMTMyLjcxOSA0My42NTk1IDEzMi43MzcgNDMuMzAxOSAxMzIuNjc3QzQyLjY2MDIgMTMyLjU3IDQxLjkxMDEgMTMyLjUxMyA0MS4xNjM5IDEzMi40MThaTTMyLjU5NjkgMTIyLjczNUMzMS42ODEzIDEyMi41ODMgMzAuODI0MiAxMjEuNDQyIDMwLjgyNDIgMTIwLjM3NEMzMC44MjQyIDExOS40MDcgMzIuMjM4MSAxMTcuOTM3IDMzLjE2ODUgMTE3LjkzN0MzNC42NjY2IDExNy45MzcgMzUuODM5MiAxMjAuNTEzIDM0Ljk0ODQgMTIxLjg0N0MzNC41NTE3IDEyMi40NDEgMzMuNDE0NyAxMjIuODcgMzIuNTk2OSAxMjIuNzM1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExNC4wMjEgMTM3LjQ5OEMxMDcuMzE4IDEzNS43NCAxMDYuMjczIDEzNC4xMDQgMTA2LjYwOSAxMjUuODkxQzEwNi43MTYgMTIzLjI4MSAxMDYuODg1IDEyMC41MzkgMTA2Ljk4NiAxMTkuNzk3QzEwNy41NDUgMTE1LjY2NCAxMDguMzQyIDExMi4xNzMgMTA5LjA4NiAxMTAuNTk5QzEwOS43NDQgMTA5LjIwNiAxMDkuODQyIDEwOC43MTIgMTA5LjUzNSAxMDguMzQyQzEwOC40NSAxMDcuMDM1IDExMC4zNzEgMTA0Ljk5NSAxMTEuOTEgMTA1LjgxOUMxMTIuNDU3IDEwNi4xMTEgMTEyLjkxOCAxMDYuMDc3IDExMy45NDUgMTA1LjY2NUMxMTcuMDYyIDEwNC40MTkgMTIzLjExNyAxMDUuNTcxIDEyNi44MTQgMTA4LjExNUMxMjguMTQ5IDEwOS4wMzMgMTI4LjQ4NSAxMDkuMTM2IDEyOS4wMzggMTA4Ljc5MUMxMzAuNTIzIDEwNy44NjMgMTMyLjQ1MSAxMTAuNTczIDEzMS4yNSAxMTEuOUMxMzAuNzg3IDExMi40MTIgMTMwLjc1NSAxMTIuNzA1IDEzMS4wNjUgMTEzLjU5NkMxMzEuODUgMTE1Ljg0NiAxMzEuNzk0IDExNi4xMDQgMTI4LjAwNiAxMjcuNzE5QzEyNS41OCAxMzUuMTYgMTI0LjU0MyAxMzcuMzY1IDEyMy4yNjQgMTM3LjgxMUMxMjEuNjUzIDEzOC4zNzMgMTE2LjcyMyAxMzguMjA2IDExNC4wMjEgMTM3LjQ5OFpNMTIyLjU0MSAxMzUuMjI5QzEyMy4wMDMgMTM0LjU0MSAxMjMuMzU5IDEzMy4zMTMgMTIzLjUxMyAxMzEuODc4QzEyMy43OTQgMTI5LjI1IDEyMy44MTkgMTI5LjI4MyAxMjAuMzE3IDEyNy42MDFDMTE3LjY4NSAxMjYuMzM4IDExMy44MzMgMTI1Ljk3MiAxMTEuODU1IDEyNi43OThDMTEwLjgyOSAxMjcuMjI3IDExMC41OTUgMTI3LjU1NiAxMTAuMDU5IDEyOS4zMjdDMTA5LjExNiAxMzIuNDQzIDEwOS43MDMgMTM0LjMwOCAxMTEuODMyIDEzNC45NThDMTEzLjEzOSAxMzUuMzU3IDEyMC4wOSAxMzYuNDMgMTIwLjk4IDEzNi4zN0MxMjEuNTA0IDEzNi4zMzUgMTIyLjA4MiAxMzUuOTEyIDEyMi41NDEgMTM1LjIyOVpNMTE5LjQ1MSAxMjIuNDJDMTE5LjYzIDEyMi4wODEgMTE5LjY4NSAxMjEuNTU2IDExOS42ODUgMTIxLjU1NkMxMjAuMTU2IDEyMS42NTQgMTIwLjQ4IDEyMS42ODMgMTIwLjcyNiAxMjEuNzE5QzEyMS4xMDUgMTIxLjc3NCAxMjEuNTY0IDEyMS41ODcgMTIxLjc0NSAxMjEuMzAzQzEyMi4xNDkgMTIwLjY3MSAxMjAuNDc0IDExNy43MDEgMTE5LjU0OCAxMTcuNDA4QzExOC42NjggMTE3LjEyOCAxMTUuOTM1IDExOC44MjcgMTE1LjkzNSAxMTkuNjUzQzExNS45MzUgMTIwLjAyMiAxMTYuNTUzIDEyMC40MTEgMTE2LjgzMSAxMjAuNTE4QzExNi45ODIgMTIwLjU3NiAxMTcuMjUyIDEyMC43MzggMTE3LjU3NiAxMjAuOTM4QzExNy4zOCAxMjEuMzUxIDExNy4zNDYgMTIxLjQ3OCAxMTcuMzEyIDEyMS43MjRDMTE3LjIwNCAxMjIuNDk4IDExNy40MzUgMTIyLjY4NiAxMTguNDE2IDEyMi45MTJDMTE5LjE1MSAxMjIuOTkxIDExOS4yNSAxMjIuODQ1IDExOS40NTEgMTIyLjQyWk0xMjcuMjY1IDExNi44MzZDMTMwLjkzMyAxMTMuNDc1IDEyNy4wNzQgMTA3LjQxIDEyMi43MDUgMTA5LjY3QzEyMS42MjYgMTEwLjIyOCAxMjAuNjU0IDExMi4wMTkgMTIwLjY1NCAxMTMuNDQ5QzEyMC42NTQgMTE1LjY2NCAxMjIuODMxIDExNy45MzcgMTI0Ljk1NyAxMTcuOTQxQzEyNS43MzMgMTE3Ljk0MyAxMjYuNDE0IDExNy42MTcgMTI3LjI2NSAxMTYuODM2Wk0xMTcuMTQxIDExNS42MjJDMTE5LjAzNSAxMTQuNDY4IDExOS44MDQgMTExLjc5NSAxMTguODAyIDEwOS44NTdDMTE4LjA4MiAxMDguNDY0IDExNy4wMDggMTA3LjgzIDExNS4zNjYgMTA3LjgzQzExMS41MDggMTA3LjgzIDEwOS40ODUgMTEzLjIzNCAxMTIuNDY1IDExNS41NzhDMTEzLjU3IDExNi40NDggMTE1Ljc1NCAxMTYuNDY4IDExNy4xNDEgMTE1LjYyMloiIGZpbGw9IiMwOTk2RDEiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMzMuMTc1NyAyNkwzMi4zODEgMjcuMjE5QzMxLjk0NDkgMjcuODg5IDMxLjI4MzYgMjkuMzI0OCAzMC45MDkxIDMwLjQwODhDMzAuNTM0NyAzMS40OTI4IDI5Ljk5MjIgMzIuOTcwMSAyOS43MDQzIDMzLjY5MjhDMjkuNDE2MyAzNC40MTU0IDI5LjE3MzMgMzYuMTE1IDI5LjE2MzggMzcuNDdDMjkuMTQzNiA0MC4zNTMgMjguNzQ5NCA0MS44ODg4IDI3LjYzNjQgNDMuNDIyNUMyNi45MjEyIDQ0LjQwOCAyNi42NzUxIDQ0LjUyMjMgMjUuNDUzMiA0NC40NDFDMjMuODk5NSA0NC4zMzc3IDIyLjgxNTMgNDUuMDgxNSAyMS4yMTcgNDcuMzQ4MUMyMC43MTY1IDQ4LjA1OCAyMC4xMzY3IDQ4LjYzOTMgMTkuOTI4OSA0OC42MzkzQzE5LjcyMTEgNDguNjM5MyAxOS4xODA1IDQ4LjIzMTkgMTguNzI2MiA0Ny43MzUxQzE4LjI3MTkgNDcuMjM4MiAxNy45OTQ0IDQ3LjAxMTUgMTguMTExIDQ3LjIyOThDMTguNDkgNDcuOTM5NiAxNy41OTA0IDUzLjI2MTUgMTYuODM3OCA1NC43NjQyQzE1Ljk2NyA1Ni41MDI4IDE0LjM4NzIgNTcuNzIzMyAxMi41MzU0IDU4LjA4NDNDMTEuMDA1OSA1OC4zODI2IDExLjIyODMgNTguMDkgOC43MTc5NSA2My4wOTQ2QzYuNjYzMzQgNjcuMTkwNyA1Ljk2OTM1IDY3LjgyNjQgMi42NTUzMyA2OC42NTQyQzEuNDk3MTcgNjguOTQzNCAwLjQ1ODc1OSA2OS43MTQyIDAgNzAuNTI4N1Y3Mi44MjYzQzAuMzU2MTkzIDcyLjc0NzMgMC44Mjg3MjggNzIuNjIwMyAxLjYxNDk5IDcyLjM4NzNDMi45OTQ4NiA3MS45NzgyIDQuODIzNDggNzEuNDgwNiA1LjY3ODEgNzEuMjgwNkM3LjcyOTM0IDcwLjgwMDYgOS4zOTM1MSA2OS4yMTk1IDkuOTIyNzkgNjcuMjQ2N0MxMC4yNDI0IDY2LjA1NTQgMTAuNzAzMyA2NS40MjQxIDExLjk5OTIgNjQuNDA1OEMxMy4yODQgNjMuMzk2MiAxMy43NTY1IDYyLjc1NDYgMTQuMDY3MSA2MS41OTY5QzE0LjM3MzkgNjAuNDUzMiAxNC43MDExIDYwLjAwNCAxNS40NDA3IDU5LjcwNjNDMTcuMDE1MyA1OS4wNzI0IDIwLjY0NDQgNTUuODY1NSAyMS4yMzYzIDU0LjU4NThDMjEuNTM3MyA1My45MzQ5IDIyLjExOTggNTIuNTM5OSAyMi41Mjg3IDUxLjQ4NjJDMjMuMjYzNCA0OS41OTMyIDI1LjAxOTUgNDcuMzI2MSAyNS43NTAxIDQ3LjMyNjFDMjUuOTU3NCA0Ny4zMjYxIDI3LjEwOSA0Ni43MjQ4IDI4LjMwOTMgNDUuOTkwOEMzMS4yMzc2IDQ0LjIwMDMgMzEuNTk5MSA0My40MTM2IDMxLjU5OTEgMzguODYxNEMzMS41OTkxIDM1LjY4MTQgMzEuNjg3IDM1LjE1NTcgMzIuMzQ2OCAzNC4zNjg0QzMzLjAwMzcgMzMuNTg0NyAzMy4wOTk3IDMzLjAyNDkgMzMuMTM1MSAyOS43MzkxTDMzLjE3NTcgMjZaTTI0LjMzMzggNjMuNTk1OEMyNC4yMDM3IDYzLjYxMzUgMjQuMDczOCA2My42NjE4IDIzLjkyNTggNjMuNzM2MkMyMi45Mzk3IDY0LjIzMTUgMjIuNjEzNiA2NC45MTAyIDIxLjU5NzMgNjguNTg2QzIxLjAxNzkgNzAuNjgxNSAyMC40MjEyIDcyLjA4MTkgMTkuODc5OCA3Mi42MTc4QzE5LjQyMzUgNzMuMDY5NSAxOC45MzgzIDczLjg4MjMgMTguODAxIDc0LjQyNDJDMTguMTgxIDc2Ljg3MTUgMTYuNzQ1NCA3OC42MDczIDE0LjQ0OTUgNzkuNjg3MUMxMi40NTU1IDgwLjYyNDkgMTAuNjQwNyA4Mi4xMTc5IDkuMTExMDIgODQuMDc5OEM4LjMyMTA5IDg1LjA5MjkgNy40ODc1MiA4Ni4wMjkgNy4yNTY3OCA4Ni4xNjA5QzYuNzYxNjQgODYuNDQ0IDUuNzA4OTkgODguODk0MSA0LjYwNzg1IDkyLjMyOEMzLjcxMDkyIDk1LjEyNSAxLjcxMDY1IDk3LjQ2ODIgMC40Nzg1MTQgOTcuMTY1OEMwLjI1NDkzMSA5Ny4xMTA5IDAuMTA2OTExIDk3LjExMzcgMCA5Ny4yOTAxVjEwNC40OTJDMC41NTY0MTEgMTAzLjY2NCAxLjIzNDIgMTAyLjYyOSAyLjU2MzQ3IDEwMC41NEM0LjM0NTExIDk3LjczOTcgNi40NjM4NSA5NC40ODY3IDcuMjcxNzMgOTMuMzEyNEM4LjA3OTYgOTIuMTM4MSA5LjM1Njg3IDkwLjE0ODggMTAuMTA4NiA4OC44OTE2QzExLjIzNDIgODcuMDA5MiAxMi4xMDE2IDg2LjEyNDMgMTUuMDI4NCA4My44ODMzTDE4LjU4MzEgODEuMTYyN0wyMC40MDUzIDc1Ljk4ODFDMjMuMTg5NSA2OC4wODE3IDIzLjk1ODUgNjcuMTk5NyAyNy43NjI0IDY3LjU1MTVDMjkuNDYwNSA2Ny43MDg1IDMwLjYzMzQgNjcuNjE5NiAzMi4wNzM0IDY3LjIyNjdDMzQuMTgyNiA2Ni42NTEyIDM0LjQ3OTkgNjYuMTg3MiAzMy4zNTUxIDY1LjIzMThDMzIuNjU1NCA2NC42Mzc2IDMxLjMxNTMgNjQuNjQgMjguMjM4OCA2NS4yNDE4QzI3LjMzOTcgNjUuNDE3NyAyNi45MzQzIDY1LjI3NTcgMjUuODkzMiA2NC40MTc4QzI1LjEwNTEgNjMuNzY4NCAyNC43MjQxIDYzLjU0MjYgMjQuMzMzOCA2My41OTU4Wk0zMS43MTY2IDgzLjI1OThDMzEuNjYwNSA4My4yNzQ5IDMxLjU5MjEgODMuMzEyNiAzMS41MTE1IDgzLjM3MjFDMzEuMjcwOSA4My41NSAzMC42NTM2IDgzLjc5IDMwLjEzNzkgODMuOTA1NEMyOS4zODc2IDg0LjA3MzQgMjkuMDQ5OCA4NC40OTMyIDI4LjQ0ODIgODYuMDA0NUMyOC4wMzQ3IDg3LjA0MzIgMjcuNDkxNSA4OC4xMTUzIDI3LjI0MTIgODguMzg2M0MyNi45OTA5IDg4LjY1NzMgMjYuNDc1IDg5LjU1MSAyNi4wOTQxIDkwLjM3MzJDMjQuOTQyMiA5Mi44NTkyIDIzLjUyODIgOTQuMDYxOCAxOS45MDExIDk1LjY0MjFDMTYuNjEwNyA5Ny4wNzU2IDE2LjU2NyA5Ny4xMDg2IDE1LjY2NzEgOTguOTgwMkMxNS4xMDI3IDEwMC4xNTQgMTQuNjc5MiAxMDEuNzU3IDE0LjU0OTkgMTAzLjIwNUMxNC4yNzMxIDEwNi4zMDIgMTMuNTk2MiAxMDcuMDMxIDkuNTIxMTggMTA4LjYxNkM1LjkxNDk3IDExMC4wMTkgMy41NzcwMiAxMTEuNzQ1IDMuNDE1ODMgMTEzLjEyM0MzLjI0MDQxIDExNC42MjMgMi41OTgxMyAxMTUuMDg0IDAuOTI5MjYgMTE0LjkwN0MwLjUzOTUyOSAxMTQuODY2IDAuMjQ0MzMyIDExNC44NTEgMCAxMTQuODgxVjEyMUMxLjAyNjU4IDExOS42NTggMi43MTkyMiAxMTguMzYxIDYuMjI0OTcgMTE2LjIwNkMxMC4zNjA0IDExMy42NjUgMTIuNzA2NSAxMTEuNTc1IDEzLjU3NzkgMTA5LjY1NEMxMy45MjYgMTA4Ljg4NyAxNC42NTQ3IDEwNy4zOTMgMTUuMTk3MSAxMDYuMzM0QzE1LjczOTUgMTA1LjI3NSAxNi4yODQ1IDEwMy45MDEgMTYuNDA4NCAxMDMuMjgxQzE2LjczMjQgMTAxLjY2IDE4LjMwMzIgMTAwLjM0OSAyMC42NjU5IDk5LjcyNkMyNS4xNzcgOTguNTM3MiAyNS43NDYxIDk4LjAxNjMgMjYuMzUyNSA5NC41MzU0QzI2Ljg1NjEgOTEuNjQ1MiAyOC42MTIgODguMDY2MSAzMC41MjY3IDg2LjAyNDZDMzEuMzA5NSA4NS4xOSAzMS45NDk1IDg0LjE4IDMxLjk0OTUgODMuNzc5MUMzMS45NDk1IDgzLjM3NjYgMzEuODg0OSA4My4yMTQ2IDMxLjcxNjYgODMuMjU5OFoiIGZpbGw9IiMzNTkxMzYiLz4KPHBhdGggZD0iTTguMDgxNzcgNzQuNDA4M0M2LjAzNDE5IDczLjg3MDUgNS44OTQ0MyA3My43MzAyIDYuMDQyNzEgNzIuMzYxNUM2LjEzMDI1IDcxLjU1MzMgNi4yNDAxNyA3MC44NTc1IDYuMjg2OTYgNzAuODE1NEM2LjMzMzc2IDcwLjc3MzMgNy43MDQ0MyA3MS4wNjg3IDkuMzMyOTIgNzEuNDcxOUMxMS45NzY4IDcyLjEyNjQgMTIuNDg2NiA3Mi4xMjM4IDE0LjA5NDcgNzEuNDQ3NEMxNi40MDQxIDcwLjQ3NiAxNy4yMzgzIDY4Ljc3NTMgMTYuNDAyMiA2Ni43NDMxQzE1Ljk0MjQgNjUuNjI1NyAxNC45MjA0IDY0LjgyODEgMTIuMjM4NCA2My40OTRDNy42NDE3IDYxLjIwNzUgNi41MzA2MiA1OS45OTkgNi4yNzQ2NSA1Ny4wMDc2QzUuODkzMzcgNTIuNTUxOSA4Ljg0Njg5IDQ5Ljk4MzYgMTQuMzUyMiA0OS45ODM2QzE1Ljk3MzMgNDkuOTgzNiAxNy44NDg3IDUwLjE5MzcgMTguNTE5NiA1MC40NTA1QzE5LjYzNjggNTAuODc4MSAxOS42OTM3IDUxLjAzOTkgMTkuMTk0NSA1Mi4zNzEyQzE4LjcxODIgNTMuNjQxNiAxOC41MDI3IDUzLjc2ODggMTcuNDg2MSA1My4zNzk2QzE1LjUxOTkgNTIuNjI3IDEyLjE5NDggNTIuODU1NCAxMS4wMDU4IDUzLjgyNDdDOS43OTA1OCA1NC44MTUzIDkuNTU3MzYgNTYuOTI1MiAxMC41MzI0IDU4LjEwNzlDMTAuODcyNyA1OC41MjA3IDEyLjkwODcgNTkuNzc5IDE1LjA1NjkgNjAuOTA0MUMxOC40NjI4IDYyLjY4ODEgMTkuMDgyIDYzLjIyMTQgMTkuODk1MSA2NS4wNzE5QzIxLjExNTIgNjcuODQ4NyAyMC42Nzg4IDcwLjM0MzcgMTguNjA3OCA3Mi40MzIzQzE2LjE2MDcgNzQuOTAwMiAxMi41NDEzIDc1LjU3OTYgOC4wODE3NyA3NC40MDgzWk0yOC45MzI4IDc0LjM4MjNDMjUuMjM2NSA3Mi45OTU4IDIzLjcxMzggNzAuNTQwNSAyMy43MTM4IDY1Ljk2NjdDMjMuNzEzOCA2Mi41MDM0IDI0LjU1ODggNjAuNDY5NyAyNi44MzMzIDU4LjQ1OTNDMjguMzk2NCA1Ny4wNzc2IDI4Ljk4NjcgNTYuODY4NiAzMS4zMjY4IDU2Ljg2ODZDMzIuODE2OCA1Ni44Njg2IDM0LjY4MjEgNTcuMjEyOSAzNS41MDA1IDU3LjYzODlDMzcuMzE2OSA1OC41ODQ2IDM4LjgzMTkgNjEuNzQyNiAzOC44NDY2IDY0LjYxNDNMMzguODU3MyA2Ni43MDQ0SDMyLjk0MjNIMjcuMDI3M0wyNy4zNDIgNjguMDU2OUMyNy41MTUgNjguODAwNyAyOC4zMzU0IDcwLjAzOTEgMjkuMTY1IDcwLjgwOUMzMC41NzczIDcyLjExOTYgMzAuODk0OSA3Mi4xOTc5IDM0LjE1NDcgNzIuMDM4NUMzNy4zOTM4IDcxLjg4MDEgMzcuNjQ2MyA3MS45NDA5IDM3Ljc4NCA3Mi45MTIyQzM3Ljk2MjYgNzQuMTcyNSAzNy4xODgyIDc0LjUyMzYgMzMuNTI0MiA3NC44NDM0QzMxLjgwODUgNzQuOTkzMiAzMC4xMDU2IDc0LjgyMjIgMjguOTMyOCA3NC4zODIzWk0zNS4wODgxIDYyLjUyNDJDMzQuOTU1OCA2MC42NzMgMzMuMzY0NCA1OS4zMjc2IDMxLjMwNzIgNTkuMzI3NkMyOS43MDg2IDU5LjMyNzYgMjguNzI4MSA2MC4wOTA5IDI3LjY2MiA2Mi4xNjU1QzI2Ljc0NTcgNjMuOTQ4NiAyNy40MTIgNjQuMjk2NSAzMS40NDg4IDY0LjE0MjVMMzUuMTkzNiA2My45OTk2TDM1LjA4ODEgNjIuNTI0MlpNNDQuMzkxNCA3NC4zNzA4QzQyLjU3MTEgNzMuNTQ2OCA0MS43MDU5IDcyLjEyODYgNDEuNjQyMSA2OS44NjQ3QzQxLjU0MTYgNjYuMjk0NCA0NC4xMTEgNjQuMTQ2OCA0OS4yNTc2IDYzLjQ5OTRDNTEuODQxNCA2My4xNzQ0IDUyLjA0OTUgNjMuMDU3NyA1MS43NTkzIDYyLjA5NjlDNTAuOTY1IDU5LjQ2NjYgNDguMjQyMyA1OC41NjQ0IDQ0LjkyNzYgNTkuODMzMUM0My40MzAzIDYwLjQwNjMgNDMuNDg2OCA2MC40MzEzIDQzLjA1MTQgNTkuMDAzMkM0Mi43ODAxIDU4LjExMzUgNDIuOTk4MiA1Ny44NTExIDQ0LjM5NSA1Ny4zODdDNDYuOTM2NCA1Ni41NDI3IDUxLjM3NDUgNTYuNjM0MiA1Mi43Nzc5IDU3LjU2QzU0LjkzOTIgNTguOTg1NyA1NS4zNzUxIDYwLjYwMTkgNTUuNTQ4NyA2Ny44MzI4TDU1LjcxMDYgNzQuNTc0NUw1NC4xMjMgNzQuNTc0QzUzLjAzNzcgNzQuNTczMyA1Mi41MzUzIDc0LjMzOTYgNTIuNTM1MyA3My44MzU0QzUyLjUzNTMgNzIuOTA2NiA1Mi4wNTI4IDcyLjkwMjQgNTAuNzUyIDczLjgxOTZDNDkuMjAxMyA3NC45MTMgNDYuMTY5NyA3NS4xNzU3IDQ0LjM5MTQgNzQuMzcwOFpNNTAuOTQ3NyA3MC44MTc1QzUxLjcwOTkgNjkuOTczNSA1Mi4wNDY4IDY4Ljk4NiA1Mi4wNDY4IDY3LjU5NjZWNjUuNTkyOUw0OS44MTgyIDY1Ljg0NThDNDUuNzE5IDY2LjMxMSA0My44NzQ5IDY5LjUxMTggNDYuNTA1OCA3MS41OTUzQzQ4LjAzNzEgNzIuODA3OSA0OS4zNTk0IDcyLjU3NjMgNTAuOTQ3NyA3MC44MTc1Wk05Mi4wMDIgNzQuNTc4OEM4OC40MDI0IDczLjQ4NjQgODYuMjQxOSA3MC4yNDY2IDg2LjI0MTkgNjUuOTQxQzg2LjI0MTkgNjAuNDA0MiA4OS41MjExIDU2LjgzMjUgOTQuNjQxIDU2Ljc5MjVDOTguNjk4OSA1Ni43NjA5IDEwMS4yNjMgNTkuNDY3OSAxMDEuNTAzIDY0LjAzNjZMMTAxLjYzIDY2LjQ1ODVMOTYuMjU2MiA2Ni41ODg1QzkzLjMwMDcgNjYuNjYgOTAuNjE1OCA2Ni44MTYgOTAuMjg5NyA2Ni45MzUxQzg5LjM4MTggNjcuMjY2OCA5MC40Nzg4IDY5Ljk0NyA5Mi4wMzA2IDcxLjE4ODZDOTMuMTU5OSA3Mi4wOTIxIDkzLjc3MSA3Mi4xOTEyIDk2LjgxNzggNzEuOTY1QzEwMC4xOTMgNzEuNzE0NCAxMDAuMzE4IDcxLjc0NDkgMTAwLjUzMSA3Mi44Njg0QzEwMC43MyA3My45MTMzIDEwMC41MDkgNzQuMDgzNSA5OC4zNTc5IDc0LjU0OEM5NS42MTAzIDc1LjE0MTIgOTMuODgyOSA3NS4xNDk2IDkyLjAwMiA3NC41Nzg4Wk05Ny45NjU5IDYzLjA4MjNDOTcuOTY1OSA2MS4xMjMxIDk2LjE4NTggNTkuMzI3NiA5NC4yNDM0IDU5LjMyNzZDOTIuMjQ5NCA1OS4zMjc2IDkwLjE0OTkgNjEuMjU2MiA5MC4xNDk5IDYzLjA4NzhDOTAuMTQ5OSA2NC4yMDcgOTAuMjc5NyA2NC4yNDU1IDk0LjA1NzkgNjQuMjQ1NUM5Ny44NDE0IDY0LjI0NTUgOTcuOTY1OSA2NC4yMDg0IDk3Ljk2NTkgNjMuMDgyM1pNMTEwLjA0MiA3NC40N0MxMDYuMTQ5IDczLjQzIDEwMy45MyA2OS40MDI5IDEwNC41NCA2NC40ODYyQzEwNS4xNjYgNTkuNDQ0MiAxMDcuOTUxIDU2Ljg3MzYgMTEyLjc5MiA1Ni44NzA1QzExNS4zNzQgNTYuODY5IDExNS44MDUgNTcuMDI0OSAxMTcuMjYgNTguNDlDMTE4Ljg3OCA2MC4xMTg1IDExOS45NDEgNjIuODM0MyAxMTkuOTQ2IDY1LjM1MkwxMTkuOTQ5IDY2LjcwNDRIMTE0LjA4N0MxMDguNDg4IDY2LjcwNDQgMTA4LjIyNSA2Ni43NTAxIDEwOC4yMjUgNjcuNzIwM0MxMDguMjI1IDcwLjcxMjIgMTEwLjk1MiA3Mi4zNDQyIDExNS4zNTcgNzEuOTg4MkMxMTguMTM2IDcxLjc2MzcgMTE4LjQyMyA3MS44MzE1IDExOC42NjcgNzIuNzY3NEMxMTguOTk4IDc0LjA0NDMgMTE4Ljk2OCA3NC4wNzIgMTE2LjY5IDc0LjYwNDNDMTE0LjM2NyA3NS4xNDcgMTEyLjQzIDc1LjEwNzggMTEwLjA0MiA3NC40N1pNMTE2LjExOSA2Mi43NzAxQzExNS44NjQgNjAuODc4NyAxMTQuMTU5IDU5LjMyNzYgMTEyLjMzNSA1OS4zMjc2QzExMC41NjYgNTkuMzI3NiAxMDguMjI0IDYxLjYwMTQgMTA4LjIyNCA2My4zMTk1QzEwOC4yMjQgNjQuMjEyOCAxMDguNTI3IDY0LjI3NDYgMTEyLjI1NSA2NC4xNDI0QzExNi4yNDEgNjQuMDAxMSAxMTYuMjgzIDYzLjk4NjIgMTE2LjExOSA2Mi43NzAxWk0xMjYuODk0IDc0LjI0N0MxMjQuODI2IDczLjIyMDggMTIzLjUzMiA3MS4zNTg5IDEyMi44OTQgNjguNDg4OUMxMjEuOTc1IDY0LjM2MDUgMTIzLjA3NCA2MC40OTE0IDEyNS44MyA1OC4xNTY3QzEyNy44MjcgNTYuNDY1NyAxMzEuODM4IDU2LjMzMDUgMTMzLjgwNSA1Ny44ODc5TDEzNS4wOTIgNTguOTA3MlY1My45NTM2VjQ5SDEzNy4wNDZIMTM5VjYxLjc4NjVWNzQuNTczMUgxMzcuMjlDMTM1Ljc2MiA3NC41NzMxIDEzNS41OCA3NC40MzMxIDEzNS41OCA3My4yNTc5VjcxLjk0MjdMMTM0LjQ4MSA3Mi45NzkyQzEzMi4yMzMgNzUuMDk5OCAxMjkuNTI1IDc1LjU1MjMgMTI2Ljg5NCA3NC4yNDdaTTEzMy42NjQgNzAuNjc2NkMxMzQuOTc2IDY5LjM1NTcgMTM1LjA5MiA2OC45NTM3IDEzNS4wOTIgNjUuNzIwOUMxMzUuMDkyIDYyLjQ1NzIgMTM0Ljk4NSA2Mi4wOTQ1IDEzMy42MDcgNjAuNzA3NkMxMzIuMzY1IDU5LjQ1NzUgMTMxLjg2NSA1OS4yNjIyIDEzMC41NTQgNTkuNTE1NEMxMjYuMTQ0IDYwLjM2NzIgMTI0LjgzNSA2OC4xNDIzIDEyOC41OTggNzEuMTIyOUMxMzAuMzQ4IDcyLjUwODEgMTMxLjk4OCA3Mi4zNjM1IDEzMy42NjQgNzAuNjc2NlpNNjEuNDEwNyA2Ni4wNTg0QzYwLjAyMiA2MS4zNzU0IDU4Ljg4NTkgNTcuMzkxOSA1OC44ODU5IDU3LjIwNjJDNTguODg1OSA1Ny4wMjA2IDU5LjcyNzQgNTYuODY4NiA2MC43NTU5IDU2Ljg2ODZINjIuNjI1OUw2NC4yNTUxIDYzLjg3NjZDNjUuMTUxMiA2Ny43MzEgNjUuOTU2IDcwLjY2MzMgNjYuMDQzNyA3MC4zOTI5QzY2LjEzMTMgNzAuMTIyNCA2Ny4wNTU3IDY3LjAyNDEgNjguMDk3OCA2My41MDc4TDY5Ljk5MjYgNTcuMTE0NUg3MS41OTY5SDczLjIwMTJMNzQuODg2NSA2My4yNjE5Qzc1LjgxMzQgNjYuNjQzIDc2LjY4MzIgNjkuNzQxMiA3Ni44MTk0IDcwLjE0N0M3Ni45NTU3IDcwLjU1MjcgNzcuODQxOSA2Ny43MzEgNzguNzg5IDYzLjg3NjZMODAuNTEwOSA1Ni44Njg2SDgyLjQ1MTdDODMuOTUxNyA1Ni44Njg2IDg0LjMzMDMgNTcuMDMxNiA4NC4xMTkgNTcuNTg2QzgzLjk2ODYgNTcuOTgwNiA4Mi42OTU2IDYxLjk2NDEgODEuMjkwMiA2Ni40MzgyTDc4LjczNDkgNzQuNTczMUg3Ni45NjM1SDc1LjE5MjFMNzMuNTgxMiA2OC43OTQ1QzcyLjY5NTIgNjUuNjE2MyA3MS44NTg1IDYyLjY4NDEgNzEuNzIxNyA2Mi4yNzgzQzcxLjQ0NjUgNjEuNDYxNiA3MS41OTExIDYxLjA3MzMgNjkuMTExNCA2OS4yODYzTDY3LjUxNTIgNzQuNTczMUg2NS43MjU0SDYzLjkzNTZMNjEuNDEwNyA2Ni4wNTg0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTE5Ljk3NDYgMTE5LjI3NEMxOS4wMTU4IDExOC4xMTkgMjAuMzM4MSAxMTYuMTY2IDIxLjU2MDQgMTE2LjkzMkMyMi43NjMyIDExNy42ODYgMjIuMzMwNSAxMTkuNzYxIDIwLjk3MDQgMTE5Ljc2MUMyMC42NDUgMTE5Ljc2MSAyMC4xOTY5IDExOS41NDIgMTkuOTc0NiAxMTkuMjc0WiIgZmlsbD0idXJsKCNwYWludDNfcmFkaWFsXzY3OV8xOTEwKSIvPgo8cGF0aCBkPSJNMjMuODM2IDExMi42M0MyMi4xMTUyIDExMS42ODkgMjEuODAyOSAxMDkuNzk3IDIzLjE0NjUgMTA4LjQ1M0MyNC4wODU3IDEwNy41MTQgMjUuMjEgMTA3LjM5NCAyNi4yNTA3IDEwOC4xMjNDMjcuODU3MSAxMDkuMjQ5IDI3LjQ2NTUgMTEyLjAxMyAyNS42MDc5IDExMi42NkMyNS42MDc5IDExMi42NiAyNC40NzQ1IDExMi45NzMgMjMuODM2IDExMi42M1oiIGZpbGw9InVybCgjcGFpbnQ0X3JhZGlhbF82NzlfMTkxMCkiLz4KPHBhdGggZD0iTTMzLjc4NTUgMTIwLjAzNkMzMy43ODU1IDEyMC4xODggMzMuNzU1NyAxMjAuMzM4IDMzLjY5NzYgMTIwLjQ3OUMzMy42Mzk1IDEyMC42MTkgMzMuNTU0NCAxMjAuNzQ2IDMzLjQ0NzEgMTIwLjg1M0MzMy4zMzk4IDEyMC45NjEgMzMuMjEyNCAxMjEuMDQ2IDMzLjA3MjMgMTIxLjEwNEMzMi45MzIxIDEyMS4xNjIgMzIuNzgxOCAxMjEuMTkyIDMyLjYzMDEgMTIxLjE5MkMzMi40NzgzIDEyMS4xOTIgMzIuMzI4MSAxMjEuMTYyIDMyLjE4NzkgMTIxLjEwNEMzMi4wNDc3IDEyMS4wNDYgMzEuOTIwMyAxMjAuOTYxIDMxLjgxMyAxMjAuODUzQzMxLjcwNTcgMTIwLjc0NiAzMS42MjA2IDEyMC42MTkgMzEuNTYyNiAxMjAuNDc5QzMxLjUwNDUgMTIwLjMzOCAzMS40NzQ2IDEyMC4xODggMzEuNDc0NiAxMjAuMDM2QzMxLjQ3NDYgMTE5LjczIDMxLjU5NjMgMTE5LjQzNiAzMS44MTMgMTE5LjIxOUMzMi4wMjk3IDExOS4wMDMgMzIuMzIzNiAxMTguODgxIDMyLjYzMDEgMTE4Ljg4MUMzMi45MzY1IDExOC44ODEgMzMuMjMwNCAxMTkuMDAzIDMzLjQ0NzEgMTE5LjIxOUMzMy42NjM4IDExOS40MzYgMzMuNzg1NSAxMTkuNzMgMzMuNzg1NSAxMjAuMDM2WiIgZmlsbD0iYmxhY2siLz4KPHBhdGggZD0iTTEyMC43MjEgMTE4LjI3NkMxMjAuNzIxIDExOC42MjMgMTIwLjU2NSAxMTguOTU2IDEyMC4yODcgMTE5LjIwMUMxMjAuMDA5IDExOS40NDYgMTE5LjYzMiAxMTkuNTg0IDExOS4yMzkgMTE5LjU4NEMxMTguODQ2IDExOS41ODQgMTE4LjQ2OSAxMTkuNDQ2IDExOC4xOTEgMTE5LjIwMUMxMTcuOTEzIDExOC45NTYgMTE3Ljc1NyAxMTguNjIzIDExNy43NTcgMTE4LjI3NkMxMTcuNzU3IDExOC4xMDUgMTE3Ljc5NSAxMTcuOTM1IDExNy44NyAxMTcuNzc2QzExNy45NDQgMTE3LjYxNyAxMTguMDUzIDExNy40NzMgMTE4LjE5MSAxMTcuMzUyQzExOC4zMjkgMTE3LjIzIDExOC40OTIgMTE3LjEzNCAxMTguNjcyIDExNy4wNjhDMTE4Ljg1MSAxMTcuMDAzIDExOS4wNDQgMTE2Ljk2OSAxMTkuMjM5IDExNi45NjlDMTE5LjQzMyAxMTYuOTY5IDExOS42MjYgMTE3LjAwMyAxMTkuODA2IDExNy4wNjhDMTE5Ljk4NiAxMTcuMTM0IDEyMC4xNDkgMTE3LjIzIDEyMC4yODcgMTE3LjM1MkMxMjAuNDI0IDExNy40NzMgMTIwLjUzMyAxMTcuNjE3IDEyMC42MDggMTE3Ljc3NkMxMjAuNjgyIDExNy45MzUgMTIwLjcyMSAxMTguMTA1IDEyMC43MjEgMTE4LjI3NloiIGZpbGw9IiM1OTY4NkYiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82NzlfMTkxMCIgeDE9IjExIiB5MT0iLTQuNzc3NjhlLTA3IiB4Mj0iMTY0LjUiIHkyPSIxNTAuNSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjNjRCN0ZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzAwNURBRCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50MV9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTI0LjkwNCAxMjguNjM2KSByb3RhdGUoLTAuMDQ4NTUyKSBzY2FsZSgzNi4yODAyIDMxLjQwMzIpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzExNzdDRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM3RUM3RkYiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50Ml9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzkuMzUxMiAxMjEuNDYpIHJvdGF0ZSgtMC4wNTczKSBzY2FsZSg1MC4yMjc2IDUxLjMwOTEpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzExNzdDRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM3RUM3RkYiIHN0b3Atb3BhY2l0eT0iMCIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50M19yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjAuOTU0OCAxMTguMjYpIHNjYWxlKDEuMzA5MjkgMS41MDEyNykiPgo8c3RvcCBzdG9wLWNvbG9yPSIjODhBM0QwIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzVEODNCRiIvPgo8L3JhZGlhbEdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50NF9yYWRpYWxfNjc5XzE5MTAiIGN4PSIwIiBjeT0iMCIgcj0iMSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIGdyYWRpZW50VHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQuNzg0MyAxMTAuMjIxKSBzY2FsZSgyLjQ3Mjc3IDIuNTY5NTQpIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzg4QTNEMCIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM1RDgzQkYiLz4KPC9yYWRpYWxHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "topology"], ["spec", "replicationFactor"], ["spec", "db"], ["spec", "db", "replicas"], ["spec", "db", "size"], ["spec", "db", "storageClass"], ["spec", "db", "resources"], ["spec", "db", "resourcesPreset"], ["spec", "master"], ["spec", "master", "replicas"], ["spec", "master", "resources"], ["spec", "master", "resourcesPreset"], ["spec", "filer"], ["spec", "filer", "replicas"], ["spec", "filer", "resources"], ["spec", "filer", "resourcesPreset"], ["spec", "filer", "grpcHost"], ["spec", "filer", "grpcPort"], ["spec", "filer", "whitelist"], ["spec", "volume"], ["spec", "volume", "replicas"], ["spec", "volume", "size"], ["spec", "volume", "storageClass"], ["spec", "volume", "resources"], ["spec", "volume", "resourcesPreset"], ["spec", "volume", "zones"], ["spec", "s3"], ["spec", "s3", "replicas"], ["spec", "s3", "resources"], ["spec", "s3", "resourcesPreset"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - seaweedfs-{{ .name }}-s3 + ingresses: + exclude: [] + include: + - resourceNames: + - ingress-seaweedfs-{{ .name }}-s3 diff --git a/packages/system/seaweedfs-rd/templates/cozyrd.yaml b/packages/system/seaweedfs-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/seaweedfs-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/seaweedfs-rd/values.yaml b/packages/system/seaweedfs-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/seaweedfs-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/tcp-balancer-rd/Chart.yaml b/packages/system/tcp-balancer-rd/Chart.yaml new file mode 100644 index 00000000..9543455e --- /dev/null +++ b/packages/system/tcp-balancer-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: tcp-balancer-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/tcp-balancer-rd/Makefile b/packages/system/tcp-balancer-rd/Makefile new file mode 100644 index 00000000..39a0495f --- /dev/null +++ b/packages/system/tcp-balancer-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=tcp-balancer-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/tcp-balancer-rd/cozyrds/tcp-balancer.yaml b/packages/system/tcp-balancer-rd/cozyrds/tcp-balancer.yaml new file mode 100644 index 00000000..057bc922 --- /dev/null +++ b/packages/system/tcp-balancer-rd/cozyrds/tcp-balancer.yaml @@ -0,0 +1,33 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: tcp-balancer +spec: + application: + kind: TCPBalancer + plural: tcpbalancers + singular: tcpbalancer + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"httpAndHttps":{"description":"HTTP and HTTPS configuration.","type":"object","default":{},"required":["mode","targetPorts"],"properties":{"endpoints":{"description":"Endpoint addresses list.","type":"array","default":[],"items":{"type":"string"}},"mode":{"description":"Mode for balancer.","type":"string","default":"tcp","enum":["tcp","tcp-with-proxy"]},"targetPorts":{"description":"Target ports configuration.","type":"object","default":{},"required":["http","https"],"properties":{"http":{"description":"HTTP port number.","type":"integer","default":80},"https":{"description":"HTTPS port number.","type":"integer","default":443}}}}},"replicas":{"description":"Number of HAProxy replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each TCP Balancer replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"whitelist":{"description":"List of allowed client networks.","type":"array","default":[],"items":{"type":"string"}},"whitelistHTTP":{"description":"Secure HTTP by whitelisting client networks (default: false).","type":"boolean","default":false}}} + release: + prefix: tcp-balancer- + labels: + cozystack.io/ui: "true" + chart: + name: tcp-balancer + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: NaaS + singular: TCP Balancer + plural: TCP Balancer + description: Layer4 load balancer service + tags: + - network + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODNfMjk4NSkiLz4KPHBhdGggZD0iTTcyLjE2NDUgNTkuNDI0M0w2Mi41IDQ4LjQ5OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjI2IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTQxLjY4NTUgNTEuMDIxNUw0OS4yNDcgNjIuMDY5MyIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTcyLjE2NDYgNTkuNDQxNEw4MS43MjYzIDQ4LjM5MzZNODMuNzE3MSA3MS42Mjk0TDk1LjA2NCA2Mi4wNjc4TTgzLjcxNzEgNzEuNjEwOEw5NS4wNjQgODEuNTkzTTgxLjgyOTEgOTQuMjAxN0w3Mi4xNjQ2IDgzLjQ4MTFNNjIuNTAwMSA5NC4yMDE3TDcyLjE2NDYgODMuNDkwNE00OS4yNTU5IDgxLjE3MjRMNjAuMTgyMSA3MS42MTA4TTYwLjE5MTUgNzEuNjEwOEw0OS4yNjUyIDYyLjA0OTFMNzIuMTY0NiA1OS40MjI3TDk1LjA2NCA2Mi4wNDkxIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMjYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNODEuNzE2OCA0OC4zOTM2TDgzLjcxNyA3MS42MTA4TDgxLjgyOSA5NC4xOTI0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMjYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDY0IDgxLjU5MjVMNzIuMTY0NiA4My40ODA1TTQ5LjI1NTkgODEuMTcxOUw3Mi4xNTUzIDgzLjQ5OTIiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4yNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik02Mi41MDEyIDk0LjIwMTRMNjAuMTczOCA3MS42MTk4TTYyLjUwMTIgNDguNDk2MUw2MC4xNzM4IDcxLjYxMDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4yNiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0zOC43NSA2NC45OTQ4TDQ5LjI1NTcgNjIuMDUwNk01MS40NjE1IDQwLjYxODdMNjIuNTA5MyA0OC40OTc5TTYyLjQ5MDYgNDguNDk3OUw2NS4wMTQyIDM1LjY4MzZMODEuNzE2OCA0OC4zOTUxIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNzkuMjAzMSAzNS42ODM2TDgxLjcyNjcgNDguMzk1MU05Mi43NTU4IDQwLjYxODdMODEuNzA4IDQ4LjM5NTFNMTAyLjYyNiA1MS4wMjE1TDgxLjcxNzQgNDguMzk1MU0xMDIuNjI2IDUxLjAwMjhMOTUuMDY0NSA2Mi4wNTA2TDEwNS43NzYgNjQuOTk0OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTk1LjA2MzkgNjIuMDUwNkwxMDUuNTcgNzguMDE0OE03OS4yMDI1IDM1LjY4MzZMNjIuNSA0OC40OTc5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDYzNyA2Mi4wNTExTDkyLjczNjMgNDAuNjE5MU05NS4wNjM3IDgxLjU5NTFMMTA1LjU2OSA3OC4wMTUzIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTUuMDY1IDgxLjU5NDlMMTA1Ljc3NiA2NC45OTUxTTk1LjA2NSA4MS41OTQ5TDEwMi42MjYgOTEuNzgyOE05NS4wNjUgODEuNTk0OUw5Mi43Mzc3IDEwMi4xODZNODEuODMwMSA5NC4yMDM1TDkyLjc1NjQgMTAyLjE4NiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTgxLjgyOSA5NC4yMDNMMTAyLjYyNSA5MS43ODIyTTgxLjgyOSA5NC4yMDNMNzkuMzI0MSAxMDcuMTExTTgxLjgyOSA5NC4yMDNMNjUuMDE0MyAxMDcuMTAxTTYyLjUgOTQuMjAzTDY1LjAyMzYgMTA3LjEzOSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTYyLjUwMTIgOTQuMjAzMUw3OS4zMjUzIDEwNy4xMTFNNTEuNDYyOCAxMDIuMTg1TDYyLjUxMDUgOTQuMjAzMUw0MS42NzY4IDkxLjg4NTFMNDkuMjU2OSA4MS4xNzM4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTMiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNTEuNDYxOCAxMDIuMTg1TDQ5LjI1NiA4MS4xNzMxTDM4LjY0NzUgNzcuOTExMUw0OS4yNTYgNjIuMDQ5OCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEzIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTQ5LjI1NTcgODEuMTc0NUwzOC43NSA2NC45OTUzTTUxLjQ2MTUgNDAuNjE5MUw0OS4yNTU3IDYyLjA1MTEiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik00MS42ODU1IDUxLjAyMTdMNjIuNDgxOSA0OC40OTgiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMyIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik00My4zNzYgMzYuODMzOEw1MS40NjA5IDQwLjYxOTJMNTAuODM0NiAzMS43OTU5TDY1LjAxMzYgMzUuNjg0MSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik01OC45Mjg5IDI4LjIyNDRMNjUuMDEzNiAzNS42ODMxTDY3LjUzNzMgMjYuNzM4M0w3OS4yMDE5IDM1LjY4MzFNNTEuNDYwOSA0MC42MTgxTDU4LjkxOTYgMjguMjI0NCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik03Ni41NjY3IDI2LjQ0MDRMNzkuMjAyNSAzNS42ODQzTDg1LjI5NjYgMjguMjI1Nk02NS4wMDQ5IDM1LjY4NDNMNzYuNTU3NCAyNi40NDA0TTkyLjc1NTIgNDAuNjE5NEw4NS4yNzc5IDI4LjIyNTYiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNOTIuNzU0OSA0MC42MTkyTDkzLjQ5MzIgMzEuNzk1OU05Mi43NTQ5IDQwLjYxOTJMMTAxLjAzNiAzNi40MTMyTTkyLjc1NDkgNDAuNjE5MkwxMDcuMTQ5IDQyLjgyNU03OS4yMDIxIDM1LjY4NDFMOTMuNDgzOSAzMS43OTU5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTEwMi42MjUgNTEuMDIxNEwxMDcuMTM5IDQyLjgyNDRNMTAyLjYyNSA1MS4wMjE0TDEwMS4wNDUgMzYuNDIxOU0xMDIuNjI1IDUxLjAyMTRMMTEyLjA4MyA1MC4yODNNMTAyLjYyNSA1MS4wMjE0TDExNS41NiA1OC4zNzczIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTEwNS43NzQgNjQuOTk0OUwxMTIuMDgzIDUwLjI4MzJNMTA1Ljc3NCA2NC45OTQ5TDExNS41NDEgNTguMzc3NE0xMDUuNzc0IDY0Ljk5NDlMMTE2LjcgNjcuMjAwN0wxMDUuNTY4IDc4LjAxNDkiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMTE3LjAxOSA3NS45MTIxTDEwNS41NjkgNzguMDE1MUwxMTUuMzM3IDg0LjUyOTdMMTAyLjYyNSA5MS43ODI3TTEwNS43NzUgNjQuOTk1MUwxMTcuMDE5IDc1LjkyMTQiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMTAyLjYyNSA5MS43ODMzTDExMS45NzEgOTIuNzI3M00xMDUuNTc4IDc4LjAxNTZMMTExLjk3MSA5Mi43MThNMTA3LjA1NSAxMDAuMDY0TDEwMi42NDMgOTEuNzgzM0wxMDAuOTYxIDEwNi4yOCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0xMDAuOTQzIDEwNi4yNzlMOTIuNzQ1OCAxMDIuMTg1TTkyLjc1NTEgMTAyLjE4NUw5My4zODEzIDExMS4zNDVNOTIuNzU1MSAxMDIuMTg1TDEwNy4wMzcgMTAwLjA4Mk05Mi43NTUxIDEwMi4xODVMODUuMjg3MSAxMTQuNzk0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTc5LjMyMzIgMTA3LjEwM0w4NS4yNzcgMTE0Ljc2N003OS4zMjMyIDEwNy4xMDNMOTMuMzk5MyAxMTEuMzA5TTc5LjMyMzIgMTA3LjEwM0w3Ni41NjU5IDExNi41NjFNNzkuMzIzMiAxMDcuMTAzTDY3LjU1NTcgMTE2LjU2MSIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik02NS4wMTM2IDEwNy4xMDJMNjcuNTM3MyAxMTYuNTYxTTY1LjAxMzYgMTA3LjEwMkw3Ni41NTY4IDExNi41NjFNNjUuMDEzNiAxMDcuMTAyTDU5LjAyMjQgMTE0Ljc2Nk01MS40NjA5IDEwMi4xODZMNTkuMDIyNCAxMTQuNzk0IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTY1LjAxMzkgMTA3LjEwMUw1MC43MzIyIDExMS41MTNNNTAuNzIyOCAxMTEuNTMyTDUxLjQ2MTIgMTAyLjE4NUw0My4yNjQyIDEwNi42OTlMNDEuNjg0NiA5MS44ODQ4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTUxLjQ2MSAxMDIuMTg2TDM3LjA2NzEgMTAwLjE5NU00MS42ODQ0IDkxLjg4NkwzNy4wNTc4IDEwMC4xNjdNNDEuNjg0NCA5MS44ODZMMzIuMjI1NSA5Mi44MzAxTTQxLjY4NDQgOTEuODg2TDI4LjY3MzggODQuNjQyM0wzOC42NDY3IDc3LjkxMjdMMjcuMjk5OCA3NS45MjE5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTM4LjY0NjcgNzcuOTEyM0wzMi4yNTM2IDkyLjgyOTZNMzguNzQ5NSA2NC45OTUxTDI3LjI5OTggNzUuOTIxNCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik0zOC42NDY3IDc3LjkxMjJMMjcuMjk5OCA2Ny4yMDA5TTM4Ljc1ODkgNjQuOTk1MUwyOC45ODIyIDU4LjQ4MDUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNMjcuMjk5OCA2Ny4yMDA3TDM4Ljc0OTUgNjQuOTk0OUwzMi4yNDQyIDUwLjI4MzIiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMC4xMDEiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBkPSJNNDEuNjgzNiA1MS4wMjE3TDMyLjIyNDcgNTAuMjgzM000MS42ODM2IDUxLjAyMTdMMjguOTgxNCA1OC40ODA0TTQxLjY4MzYgNTEuMDIxN0wzNy4xNzg1IDQzLjI0NTNNNDEuNjgzNiA1MS4wMjE3TDQzLjM2NiAzNi44NDI4IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjAuMTAxIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggZD0iTTUxLjQ2MSA0MC42MTkxTDM3LjE2OTkgNDMuMjQ1NiIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIwLjEwMSIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIGQ9Ik01NC41NjQ1IDc3LjA3MDJMNTQuNjM5MiA2Ni4wMjI0TDY1LjY4NyA2Ni4wOTcxTDY1LjYxMjMgNzcuMTQ0OUw1NC41NjQ1IDc3LjA3MDJaTTY2LjUxODkgNjQuOTEwMUw2Ni41OTM3IDUzLjg2MjNMNzcuNjQxNSA1My45MzcxTDc3LjU2NjcgNjQuOTg0OUw2Ni41MTg5IDY0LjkxMDFaTTY2LjUxODkgODkuMTI3NEw2Ni41OTM3IDc4LjA3OTZMNzcuNjQxNSA3OC4xNTQ0TDc3LjU2NjcgODkuMjAyMkw2Ni41MTg5IDg5LjEyNzRaTTc4LjU3NjEgNzYuOTY3M0w3OC42NTA5IDY1LjkxOTVMODkuNjk4NyA2NS45OTQzTDg5LjYyMzkgNzcuMDQyMUw3OC41NzYxIDc2Ljk2NzNaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNzcuOTQwNiA1Mi4yMzY2TDc3Ljk5NjYgNDQuNTcyM0w4NS42OTgzIDQ0LjYyODNMODUuNjQyMiA1Mi4yOTI2TDc3Ljk0MDYgNTIuMjM2NlpNNTguNjg2NCA1Mi4yMzY2TDU4Ljc0MjQgNDQuNTcyM0w2Ni40NDQxIDQ0LjYyODNMNjYuMzg4IDUyLjI5MjZMNTguNjg2NCA1Mi4yMzY2Wk00NS4zNTggNjUuODkyMUw0NS40MTQxIDU4LjIyNzhMNTMuMTE1NyA1OC4yODM5TDUzLjA1OTcgNjUuOTQ4Mkw0NS4zNTggNjUuODkyMVpNNDUuMzQ4NiA4NS4xNjVMNDUuNDMyOCA3Ny41MDA3TDUzLjEzNDQgNzcuNTg0OEw1My4wNTAzIDg1LjI0OTFMNDUuMzQ4NiA4NS4xNjVaTTkxLjI2OSA4NS4wMTU0TDkxLjMyNSA3Ny4zNTExTDk5LjAyNjcgNzcuNDA3Mkw5OC45NzA2IDg1LjA3MTVMOTEuMjY5IDg1LjAxNTRaTTkxLjQxODUgNjUuOTQ4Mkw5MS41MDI2IDU4LjI4MzlMOTkuMjA0MyA1OC4zNjhMOTkuMTIwMiA2Ni4wMzIzTDkxLjQxODUgNjUuOTQ4MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0zOS4xMTQzIDUzLjUyNjNMMzkuMTUxNyA0OC40NzkxTDQ0LjE4MDIgNDguNTE2NUw0NC4xNDI4IDUzLjU2MzdMMzkuMTE0MyA1My41MjYzWk00OC45NTYzIDQzLjI2MzdMNDguOTkzNyAzOC4yMTY0TDU0LjAyMjMgMzguMjUzOEw1My45ODQ5IDQzLjMwMUw0OC45NTYzIDQzLjI2MzdaTTYyLjQ5OTcgMzguMTg4NEw2Mi41MzcxIDMzLjE0MTJMNjcuNTY1NiAzMy4xNzg2TDY3LjUyODIgMzguMjI1OEw2Mi40OTk3IDM4LjE4ODRaTTM2LjE1MTQgNjcuNDkwM0wzNi4xODg4IDYyLjQ0MzFMNDEuMTg5MiA2Mi40ODA1TDQxLjE1MTkgNjcuNTI3N0wzNi4xNTE0IDY3LjQ5MDNaTTEwMC4wODMgNDguNTUzOUwxMDUuMTMgNDguNTE2NUwxMDUuMTY3IDUzLjU0NUwxMDAuMTIgNTMuNTgyNEwxMDAuMDgzIDQ4LjU1MzlaTTkwLjI0MDcgMzguMTEzNkw5NS4yODc5IDM4LjA3NjJMOTUuMzI1MyA0My4xMDQ4TDkwLjI3ODEgNDMuMTQyMUw5MC4yNDA3IDM4LjExMzZaTTc2LjY1MDYgMzMuMTY5Mkw4MS42OTc4IDMzLjEzMThMODEuNzM1MiAzOC4xNjA0TDc2LjY4OCAzOC4xOTc3TDc2LjY1MDYgMzMuMTY5MlpNMTAzLjAxOCA2Mi40OTkyTDEwOC4wNjUgNjIuNDYxOEwxMDguMTAyIDY3LjQ5MDNMMTAzLjA1NSA2Ny41Mjc3TDEwMy4wMTggNjIuNDk5MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik01OC41ODMgOTguMjQwNUw1OC42MzkxIDkwLjU3NjJMNjYuMzQwOCA5MC42MzIzTDY2LjI4NDcgOTguMjk2NUw1OC41ODMgOTguMjQwNVpNNzcuODM3MiA5OC4yNDA1TDc3Ljg5MzMgOTAuNTc2Mkw4NS41OTUgOTAuNjMyM0w4NS41Mzg5IDk4LjI5NjVMNzcuODM3MiA5OC4yNDA1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEwMC4wNDUgOTQuMzYxOUwxMDAuMDgyIDg5LjMxNDdMMTA1LjExMSA4OS4zNTIxTDEwNS4wNzQgOTQuMzk5M0wxMDAuMDQ1IDk0LjM2MTlaTTkwLjMxNTIgMTA0LjcyN0w5MC4zNTI2IDk5LjY4MDJMOTUuMzgxMSA5OS43MTc2TDk1LjM0MzcgMTA0Ljc2NUw5MC4zMTUyIDEwNC43MjdaTTc2Ljc3MTggMTA5LjdMNzYuODA5MiAxMDQuNjUzTDgxLjgzNzcgMTA0LjY5TDgxLjgwMDQgMTA5LjczN0w3Ni43NzE4IDEwOS43Wk0xMDMuMDA4IDgwLjM5NzlMMTAzLjA0NSA3NS4zNTA3TDEwOC4wNzQgNzUuMzg4MUwxMDguMDM3IDgwLjQzNTNMMTAzLjAwOCA4MC4zOTc5Wk0zOS4xMjMzIDg5LjMxNDdMNDQuMTcwNiA4OS4yNzczTDQ0LjIwNzkgOTQuMzA1OEwzOS4xNjA3IDk0LjM0MzJMMzkuMTIzMyA4OS4zMTQ3Wk00OC45NjU0IDk5LjY0MjhMNTQuMDEyNiA5OS42MDU0TDU0LjA1IDEwNC42MzRMNDkuMDAyOCAxMDQuNjcxTDQ4Ljk2NTQgOTkuNjQyOFpNNjIuNDQzMyAxMDQuNTk3TDY3LjQ5MDYgMTA0LjU1OUw2Ny41Mjc5IDEwOS41ODhMNjIuNDgwNyAxMDkuNjI1TDYyLjQ0MzMgMTA0LjU5N1pNMzYuMTg4NSA3NS4zNjk0TDQxLjIzNTcgNzUuMzMyTDQxLjI3MzEgODAuMzYwNkwzNi4yMjU5IDgwLjM5NzlMMzYuMTg4NSA3NS4zNjk0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExMC42MjUgNTEuNjM4NEwxMTAuNjQ0IDQ4LjkwOTJMMTEzLjQyOSA0OC45Mjc5TDExMy40MSA1MS42NTcxTDExMC42MjUgNTEuNjM4NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTQuMjI0IDU5Ljg5MTNMMTE0LjI0MiA1Ny4xNjIxTDExNy4wMjggNTcuMTgwOEwxMTcuMDA5IDU5LjkxTDExNC4yMjQgNTkuODkxM1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMDUuNzY3IDQ0LjMzNzZMMTA1Ljc4NSA0MS42MDg0TDEwOC41NzEgNDEuNjI3MUwxMDguNTUyIDQ0LjM1NjNMMTA1Ljc2NyA0NC4zMzc2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTQxLjk3MzYgMzguMDk0NUw0MS45OTIzIDM1LjM2NTJMNDQuNzc3NiAzNS4zODM5TDQ0Ljc1ODkgMzguMTEzMkw0MS45NzM2IDM4LjA5NDVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMjYgNjguNTU1NEwyNi4wMTg3IDY1LjgyNjJMMjguODA0IDY1Ljg0NDlMMjguNzg1MyA2OC41NzQxTDI2IDY4LjU1NTRaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOTkuNjI0IDM4LjA5NDVMOTkuNjQyNyAzNS4zNjUyTDEwMi40MjggMzUuMzgzOUwxMDIuNDA5IDM4LjExMzJMOTkuNjI0IDM4LjA5NDVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMjcuNTg5OCA1OS44ODE2TDI3LjYwODUgNTcuMTUyM0wzMC4zOTM5IDU3LjE3MUwzMC4zNzUyIDU5LjkwMDNMMjcuNTg5OCA1OS44ODE2WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTU3LjYyOTkgMjkuNjM1NUw1Ny42NDg2IDI2LjkwNjJMNjAuNDMzOSAyNi45MjQ5TDYwLjQxNTIgMjkuNjU0Mkw1Ny42Mjk5IDI5LjYzNTVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzAuOTcyNyA1MS42Mzg0TDMwLjk5MTMgNDguOTA5MkwzMy43NzY3IDQ4LjkyNzlMMzMuNzU4IDUxLjY1NzFMMzAuOTcyNyA1MS42Mzg0WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTM1Ljk0NTMgNDQuMjM2MUwzNS45NjQgNDEuNTA2OEwzOC43NDkzIDQxLjUyNTVMMzguNzMwNiA0NC4yNTQ4TDM1Ljk0NTMgNDQuMjM2MVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00OS40MjI5IDMwLjQyMDRMNTIuMTUyMSAzMC40MDE3TDUyLjE3MDggMzMuMTg3TDQ5LjQ0MTUgMzMuMjA1N0w0OS40MjI5IDMwLjQyMDRaTTY2LjMwMyAyNS4wNDZMNjkuMDMyMiAyNS4wMjczTDY5LjA1MDkgMjcuODEyN0w2Ni4zMjE3IDI3LjgzMTRMNjYuMzAzIDI1LjA0NloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4yMjI3IDMzLjIyNDRMOTIuMjQxNCAzMC40OTUxTDk1LjAyNjcgMzAuNTEzOEw5NS4wMDggMzMuMjQzTDkyLjIyMjcgMzMuMjI0NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTUuNTk4IDY4LjQ1MjlMMTE1LjYxNiA2NS43MjM2TDExOC40MDIgNjUuNzQyM0wxMTguMzgzIDY4LjQ3MTZMMTE1LjU5OCA2OC40NTI5WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTc1LjE5MTQgMjcuNzI5Mkw3NS4yMTAxIDI1TDc3Ljk5NTQgMjUuMDE4N0w3Ny45NzY3IDI3Ljc0NzlMNzUuMTkxNCAyNy43MjkyWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTgzLjg2NjIgMjkuNTIzMkw4My44ODQ5IDI2Ljc5MzlMODYuNjcwMiAyNi44MTI2TDg2LjY1MTUgMjkuNTQxOUw4My44NjYyIDI5LjUyMzJaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOTkuNjI0IDEwNy43TDk5LjY0MjcgMTA0Ljk3MUwxMDIuNDI4IDEwNC45ODlMMTAyLjQwOSAxMDcuNzE5TDk5LjYyNCAxMDcuN1oiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xMTUuNTk4IDc3LjIzOUwxMTUuNjE2IDc0LjUwOThMMTE4LjQwMiA3NC41Mjg1TDExOC4zODMgNzcuMjU3N0wxMTUuNTk4IDc3LjIzOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik00MS45NzM2IDEwNy43TDQxLjk5MjMgMTA0Ljk3MUw0NC43Nzc2IDEwNC45ODlMNDQuNzU4OSAxMDcuNzE5TDQxLjk3MzYgMTA3LjdaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMTE0LjIyNCA4Ni4wMzI5TDExNC4yNDIgODMuMzAzN0wxMTcuMDI4IDgzLjMyMjRMMTE3LjAwOSA4Ni4wNTE2TDExNC4yMjQgODYuMDMyOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik04My44NjYyIDExNi4yN0w4My44ODQ5IDExMy41NDFMODYuNjcwMiAxMTMuNTZMODYuNjUxNSAxMTYuMjg5TDgzLjg2NjIgMTE2LjI3WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExMC42MjUgOTQuMjY4M0wxMTAuNjQ0IDkxLjUzOTFMMTEzLjQyOSA5MS41NTc4TDExMy40MSA5NC4yODdMMTEwLjYyNSA5NC4yNjgzWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTEwNS43NjcgMTAxLjY3MkwxMDUuNzg1IDk4Ljk0MjRMMTA4LjU3MSA5OC45NjExTDEwOC41NTIgMTAxLjY5TDEwNS43NjcgMTAxLjY3MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik05Mi4xMDk0IDExMC4wNjVMOTQuODM4NiAxMTAuMDQ2TDk0Ljg1NzMgMTEyLjgzMUw5Mi4xMjggMTEyLjg1TDkyLjEwOTQgMTEwLjA2NVpNNzUuMzMyIDExNS4yMTVMNzguMDYxMyAxMTUuMTk2TDc4LjA4IDExNy45ODFMNzUuMzUwNyAxMThMNzUuMzMyIDExNS4yMTVaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNNDkuNDc4NSAxMTIuODg2TDQ5LjQ5NzIgMTEwLjE1N0w1Mi4yODI1IDExMC4xNzZMNTIuMjYzOCAxMTIuOTA1TDQ5LjQ3ODUgMTEyLjg4NloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0zMC44NTk0IDk0LjE2NThMMzAuODc4MSA5MS40MzY1TDMzLjY2MzQgOTEuNDU1MkwzMy42NDQ3IDk0LjE4NDVMMzAuODU5NCA5NC4xNjU4WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTI3LjU4MDEgODYuMDE0NEwyNy41OTg4IDgzLjI4NTJMMzAuMzg0MSA4My4zMDM5TDMwLjM2NTQgODYuMDMzMUwyNy41ODAxIDg2LjAxNDRaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNMzUuODMyIDEwMS42NzJMMzUuODUwNyA5OC45NDI0TDM4LjYzNiA5OC45NjExTDM4LjYxNzMgMTAxLjY5TDM1LjgzMiAxMDEuNjcyWiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTI2IDc3LjIzOUwyNi4wMTg3IDc0LjUwOThMMjguODA0IDc0LjUyODVMMjguNzg1MyA3Ny4yNTc3TDI2IDc3LjIzOVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik02Ni40MDUzIDExNy45NjJMNjYuNDI0IDExNS4yMzJMNjkuMjA5MyAxMTUuMjUxTDY5LjE5MDYgMTE3Ljk4TDY2LjQwNTMgMTE3Ljk2MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik01Ny41MTc2IDExNi4xNjhMNTcuNTM2MyAxMTMuNDM4TDYwLjMyMTYgMTEzLjQ1N0w2MC4zMDI5IDExNi4xODZMNTcuNTE3NiAxMTYuMTY4WiIgZmlsbD0id2hpdGUiLz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODNfMjk4NSIgeDE9IjEwIiB5MT0iMTUuNSIgeDI9IjE0NCIgeTI9IjEzMS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwMEE4REEiLz4KPHN0b3Agb2Zmc2V0PSIwLjQ5NSIgc3RvcC1jb2xvcj0iIzM1NzlCQyIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyODZFQTUiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "external"], ["spec", "httpAndHttps"], ["spec", "httpAndHttps", "mode"], ["spec", "httpAndHttps", "targetPorts"], ["spec", "httpAndHttps", "targetPorts", "http"], ["spec", "httpAndHttps", "targetPorts", "https"], ["spec", "httpAndHttps", "endpoints"], ["spec", "whitelistHTTP"], ["spec", "whitelist"]] + secrets: + exclude: [] + include: [] diff --git a/packages/system/tcp-balancer-rd/templates/cozyrd.yaml b/packages/system/tcp-balancer-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/tcp-balancer-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/tcp-balancer-rd/values.yaml b/packages/system/tcp-balancer-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/tcp-balancer-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/tenant-rd/Chart.yaml b/packages/system/tenant-rd/Chart.yaml new file mode 100644 index 00000000..ad3d27f4 --- /dev/null +++ b/packages/system/tenant-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: tenant-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/tenant-rd/Makefile b/packages/system/tenant-rd/Makefile new file mode 100644 index 00000000..37852fe6 --- /dev/null +++ b/packages/system/tenant-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=tenant-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/tenant-rd/cozyrds/tenant.yaml b/packages/system/tenant-rd/cozyrds/tenant.yaml new file mode 100644 index 00000000..a5c497ac --- /dev/null +++ b/packages/system/tenant-rd/cozyrds/tenant.yaml @@ -0,0 +1,31 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: tenant +spec: + application: + kind: Tenant + singular: tenant + plural: tenants + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"etcd":{"description":"Deploy own Etcd cluster.","type":"boolean","default":false},"host":{"description":"The hostname used to access tenant services (defaults to using the tenant name as a subdomain for its parent tenant host).","type":"string","default":""},"ingress":{"description":"Deploy own Ingress Controller.","type":"boolean","default":false},"isolated":{"description":"Enforce tenant namespace with network policies (default: true).","type":"boolean","default":true},"monitoring":{"description":"Deploy own Monitoring Stack.","type":"boolean","default":false},"resourceQuotas":{"description":"Define resource quotas for the tenant.","type":"object","default":{},"additionalProperties":{"pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}},"seaweedfs":{"description":"Deploy own SeaweedFS.","type":"boolean","default":false}}} + release: + prefix: tenant- + labels: + cozystack.io/ui: "true" + chart: + name: tenant + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: Administration + singular: Tenant + plural: Tenants + description: Separated tenant namespace + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQwMykiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDAzKSI+CjxwYXRoIGQ9Ik03MiAyOUM2Ni4zOTI2IDI5IDYxLjAxNDggMzEuMjM4OCA1Ny4wNDk3IDM1LjIyNEM1My4wODQ3IDM5LjIwOTEgNTAuODU3MSA0NC42MTQxIDUwLjg1NzEgNTAuMjVDNTAuODU3MSA1NS44ODU5IDUzLjA4NDcgNjEuMjkwOSA1Ny4wNDk3IDY1LjI3NkM2MS4wMTQ4IDY5LjI2MTIgNjYuMzkyNiA3MS41IDcyIDcxLjVDNzcuNjA3NCA3MS41IDgyLjk4NTIgNjkuMjYxMiA4Ni45NTAzIDY1LjI3NkM5MC45MTUzIDYxLjI5MDkgOTMuMTQyOSA1NS44ODU5IDkzLjE0MjkgNTAuMjVDOTMuMTQyOSA0NC42MTQxIDkwLjkxNTMgMzkuMjA5MSA4Ni45NTAzIDM1LjIyNEM4Mi45ODUyIDMxLjIzODggNzcuNjA3NCAyOSA3MiAyOVpNNjAuOTgyNiA4My4zMDM3QzYwLjQ1NCA4Mi41ODk4IDU5LjU5NTEgODIuMTkxNCA1OC43MTk2IDgyLjI3NDRDNDUuMzg5NyA4My43MzU0IDM1IDk1LjEwNzQgMzUgMTA4LjkwM0MzNSAxMTEuNzI2IDM3LjI3OTUgMTE0IDQwLjA3MSAxMTRIMTAzLjkyOUMxMDYuNzM3IDExNCAxMDkgMTExLjcwOSAxMDkgMTA4LjkwM0MxMDkgOTUuMTA3NCA5OC42MTAzIDgzLjc1MiA4NS4yNjM4IDgyLjI5MUM4NC4zODg0IDgyLjE5MTQgODMuNTI5NSA4Mi42MDY0IDgzLjAwMDkgODMuMzIwM0w3NC4wOTc4IDk1LjI0MDJDNzMuMDQwNiA5Ni42NTE0IDcwLjkyNjMgOTYuNjUxNCA2OS44NjkyIDk1LjI0MDJMNjAuOTY2MSA4My4zMjAzTDYwLjk4MjYgODMuMzAzN1oiIGZpbGw9ImJsYWNrIi8+CjwvZz4KPGRlZnM+CjxsaW5lYXJHcmFkaWVudCBpZD0icGFpbnQwX2xpbmVhcl82ODdfMzQwMyIgeDE9IjcyIiB5MT0iMTQ0IiB4Mj0iLTEuMjgxN2UtMDUiIHkyPSI0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiNDMEQ2RkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjMiIHN0b3AtY29sb3I9IiNDNERBRkYiLz4KPHN0b3Agb2Zmc2V0PSIwLjY1IiBzdG9wLWNvbG9yPSIjRDNFOUZGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0U5RkZGRiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzY4N18zNDAzIj4KPHJlY3Qgd2lkdGg9Ijc0IiBoZWlnaHQ9Ijg1IiBmaWxsPSJ3aGl0ZSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzUgMjkpIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "host"], ["spec", "etcd"], ["spec", "monitoring"], ["spec", "ingress"], ["spec", "seaweedfs"], ["spec", "isolated"], ["spec", "resourceQuotas"]] + secrets: + exclude: [] + include: [] diff --git a/packages/system/tenant-rd/templates/cozyrd.yaml b/packages/system/tenant-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/tenant-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/tenant-rd/values.yaml b/packages/system/tenant-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/tenant-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/virtual-machine-rd/Chart.yaml b/packages/system/virtual-machine-rd/Chart.yaml new file mode 100644 index 00000000..6228a221 --- /dev/null +++ b/packages/system/virtual-machine-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: virtual-machine-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/virtual-machine-rd/Makefile b/packages/system/virtual-machine-rd/Makefile new file mode 100644 index 00000000..4d59946b --- /dev/null +++ b/packages/system/virtual-machine-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=virtual-machine-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/virtual-machine-rd/cozyrds/virtual-machine.yaml b/packages/system/virtual-machine-rd/cozyrds/virtual-machine.yaml new file mode 100644 index 00000000..a1e384c4 --- /dev/null +++ b/packages/system/virtual-machine-rd/cozyrds/virtual-machine.yaml @@ -0,0 +1,39 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: virtual-machine +spec: + application: + kind: VirtualMachine + plural: virtualmachines + singular: virtualmachine + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Whether the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"subnets":{"description":"Additional subnets","type":"array","default":[],"items":{"type":"object","properties":{"name":{"description":"Subnet name","type":"string"}}}},"systemDisk":{"description":"System disk configuration.","type":"object","default":{},"required":["image","storage"],"properties":{"image":{"description":"The base image for the virtual machine.","type":"string","default":"ubuntu","enum":["ubuntu","cirros","alpine","fedora","talos"]},"storage":{"description":"The size of the disk allocated for the virtual machine.","type":"string","default":"5Gi"},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}}}} + release: + prefix: virtual-machine- + labels: + cozystack.io/ui: "true" + chart: + name: virtual-machine + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: IaaS + singular: Virtual Machine + plural: Virtual Machines + description: Virtual Machine (simple) + weight: 10 + tags: + - compute + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQ1NCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDU0KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMDBCM0ZGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi41Mjc1IDUzLjgzNjdDNzIuNDQzMSA1My44MzUxIDcyLjM2MDUgNTMuODEyMiA3Mi4yODczIDUzLjc3MDFMNTYuNDY5OSA0NC43OTM0QzU2LjM5ODMgNDQuNzUxOSA1Ni4zMzg4IDQ0LjY5MjMgNTYuMjk3MyA0NC42MjA3QzU2LjI1NTkgNDQuNTQ5IDU2LjIzMzggNDQuNDY3OCA1Ni4yMzM0IDQ0LjM4NUM1Ni4yMzM0IDQ0LjIxNjkgNTYuMzI1OCA0NC4wNjE3IDU2LjQ2OTkgNDMuOTc4NUw3Mi4xOTEyIDM1LjA2MDlDNzIuMjYzNyAzNS4wMjEgNzIuMzQ1IDM1IDcyLjQyNzcgMzVDNzIuNTEwNSAzNSA3Mi41OTE4IDM1LjAyMSA3Mi42NjQzIDM1LjA2MDlMODguNDg3MiA0NC4wMzk1Qzg4LjU1OTEgNDQuMDgwMSA4OC42MTg4IDQ0LjEzOTIgODguNjYgNDQuMjEwN0M4OC43MDEzIDQ0LjI4MjIgODguNzIyNyA0NC4zNjM1IDg4LjcyMTkgNDQuNDQ2Qzg4LjcyMjUgNDQuNTI4NSA4OC43MDEgNDQuNjA5NyA4OC42NTk4IDQ0LjY4MTJDODguNjE4NSA0NC43NTI2IDg4LjU1ODkgNDQuODExOCA4OC40ODcyIDQ0Ljg1MjVMNzIuNzcxNCA1My43NjgzQzcyLjY5NzIgNTMuODExNCA3Mi42MTMzIDUzLjgzNDkgNzIuNTI3NSA1My44MzY3IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjciIGQ9Ik03MC4yNTUzIDc1LjY1MTdDNzAuMTcxIDc1LjY1MzUgNzAuMDg3OCA3NS42MzE3IDcwLjAxNTEgNzUuNTg4OEw1NC4yNDU4IDY2LjY0MTdDNTQuMTcxNSA2Ni42MDI0IDU0LjEwOTUgNjYuNTQzNiA1NC4wNjYxIDY2LjQ3MTZDNTQuMDIyOCA2Ni4zOTk3IDU0IDY2LjMxNzMgNTQgNjYuMjMzM1Y0OC4yNzhDNTQgNDguMTA4IDU0LjA5MjQgNDcuOTU0NiA1NC4yNDM5IDQ3Ljg2OTZDNTQuMzE3MiA0Ny44MjcxIDU0LjQwMDQgNDcuODA0NyA1NC40ODUxIDQ3LjgwNDdDNTQuNTY5NyA0Ny44MDQ3IDU0LjY1MjkgNDcuODI3MSA1NC43MjYyIDQ3Ljg2OTZMNzAuNDkzNyA1Ni44MTMxQzcwLjU2NDIgNTYuODU2NSA3MC42MjI1IDU2LjkxNyA3MC42NjMyIDU2Ljk4OTFDNzAuNzAzOSA1Ny4wNjEyIDcwLjcyNTcgNTcuMTQyNCA3MC43MjY1IDU3LjIyNTFWNzUuMTgwNUM3MC43MjU5IDc1LjI2MjggNzAuNzA0MiA3NS4zNDM2IDcwLjY2MzUgNzUuNDE1MUM3MC42MjI3IDc1LjQ4NjYgNzAuNTY0MiA3NS41NDY0IDcwLjQ5MzcgNzUuNTg4OEM3MC40MjA2IDc1LjYyOTEgNzAuMzM4NyA3NS42NTA3IDcwLjI1NTMgNzUuNjUxNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC40IiBkPSJNNzQuNzE5OCA3NS42NTExQzc0LjYzMzMgNzUuNjUxMiA3NC41NDgyIDc1LjYyOTYgNzQuNDcyMiA3NS41ODgzQzc0LjQwMTYgNzUuNTQ2MSA3NC4zNDMyIDc1LjQ4NjIgNzQuMzAyNyA3NS40MTQ3Qzc0LjI2MjMgNzUuMzQzMSA3NC4yNDExIDc1LjI2MjIgNzQuMjQxMiA3NS4xOFY1Ny4zMzczQzc0LjI0MTIgNTcuMTcxIDc0LjMzMzYgNTcuMDE1OCA3NC40NzIyIDU2LjkyOUw5MC4yMzk3IDQ3Ljk4NTVDOTAuMzExOSA0Ny45NDM4IDkwLjM5MzggNDcuOTIxOSA5MC40NzcxIDQ3LjkyMTlDOTAuNTYwNSA0Ny45MjE5IDkwLjY0MjQgNDcuOTQzOCA5MC43MTQ2IDQ3Ljk4NTVDOTAuNzg3NiA0OC4wMjU1IDkwLjg0ODUgNDguMDg0MiA5MC44OTExIDQ4LjE1NTdDOTAuOTMzNyA0OC4yMjcyIDkwLjk1NjMgNDguMzA4OCA5MC45NTY2IDQ4LjM5MlY2Ni4yMzI4QzkwLjk1NyA2Ni4zMTY0IDkwLjkzNDcgNjYuMzk4NSA5MC44OTIxIDY2LjQ3MDRDOTAuODQ5NSA2Ni41NDI0IDkwLjc4ODEgNjYuNjAxNCA5MC43MTQ2IDY2LjY0MTFMNzQuOTUyNiA3NS41ODgzQzc0Ljg4MjUgNzUuNjMwNyA3NC44MDE4IDc1LjY1MjUgNzQuNzE5OCA3NS42NTExIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zNDU0IiB4MT0iMTYxIiB5MT0iMTgwIiB4Mj0iMy41OTI4NGUtMDciIHkyPSI0Ljk5OTk4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTk1NjU2Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNjg3XzM0NTQiPgo8cmVjdCB3aWR0aD0iOTQiIGhlaWdodD0iOTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSAyNSkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "systemDisk"], ["spec", "systemDisk", "image"], ["spec", "systemDisk", "storage"], ["spec", "systemDisk", "storageClass"], ["spec", "subnets"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - resourceNames: + - virtual-machine-{{ .name }} diff --git a/packages/system/virtual-machine-rd/templates/cozyrd.yaml b/packages/system/virtual-machine-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/virtual-machine-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/virtual-machine-rd/values.yaml b/packages/system/virtual-machine-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/virtual-machine-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/virtualprivatecloud-rd/Chart.yaml b/packages/system/virtualprivatecloud-rd/Chart.yaml new file mode 100644 index 00000000..be5235dc --- /dev/null +++ b/packages/system/virtualprivatecloud-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: virtualprivatecloud-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/virtualprivatecloud-rd/Makefile b/packages/system/virtualprivatecloud-rd/Makefile new file mode 100644 index 00000000..9d9b6c50 --- /dev/null +++ b/packages/system/virtualprivatecloud-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=virtualprivatecloud-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/virtualprivatecloud-rd/cozyrds/virtualprivatecloud.yaml b/packages/system/virtualprivatecloud-rd/cozyrds/virtualprivatecloud.yaml new file mode 100644 index 00000000..8d05a5b6 --- /dev/null +++ b/packages/system/virtualprivatecloud-rd/cozyrds/virtualprivatecloud.yaml @@ -0,0 +1,34 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: virtualprivatecloud +spec: + application: + kind: VirtualPrivateCloud + plural: virtualprivateclouds + singular: virtualprivatecloud + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"subnets":{"description":"Subnets of a VPC","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"cidr":{"description":"IP address range","type":"string"}}}}}} + release: + prefix: "virtualprivatecloud-" + labels: + cozystack.io/ui: "true" + chart: + name: virtualprivatecloud + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: IaaS + singular: VPC + plural: VPCs + description: "Isolated networks" + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8xMDI1XzMpIi8+CjxwYXRoIGQ9Ik0xMDkuNiA4Ni4xSDExNC4zQzExNi44ODUgODYuMSAxMTkgODguMjE1IDExOSA5MC44NDdWMTA0Ljg1M0MxMTkgMTA3LjQ4NSAxMTYuODg1IDEwOS42IDExNC4zIDEwOS42SDk1LjVDOTIuOTE1IDEwOS42IDkwLjggMTA3LjQ4NSA5MC44IDEwNC44NTNWOTAuODQ3QzkwLjggODguMjE1IDkyLjkxNSA4Ni4xIDk1LjUgODYuMUgxMDAuMlY3Ni43SDc2LjdWODYuMUg4MS40QzgzLjk4NSA4Ni4xIDg2LjEgODguMjE1IDg2LjEgOTAuODQ3VjEwNC44NTNDODYuMSAxMDcuNDg1IDgzLjk4NSAxMDkuNiA4MS40IDEwOS42SDYyLjZDNjAuMDE1IDEwOS42IDU3LjkgMTA3LjQ4NSA1Ny45IDEwNC44NTNWOTAuODQ3QzU3LjkgODguMjE1IDYwLjAxNSA4Ni4xIDYyLjYgODYuMUg2Ny4zVjc2LjdINDMuOFY4Ni4xSDQ4LjVDNTEuMDg1IDg2LjEgNTMuMiA4OC4yMTUgNTMuMiA5MC44NDdWMTA0Ljg1M0M1My4yIDEwNy40ODUgNTEuMDg1IDEwOS42IDQ4LjUgMTA5LjZIMjkuN0MyNy4xMTUgMTA5LjYgMjUgMTA3LjQ4NSAyNSAxMDQuODUzVjkwLjg0N0MyNSA4OC4yMTUgMjcuMTE1IDg2LjEgMjkuNyA4Ni4xSDM0LjRWNzYuN0MzNC40IDcxLjUzIDM4LjYzIDY3LjMgNDMuOCA2Ny4zSDY3LjNWNTcuOUg2Mi42QzYwLjAxNSA1Ny45IDU3LjkgNTUuNzg1IDU3LjkgNTMuMTUzVjM5LjE0N0M1Ny45IDM2LjUxNSA2MC4wMTUgMzQuNCA2Mi42IDM0LjRIODEuNEM4My45ODUgMzQuNCA4Ni4xIDM2LjUxNSA4Ni4xIDM5LjE0N1Y1My4xNTNDODYuMSA1NS43ODUgODMuOTg1IDU3LjkgODEuNCA1Ny45SDc2LjdWNjcuM0gxMDAuMkMxMDUuMzcgNjcuMyAxMDkuNiA3MS41MyAxMDkuNiA3Ni43Vjg2LjFaIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzEwMjVfMyIgeDE9IjE0Mi41IiB5MT0iMTQzIiB4Mj0iMy45OTk5OSIgeTI9IjkuNDk5OTkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzAwMDgyRSIvPgo8c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyRTMwNjciLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "subnets"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: [] diff --git a/packages/system/virtualprivatecloud-rd/templates/cozyrd.yaml b/packages/system/virtualprivatecloud-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/virtualprivatecloud-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/virtualprivatecloud-rd/values.yaml b/packages/system/virtualprivatecloud-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/virtualprivatecloud-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/vm-disk-rd/Chart.yaml b/packages/system/vm-disk-rd/Chart.yaml new file mode 100644 index 00000000..d405b0f0 --- /dev/null +++ b/packages/system/vm-disk-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: vm-disk-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/vm-disk-rd/Makefile b/packages/system/vm-disk-rd/Makefile new file mode 100644 index 00000000..e6de276d --- /dev/null +++ b/packages/system/vm-disk-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=vm-disk-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/vm-disk-rd/cozyrds/vm-disk.yaml b/packages/system/vm-disk-rd/cozyrds/vm-disk.yaml new file mode 100644 index 00000000..c3c1b830 --- /dev/null +++ b/packages/system/vm-disk-rd/cozyrds/vm-disk.yaml @@ -0,0 +1,34 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: vm-disk +spec: + application: + kind: VMDisk + singular: vmdisk + plural: vmdisks + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"optical":{"description":"Defines if disk should be considered optical.","type":"boolean","default":false},"source":{"description":"The source image location used to create a disk.","type":"object","default":{},"properties":{"http":{"description":"Download image from an HTTP source.","type":"object","required":["url"],"properties":{"url":{"description":"URL to download the image.","type":"string"}}},"image":{"description":"Use image by name.","type":"object","required":["name"],"properties":{"name":{"description":"Name of the image to use (uploaded as \"golden image\" or from the list: `ubuntu`, `fedora`, `cirros`, `alpine`, `talos`).","type":"string"}}},"upload":{"description":"Upload local image."}}},"storage":{"description":"The size of the disk allocated for the virtual machine.","default":"5Gi","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"storageClass":{"description":"StorageClass used to store the data.","type":"string","default":"replicated"}}} + release: + prefix: vm-disk- + labels: + cozystack.io/ui: "true" + chart: + name: vm-disk + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: IaaS + singular: VM Disk + plural: VM Disks + description: Virtual Machine disk + weight: 51 + tags: + - storage + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8zMzBfNDg5NjMpIi8+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2lfMzMwXzQ4OTYzKSI+CjxwYXRoIGQ9Ik03Mi4wMDAxIDI2LjYzNjdDNDYuODc3MiAyNi42MzY3IDI2LjUxMTIgNDcuMDAyNyAyNi41MTEyIDcyLjEyNTZDMjYuNTExMiA5Ny4yNDg0IDQ2Ljg3NzIgMTE3LjYxNCA3Mi4wMDAxIDExNy42MTRDOTcuMTIyOSAxMTcuNjE0IDExNy40ODkgOTcuMjQ4MiAxMTcuNDg5IDcyLjEyNTRDMTE3LjQ4OSA0Ny4wMDI1IDk3LjEyMjkgMjYuNjM2NyA3Mi4wMDAxIDI2LjYzNjdaTTcyLjAwMDEgODEuNjIxMkM2Ni43NTU3IDgxLjYyMTIgNjIuNTA0NCA3Ny4zNjk5IDYyLjUwNDQgNzIuMTI1NkM2Mi41MDQ0IDY2Ljg4MTIgNjYuNzU1NyA2Mi42Mjk5IDcyLjAwMDEgNjIuNjI5OUM3Ny4yNDQ0IDYyLjYyOTkgODEuNDk1NyA2Ni44ODEyIDgxLjQ5NTcgNzIuMTI1NkM4MS40OTU3IDc3LjM2OTkgNzcuMjQ0NCA4MS42MjEyIDcyLjAwMDEgODEuNjIxMloiIGZpbGw9IiNCQUQ5RkYiLz4KPC9nPgo8cGF0aCBkPSJNNTIuMDA3NSA2NS43MjA5TDMyLjI5NzYgNTkuMDQ5OEMzNi4yODQyIDQ3LjI3MTEgNDUuMzI4NSAzNy42MzE1IDU2LjQ5MSAzMy4yNjRMNjQuMDcyOCA1Mi42NDE5QzU4LjY0MiA1NC43NjY3IDU0LjAxOSA1OS43NzgzIDUyLjAwNzUgNjUuNzIwOVpNOTEuOTkyNiA3OC41M0wxMTEuNzAzIDg1LjIwMTFDMTA3LjcxNiA5Ni45Nzk5IDk4LjY3MTggMTA2LjYxOSA4Ny41MDkzIDExMC45ODdMNzkuOTI3NSA5MS42MDlDODUuMzU4MSA4OS40ODQyIDg5Ljk4MTMgODQuNDcyNiA5MS45OTI2IDc4LjUzWiIgZmlsbD0iI0VERjZGRiIvPgo8cGF0aCBkPSJNNTUuOTMyNCA1OC43MDI4QzU3LjY1MTQgNTYuNjE0IDU5LjcxOTQgNTQuODYzMiA2MS45ODk0IDUzLjYxODNDNjMuMTQ5IDUyLjk4MjQgNjQuMjYzMyA1My4xMjk2IDYzLjc4MTQgNTEuODk3OUw1Ny4yMDk1IDM1LjEwMDlDNTYuMjkwOSAzMi43NTI5IDU1LjI4MTQgMzMuNzI4NSA1My45MDYgMzQuMzg2OEM0OC45NzM0IDM2Ljc0NzYgNDQuNTM0OSA0MC4xNTkgNDAuODYwMSA0NC4zMTU0TDU1LjkzMjQgNTguNzAyOFpNODguMDY3NiA4NS41NDgxQzg1LjgzNTIgODguMjYwNSA4My4wMTQ4IDkwLjQwMjkgNzkuOTI2OSA5MS42MDhMODcuNTA4OSAxMTAuOTg2QzkzLjQ3ODUgMTA4LjY1NCA5OC44MzM2IDEwNC44MDYgMTAzLjE0IDk5LjkzNTVMODguMDY3NiA4NS41NDgxWiIgZmlsbD0iI0NERTNGRiIvPgo8cGF0aCBkPSJNNzIgODkuNDM4OEM2Mi40NTM0IDg5LjQzODggNTQuNjg2NSA4MS42NzIxIDU0LjY4NjUgNzIuMTI1NEM1NC42ODY1IDYyLjU3ODYgNjIuNDUzNCA1NC44MTE5IDcyIDU0LjgxMTlDODEuNTQ2OCA1NC44MTE5IDg5LjMxMzQgNjIuNTc4OCA4OS4zMTM0IDcyLjEyNTRDODkuMzEzNCA4MS42NzIgODEuNTQ2OCA4OS40Mzg4IDcyIDg5LjQzODhaTTcyIDU5LjExMDVDNjQuODIzNCA1OS4xMTA1IDU4Ljk4NDkgNjQuOTQ5IDU4Ljk4NDkgNzIuMTI1NkM1OC45ODQ5IDc5LjMwMjIgNjQuODIzNCA4NS4xNDA2IDcyIDg1LjE0MDZDNzkuMTc2NiA4NS4xNDA2IDg1LjAxNSA3OS4zMDIyIDg1LjAxNSA3Mi4xMjU2Qzg1LjAxNSA2NC45NDkgNzkuMTc2NiA1OS4xMTA1IDcyIDU5LjExMDVaIiBmaWxsPSIjMDBCNEZGIi8+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2lfMzMwXzQ4OTYzIiB4PSIyNi41MTEyIiB5PSIyNi42MzY3IiB3aWR0aD0iOTIuOTc3OCIgaGVpZ2h0PSI5Mi45Nzc1IiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+CjxmZUNvbG9yTWF0cml4IGluPSJTb3VyY2VBbHBoYSIgdHlwZT0ibWF0cml4IiB2YWx1ZXM9IjAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDAgMCAwIDEyNyAwIiByZXN1bHQ9ImhhcmRBbHBoYSIvPgo8ZmVPZmZzZXQgZHg9IjIiIGR5PSIyIi8+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjIuNSIvPgo8ZmVDb21wb3NpdGUgaW4yPSJoYXJkQWxwaGEiIG9wZXJhdG9yPSJhcml0aG1ldGljIiBrMj0iLTEiIGszPSIxIi8+CjxmZUNvbG9yTWF0cml4IHR5cGU9Im1hdHJpeCIgdmFsdWVzPSIwIDAgMCAwIDEgMCAwIDAgMCAxIDAgMCAwIDAgMSAwIDAgMCAwLjIxIDAiLz4KPGZlQmxlbmQgbW9kZT0ibm9ybWFsIiBpbjI9InNoYXBlIiByZXN1bHQ9ImVmZmVjdDFfaW5uZXJTaGFkb3dfMzMwXzQ4OTYzIi8+CjwvZmlsdGVyPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMzMwXzQ4OTYzIiB4MT0iLTE1LjUiIHkxPSItMTIiIHgyPSIyMTYuNSIgeTI9IjE4NS41IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiM2NUNDRkYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDQ0Mzc0Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "source"], ["spec", "optical"], ["spec", "storage"], ["spec", "storageClass"]] + secrets: + exclude: [] + include: [] diff --git a/packages/system/vm-disk-rd/templates/cozyrd.yaml b/packages/system/vm-disk-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/vm-disk-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/vm-disk-rd/values.yaml b/packages/system/vm-disk-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/vm-disk-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/vm-instance-rd/Chart.yaml b/packages/system/vm-instance-rd/Chart.yaml new file mode 100644 index 00000000..270db7d6 --- /dev/null +++ b/packages/system/vm-instance-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: vm-instance-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/vm-instance-rd/Makefile b/packages/system/vm-instance-rd/Makefile new file mode 100644 index 00000000..badc4951 --- /dev/null +++ b/packages/system/vm-instance-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=vm-instance-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/vm-instance-rd/cozyrds/vm-instance.yaml b/packages/system/vm-instance-rd/cozyrds/vm-instance.yaml new file mode 100644 index 00000000..58eb5f9a --- /dev/null +++ b/packages/system/vm-instance-rd/cozyrds/vm-instance.yaml @@ -0,0 +1,39 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: vm-instance +spec: + application: + kind: VMInstance + singular: vminstance + plural: vminstances + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"cloudInit":{"description":"Cloud-init user data.","type":"string","default":""},"cloudInitSeed":{"description":"Seed string to generate SMBIOS UUID for the VM.","type":"string","default":""},"disks":{"description":"List of disks to attach.","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"bus":{"description":"Disk bus type (e.g. \"sata\").","type":"string"},"name":{"description":"Disk name.","type":"string"}}}},"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalMethod":{"description":"Method to pass through traffic to the VM.","type":"string","default":"PortList","enum":["PortList","WholeIP"]},"externalPorts":{"description":"Ports to forward from outside the cluster.","type":"array","default":[22],"items":{"type":"integer"}},"gpus":{"description":"List of GPUs to attach (NVIDIA driver requires at least 4 GiB RAM).","type":"array","default":[],"items":{"type":"object","required":["name"],"properties":{"name":{"description":"The name of the GPU resource to attach.","type":"string"}}}},"instanceProfile":{"description":"Virtual Machine preferences profile.","type":"string","default":"ubuntu","enum":["alpine","centos.7","centos.7.desktop","centos.stream10","centos.stream10.desktop","centos.stream8","centos.stream8.desktop","centos.stream8.dpdk","centos.stream9","centos.stream9.desktop","centos.stream9.dpdk","cirros","fedora","fedora.arm64","opensuse.leap","opensuse.tumbleweed","rhel.10","rhel.10.arm64","rhel.7","rhel.7.desktop","rhel.8","rhel.8.desktop","rhel.8.dpdk","rhel.9","rhel.9.arm64","rhel.9.desktop","rhel.9.dpdk","rhel.9.realtime","sles","ubuntu","windows.10","windows.10.virtio","windows.11","windows.11.virtio","windows.2k16","windows.2k16.virtio","windows.2k19","windows.2k19.virtio","windows.2k22","windows.2k22.virtio","windows.2k25","windows.2k25.virtio",""]},"instanceType":{"description":"Virtual Machine instance type.","type":"string","default":"u1.medium"},"resources":{"description":"Resource configuration for the virtual machine.","type":"object","default":{},"properties":{"cpu":{"description":"Number of CPU cores allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Amount of memory allocated.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"sockets":{"description":"Number of CPU sockets (vCPU topology).","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"running":{"description":"Determines if the virtual machine should be running.","type":"boolean","default":true},"sshKeys":{"description":"List of SSH public keys for authentication.","type":"array","default":[],"items":{"type":"string"}},"subnets":{"description":"Additional subnets","type":"array","default":[],"items":{"type":"object","properties":{"name":{"description":"Subnet name","type":"string"}}}}}} + release: + prefix: vm-instance- + labels: + cozystack.io/ui: "true" + chart: + name: vm-instance + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: IaaS + singular: VM Instance + plural: VM Instances + description: Virtual machine instance + weight: 50 + tags: + - compute + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxyZWN0IHdpZHRoPSIxNDQiIGhlaWdodD0iMTQ0IiByeD0iMjQiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODdfMzQ1NCkiLz4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzY4N18zNDU0KSI+CjxwYXRoIGQ9Ik04OS41MDM5IDExMS43MDdINTQuNDk3QzU0LjE3MjcgMTExLjcwNyA1NC4wMTA4IDExMS4yMjEgNTQuMzM0OSAxMTEuMDU5TDU3LjI1MjIgMTA4Ljk1MkM2MC4zMzE0IDEwNi42ODMgNjEuOTUyMiAxMDIuNjMxIDYwLjk3OTcgOTguNzQxMkg4My4wMjFDODIuMDQ4NSAxMDIuNjMxIDgzLjY2OTMgMTA2LjY4MyA4Ni43NDg1IDEwOC45NTJMODkuNjY1OCAxMTEuMDU5Qzg5Ljk5IDExMS4yMjEgODkuODI3OSAxMTEuNzA3IDg5LjUwMzkgMTExLjcwN1oiIGZpbGw9IiNCMEI2QkIiLz4KPHBhdGggZD0iTTExMy4zMjggOTguNzQxSDMwLjY3MjVDMjcuNTkzMSA5OC43NDEgMjUgOTYuMTQ4IDI1IDkzLjA2ODdWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJWOTMuMDY4N0MxMTkgOTYuMTQ4IDExNi40MDcgOTguNzQxIDExMy4zMjggOTguNzQxWiIgZmlsbD0iI0U4RURFRSIvPgo8cGF0aCBkPSJNMTE5IDg0LjE1NDlIMjVWMzMuMTAzMkMyNSAzMC4wMjM5IDI3LjU5MzEgMjcuNDMwNyAzMC42NzI1IDI3LjQzMDdIMTEzLjMyOEMxMTYuNDA3IDI3LjQzMDcgMTE5IDMwLjAyMzcgMTE5IDMzLjEwMzJMMTE5IDg0LjE1NDlaIiBmaWxsPSIjMDBCM0ZGIi8+CjxwYXRoIGQ9Ik05MC42Mzc0IDExNi41NjlINTMuMzYxNkM1Mi4wNjUxIDExNi41NjkgNTAuOTMwNyAxMTUuNDM1IDUwLjkzMDcgMTE0LjEzOEM1MC45MzA3IDExMi44NDEgNTIuMDY1MSAxMTEuNzA3IDUzLjM2MTYgMTExLjcwN0g5MC42Mzc0QzkxLjkzMzkgMTExLjcwNyA5My4wNjg0IDExMi44NDEgOTMuMDY4NCAxMTQuMTM4QzkzLjA2ODQgMTE1LjQzNSA5MS45MzM5IDExNi41NjkgOTAuNjM3NCAxMTYuNTY5WiIgZmlsbD0iI0U4RURFRSIvPgo8L2c+CjxwYXRoIGQ9Ik03Mi41Mjc1IDUzLjgzNjdDNzIuNDQzMSA1My44MzUxIDcyLjM2MDUgNTMuODEyMiA3Mi4yODczIDUzLjc3MDFMNTYuNDY5OSA0NC43OTM0QzU2LjM5ODMgNDQuNzUxOSA1Ni4zMzg4IDQ0LjY5MjMgNTYuMjk3MyA0NC42MjA3QzU2LjI1NTkgNDQuNTQ5IDU2LjIzMzggNDQuNDY3OCA1Ni4yMzM0IDQ0LjM4NUM1Ni4yMzM0IDQ0LjIxNjkgNTYuMzI1OCA0NC4wNjE3IDU2LjQ2OTkgNDMuOTc4NUw3Mi4xOTEyIDM1LjA2MDlDNzIuMjYzNyAzNS4wMjEgNzIuMzQ1IDM1IDcyLjQyNzcgMzVDNzIuNTEwNSAzNSA3Mi41OTE4IDM1LjAyMSA3Mi42NjQzIDM1LjA2MDlMODguNDg3MiA0NC4wMzk1Qzg4LjU1OTEgNDQuMDgwMSA4OC42MTg4IDQ0LjEzOTIgODguNjYgNDQuMjEwN0M4OC43MDEzIDQ0LjI4MjIgODguNzIyNyA0NC4zNjM1IDg4LjcyMTkgNDQuNDQ2Qzg4LjcyMjUgNDQuNTI4NSA4OC43MDEgNDQuNjA5NyA4OC42NTk4IDQ0LjY4MTJDODguNjE4NSA0NC43NTI2IDg4LjU1ODkgNDQuODExOCA4OC40ODcyIDQ0Ljg1MjVMNzIuNzcxNCA1My43NjgzQzcyLjY5NzIgNTMuODExNCA3Mi42MTMzIDUzLjgzNDkgNzIuNTI3NSA1My44MzY3IiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBvcGFjaXR5PSIwLjciIGQ9Ik03MC4yNTUzIDc1LjY1MTdDNzAuMTcxIDc1LjY1MzUgNzAuMDg3OCA3NS42MzE3IDcwLjAxNTEgNzUuNTg4OEw1NC4yNDU4IDY2LjY0MTdDNTQuMTcxNSA2Ni42MDI0IDU0LjEwOTUgNjYuNTQzNiA1NC4wNjYxIDY2LjQ3MTZDNTQuMDIyOCA2Ni4zOTk3IDU0IDY2LjMxNzMgNTQgNjYuMjMzM1Y0OC4yNzhDNTQgNDguMTA4IDU0LjA5MjQgNDcuOTU0NiA1NC4yNDM5IDQ3Ljg2OTZDNTQuMzE3MiA0Ny44MjcxIDU0LjQwMDQgNDcuODA0NyA1NC40ODUxIDQ3LjgwNDdDNTQuNTY5NyA0Ny44MDQ3IDU0LjY1MjkgNDcuODI3MSA1NC43MjYyIDQ3Ljg2OTZMNzAuNDkzNyA1Ni44MTMxQzcwLjU2NDIgNTYuODU2NSA3MC42MjI1IDU2LjkxNyA3MC42NjMyIDU2Ljk4OTFDNzAuNzAzOSA1Ny4wNjEyIDcwLjcyNTcgNTcuMTQyNCA3MC43MjY1IDU3LjIyNTFWNzUuMTgwNUM3MC43MjU5IDc1LjI2MjggNzAuNzA0MiA3NS4zNDM2IDcwLjY2MzUgNzUuNDE1MUM3MC42MjI3IDc1LjQ4NjYgNzAuNTY0MiA3NS41NDY0IDcwLjQ5MzcgNzUuNTg4OEM3MC40MjA2IDc1LjYyOTEgNzAuMzM4NyA3NS42NTA3IDcwLjI1NTMgNzUuNjUxNyIgZmlsbD0id2hpdGUiLz4KPHBhdGggb3BhY2l0eT0iMC40IiBkPSJNNzQuNzE5OCA3NS42NTExQzc0LjYzMzMgNzUuNjUxMiA3NC41NDgyIDc1LjYyOTYgNzQuNDcyMiA3NS41ODgzQzc0LjQwMTYgNzUuNTQ2MSA3NC4zNDMyIDc1LjQ4NjIgNzQuMzAyNyA3NS40MTQ3Qzc0LjI2MjMgNzUuMzQzMSA3NC4yNDExIDc1LjI2MjIgNzQuMjQxMiA3NS4xOFY1Ny4zMzczQzc0LjI0MTIgNTcuMTcxIDc0LjMzMzYgNTcuMDE1OCA3NC40NzIyIDU2LjkyOUw5MC4yMzk3IDQ3Ljk4NTVDOTAuMzExOSA0Ny45NDM4IDkwLjM5MzggNDcuOTIxOSA5MC40NzcxIDQ3LjkyMTlDOTAuNTYwNSA0Ny45MjE5IDkwLjY0MjQgNDcuOTQzOCA5MC43MTQ2IDQ3Ljk4NTVDOTAuNzg3NiA0OC4wMjU1IDkwLjg0ODUgNDguMDg0MiA5MC44OTExIDQ4LjE1NTdDOTAuOTMzNyA0OC4yMjcyIDkwLjk1NjMgNDguMzA4OCA5MC45NTY2IDQ4LjM5MlY2Ni4yMzI4QzkwLjk1NyA2Ni4zMTY0IDkwLjkzNDcgNjYuMzk4NSA5MC44OTIxIDY2LjQ3MDRDOTAuODQ5NSA2Ni41NDI0IDkwLjc4ODEgNjYuNjAxNCA5MC43MTQ2IDY2LjY0MTFMNzQuOTUyNiA3NS41ODgzQzc0Ljg4MjUgNzUuNjMwNyA3NC44MDE4IDc1LjY1MjUgNzQuNzE5OCA3NS42NTExIiBmaWxsPSJ3aGl0ZSIvPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzY4N18zNDU0IiB4MT0iMTYxIiB5MT0iMTgwIiB4Mj0iMy41OTI4NGUtMDciIHkyPSI0Ljk5OTk4IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTk1NjU2Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNjg3XzM0NTQiPgo8cmVjdCB3aWR0aD0iOTQiIGhlaWdodD0iOTQiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNSAyNSkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "external"], ["spec", "externalMethod"], ["spec", "externalPorts"], ["spec", "running"], ["spec", "instanceType"], ["spec", "instanceProfile"], ["spec", "disks"], ["spec", "subnets"], ["spec", "gpus"], ["spec", "resources"], ["spec", "sshKeys"], ["spec", "cloudInit"], ["spec", "cloudInitSeed"]] + secrets: + exclude: [] + include: [] + services: + exclude: [] + include: + - matchLabels: + apps.cozystack.io/user-service: "true" diff --git a/packages/system/vm-instance-rd/templates/cozyrd.yaml b/packages/system/vm-instance-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/vm-instance-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/vm-instance-rd/values.yaml b/packages/system/vm-instance-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/vm-instance-rd/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/vpn-rd/Chart.yaml b/packages/system/vpn-rd/Chart.yaml new file mode 100644 index 00000000..fe0a2dd3 --- /dev/null +++ b/packages/system/vpn-rd/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: vpn-rd +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/vpn-rd/Makefile b/packages/system/vpn-rd/Makefile new file mode 100644 index 00000000..c6ee47bb --- /dev/null +++ b/packages/system/vpn-rd/Makefile @@ -0,0 +1,4 @@ +export NAME=vpn-rd +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/vpn-rd/cozyrds/vpn.yaml b/packages/system/vpn-rd/cozyrds/vpn.yaml new file mode 100644 index 00000000..59d940c0 --- /dev/null +++ b/packages/system/vpn-rd/cozyrds/vpn.yaml @@ -0,0 +1,40 @@ +apiVersion: cozystack.io/v1alpha1 +kind: CozystackResourceDefinition +metadata: + name: vpn +spec: + application: + kind: VPN + plural: vpns + singular: vpn + openAPISchema: |- + {"title":"Chart Values","type":"object","properties":{"external":{"description":"Enable external access from outside the cluster.","type":"boolean","default":false},"externalIPs":{"description":"List of externalIPs for service. Optional. If not specified, will use LoadBalancer service by default.","type":"array","default":[],"items":{"type":"string"}},"host":{"description":"Host used to substitute into generated URLs.","type":"string","default":""},"replicas":{"description":"Number of VPN server replicas.","type":"integer","default":2},"resources":{"description":"Explicit CPU and memory configuration for each VPN server replica. When omitted, the preset defined in `resourcesPreset` is applied.","type":"object","default":{},"properties":{"cpu":{"description":"CPU available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true},"memory":{"description":"Memory (RAM) available to each replica.","pattern":"^(\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\\+|-)?(([0-9]+(\\.[0-9]*)?)|(\\.[0-9]+))))?$","anyOf":[{"type":"integer"},{"type":"string"}],"x-kubernetes-int-or-string":true}}},"resourcesPreset":{"description":"Default sizing preset used when `resources` is omitted.","type":"string","default":"nano","enum":["nano","micro","small","medium","large","xlarge","2xlarge"]},"users":{"description":"Users configuration map.","type":"object","default":{},"additionalProperties":{"type":"object","properties":{"password":{"description":"Password for the user (autogenerated if not provided).","type":"string"}}}}}} + release: + prefix: vpn- + labels: + cozystack.io/ui: "true" + chart: + name: vpn + sourceRef: + kind: HelmRepository + name: cozystack-apps + namespace: cozy-public + dashboard: + category: NaaS + singular: VPN + plural: VPN + description: Managed VPN service + tags: + - network + icon: PHN2ZyB3aWR0aD0iMTQ0IiBoZWlnaHQ9IjE0NCIgdmlld0JveD0iMCAwIDE0NCAxNDQiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xNDMuOTkyIDMwLjM2OTdDMTQzLjk5MiAyOS4yNTU2IDE0My45OTIgMjguMTUxNyAxNDMuOTkyIDI3LjA0NzdDMTQzLjk0NSAyNC42Mjg3IDE0My43MTcgMjIuMjE2NiAxNDMuMzA5IDE5LjgzMTZDMTQyLjkxMiAxNy40NDczIDE0Mi4xNTcgMTUuMTM2NSAxNDEuMDcyIDEyLjk3NjlDMTM5Ljk3IDEwLjgxOCAxMzguNTM0IDguODQ2NjUgMTM2LjgxNyA3LjEzNTc3TDEzMC45OTcgMi44OTA0NEMxMjguODM3IDEuODAyODkgMTI2LjUyNyAxLjA0MTg5IDEyNC4xNDQgMC42MzIyODNDMTIxLjc1NiAwLjIzNDgwOCAxMTkuMzQgMC4wMjM0MTEzIDExNi45MTkgMEMxMTUuODE1IDAgMjguMTQ2MSAwIDI3LjAzMjMgMEMyNC42MDQ3IDAuMDI0MjIxMSAyMi4xODI2IDAuMjM1NjA5IDE5Ljc4NzYgMC42MzIyODNDMTcuNDEyOCAxLjAzODUxIDE1LjExMjYgMS43OTk3NCAxMi45NjQzIDIuODkwNDRDMTAuODEzIDMuOTk1MTkgOC44NDYyNSA1LjQyNzM2IDcuMTM0MzYgNy4xMzU3N0M1LjQxNzY4IDguODQ0NCAzLjk4NDggMTAuODE2MyAyLjg4OTg3IDEyLjk3NjlDMS44MDA4NiAxNS4xMzYgMS4wNDMxMyAxNy40NDY4IDAuNjQyMTkzIDE5LjgzMTZDMC4yNDM0OTcgMjIuMjE2OSAwLjAyODc5OTggMjQuNjI5NCAwIDI3LjA0NzdDMCAyOC4xNTE3IDAgMTE1LjgzOCAwIDExNi45NTJDMC4wMjYxNzU1IDExOS4zODQgMC4yNDA4ODQgMTIxLjgxIDAuNjQyMTkzIDEyNC4yMDlDMS4wNDA0NCAxMjYuNTk0IDEuNzk4MjkgMTI4LjkwNSAyLjg4OTg3IDEzMS4wNjNDMy45ODUxNSAxMzMuMjE4IDUuNDE4MSAxMzUuMTgzIDcuMTM0MzYgMTM2Ljg4NEM4Ljg0MDk1IDEzOC41OTkgMTAuODA4NyAxNDAuMDMyIDEyLjk2NDMgMTQxLjEzQzE1LjExNDcgMTQyLjIwOSAxNy40MTQ2IDE0Mi45NiAxOS43ODc2IDE0My4zNThDMjIuMTczMSAxNDMuNzUxIDI0LjU4NDcgMTQzLjk2NiAyNy4wMDIyIDE0NEMyOC4xMTYgMTQ0IDExNS43ODUgMTQ0IDExNi44ODkgMTQ0QzExOS4zMDMgMTQzLjk2NyAxMjEuNzEyIDE0My43NTIgMTI0LjA5NCAxNDMuMzU4QzEyNi40ODUgMTQyLjk0NiAxMjguODAxIDE0Mi4xODIgMTMwLjk2NyAxNDEuMDg5QzEzMy4xMjEgMTM5Ljk5NCAxMzUuMDg2IDEzOC41NjEgMTM2Ljc4NyAxMzYuODQ0QzEzOC41MDMgMTM1LjE0IDEzOS45MzkgMTMzLjE3NiAxNDEuMDQyIDEzMS4wMjNDMTQyLjEzNyAxMjguODc5IDE0Mi45MDEgMTI2LjU4MSAxNDMuMzA5IDEyNC4yMDlDMTQzLjcxIDEyMS44MjMgMTQzLjkzMiAxMTkuNDExIDE0My45NzIgMTE2Ljk5MkMxNDMuOTkyIDExNS44MzggMTQ0LjAxMiAzMS42NzQ0IDE0My45OTIgMzAuMzY5N1oiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl82ODFfMjgxOCkiLz4KPHBhdGggZD0iTTExNS45NTUgNjcuNDIzMUMxMTQuOTQxIDU3LjgyMzQgMTEwLjcwMSA0OC44NTE4IDEwMy45MjggNDEuOTc1MkM5Ny4xNTQ5IDM1LjA5ODYgODguMjQ5NSAzMC43MjM5IDc4LjY2OCAyOS41NjY0VjQ2Ljc3ODZDODQuNDg4NyA0Ny45MTI3IDg5LjczMzggNTEuMDM2MiA5My41MDQ5IDU1LjYxMzdDOTcuMjc2IDYwLjE5MTIgOTkuMzM4MSA2NS45Mzc5IDk5LjMzODEgNzEuODY5MkM5OS4zMzgxIDc3LjgwMDQgOTcuMjc2IDgzLjU0NzEgOTMuNTA0OSA4OC4xMjQ2Qzg5LjczMzggOTIuNzAyMiA4NC40ODg3IDk1LjgyNTYgNzguNjY4IDk2Ljk1OThWMTE0LjIyMkM4OS43ODAxIDExMi44NzcgOTkuOTE3OCAxMDcuMjE1IDEwNi44OTQgOTguNDYwMUMxMTMuODY5IDg5LjcwNDggMTE3LjEyNCA3OC41NTczIDExNS45NTUgNjcuNDIzMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0yOC4wMTU1IDc2LjM2NTRDMjkuMDMxMSA4NS45NjQ0IDMzLjI3MTggOTQuOTM1MSA0MC4wNDQ3IDEwMS44MTFDNDYuODE3NSAxMDguNjg4IDU1LjcyMiAxMTMuMDYzIDY1LjMwMjggMTE0LjIyMlYyOS41NjY0QzU0LjE5MDcgMzAuOTExOSA0NC4wNTMgMzYuNTczMSAzNy4wNzcyIDQ1LjMyODRDMzAuMTAxMyA1NC4wODM3IDI2Ljg0NjcgNjUuMjMxMiAyOC4wMTU1IDc2LjM2NTRaIiBmaWxsPSIjNUJCMTkzIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNjgxXzI4MTgiIHgxPSIxMzIuNSIgeTE9IjEzMi41IiB4Mj0iLTI0IiB5Mj0iLTE5IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMxODM3MjkiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNDU5RDc1Ii8+CjwvbGluZWFyR3JhZGllbnQ+CjwvZGVmcz4KPC9zdmc+Cg== + keysOrder: [["apiVersion"], ["appVersion"], ["kind"], ["metadata"], ["metadata", "name"], ["spec", "replicas"], ["spec", "resources"], ["spec", "resourcesPreset"], ["spec", "external"], ["spec", "host"], ["spec", "users"], ["spec", "externalIPs"]] + secrets: + exclude: [] + include: + - resourceNames: + - vpn-{{ .name }}-urls + services: + exclude: [] + include: + - resourceNames: + - vpn-{{ .name }}-vpn diff --git a/packages/system/vpn-rd/templates/cozyrd.yaml b/packages/system/vpn-rd/templates/cozyrd.yaml new file mode 100644 index 00000000..e079ddcf --- /dev/null +++ b/packages/system/vpn-rd/templates/cozyrd.yaml @@ -0,0 +1,4 @@ +{{- range $path, $_ := .Files.Glob "cozyrds/*" }} +--- +{{ $.Files.Get $path }} +{{- end }} diff --git a/packages/system/vpn-rd/values.yaml b/packages/system/vpn-rd/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/vpn-rd/values.yaml @@ -0,0 +1 @@ +{} From 6466d69b6bd452e30b5ada41a2c51eff0d6afdbd Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Fri, 19 Dec 2025 13:59:16 +0100 Subject: [PATCH 11/15] 1 Signed-off-by: Andrei Kvapil --- cmd/cozystack-operator/main.go | 9 + internal/operator/package_reconciler.go | 889 +++++++++++++ packages/core/installer/example/platform.yaml | 11 +- .../templates/cozystack-operator.yaml | 18 +- packages/core/installer/values.yaml | 4 +- packages/core/platform/Makefile | 50 +- .../platform/images/migrations/Dockerfile | 13 + .../platform/images/migrations/migrations/1 | 25 + .../platform/images/migrations/migrations/10 | 15 + .../platform/images/migrations/migrations/11 | 21 + .../platform/images/migrations/migrations/12 | 35 + .../platform/images/migrations/migrations/13 | 10 + .../platform/images/migrations/migrations/14 | 10 + .../platform/images/migrations/migrations/15 | 28 + .../platform/images/migrations/migrations/16 | 95 ++ .../platform/images/migrations/migrations/17 | 10 + .../platform/images/migrations/migrations/18 | 18 + .../platform/images/migrations/migrations/19 | 53 + .../platform/images/migrations/migrations/2 | 16 + .../platform/images/migrations/migrations/20 | 56 + .../platform/images/migrations/migrations/21 | 21 + .../platform/images/migrations/migrations/22 | 161 +++ .../platform/images/migrations/migrations/3 | 12 + .../platform/images/migrations/migrations/4 | 15 + .../platform/images/migrations/migrations/5 | 15 + .../platform/images/migrations/migrations/6 | 16 + .../platform/images/migrations/migrations/7 | 8 + .../platform/images/migrations/migrations/8 | 9 + .../platform/images/migrations/migrations/9 | 10 + .../images/migrations/run-migrations.sh | 42 + packages/core/platform/psds/dependencies.dot | 190 --- packages/core/platform/psds/dependencies.svg | 1128 ----------------- packages/core/platform/templates/_helpers.tpl | 108 -- packages/core/platform/templates/apps.yaml | 67 - packages/core/platform/templates/config.yaml | 23 + .../templates/containerd-registry-secret.yaml | 35 + .../platform/templates/cozystack-assets.yaml | 73 -- .../core/platform/templates/helmreleases.yaml | 97 -- .../core/platform/templates/helmrepos.yaml | 40 - .../platform/templates/migration-hook.yaml | 68 + .../core/platform/templates/namespaces.yaml | 40 - .../platform/templates/packages/isp-full.yaml | 215 ++++ .../core/platform/templates/repository.yaml | 17 + .../core/platform/templates/scheduling.yaml | 11 + .../templates/sources/backup-controller.yaml | 22 + .../sources}/bootbox-application.yaml | 0 .../{psds => templates/sources}/bootbox.yaml | 0 .../sources}/bucket-application.yaml | 0 .../sources}/capi-operator.yaml | 0 .../sources}/capi-providers-bootstrap.yaml | 0 .../sources}/capi-providers-core.yaml | 0 .../sources}/capi-providers-cpprovider.yaml | 0 .../capi-providers-infraprovider.yaml | 0 .../sources}/cert-manager.yaml | 0 .../sources}/clickhouse-application.yaml | 0 .../sources}/clickhouse-operator.yaml | 2 - .../sources}/cozy-proxy.yaml | 0 .../templates/sources/cozystack-basics.yaml | 21 + .../sources}/cozystack-engine.yaml | 22 +- .../sources}/etcd-application.yaml | 0 .../sources}/etcd-operator.yaml | 0 .../sources}/external-dns.yaml | 0 .../sources}/external-secrets-operator.yaml | 0 .../sources}/ferretdb-application.yaml | 0 .../sources}/foundationdb-application.yaml | 0 .../sources}/foundationdb-operator.yaml | 0 .../sources}/goldpinger.yaml | 4 +- .../sources}/gpu-operator.yaml | 0 .../sources}/grafana-operator.yaml | 0 .../sources}/hetzner-robotlb.yaml | 0 .../sources}/http-cache-application.yaml | 0 .../sources}/info-application.yaml | 0 .../sources}/ingress-application.yaml | 0 .../sources}/kafka-application.yaml | 0 .../sources}/kafka-operator.yaml | 0 .../{psds => templates/sources}/kamaji.yaml | 0 .../sources}/keycloak-operator.yaml | 0 .../{psds => templates/sources}/keycloak.yaml | 0 .../templates/sources/kubeovn-plunger.yaml | 23 + .../templates/sources/kubeovn-webhook.yaml | 22 + .../sources}/kubernetes-application.yaml | 0 .../sources}/kubevirt-cdi.yaml | 0 .../{psds => templates/sources}/kubevirt.yaml | 0 .../{psds => templates/sources}/linstor.yaml | 8 +- .../sources}/mariadb-operator.yaml | 0 .../{psds => templates/sources}/metallb.yaml | 0 .../sources}/monitoring-agents.yaml | 2 - .../sources}/monitoring-application.yaml | 0 .../{psds => templates/sources}/multus.yaml | 0 .../sources}/mysql-application.yaml | 0 .../sources}/nats-application.yaml | 0 .../sources}/networking.yaml | 23 +- .../sources}/nfs-driver.yaml | 0 .../sources}/objectstorage-controller.yaml | 0 .../sources}/postgres-application.yaml | 0 .../templates/sources/postgres-operator.yaml | 26 + .../sources/prometheus-operator-crds.yaml | 20 + .../sources}/rabbitmq-application.yaml | 0 .../sources}/rabbitmq-operator.yaml | 0 .../sources}/redis-application.yaml | 0 .../sources}/redis-operator.yaml | 0 .../{psds => templates/sources}/reloader.yaml | 0 .../sources}/seaweedfs-application.yaml | 0 .../sources}/snapshot-controller.yaml | 2 - .../sources}/tcp-balancer-application.yaml | 0 .../sources}/telepresence.yaml | 0 .../sources}/tenant-application.yaml | 1 - .../{psds => templates/sources}/velero.yaml | 2 - .../sources}/vertical-pod-autoscaler.yaml | 3 +- .../sources}/victoria-metrics-operator.yaml | 0 .../sources}/virtual-machine-application.yaml | 0 .../virtualprivatecloud-application.yaml | 0 .../sources}/vm-disk-application.yaml | 0 .../sources}/vm-instance-application.yaml | 0 .../sources}/vpn-application.yaml | 0 packages/core/platform/templates/version.yaml | 8 + packages/core/platform/values-isp-full.yaml | 12 + packages/core/platform/values-isp-hosted.yaml | 12 + packages/core/platform/values.yaml | 91 +- packages/system/cozystack-basics/Chart.yaml | 3 + packages/system/cozystack-basics/Makefile | 4 + .../templates/cozy-public.yaml | 4 + .../templates/tenant-root.yaml | 25 + packages/system/cozystack-basics/values.yaml | 1 + .../templates/vpa-for-vpa.yaml | 13 +- 125 files changed, 2342 insertions(+), 1841 deletions(-) create mode 100644 internal/operator/package_reconciler.go create mode 100644 packages/core/platform/images/migrations/Dockerfile create mode 100755 packages/core/platform/images/migrations/migrations/1 create mode 100755 packages/core/platform/images/migrations/migrations/10 create mode 100755 packages/core/platform/images/migrations/migrations/11 create mode 100755 packages/core/platform/images/migrations/migrations/12 create mode 100755 packages/core/platform/images/migrations/migrations/13 create mode 100755 packages/core/platform/images/migrations/migrations/14 create mode 100755 packages/core/platform/images/migrations/migrations/15 create mode 100755 packages/core/platform/images/migrations/migrations/16 create mode 100755 packages/core/platform/images/migrations/migrations/17 create mode 100755 packages/core/platform/images/migrations/migrations/18 create mode 100755 packages/core/platform/images/migrations/migrations/19 create mode 100755 packages/core/platform/images/migrations/migrations/2 create mode 100755 packages/core/platform/images/migrations/migrations/20 create mode 100755 packages/core/platform/images/migrations/migrations/21 create mode 100755 packages/core/platform/images/migrations/migrations/22 create mode 100755 packages/core/platform/images/migrations/migrations/3 create mode 100755 packages/core/platform/images/migrations/migrations/4 create mode 100755 packages/core/platform/images/migrations/migrations/5 create mode 100755 packages/core/platform/images/migrations/migrations/6 create mode 100755 packages/core/platform/images/migrations/migrations/7 create mode 100755 packages/core/platform/images/migrations/migrations/8 create mode 100755 packages/core/platform/images/migrations/migrations/9 create mode 100755 packages/core/platform/images/migrations/run-migrations.sh delete mode 100644 packages/core/platform/psds/dependencies.dot delete mode 100644 packages/core/platform/psds/dependencies.svg delete mode 100644 packages/core/platform/templates/_helpers.tpl delete mode 100644 packages/core/platform/templates/apps.yaml create mode 100644 packages/core/platform/templates/config.yaml create mode 100644 packages/core/platform/templates/containerd-registry-secret.yaml delete mode 100644 packages/core/platform/templates/cozystack-assets.yaml delete mode 100644 packages/core/platform/templates/helmreleases.yaml delete mode 100644 packages/core/platform/templates/helmrepos.yaml create mode 100644 packages/core/platform/templates/migration-hook.yaml delete mode 100644 packages/core/platform/templates/namespaces.yaml create mode 100644 packages/core/platform/templates/packages/isp-full.yaml create mode 100644 packages/core/platform/templates/repository.yaml create mode 100644 packages/core/platform/templates/scheduling.yaml create mode 100644 packages/core/platform/templates/sources/backup-controller.yaml rename packages/core/platform/{psds => templates/sources}/bootbox-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/bootbox.yaml (100%) rename packages/core/platform/{psds => templates/sources}/bucket-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/capi-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/capi-providers-bootstrap.yaml (100%) rename packages/core/platform/{psds => templates/sources}/capi-providers-core.yaml (100%) rename packages/core/platform/{psds => templates/sources}/capi-providers-cpprovider.yaml (100%) rename packages/core/platform/{psds => templates/sources}/capi-providers-infraprovider.yaml (100%) rename packages/core/platform/{psds => templates/sources}/cert-manager.yaml (100%) rename packages/core/platform/{psds => templates/sources}/clickhouse-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/clickhouse-operator.yaml (90%) rename packages/core/platform/{psds => templates/sources}/cozy-proxy.yaml (100%) create mode 100644 packages/core/platform/templates/sources/cozystack-basics.yaml rename packages/core/platform/{psds => templates/sources}/cozystack-engine.yaml (74%) rename packages/core/platform/{psds => templates/sources}/etcd-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/etcd-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/external-dns.yaml (100%) rename packages/core/platform/{psds => templates/sources}/external-secrets-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/ferretdb-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/foundationdb-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/foundationdb-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/goldpinger.yaml (84%) rename packages/core/platform/{psds => templates/sources}/gpu-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/grafana-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/hetzner-robotlb.yaml (100%) rename packages/core/platform/{psds => templates/sources}/http-cache-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/info-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/ingress-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/kafka-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/kafka-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/kamaji.yaml (100%) rename packages/core/platform/{psds => templates/sources}/keycloak-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/keycloak.yaml (100%) create mode 100644 packages/core/platform/templates/sources/kubeovn-plunger.yaml create mode 100644 packages/core/platform/templates/sources/kubeovn-webhook.yaml rename packages/core/platform/{psds => templates/sources}/kubernetes-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/kubevirt-cdi.yaml (100%) rename packages/core/platform/{psds => templates/sources}/kubevirt.yaml (100%) rename packages/core/platform/{psds => templates/sources}/linstor.yaml (81%) rename packages/core/platform/{psds => templates/sources}/mariadb-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/metallb.yaml (100%) rename packages/core/platform/{psds => templates/sources}/monitoring-agents.yaml (90%) rename packages/core/platform/{psds => templates/sources}/monitoring-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/multus.yaml (100%) rename packages/core/platform/{psds => templates/sources}/mysql-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/nats-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/networking.yaml (73%) rename packages/core/platform/{psds => templates/sources}/nfs-driver.yaml (100%) rename packages/core/platform/{psds => templates/sources}/objectstorage-controller.yaml (100%) rename packages/core/platform/{psds => templates/sources}/postgres-application.yaml (100%) create mode 100644 packages/core/platform/templates/sources/postgres-operator.yaml create mode 100644 packages/core/platform/templates/sources/prometheus-operator-crds.yaml rename packages/core/platform/{psds => templates/sources}/rabbitmq-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/rabbitmq-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/redis-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/redis-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/reloader.yaml (100%) rename packages/core/platform/{psds => templates/sources}/seaweedfs-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/snapshot-controller.yaml (90%) rename packages/core/platform/{psds => templates/sources}/tcp-balancer-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/telepresence.yaml (100%) rename packages/core/platform/{psds => templates/sources}/tenant-application.yaml (95%) rename packages/core/platform/{psds => templates/sources}/velero.yaml (90%) rename packages/core/platform/{psds => templates/sources}/vertical-pod-autoscaler.yaml (92%) rename packages/core/platform/{psds => templates/sources}/victoria-metrics-operator.yaml (100%) rename packages/core/platform/{psds => templates/sources}/virtual-machine-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/virtualprivatecloud-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/vm-disk-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/vm-instance-application.yaml (100%) rename packages/core/platform/{psds => templates/sources}/vpn-application.yaml (100%) create mode 100644 packages/core/platform/templates/version.yaml create mode 100644 packages/core/platform/values-isp-full.yaml create mode 100644 packages/core/platform/values-isp-hosted.yaml create mode 100644 packages/system/cozystack-basics/Chart.yaml create mode 100644 packages/system/cozystack-basics/Makefile create mode 100644 packages/system/cozystack-basics/templates/cozy-public.yaml create mode 100644 packages/system/cozystack-basics/templates/tenant-root.yaml create mode 100644 packages/system/cozystack-basics/values.yaml diff --git a/cmd/cozystack-operator/main.go b/cmd/cozystack-operator/main.go index 6cabbd5d..4c182735 100644 --- a/cmd/cozystack-operator/main.go +++ b/cmd/cozystack-operator/main.go @@ -200,6 +200,15 @@ func main() { os.Exit(1) } + // Setup Package reconciler + if err := (&operator.PackageReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "Package") + os.Exit(1) + } + // +kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil { diff --git a/internal/operator/package_reconciler.go b/internal/operator/package_reconciler.go new file mode 100644 index 00000000..8ac5ed74 --- /dev/null +++ b/internal/operator/package_reconciler.go @@ -0,0 +1,889 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 operator + +import ( + "context" + "fmt" + "strings" + + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + helmv2 "github.com/fluxcd/helm-controller/api/v2" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/reconcile" +) + +// PackageReconciler reconciles Package resources +type PackageReconciler struct { + client.Client + Scheme *runtime.Scheme +} + +// +kubebuilder:rbac:groups=cozystack.io,resources=packages,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=cozystack.io,resources=packages/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=cozystack.io,resources=packagesources,verbs=get;list;watch +// +kubebuilder:rbac:groups=helm.toolkit.fluxcd.io,resources=helmreleases,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=core,resources=namespaces,verbs=get;list;watch;create;update;patch + +// Reconcile is part of the main kubernetes reconciliation loop +func (r *PackageReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + logger := log.FromContext(ctx) + + pkg := &cozyv1alpha1.Package{} + if err := r.Get(ctx, req.NamespacedName, pkg); err != nil { + if apierrors.IsNotFound(err) { + // Resource not found, return (ownerReference will handle cleanup) + return ctrl.Result{}, nil + } + return ctrl.Result{}, err + } + + // Get PackageSource with the same name + packageSource := &cozyv1alpha1.PackageSource{} + if err := r.Get(ctx, types.NamespacedName{Name: pkg.Name}, packageSource); err != nil { + if apierrors.IsNotFound(err) { + meta.SetStatusCondition(&pkg.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionFalse, + Reason: "PackageSourceNotFound", + Message: fmt.Sprintf("PackageSource %s not found", pkg.Name), + }) + if err := r.Status().Update(ctx, pkg); err != nil { + return ctrl.Result{}, err + } + return ctrl.Result{}, nil + } + return ctrl.Result{}, err + } + + // Determine variant (default to "default" if not specified) + variantName := pkg.Spec.Variant + if variantName == "" { + variantName = "default" + } + + // Find the variant in PackageSource + var variant *cozyv1alpha1.Variant + for i := range packageSource.Spec.Variants { + if packageSource.Spec.Variants[i].Name == variantName { + variant = &packageSource.Spec.Variants[i] + break + } + } + + if variant == nil { + meta.SetStatusCondition(&pkg.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionFalse, + Reason: "VariantNotFound", + Message: fmt.Sprintf("Variant %s not found in PackageSource %s", variantName, pkg.Name), + }) + if err := r.Status().Update(ctx, pkg); err != nil { + return ctrl.Result{}, err + } + return ctrl.Result{}, nil + } + + // Reconcile namespaces from components + if err := r.reconcileNamespaces(ctx, pkg, variant); err != nil { + logger.Error(err, "failed to reconcile namespaces") + return ctrl.Result{}, err + } + + // Validate variant dependencies before creating HelmReleases + // If dependencies are missing, we don't create new HelmReleases but don't delete existing ones + if err := r.validateVariantDependencies(ctx, pkg, variant); err != nil { + logger.Info("variant dependencies not ready, skipping HelmRelease creation", "package", pkg.Name, "error", err) + meta.SetStatusCondition(&pkg.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionFalse, + Reason: "DependenciesNotReady", + Message: fmt.Sprintf("Variant dependencies not ready: %v", err), + }) + if err := r.Status().Update(ctx, pkg); err != nil { + return ctrl.Result{}, err + } + // Return success to avoid requeue, but don't create HelmReleases + return ctrl.Result{}, nil + } + + // Create HelmReleases for components with Install section + helmReleaseCount := 0 + for _, component := range variant.Components { + // Skip components without Install section + if component.Install == nil { + continue + } + + // Check if component is disabled via Package spec + if pkgComponent, ok := pkg.Spec.Components[component.Name]; ok { + if pkgComponent.Enabled != nil && !*pkgComponent.Enabled { + logger.V(1).Info("skipping disabled component", "package", pkg.Name, "component", component.Name) + continue + } + } + + // Build artifact name: -- (with dots replaced by dashes) + artifactName := fmt.Sprintf("%s-%s-%s", + strings.ReplaceAll(packageSource.Name, ".", "-"), + strings.ReplaceAll(variantName, ".", "-"), + strings.ReplaceAll(component.Name, ".", "-")) + + // Determine namespace (from Install or default to cozy-system) + namespace := component.Install.Namespace + if namespace == "" { + namespace = "cozy-system" + } + + // Determine release name (from Install or use component name) + releaseName := component.Install.ReleaseName + if releaseName == "" { + releaseName = component.Name + } + + // Build labels + labels := make(map[string]string) + labels["cozystack.io/package"] = pkg.Name + if component.Install.Privileged { + labels["cozystack.io/privileged"] = "true" + } + + // Create HelmRelease + hr := &helmv2.HelmRelease{ + ObjectMeta: metav1.ObjectMeta{ + Name: releaseName, + Namespace: namespace, + Labels: labels, + }, + Spec: helmv2.HelmReleaseSpec{ + Interval: metav1.Duration{Duration: 5 * 60 * 1000000000}, // 5m + ChartRef: &helmv2.CrossNamespaceSourceReference{ + Kind: "ExternalArtifact", + Name: artifactName, + Namespace: "cozy-system", + }, + Install: &helmv2.Install{ + Remediation: &helmv2.InstallRemediation{ + Retries: -1, + }, + }, + Upgrade: &helmv2.Upgrade{ + Remediation: &helmv2.UpgradeRemediation{ + Retries: -1, + }, + }, + }, + } + + // Set ownerReference + hr.OwnerReferences = []metav1.OwnerReference{ + { + APIVersion: pkg.APIVersion, + Kind: pkg.Kind, + Name: pkg.Name, + UID: pkg.UID, + Controller: func() *bool { b := true; return &b }(), + }, + } + + // Merge values from Package spec if provided + if pkgComponent, ok := pkg.Spec.Components[component.Name]; ok && pkgComponent.Values != nil { + hr.Spec.Values = pkgComponent.Values + } + + // Build DependsOn from component Install and variant DependsOn + dependsOn, err := r.buildDependsOn(ctx, pkg, packageSource, variant, &component) + if err != nil { + logger.Error(err, "failed to build DependsOn", "component", component.Name) + meta.SetStatusCondition(&pkg.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionFalse, + Reason: "DependsOnFailed", + Message: fmt.Sprintf("Failed to build DependsOn for component %s: %v", component.Name, err), + }) + if err := r.Status().Update(ctx, pkg); err != nil { + return ctrl.Result{}, err + } + return ctrl.Result{}, err + } + if len(dependsOn) > 0 { + hr.Spec.DependsOn = dependsOn + } + + if err := r.createOrUpdateHelmRelease(ctx, hr); err != nil { + logger.Error(err, "failed to reconcile HelmRelease", "name", releaseName, "namespace", namespace) + meta.SetStatusCondition(&pkg.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionFalse, + Reason: "HelmReleaseFailed", + Message: fmt.Sprintf("Failed to create HelmRelease %s: %v", releaseName, err), + }) + if err := r.Status().Update(ctx, pkg); err != nil { + return ctrl.Result{}, err + } + return ctrl.Result{}, err + } + + helmReleaseCount++ + logger.Info("reconciled HelmRelease", "package", pkg.Name, "component", component.Name, "releaseName", releaseName, "namespace", namespace) + } + + // Cleanup orphaned HelmReleases + if err := r.cleanupOrphanedHelmReleases(ctx, pkg, variant); err != nil { + logger.Error(err, "failed to cleanup orphaned HelmReleases") + // Don't return error, continue with status update + } + + // Update status with success message + message := fmt.Sprintf("reconciliation succeeded, generated %d helmrelease(s)", helmReleaseCount) + meta.SetStatusCondition(&pkg.Status.Conditions, metav1.Condition{ + Type: "Ready", + Status: metav1.ConditionTrue, + Reason: "ReconciliationSucceeded", + Message: message, + }) + + if err := r.Status().Update(ctx, pkg); err != nil { + return ctrl.Result{}, err + } + + logger.Info("reconciled Package", "name", pkg.Name, "helmReleaseCount", helmReleaseCount) + + // Trigger reconcile for Packages that depend on this Package + if err := r.triggerDependentPackages(ctx, pkg.Name); err != nil { + logger.Error(err, "failed to trigger dependent Packages", "package", pkg.Name) + // Don't return error, this is best-effort + } + + return ctrl.Result{}, nil +} + +// createOrUpdateHelmRelease creates or updates a HelmRelease +func (r *PackageReconciler) createOrUpdateHelmRelease(ctx context.Context, hr *helmv2.HelmRelease) error { + existing := &helmv2.HelmRelease{} + key := types.NamespacedName{ + Name: hr.Name, + Namespace: hr.Namespace, + } + + err := r.Get(ctx, key, existing) + if apierrors.IsNotFound(err) { + return r.Create(ctx, hr) + } else if err != nil { + return err + } + + // Preserve resource version + hr.SetResourceVersion(existing.GetResourceVersion()) + + // Merge labels + labels := hr.GetLabels() + if labels == nil { + labels = make(map[string]string) + } + for k, v := range existing.GetLabels() { + if _, ok := labels[k]; !ok { + labels[k] = v + } + } + hr.SetLabels(labels) + + // Merge annotations + annotations := hr.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + for k, v := range existing.GetAnnotations() { + if _, ok := annotations[k]; !ok { + annotations[k] = v + } + } + hr.SetAnnotations(annotations) + + // Update Spec + existing.Spec = hr.Spec + existing.SetLabels(hr.GetLabels()) + existing.SetAnnotations(hr.GetAnnotations()) + existing.SetOwnerReferences(hr.GetOwnerReferences()) + + return r.Update(ctx, existing) +} + +// buildDependsOn builds DependsOn list for a component +// Includes: +// 1. Dependencies from component.Install.DependsOn (with namespace from referenced component) +// 2. Dependencies from variant.DependsOn (all components with Install from referenced Package) +func (r *PackageReconciler) buildDependsOn(ctx context.Context, pkg *cozyv1alpha1.Package, packageSource *cozyv1alpha1.PackageSource, variant *cozyv1alpha1.Variant, component *cozyv1alpha1.Component) ([]helmv2.DependencyReference, error) { + logger := log.FromContext(ctx) + dependsOn := []helmv2.DependencyReference{} + + // Build map of component names to their release names and namespaces in current variant + componentMap := make(map[string]struct { + releaseName string + namespace string + }) + for _, comp := range variant.Components { + if comp.Install == nil { + continue + } + compNamespace := comp.Install.Namespace + if compNamespace == "" { + compNamespace = "cozy-system" + } + compReleaseName := comp.Install.ReleaseName + if compReleaseName == "" { + compReleaseName = comp.Name + } + componentMap[comp.Name] = struct { + releaseName string + namespace string + }{ + releaseName: compReleaseName, + namespace: compNamespace, + } + } + + // Add dependencies from component.Install.DependsOn + if len(component.Install.DependsOn) > 0 { + for _, depName := range component.Install.DependsOn { + depComp, ok := componentMap[depName] + if !ok { + return nil, fmt.Errorf("component %s not found in variant for dependency %s", depName, component.Name) + } + dependsOn = append(dependsOn, helmv2.DependencyReference{ + Name: depComp.releaseName, + Namespace: depComp.namespace, + }) + logger.V(1).Info("added component dependency", "component", component.Name, "dependsOn", depName, "releaseName", depComp.releaseName, "namespace", depComp.namespace) + } + } + + // Add dependencies from variant.DependsOn + if len(variant.DependsOn) > 0 { + for _, depPackageName := range variant.DependsOn { + // Check if dependency is in IgnoreDependencies + ignore := false + for _, ignoreDep := range pkg.Spec.IgnoreDependencies { + if ignoreDep == depPackageName { + ignore = true + break + } + } + if ignore { + logger.V(1).Info("ignoring dependency", "package", pkg.Name, "dependency", depPackageName) + continue + } + + // Get the Package + depPackage := &cozyv1alpha1.Package{} + if err := r.Get(ctx, types.NamespacedName{Name: depPackageName}, depPackage); err != nil { + if apierrors.IsNotFound(err) { + return nil, fmt.Errorf("dependent Package %s not found", depPackageName) + } + return nil, fmt.Errorf("failed to get dependent Package %s: %w", depPackageName, err) + } + + // Get the variant from dependent Package + depVariantName := depPackage.Spec.Variant + if depVariantName == "" { + depVariantName = "default" + } + + // Get the PackageSource + depPackageSource := &cozyv1alpha1.PackageSource{} + if err := r.Get(ctx, types.NamespacedName{Name: depPackageName}, depPackageSource); err != nil { + if apierrors.IsNotFound(err) { + return nil, fmt.Errorf("dependent PackageSource %s not found", depPackageName) + } + return nil, fmt.Errorf("failed to get dependent PackageSource %s: %w", depPackageName, err) + } + + // Find the variant in PackageSource + var depVariant *cozyv1alpha1.Variant + for i := range depPackageSource.Spec.Variants { + if depPackageSource.Spec.Variants[i].Name == depVariantName { + depVariant = &depPackageSource.Spec.Variants[i] + break + } + } + + if depVariant == nil { + return nil, fmt.Errorf("dependent variant %s not found in PackageSource %s", depVariantName, depPackageName) + } + + // Add all components with Install from dependent variant + for _, depComp := range depVariant.Components { + if depComp.Install == nil { + continue + } + + // Check if component is disabled in dependent Package + if depPkgComponent, ok := depPackage.Spec.Components[depComp.Name]; ok { + if depPkgComponent.Enabled != nil && !*depPkgComponent.Enabled { + continue + } + } + + depCompNamespace := depComp.Install.Namespace + if depCompNamespace == "" { + depCompNamespace = "cozy-system" + } + depCompReleaseName := depComp.Install.ReleaseName + if depCompReleaseName == "" { + depCompReleaseName = depComp.Name + } + + dependsOn = append(dependsOn, helmv2.DependencyReference{ + Name: depCompReleaseName, + Namespace: depCompNamespace, + }) + logger.V(1).Info("added variant dependency", "package", pkg.Name, "dependency", depPackageName, "component", depComp.Name, "releaseName", depCompReleaseName, "namespace", depCompNamespace) + } + } + } + + return dependsOn, nil +} + +// validateVariantDependencies validates that all variant dependencies exist +// Returns error if any dependency is missing +func (r *PackageReconciler) validateVariantDependencies(ctx context.Context, pkg *cozyv1alpha1.Package, variant *cozyv1alpha1.Variant) error { + logger := log.FromContext(ctx) + + if len(variant.DependsOn) == 0 { + return nil + } + + for _, depPackageName := range variant.DependsOn { + // Check if dependency is in IgnoreDependencies + ignore := false + for _, ignoreDep := range pkg.Spec.IgnoreDependencies { + if ignoreDep == depPackageName { + ignore = true + break + } + } + if ignore { + logger.V(1).Info("ignoring dependency", "package", pkg.Name, "dependency", depPackageName) + continue + } + + // Get the Package + depPackage := &cozyv1alpha1.Package{} + if err := r.Get(ctx, types.NamespacedName{Name: depPackageName}, depPackage); err != nil { + if apierrors.IsNotFound(err) { + return fmt.Errorf("dependent Package %s not found", depPackageName) + } + return fmt.Errorf("failed to get dependent Package %s: %w", depPackageName, err) + } + + // Get the PackageSource + depPackageSource := &cozyv1alpha1.PackageSource{} + if err := r.Get(ctx, types.NamespacedName{Name: depPackageName}, depPackageSource); err != nil { + if apierrors.IsNotFound(err) { + return fmt.Errorf("dependent PackageSource %s not found", depPackageName) + } + return fmt.Errorf("failed to get dependent PackageSource %s: %w", depPackageName, err) + } + + // Get the variant from dependent Package + depVariantName := depPackage.Spec.Variant + if depVariantName == "" { + depVariantName = "default" + } + + // Find the variant in PackageSource + var depVariant *cozyv1alpha1.Variant + for i := range depPackageSource.Spec.Variants { + if depPackageSource.Spec.Variants[i].Name == depVariantName { + depVariant = &depPackageSource.Spec.Variants[i] + break + } + } + + if depVariant == nil { + return fmt.Errorf("dependent variant %s not found in PackageSource %s", depVariantName, depPackageName) + } + } + + return nil +} + +// reconcileNamespaces creates or updates namespaces based on components in the variant +func (r *PackageReconciler) reconcileNamespaces(ctx context.Context, pkg *cozyv1alpha1.Package, variant *cozyv1alpha1.Variant) error { + logger := log.FromContext(ctx) + + // Collect namespaces from components + // Map: namespace -> {isPrivileged} + type namespaceInfo struct { + privileged bool + } + namespacesMap := make(map[string]namespaceInfo) + + for _, component := range variant.Components { + // Skip components without Install section + if component.Install == nil { + continue + } + + // Check if component is disabled via Package spec + if pkgComponent, ok := pkg.Spec.Components[component.Name]; ok { + if pkgComponent.Enabled != nil && !*pkgComponent.Enabled { + continue + } + } + + // Namespace must be set + namespace := component.Install.Namespace + if namespace == "" { + return fmt.Errorf("component %s has empty namespace in Install section", component.Name) + } + + info, exists := namespacesMap[namespace] + if !exists { + info = namespaceInfo{ + privileged: false, + } + } + + // If component is privileged, mark namespace as privileged + if component.Install.Privileged { + info.privileged = true + } + + namespacesMap[namespace] = info + } + + // Create or update all namespaces + for nsName, info := range namespacesMap { + namespace := &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: nsName, + Labels: make(map[string]string), + Annotations: map[string]string{ + "helm.sh/resource-policy": "keep", + }, + }, + } + + // Add system label only for non-tenant namespaces + if !strings.HasPrefix(nsName, "tenant-") { + namespace.Labels["cozystack.io/system"] = "true" + } + + // Add privileged label if needed + if info.privileged { + namespace.Labels["pod-security.kubernetes.io/enforce"] = "privileged" + } + + if err := r.createOrUpdateNamespace(ctx, namespace); err != nil { + logger.Error(err, "failed to reconcile namespace", "name", nsName, "privileged", info.privileged) + return fmt.Errorf("failed to reconcile namespace %s: %w", nsName, err) + } + logger.Info("reconciled namespace", "name", nsName, "privileged", info.privileged) + } + + return nil +} + +// createOrUpdateNamespace creates or updates a namespace +func (r *PackageReconciler) createOrUpdateNamespace(ctx context.Context, namespace *corev1.Namespace) error { + existing := &corev1.Namespace{} + key := types.NamespacedName{Name: namespace.Name} + + err := r.Get(ctx, key, existing) + if apierrors.IsNotFound(err) { + return r.Create(ctx, namespace) + } else if err != nil { + return err + } + + // Preserve resource version + namespace.SetResourceVersion(existing.GetResourceVersion()) + + // Merge labels + labels := namespace.GetLabels() + if labels == nil { + labels = make(map[string]string) + } + for k, v := range existing.GetLabels() { + if _, ok := labels[k]; !ok { + labels[k] = v + } + } + namespace.SetLabels(labels) + + // Merge annotations + annotations := namespace.GetAnnotations() + if annotations == nil { + annotations = make(map[string]string) + } + for k, v := range existing.GetAnnotations() { + if _, ok := annotations[k]; !ok { + annotations[k] = v + } + } + namespace.SetAnnotations(annotations) + + return r.Update(ctx, namespace) +} + +// cleanupOrphanedHelmReleases removes HelmReleases that are no longer needed +func (r *PackageReconciler) cleanupOrphanedHelmReleases(ctx context.Context, pkg *cozyv1alpha1.Package, variant *cozyv1alpha1.Variant) error { + logger := log.FromContext(ctx) + + // Build map of desired HelmRelease names (from components with Install) + desiredReleases := make(map[types.NamespacedName]bool) + for _, component := range variant.Components { + if component.Install == nil { + continue + } + + // Check if component is disabled via Package spec + if pkgComponent, ok := pkg.Spec.Components[component.Name]; ok { + if pkgComponent.Enabled != nil && !*pkgComponent.Enabled { + continue + } + } + + namespace := component.Install.Namespace + if namespace == "" { + namespace = "cozy-system" + } + + releaseName := component.Install.ReleaseName + if releaseName == "" { + releaseName = component.Name + } + + desiredReleases[types.NamespacedName{ + Name: releaseName, + Namespace: namespace, + }] = true + } + + // Find all HelmReleases owned by this Package + hrList := &helmv2.HelmReleaseList{} + if err := r.List(ctx, hrList, client.MatchingLabels{ + "cozystack.io/package": pkg.Name, + }); err != nil { + return err + } + + // Delete HelmReleases that are not in desired list + for _, hr := range hrList.Items { + key := types.NamespacedName{ + Name: hr.Name, + Namespace: hr.Namespace, + } + if !desiredReleases[key] { + logger.Info("deleting orphaned HelmRelease", "name", hr.Name, "namespace", hr.Namespace, "package", pkg.Name) + if err := r.Delete(ctx, &hr); err != nil && !apierrors.IsNotFound(err) { + logger.Error(err, "failed to delete orphaned HelmRelease", "name", hr.Name, "namespace", hr.Namespace) + } + } + } + + return nil +} + +// triggerDependentPackages triggers reconcile for all Packages that depend on the given Package +func (r *PackageReconciler) triggerDependentPackages(ctx context.Context, packageName string) error { + logger := log.FromContext(ctx) + + // Get all Packages + packageList := &cozyv1alpha1.PackageList{} + if err := r.List(ctx, packageList); err != nil { + return fmt.Errorf("failed to list Packages: %w", err) + } + + // For each Package, check if it depends on the given Package + for _, pkg := range packageList.Items { + // Skip the Package itself + if pkg.Name == packageName { + continue + } + + // Get PackageSource + packageSource := &cozyv1alpha1.PackageSource{} + if err := r.Get(ctx, types.NamespacedName{Name: pkg.Name}, packageSource); err != nil { + if apierrors.IsNotFound(err) { + continue + } + logger.V(1).Error(err, "failed to get PackageSource", "package", pkg.Name) + continue + } + + // Determine variant + variantName := pkg.Spec.Variant + if variantName == "" { + variantName = "default" + } + + // Find variant + var variant *cozyv1alpha1.Variant + for i := range packageSource.Spec.Variants { + if packageSource.Spec.Variants[i].Name == variantName { + variant = &packageSource.Spec.Variants[i] + break + } + } + + if variant == nil { + continue + } + + // Check if this Package depends on the given Package + dependsOn := false + for _, dep := range variant.DependsOn { + // Check if dependency is in IgnoreDependencies + ignore := false + for _, ignoreDep := range pkg.Spec.IgnoreDependencies { + if ignoreDep == dep { + ignore = true + break + } + } + if ignore { + continue + } + + if dep == packageName { + dependsOn = true + break + } + } + + if dependsOn { + logger.V(1).Info("triggering reconcile for dependent Package", "package", pkg.Name, "dependency", packageName) + // Trigger reconcile by updating the Package (add annotation or just requeue) + // We can't directly requeue from here, but we can update the Package to trigger reconcile + // Actually, we can use the client to trigger an update, but that might cause infinite loop + // Better approach: use event handler or just log and let the watch handle it + // For now, we'll just log - the watch on PackageSource should handle it + // But we need a way to trigger reconcile... + // Let's add an annotation to trigger reconcile + if pkg.Annotations == nil { + pkg.Annotations = make(map[string]string) + } + pkg.Annotations["cozystack.io/trigger-reconcile"] = fmt.Sprintf("%d", metav1.Now().Unix()) + if err := r.Update(ctx, &pkg); err != nil { + logger.V(1).Error(err, "failed to trigger reconcile for dependent Package", "package", pkg.Name) + } + } + } + + return nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *PackageReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + Named("cozystack-package"). + For(&cozyv1alpha1.Package{}). + Watches( + &cozyv1alpha1.PackageSource{}, + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { + ps, ok := obj.(*cozyv1alpha1.PackageSource) + if !ok { + return nil + } + // Find Package with the same name as PackageSource + // PackageSource and Package share the same name + pkg := &cozyv1alpha1.Package{} + if err := mgr.GetClient().Get(ctx, types.NamespacedName{Name: ps.Name}, pkg); err != nil { + // Package not found, that's ok - it might not exist yet + return nil + } + // Trigger reconcile for the corresponding Package + return []reconcile.Request{{ + NamespacedName: types.NamespacedName{ + Name: pkg.Name, + }, + }} + }), + ). + Watches( + &cozyv1alpha1.Package{}, + handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, obj client.Object) []reconcile.Request { + updatedPkg, ok := obj.(*cozyv1alpha1.Package) + if !ok { + return nil + } + // Find all Packages that depend on this Package + packageList := &cozyv1alpha1.PackageList{} + if err := mgr.GetClient().List(ctx, packageList); err != nil { + return nil + } + var requests []reconcile.Request + for _, pkg := range packageList.Items { + if pkg.Name == updatedPkg.Name { + continue // Skip the Package itself + } + // Get PackageSource to check dependencies + packageSource := &cozyv1alpha1.PackageSource{} + if err := mgr.GetClient().Get(ctx, types.NamespacedName{Name: pkg.Name}, packageSource); err != nil { + continue + } + // Determine variant + variantName := pkg.Spec.Variant + if variantName == "" { + variantName = "default" + } + // Find variant + for _, variant := range packageSource.Spec.Variants { + if variant.Name == variantName { + // Check if this variant depends on updatedPkg + for _, dep := range variant.DependsOn { + // Check if dependency is in IgnoreDependencies + ignore := false + for _, ignoreDep := range pkg.Spec.IgnoreDependencies { + if ignoreDep == dep { + ignore = true + break + } + } + if ignore { + continue + } + if dep == updatedPkg.Name { + requests = append(requests, reconcile.Request{ + NamespacedName: types.NamespacedName{ + Name: pkg.Name, + }, + }) + break + } + } + break + } + } + } + return requests + }), + ). + Complete(r) +} diff --git a/packages/core/installer/example/platform.yaml b/packages/core/installer/example/platform.yaml index da15885d..689e5f00 100644 --- a/packages/core/installer/example/platform.yaml +++ b/packages/core/installer/example/platform.yaml @@ -2,19 +2,12 @@ apiVersion: cozystack.io/v1alpha1 kind: Package metadata: - name: cozystack.platform + name: cozystack.cozystack-platform spec: - variant: paas-full + variant: isp-full components: platform: values: - bundles: - iaas: - enabled: true - paas: - enabled: true - naas: - enabled: true publishing: host: "dev5.infra.aenix.org" apiServerEndpoint: "https://api.dev5.infra.aenix.org" diff --git a/packages/core/installer/templates/cozystack-operator.yaml b/packages/core/installer/templates/cozystack-operator.yaml index 4372bd4c..25deb21b 100644 --- a/packages/core/installer/templates/cozystack-operator.yaml +++ b/packages/core/installer/templates/cozystack-operator.yaml @@ -59,7 +59,7 @@ spec: {{- if .Values.cozystackOperator.disableTelemetry }} - --disable-telemetry {{- end }} - - --platform-source-name=cozystack-packages + - --platform-source-name=cozystack-platform - --platform-source={{ .Values.cozystackOperator.platformSource }} env: - name: KUBERNETES_SERVICE_HOST @@ -93,21 +93,25 @@ spec: releaseName: cozystack-platform name: cozystack-platform path: core/platform - - name: paas-full + valuesFiles: + - values.yaml + - name: isp-full components: - install: namespace: cozy-system releaseName: cozystack-platform name: cozystack-platform path: core/platform - #valuesFiles: - #- paas-full.yaml - - name: paas-hosted + valuesFiles: + - values.yaml + - values-isp-full.yaml + - name: isp-hosted components: - install: namespace: cozy-system releaseName: cozystack-platform name: cozystack-platform path: core/platform - #valuesFiles: - #- paas-hosted.yaml + valuesFiles: + - values.yaml + - values-isp-hosted.yaml diff --git a/packages/core/installer/values.yaml b/packages/core/installer/values.yaml index 13a3e1b4..5287ff67 100644 --- a/packages/core/installer/values.yaml +++ b/packages/core/installer/values.yaml @@ -1,6 +1,6 @@ cozystack: image: ghcr.io/cozystack/cozystack/installer:v0.38.2@sha256:9ff92b655de6f9bea3cba4cd42dcffabd9aace6966dcfb1cc02dda2420ea4a15 cozystackOperator: - image: ghcr.io/cozystack/cozystack/cozystack-operator:latest@sha256:63ff14a08eb20c16100e063b7387655c9f7ff239c50bc987b207e6e768a6725d - platformSource: 'oci://ghcr.io/cozystack/cozystack/platform-packages@sha256:bc1039d7d7dd4d204e03c35c38c1a68b34e38ca1b8f980258efeac8448ae5c77' + image: ghcr.io/cozystack/cozystack/cozystack-operator:latest@sha256:f7f6e0fd9e896b7bfa642d0bfa4378bc14e646bc5c2e86e2e09a82770ef33181 + platformSource: 'oci://ghcr.io/cozystack/cozystack/platform-packages@sha256:0576491291b33936cdf770a5c5b5692add97339c1505fc67a92df9d69dfbfdf6' cozystackVersion: latest diff --git a/packages/core/platform/Makefile b/packages/core/platform/Makefile index 5c0b4786..41b41eb7 100644 --- a/packages/core/platform/Makefile +++ b/packages/core/platform/Makefile @@ -1,34 +1,30 @@ -NAME=platform +NAME=cozystack-platform NAMESPACE=cozy-system include ../../../scripts/common-envs.mk +include ../../../scripts/package.mk -show: - cozypkg show -n $(NAMESPACE) $(NAME) --plain +image: image-migrations -apply: - cozypkg show -n $(NAMESPACE) $(NAME) --plain | kubectl apply -f- - kubectl delete helmreleases.helm.toolkit.fluxcd.io -l cozystack.io/marked-for-deletion=true -A - -reconcile: apply - -namespaces-show: - cozypkg show -n $(NAMESPACE) $(NAME) --plain -s templates/namespaces.yaml - -namespaces-apply: - cozypkg show -n $(NAMESPACE) $(NAME) --plain -s templates/namespaces.yaml | kubectl apply -f- - -diff: - cozypkg show -n $(NAMESPACE) $(NAME) --plain | kubectl diff -f- - -image: image-assets -image-assets: - docker buildx build -f images/cozystack-assets/Dockerfile ../../.. \ - --tag $(REGISTRY)/cozystack-assets:$(call settag,$(TAG)) \ - --cache-from type=registry,ref=$(REGISTRY)/cozystack-assets:latest \ +image-migrations: + docker buildx build images/migrations \ + --tag $(REGISTRY)/platform-migrations:$(call settag,$(TAG)) \ + --cache-from type=registry,ref=$(REGISTRY)/platform-migrations:latest \ --cache-to type=inline \ - --metadata-file images/cozystack-assets.json \ + --metadata-file images/migrations.json \ $(BUILDX_ARGS) - IMAGE="$(REGISTRY)/cozystack-assets:$(call settag,$(TAG))@$$(yq e '."containerimage.digest"' images/cozystack-assets.json -o json -r)" \ - yq -i '.assets.image = strenv(IMAGE)' values.yaml - rm -f images/cozystack-assets.json + IMAGE="$(REGISTRY)/platform-migrations:$(call settag,$(TAG))@$$(yq e '."containerimage.digest"' images/migrations.json -o json -r)" \ + yq -i '.migrations.image = strenv(IMAGE)' values.yaml + rm -f images/migrations.json + +generate: + @echo "Generating target version from migrations..." + @LAST_MIGRATION=$$(ls -1 images/migrations/migrations/ 2>/dev/null | grep -E '^[0-9]+$$' | sort -n | tail -1); \ + if [ -z "$$LAST_MIGRATION" ]; then \ + echo "Error: No migration files found" >&2; \ + exit 1; \ + fi; \ + TARGET_VERSION=$$((LAST_MIGRATION + 1)); \ + echo "Last migration: $$LAST_MIGRATION, Target version: $$TARGET_VERSION"; \ + yq -i '.migrations.targetVersion = $$TARGET_VERSION' values.yaml; \ + echo "Updated targetVersion to $$TARGET_VERSION in values.yaml" diff --git a/packages/core/platform/images/migrations/Dockerfile b/packages/core/platform/images/migrations/Dockerfile new file mode 100644 index 00000000..9acda394 --- /dev/null +++ b/packages/core/platform/images/migrations/Dockerfile @@ -0,0 +1,13 @@ +FROM alpine:3.22 + +RUN wget -O- https://github.com/cozystack/cozypkg/raw/refs/heads/main/hack/install.sh | sh -s -- -v 1.4.0 + +RUN apk add --no-cache kubectl helm coreutils git jq ca-certificates bash curl + +COPY migrations /migrations +COPY run-migrations.sh /usr/bin/run-migrations.sh + +WORKDIR /migrations + +ENTRYPOINT ["/usr/bin/run-migrations.sh"] + diff --git a/packages/core/platform/images/migrations/migrations/1 b/packages/core/platform/images/migrations/migrations/1 new file mode 100755 index 00000000..d2be8ce2 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/1 @@ -0,0 +1,25 @@ +#!/bin/sh +# Migration 1 --> 2 + +# Fix mariadb-operator secrets +if kubectl get -n cozy-mariadb-operator secret/mariadb-operator-webhook-cert; then + kubectl annotate -n cozy-mariadb-operator secret/mariadb-operator-webhook-cert meta.helm.sh/release-namespace=cozy-mariadb-operator meta.helm.sh/release-name=mariadb-operator + kubectl label -n cozy-mariadb-operator secret/mariadb-operator-webhook-cert app.kubernetes.io/managed-by=Helm +fi + +# Gratefully remove fluxcd release and keep resources +if kubectl get hr -n cozy-fluxcd cozy-fluxcd 2>/dev/null; then + kubectl patch hr -n cozy-fluxcd cozy-fluxcd -p '{"spec": {"suspend": true}, "metadata": {"finalizers": null}}' --type=merge + kubectl delete hr -n cozy-fluxcd cozy-fluxcd +fi +kubectl delete secret -n cozy-fluxcd -l name=fluxcd + +# Fix kubeovn crds +kubeovn_crds=$(kubectl get crd -o name | grep '\.kubeovn\.io$') +if [ -n "$kubeovn_crds" ]; then + kubectl annotate $kubeovn_crds meta.helm.sh/release-namespace=cozy-kubeovn meta.helm.sh/release-name=kubeovn + kubectl label $kubeovn_crds app.kubernetes.io/managed-by=Helm +fi + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=2 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/10 b/packages/core/platform/images/migrations/migrations/10 new file mode 100755 index 00000000..993e592c --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/10 @@ -0,0 +1,15 @@ +#!/bin/sh +# Migration 10 --> 11 + +# Force reconcile hr keycloak-configure +if kubectl get helmrelease keycloak-configure -n cozy-keycloak; then + kubectl delete po -l app=source-controller -n cozy-fluxcd + timestamp=$(date --rfc-3339=ns) + kubectl annotate helmrelease keycloak-configure -n cozy-keycloak \ + reconcile.fluxcd.io/forceAt="$timestamp" \ + reconcile.fluxcd.io/requestedAt="$timestamp" \ + --overwrite +fi + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=11 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/11 b/packages/core/platform/images/migrations/migrations/11 new file mode 100755 index 00000000..b16c7b4b --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/11 @@ -0,0 +1,21 @@ +#!/bin/sh +# Migration 11 --> 12 + +# Recreate daemonset kube-rbac-proxy + +if kubectl get daemonset kube-rbac-proxy -n cozy-monitoring; then + kubectl delete daemonset kube-rbac-proxy --cascade=orphan -n cozy-monitoring +fi + +if kubectl get helmrelease monitoring-agents -n cozy-monitoring; then + timestamp=$(date --rfc-3339=ns) + kubectl annotate helmrelease monitoring-agents -n cozy-monitoring \ + reconcile.fluxcd.io/forceAt="$timestamp" \ + reconcile.fluxcd.io/requestedAt="$timestamp" \ + --overwrite +fi + +kubectl delete pods -l app.kubernetes.io/component=kube-rbac-proxy -n cozy-monitoring + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=12 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/12 b/packages/core/platform/images/migrations/migrations/12 new file mode 100755 index 00000000..fcb951bc --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/12 @@ -0,0 +1,35 @@ +#!/bin/sh +# Migration 12 --> 13 + +# Copy configuration from ingress to cozystack configmap +if kubectl get hr -n tenant-root tenant-root > /dev/null; then + expose_services=$( + kubectl get hr -n tenant-root ingress -o go-template='{{ with .spec }}{{ with .values }}{{ if .dashboard }}dashboard,{{ end }}{{ if .cdiUploadProxy }}cdi-uploadproxy,{{ end }}{{ if .virtExportProxy }}vm-exportproxy,{{ end }}{{ end }}{{ end }}' + ) + expose_services=$(echo "$expose_services" | awk '{sub(/,$/,""); print}') + + expose_external_ips=$( + kubectl get hr -n tenant-root ingress -o go-template='{{ with .spec }}{{ with .values }}{{ if .externalIPs }}{{ range .externalIPs }}{{ . }},{{ end }}{{ end }}{{ end }}{{ end }}' + ) + expose_external_ips=$(echo "$expose_external_ips" | awk '{sub(/,$/,""); print}') + + existing_expose_external_ips=$(kubectl get cm -n cozy-system cozystack -o go-template='{{ index .data "expose-external-ips" }}') + existing_expose_services=$(kubectl get cm -n cozy-system cozystack -o go-template='{{ index .data "expose-services" }}') + + if [ "$existing_expose_external_ips" == "" ]; then + kubectl patch cm -n cozy-system cozystack --type merge -p="{\"data\":{\"expose-external-ips\":\"$expose_external_ips\"}}" + fi + + if [ "$existing_expose_services" == "" ]; then + kubectl patch cm -n cozy-system cozystack --type merge -p="{\"data\":{\"expose-services\":\"$expose_services\"}}" + fi + + kubectl patch hr -n tenant-root ingress --type json -p='[{"op": "remove", "path": "/spec/values/dashboard"}]' || true + kubectl patch hr -n tenant-root ingress --type json -p='[{"op": "remove", "path": "/spec/values/cdiUploadProxy"}]' || true + kubectl patch hr -n tenant-root ingress --type json -p='[{"op": "remove", "path": "/spec/values/virtExportProxy"}]' || true + kubectl patch hr -n tenant-root ingress --type json -p='[{"op": "remove", "path": "/spec/values/externalIPs"}]' || true + kubectl patch hr -n tenant-root ingress --type merge -p='{"spec":{"chart":{"spec":{"version":"1.6.0"}}}}' +fi + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=13 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/13 b/packages/core/platform/images/migrations/migrations/13 new file mode 100755 index 00000000..203aa29e --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/13 @@ -0,0 +1,10 @@ +#!/bin/sh +# Migration 13 --> 14 + +# Upgrade tenants.apps to new chart version +kubectl get tenants.apps.cozystack.io -A --no-headers --output=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name' | while read NAMESPACE NAME; do + kubectl patch tenants.apps.cozystack.io -n "$NAMESPACE" "$NAME" --type merge -p '{"appVersion":"1.10.0"}' +done + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=14 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/14 b/packages/core/platform/images/migrations/migrations/14 new file mode 100755 index 00000000..95735bb8 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/14 @@ -0,0 +1,10 @@ +#!/bin/sh +# Migration 14 --> 15 + +# Delete the `capi-providers` HelmRelease in the `cozy-cluster-api` namespace if present +if kubectl get hr -n cozy-cluster-api capi-providers >/dev/null 2>&1; then + kubectl delete hr -n cozy-cluster-api capi-providers +fi + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=15 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/15 b/packages/core/platform/images/migrations/migrations/15 new file mode 100755 index 00000000..e0d78cfb --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/15 @@ -0,0 +1,28 @@ +#!/bin/sh +# Migration 15 --> 16 + +if kubectl get validatingwebhookconfigurations.admissionregistration.k8s.io kamaji-validating-webhook-configuration; then + kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io kamaji-validating-webhook-configuration +fi +kubectl get kamajicontrolplane -A -o custom-columns=NAMESPACE:.metadata.namespace,NAME:.metadata.name,VERSION:.spec.version,VERSION:.status.version --no-headers | + while read namespace name version status; do + if [ "$status" = "v1.32.4" ]; then + continue + fi + (set -x; kubectl patch kamajicontrolplane "$name" -n "$namespace" --type merge -p '{"spec":{"version":"1.32.4"}}') + (set -x; kubectl patch kamajicontrolplane "$name" -n "$namespace" --type merge -p '{"status":{"version":"v1.32.4"}}' --subresource status) + (set -x; kubectl patch tcp "$name" -n "$namespace" --type merge -p '{"spec":{"kubernetes":{"version":"1.32.4"}}}') + (set -x; kubectl patch tcp "$name" -n "$namespace" --type merge -p '{"status":{"kubernetesResources":{"version":{"version":"v1.32.4"}}}} ' --subresource status) + done + +# Upgrade kubernetes.apps to new chart version +kubectl get kuberneteses.apps.cozystack.io -A --no-headers --output=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name' | while read NAMESPACE NAME; do + kubectl patch kuberneteses.apps.cozystack.io -n "$NAMESPACE" "$NAME" --type merge -p '{"appVersion":"0.24.0"}' +done + +if kubectl get helmrelease kamaji -n cozy-kamaji; then + cozypkg reconcile kamaji -n cozy-kamaji --force +fi + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=16 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/16 b/packages/core/platform/images/migrations/migrations/16 new file mode 100755 index 00000000..781e1a26 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/16 @@ -0,0 +1,95 @@ +#!/bin/sh +# Migration 16 --> 17 +# +# fix-nested-resources-map.sh – prints kubectl patch commands. +# * Replaces each resources section with {cpu,memory} merged from requests + limits +# * Adds/Replaces .appVersion with "*" + +set -e + +CRDS=' +clickhouses.apps.cozystack.io +etcds.apps.cozystack.io +ferretdb.apps.cozystack.io +httpcaches.apps.cozystack.io +kafkas.apps.cozystack.io +kuberneteses.apps.cozystack.io +monitorings.apps.cozystack.io +mysqls.apps.cozystack.io +natses.apps.cozystack.io +postgreses.apps.cozystack.io +rabbitmqs.apps.cozystack.io +redises.apps.cozystack.io +seaweedfses.apps.cozystack.io +tcpbalancers.apps.cozystack.io +virtualmachines.apps.cozystack.io +vminstances.apps.cozystack.io +vpns.apps.cozystack.io +' + +for KIND in $CRDS; do + kubectl get "$KIND" -A -o json | jq -r --arg kind "$KIND" ' + .items[] + | . as $obj + | ($obj.metadata.namespace // "") as $ns # namespace (empty string for cluster-scoped) + | $obj.metadata.name as $name # object name + + # ------------------------------------------------------------------------- + # Build an array with every JSON path ending with "resources" + # ------------------------------------------------------------------------- + | [ $obj + | paths + | select(.[-1] == "resources") + ] as $rpaths + + # ------------------------------------------------------------------------- + # Iterate through each resources path + # ------------------------------------------------------------------------- + | foreach $rpaths[] as $rpath (null; + # Current resources object + ($obj | getpath($rpath)) as $res + + # requests + limits merged; requests override limits on key collision + | ($res.requests? // {}) as $req + | ($res.limits? // {}) as $lim + | ($req + $lim) as $flat + + # Keep cpu & memory only + | ($flat + | with_entries(select(.key|test("^(cpu|memory)$"))) + ) as $value + | select(($value|length) > 0) # skip if nothing to patch + + # --------------------------------------------------------------------- + # RFC6901-encoded JSON Pointer to the resources section + # --------------------------------------------------------------------- + | ("/" + ($rpath + | map( + tostring + | gsub("~";"~0") + | gsub("/";"~1") + ) + | join("/") + ) + ) as $pointer + + # --------------------------------------------------------------------- + # Compose JSON Patch: 1) add/replace appVersion, 2) replace resources + # --------------------------------------------------------------------- + | [ + { op:"add", path:"/appVersion", value:"*" }, + { op:"replace", path:$pointer, value:$value } + ] as $patch + + # --------------------------------------------------------------------- + # Print one ready-to-run kubectl patch command + # --------------------------------------------------------------------- + | "kubectl " + + (if $ns != "" then "-n \($ns) " else "" end) + + "patch \($kind) \($name) --type=json -p '\''\($patch|tojson)'\''" + ) + ' | sh -ex +done + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=17 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/17 b/packages/core/platform/images/migrations/migrations/17 new file mode 100755 index 00000000..9749c0e2 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/17 @@ -0,0 +1,10 @@ +#!/bin/sh +# Migration 17 --> 18 + +# Upgrade kubernetes.apps to new chart version +kubectl get kuberneteses.apps.cozystack.io -A --no-headers --output=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name' | while read NAMESPACE NAME; do + kubectl patch kuberneteses.apps.cozystack.io -n "$NAMESPACE" "$NAME" --type merge -p '{"appVersion":"0.26.1"}' +done + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=18 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/18 b/packages/core/platform/images/migrations/migrations/18 new file mode 100755 index 00000000..4a166fab --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/18 @@ -0,0 +1,18 @@ +#!/bin/sh +# Migration 18 --> 19 + +# Upgrade tenants.apps to new chart version +kubectl get tenants.apps.cozystack.io -A --no-headers --output=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name' | while read NAMESPACE NAME; do + kubectl patch tenants.apps.cozystack.io -n "$NAMESPACE" "$NAME" --type merge -p '{"appVersion":"1.13.0"}' +done + +# Upgrade virtualmachines.apps to new chart version +kubectl get virtualmachines.apps.cozystack.io -A --no-headers --output=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name' | while read NAMESPACE NAME; do + kubectl patch virtualmachines.apps.cozystack.io -n "$NAMESPACE" "$NAME" --type merge -p '{"appVersion":"0.14.0"}' +done +kubectl get vminstances.apps.cozystack.io -A --no-headers --output=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name' | while read NAMESPACE NAME; do + kubectl patch vminstances.apps.cozystack.io -n "$NAMESPACE" "$NAME" --type merge -p '{"appVersion":"0.12.0"}' +done + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=19 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/19 b/packages/core/platform/images/migrations/migrations/19 new file mode 100755 index 00000000..446e10ad --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/19 @@ -0,0 +1,53 @@ +#!/bin/sh +# Migration 19 --> 20 + +set -euo pipefail + +kubectl get helmreleases.helm.toolkit.fluxcd.io -A \ + --field-selector=metadata.name=seaweedfs -o json | jq -r ' + .items[] as $o + | ($o.metadata.namespace // "") as $ns + | $o.metadata.name as $name + | $o.spec as $s + | $o.spec.values as $v + + | ( + ($s.chart.spec.version? // "") != "0.7.0" + or ($v.size? != null) + or ($v.storageClass? != null) + or ($v.replicas? != null) + or ($v.zones? != null) + ) as $needsChange + | select($needsChange) + + # JSON Patch + | [ + (if $s.chart.spec.version? then + {op:"replace", path:"/spec/chart/spec/version", value:"0.7.0"} + else + {op:"add", path:"/spec/chart/spec/version", value:"0.7.0"} + end), + + (if ($v|type) != "object" then {op:"add", path:"/spec/values", value:{}} else empty end), + + (if ($v.volume?|type) != "object" then {op:"add", path:"/spec/values/volume", value:{}} else empty end), + + (if $v.size? then {op:"add", path:"/spec/values/volume/size", value:$v.size} else empty end), + (if $v.storageClass? then {op:"add", path:"/spec/values/volume/storageClass", value:$v.storageClass} else empty end), + (if $v.replicas? then {op:"add", path:"/spec/values/volume/replicas", value:$v.replicas} else empty end), + (if $v.zones? then {op:"add", path:"/spec/values/volume/zones", value:$v.zones} else empty end), + + (if $v.size? then {op:"remove", path:"/spec/values/size"} else empty end), + (if $v.storageClass? then {op:"remove", path:"/spec/values/storageClass"} else empty end), + (if $v.replicas? then {op:"remove", path:"/spec/values/replicas"} else empty end), + (if $v.zones? then {op:"remove", path:"/spec/values/zones"} else empty end) + ] as $patch + + | "kubectl " + + (if $ns != "" then "-n \($ns) " else "" end) + + "patch helmreleases.helm.toolkit.fluxcd.io \($name) --type=json -p '\''\($patch|tojson)'\''" +' | sh -ex + +# Stamp version +kubectl create configmap -n cozy-system cozystack-version \ + --from-literal=version=20 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/2 b/packages/core/platform/images/migrations/migrations/2 new file mode 100755 index 00000000..a3bfd118 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/2 @@ -0,0 +1,16 @@ +#!/bin/sh +# Migration 2 --> 3 + +if [ -d packages/system ]; then + kubectl apply -f packages/system/mariadb-operator/charts/mariadb-operator/crds/crds.yaml --server-side --force-conflicts +fi + +# Fix mariadb-operator crds +mariadb_crds=$(kubectl get crd -o name | grep '\.k8s\.mariadb\.com$') +if [ -n "$mariadb_crds" ]; then + kubectl annotate $mariadb_crds meta.helm.sh/release-namespace=cozy-mariadb-operator meta.helm.sh/release-name=mariadb-operator + kubectl label $mariadb_crds app.kubernetes.io/managed-by=Helm +fi + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=3 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/20 b/packages/core/platform/images/migrations/migrations/20 new file mode 100755 index 00000000..0122c054 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/20 @@ -0,0 +1,56 @@ +#!/bin/sh +# Migration 20 --> 21 + +set -euo pipefail + +kubectl -n cozy-system delete helmrelease cozystack-api \ + || kubectl -n cozy-system delete deployment cozystack-api --ignore-not-found # fallback to help migration progress if it failed first time +while [ $( kubectl -n cozy-system get po -l app=cozystack-api --no-headers | wc -l ) != 0 ] ; +do + echo "Waiting for Cozystack API pods to be deleted"; + sleep 1 +done + +kubectl -n cozy-system delete helmrelease cozystack-controller \ + || kubectl -n cozy-system delete deployment cozystack-controller --ignore-not-found # same fallback +kubectl delete customresourcedefinitions.apiextensions.k8s.io cozystackresourcedefinitions.cozystack.io --ignore-not-found +while [ $( kubectl -n cozy-system get po -l app=cozystack-controller --no-headers | wc -l ) != 0 ] ; +do + echo "Waiting for Cozystack controller pods to be deleted"; + sleep 1 +done + +kubectl delete helmrelease -n cozy-dashboard dashboard --ignore-not-found +sleep 5 +if [ -d "packages/system" ]; then + cozypkg -n cozy-system -C packages/system/cozystack-resource-definition-crd apply cozystack-resource-definition-crd --plain + cozypkg -n cozy-system -C packages/system/cozystack-resource-definitions apply cozystack-resource-definitions --plain + cozypkg -n cozy-system -C packages/system/cozystack-api apply cozystack-api --plain + cozypkg -n cozy-system -C packages/system/cozystack-controller/ apply cozystack-api --plain --take-ownership + cozypkg -n cozy-system -C packages/system/lineage-controller-webhook/ apply cozystack-api --plain --take-ownership +fi + +sleep 5 +echo "Running lineage-webhook test" +kubectl delete ns cozy-lineage-webhook-test --ignore-not-found && kubectl create ns cozy-lineage-webhook-test +cleanup_test_ns() { + kubectl delete ns cozy-lineage-webhook-test --ignore-not-found +} +trap cleanup_test_ns ERR +timeout 60 sh -c 'until kubectl -n cozy-lineage-webhook-test create service clusterip lineage-webhook-test --clusterip="None" --dry-run=server; do sleep 1; done' +cleanup_test_ns + +timestamp=$(date --rfc-3339=ns || date) +kubectl get namespace -o custom-columns=NAME:.metadata.name --no-headers | + grep '^tenant-' | + while read namespace ; do + (set -x; \ + kubectl annotate \ + pods,services,pvc,secrets,ingresses.networking.k8s.io,workloadmonitors.cozystack.io \ + -n "$namespace" --all \ + migration.cozystack.io="$timestamp" --overwrite || true) + done + +# Stamp version +kubectl create configmap -n cozy-system cozystack-version \ + --from-literal=version=21 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/21 b/packages/core/platform/images/migrations/migrations/21 new file mode 100755 index 00000000..c065d23c --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/21 @@ -0,0 +1,21 @@ +#!/bin/sh +# Migration 21 --> 22 + +set -euo pipefail + +# Delete old cozystack deployment +kubectl -n cozy-system delete deployment cozystack --ignore-not-found +while [ $( kubectl -n cozy-system get po -l app=cozystack --no-headers 2>/dev/null | wc -l ) != 0 ] ; +do + echo "Waiting for old cozystack deployment pods to be deleted"; + sleep 1 +done + +kubectl delete hr -n cozy-system cozystack-resource-definitions --ignore-not-found +kubectl delete hr -n cozy-system cozystack-resource-definition-crd --ignore-not-found +kubectl delete crd cozystackresourcedefinitions.cozycloud.io --ignore-not-found +kubectl delete hr -n cozy-fluxcd fluxcd --ignore-not-found + +# Stamp version +kubectl create configmap -n cozy-system cozystack-version \ + --from-literal=version=22 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/22 b/packages/core/platform/images/migrations/migrations/22 new file mode 100755 index 00000000..97beb6f0 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/22 @@ -0,0 +1,161 @@ +#!/bin/sh +# Migration 22 --> 23 + +set -euo pipefail + +echo "Migrating HelmReleases: adding application labels for tenant-* namespaces" + +# Function to determine application type from HelmRelease name +determine_app_type() { + local name="$1" + local app_kind="" + local app_name="" + + # Try to match by prefix (longest match first) + case "$name" in + virtual-machine-*) + app_kind="VirtualMachine" + app_name="${name#virtual-machine-}" + ;; + vm-instance-*) + app_kind="VMInstance" + app_name="${name#vm-instance-}" + ;; + vm-disk-*) + app_kind="VMDisk" + app_name="${name#vm-disk-}" + ;; + virtualprivatecloud-*) + app_kind="VirtualPrivateCloud" + app_name="${name#virtualprivatecloud-}" + ;; + http-cache-*) + app_kind="HTTPCache" + app_name="${name#http-cache-}" + ;; + tcp-balancer-*) + app_kind="TCPBalancer" + app_name="${name#tcp-balancer-}" + ;; + clickhouse-*) + app_kind="ClickHouse" + app_name="${name#clickhouse-}" + ;; + foundationdb-*) + app_kind="FoundationDB" + app_name="${name#foundationdb-}" + ;; + ferretdb-*) + app_kind="FerretDB" + app_name="${name#ferretdb-}" + ;; + rabbitmq-*) + app_kind="RabbitMQ" + app_name="${name#rabbitmq-}" + ;; + kubernetes-*) + app_kind="Kubernetes" + app_name="${name#kubernetes-}" + ;; + bucket-*) + app_kind="Bucket" + app_name="${name#bucket-}" + ;; + kafka-*) + app_kind="Kafka" + app_name="${name#kafka-}" + ;; + mysql-*) + app_kind="MySQL" + app_name="${name#mysql-}" + ;; + nats-*) + app_kind="NATS" + app_name="${name#nats-}" + ;; + postgres-*) + app_kind="PostgreSQL" + app_name="${name#postgres-}" + ;; + redis-*) + app_kind="Redis" + app_name="${name#redis-}" + ;; + tenant-*) + app_kind="Tenant" + app_name="${name#tenant-}" + ;; + vpn-*) + app_kind="VPN" + app_name="${name#vpn-}" + ;; + bootbox) + app_kind="BootBox" + app_name="bootbox" + ;; + etcd) + app_kind="Etcd" + app_name="etcd" + ;; + info) + app_kind="Info" + app_name="info" + ;; + ingress|ingress-*) + app_kind="Ingress" + if [ "$name" = "ingress" ]; then + app_name="ingress" + else + app_name="${name#ingress-}" + fi + ;; + monitoring) + app_kind="Monitoring" + app_name="monitoring" + ;; + seaweedfs) + app_kind="SeaweedFS" + app_name="seaweedfs" + ;; + *) + # Unknown type + return 1 + ;; + esac + + echo "$app_kind|$app_name" + return 0 +} + +# Process all HelmReleases in tenant-* namespaces with cozystack.io/ui=true label +kubectl get helmreleases --all-namespaces -l cozystack.io/ui=true -o json | \ + jq -r '.items[] | select(.metadata.namespace | startswith("tenant-")) | "\(.metadata.namespace)|\(.metadata.name)"' | \ + while IFS='|' read -r namespace name; do + echo "Processing HelmRelease $namespace/$name" + + # Determine application type + app_type=$(determine_app_type "$name") + if [ $? -ne 0 ] || [ -z "$app_type" ]; then + echo "Warning: Could not determine application type for $namespace/$name, skipping" + continue + fi + + app_kind=$(echo "$app_type" | cut -d'|' -f1) + app_name=$(echo "$app_type" | cut -d'|' -f2) + app_group="apps.cozystack.io" + + # Build labels string + labels="apps.cozystack.io/application.kind=$app_kind" + labels="$labels apps.cozystack.io/application.group=$app_group" + labels="$labels apps.cozystack.io/application.name=$app_name" + + # Apply labels using kubectl label --overwrite + kubectl label helmrelease -n "$namespace" "$name" --overwrite $labels + echo "Added application labels to $namespace/$name: $labels" + done + +echo "Migration completed" + +# Stamp version +kubectl create configmap -n cozy-system cozystack-version \ + --from-literal=version=23 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/3 b/packages/core/platform/images/migrations/migrations/3 new file mode 100755 index 00000000..008d6604 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/3 @@ -0,0 +1,12 @@ +#!/bin/sh +# Migration 3 --> 4 + +# Fix kubeovn crds +kubeovn_crds=$(kubectl get crd -o name | grep '\.kubeovn\.io$') +if [ -n "$kubeovn_crds" ]; then + kubectl annotate $kubeovn_crds meta.helm.sh/release-namespace=cozy-kubeovn meta.helm.sh/release-name=kubeovn + kubectl label $kubeovn_crds app.kubernetes.io/managed-by=Helm +fi + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=4 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/4 b/packages/core/platform/images/migrations/migrations/4 new file mode 100755 index 00000000..14603dbb --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/4 @@ -0,0 +1,15 @@ +#!/bin/sh +# Migration 4 --> 5 + +# Fix tenant-kubernetes PVCs +kubectl get secret -l kamaji.clastix.io/project=kamaji,kamaji.clastix.io/component=admin-kubeconfig -A --output=go-template='{{ range .items }}{{ printf "%s %s %s %s\n" .metadata.namespace .metadata.name (index .metadata.labels "kamaji.clastix.io/name") (index .data "super-admin.conf") }}{{ end }}' | while read NAMESPACE NAME CLUSTER CONFIGB64; do + config=$(mktemp) + echo "$CONFIGB64" | base64 -d > "$config" + kubectl get pv --kubeconfig="$config" --output=go-template='{{ range .items }}{{ printf "%s\n" .metadata.name }}{{ end }}' | while read PVC; do + (set -x; kubectl label pvc --overwrite -n "$NAMESPACE" "$PVC" "cluster.x-k8s.io/cluster-name=$CLUSTER") + done + rm -f "$config" +done + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=5 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/5 b/packages/core/platform/images/migrations/migrations/5 new file mode 100755 index 00000000..d1abc6ea --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/5 @@ -0,0 +1,15 @@ +#!/bin/sh +# Migration 5 --> 6 + +# Fix tenant-kubernetes PVCs +kubectl get secret -l kamaji.clastix.io/project=kamaji,kamaji.clastix.io/component=admin-kubeconfig -A --output=go-template='{{ range .items }}{{ printf "%s %s %s %s\n" .metadata.namespace .metadata.name (index .metadata.labels "kamaji.clastix.io/name") (index .data "super-admin.conf") }}{{ end }}' | while read NAMESPACE NAME CLUSTER CONFIGB64; do + config=$(mktemp) + echo "$CONFIGB64" | base64 -d > "$config" + kubectl get pv --kubeconfig="$config" --output=go-template='{{ range .items }}{{ printf "%s\n" .metadata.name }}{{ end }}' | while read PVC; do + (set -x; kubectl label pvc --overwrite -n "$NAMESPACE" "$PVC" "cluster.x-k8s.io/cluster-name=$CLUSTER") + (set -x; kubectl label dv --overwrite -n "$NAMESPACE" "$PVC" "cluster.x-k8s.io/cluster-name=$CLUSTER") + done + rm -f "$config" +done + +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=6 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/6 b/packages/core/platform/images/migrations/migrations/6 new file mode 100755 index 00000000..b5486da9 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/6 @@ -0,0 +1,16 @@ +#!/bin/sh +# Migration 6 --> 7 + +# Delete cert-manager crds labels and annotations +kubectl patch hr -n cozy-cert-manager cert-manager -p '{"spec": {"suspend": true}}' --type=merge --field-manager=flux-client-side-apply +certmanager_crds=$(kubectl get crd -o name | grep '\.cert-manager\.io$') +if [ -n "$certmanager_crds" ]; then + kubectl annotate $certmanager_crds meta.helm.sh/release-namespace=cozy-cert-manager meta.helm.sh/release-name=cert-manager-crds + kubectl label $certmanager_crds app.kubernetes.io/managed-by=Helm +fi + +# Remove monitoring, because it is renamed to monitoring-agents +kubectl get hr -n cozy-monitoring monitoring && kubectl delete hr -n cozy-monitoring monitoring --wait=0 + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=7 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/7 b/packages/core/platform/images/migrations/migrations/7 new file mode 100755 index 00000000..2becfce4 --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/7 @@ -0,0 +1,8 @@ +#!/bin/sh +# Migration 7 --> 8 + +host=$(kubectl get hr tenant-root -n tenant-root -o yaml | grep 'host:' | awk '{print $2}') +kubectl patch configmap -n cozy-system cozystack --type merge -p "{\"data\":{\"root-host\":\"$host\"}}" + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=8 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/8 b/packages/core/platform/images/migrations/migrations/8 new file mode 100755 index 00000000..c7d7350c --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/8 @@ -0,0 +1,9 @@ +#!/bin/sh +# Migration 8 --> 9 + +if kubectl get clusterrolebinding kubeapps-admin-group; then + kubectl delete clusterrolebinding kubeapps-admin-group +fi + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=9 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/migrations/9 b/packages/core/platform/images/migrations/migrations/9 new file mode 100755 index 00000000..cf6643af --- /dev/null +++ b/packages/core/platform/images/migrations/migrations/9 @@ -0,0 +1,10 @@ +#!/bin/sh +# Migration 9 --> 10 + +# Upgrade kubernetes.apps to new chart version +kubectl get kuberneteses.apps.cozystack.io -A --no-headers --output=custom-columns='NAMESPACE:.metadata.namespace,NAME:.metadata.name' | while read NAMESPACE NAME; do + kubectl patch kuberneteses.apps.cozystack.io -n "$NAMESPACE" "$NAME" --type merge -p '{"appVersion":"0.15.1"}' +done + +# Write version to cozystack-version config +kubectl create configmap -n cozy-system cozystack-version --from-literal=version=10 --dry-run=client -o yaml | kubectl apply -f- diff --git a/packages/core/platform/images/migrations/run-migrations.sh b/packages/core/platform/images/migrations/run-migrations.sh new file mode 100755 index 00000000..8e4cc1c6 --- /dev/null +++ b/packages/core/platform/images/migrations/run-migrations.sh @@ -0,0 +1,42 @@ +#!/bin/sh +set -euo pipefail + +NAMESPACE="${NAMESPACE:-cozy-system}" +CURRENT_VERSION="${CURRENT_VERSION:-0}" +TARGET_VERSION="${TARGET_VERSION:-0}" + +echo "Starting migrations from version $CURRENT_VERSION to $TARGET_VERSION" + +# Check if ConfigMap exists +if ! kubectl get configmap -n "$NAMESPACE" cozystack-version >/dev/null 2>&1; then + echo "ConfigMap cozystack-version does not exist, creating it with version $TARGET_VERSION" + kubectl create configmap -n "$NAMESPACE" cozystack-version \ + --from-literal=version="$TARGET_VERSION" \ + --dry-run=client -o yaml | kubectl apply -f- + echo "ConfigMap created with version $TARGET_VERSION" + exit 0 +fi + +# If current version is already at target, nothing to do +if [ "$CURRENT_VERSION" -ge "$TARGET_VERSION" ]; then + echo "Current version $CURRENT_VERSION is already at or above target version $TARGET_VERSION" + exit 0 +fi + +# Run migrations sequentially from current version to target version +for i in $(seq $((CURRENT_VERSION + 1)) $TARGET_VERSION); do + if [ -f "/migrations/$i" ]; then + echo "Running migration $i" + chmod +x /migrations/$i + /migrations/$i || { + echo "Migration $i failed" + exit 1 + } + echo "Migration $i completed successfully" + else + echo "Migration $i not found, skipping" + fi +done + +echo "All migrations completed successfully" + diff --git a/packages/core/platform/psds/dependencies.dot b/packages/core/platform/psds/dependencies.dot deleted file mode 100644 index 3aa641fd..00000000 --- a/packages/core/platform/psds/dependencies.dot +++ /dev/null @@ -1,190 +0,0 @@ -digraph { - nodesep="0.5";rankdir="LR";ranksep="1.0"; - n40[fillcolor="lightblue",label="bootbox",shape="box",style="rounded,filled"]; - n45[fillcolor="lightblue",label="bootbox-application",shape="box",style="rounded,filled"]; - n64[fillcolor="lightblue",label="bucket-application",shape="box",style="rounded,filled"]; - n17[fillcolor="lightblue",label="capi-operator",shape="box",style="rounded,filled"]; - n65[fillcolor="lightblue",label="capi-providers-bootstrap",shape="box",style="rounded,filled"]; - n1[fillcolor="lightblue",label="capi-providers-core",shape="box",style="rounded,filled"]; - n58[fillcolor="lightblue",label="capi-providers-cpprovider",shape="box",style="rounded,filled"]; - n22[fillcolor="lightblue",label="capi-providers-infraprovider",shape="box",style="rounded,filled"]; - n13[fillcolor="lightblue",label="cert-manager",shape="box",style="rounded,filled"]; - n51[fillcolor="lightblue",label="clickhouse-application",shape="box",style="rounded,filled"]; - n50[fillcolor="lightblue",label="clickhouse-operator",shape="box",style="rounded,filled"]; - n52[fillcolor="lightblue",label="cozy-proxy",shape="box",style="rounded,filled"]; - n9[fillcolor="lightblue",label="cozystack",shape="box",style="rounded,filled"]; - n36[fillcolor="lightblue",label="cozystack-core",shape="box",style="rounded,filled"]; - n7[fillcolor="lightblue",label="etcd-application",shape="box",style="rounded,filled"]; - n18[fillcolor="lightblue",label="etcd-operator",shape="box",style="rounded,filled"]; - n53[fillcolor="lightblue",label="external-dns",shape="box",style="rounded,filled"]; - n46[fillcolor="lightblue",label="external-secrets-operator",shape="box",style="rounded,filled"]; - n8[fillcolor="lightblue",label="ferretdb-application",shape="box",style="rounded,filled"]; - n23[fillcolor="lightblue",label="foundationdb-application",shape="box",style="rounded,filled"]; - n14[fillcolor="lightblue",label="foundationdb-operator",shape="box",style="rounded,filled"]; - n37[fillcolor="lightblue",label="goldpinger",shape="box",style="rounded,filled"]; - n42[fillcolor="lightblue",label="gpu-operator",shape="box",style="rounded,filled"]; - n30[fillcolor="lightblue",label="grafana-operator",shape="box",style="rounded,filled"]; - n48[fillcolor="lightblue",label="hetzner-robotlb",shape="box",style="rounded,filled"]; - n2[fillcolor="lightblue",label="http-cache-application",shape="box",style="rounded,filled"]; - n66[fillcolor="lightblue",label="info-application",shape="box",style="rounded,filled"]; - n59[fillcolor="lightblue",label="ingress-application",shape="box",style="rounded,filled"]; - n4[fillcolor="lightblue",label="kafka-application",shape="box",style="rounded,filled"]; - n3[fillcolor="lightblue",label="kafka-operator",shape="box",style="rounded,filled"]; - n41[fillcolor="lightblue",label="kamaji",shape="box",style="rounded,filled"]; - n10[fillcolor="lightblue",label="keycloak",shape="box",style="rounded,filled"]; - n54[fillcolor="lightblue",label="keycloak-operator",shape="box",style="rounded,filled"]; - n15[fillcolor="lightblue",label="kubernetes-application",shape="box",style="rounded,filled"]; - n61[fillcolor="lightblue",label="kubevirt",shape="box",style="rounded,filled"]; - n31[fillcolor="lightblue",label="kubevirt-cdi",shape="box",style="rounded,filled"]; - n55[fillcolor="lightblue",label="linstor",shape="box",style="rounded,filled"]; - n56[fillcolor="lightblue",label="mariadb-operator",shape="box",style="rounded,filled"]; - n62[fillcolor="lightblue",label="metallb",shape="box",style="rounded,filled"]; - n35[fillcolor="lightblue",label="monitoring",shape="box",style="rounded,filled"]; - n24[fillcolor="lightblue",label="monitoring-agents",shape="box",style="rounded,filled"]; - n47[fillcolor="lightblue",label="monitoring-application",shape="box",style="rounded,filled"]; - n32[fillcolor="lightblue",label="multus",shape="box",style="rounded,filled"]; - n39[fillcolor="lightblue",label="mysql-application",shape="box",style="rounded,filled"]; - n20[fillcolor="lightblue",label="nats-application",shape="box",style="rounded,filled"]; - n28[fillcolor="lightblue",label="networking",shape="box",style="rounded,filled"]; - n25[fillcolor="lightblue",label="nfs-driver",shape="box",style="rounded,filled"]; - n29[fillcolor="lightblue",label="objectstorage-controller",shape="box",style="rounded,filled"]; - n11[fillcolor="lightblue",label="postgres-application",shape="box",style="rounded,filled"]; - n43[fillcolor="lightblue",label="postgres-operator",shape="box",style="rounded,filled"]; - n16[fillcolor="lightblue",label="rabbitmq-application",shape="box",style="rounded,filled"]; - n5[fillcolor="lightblue",label="rabbitmq-operator",shape="box",style="rounded,filled"]; - n26[fillcolor="lightblue",label="redis-application",shape="box",style="rounded,filled"]; - n27[fillcolor="lightblue",label="redis-operator",shape="box",style="rounded,filled"]; - n19[fillcolor="lightblue",label="reloader",shape="box",style="rounded,filled"]; - n67[fillcolor="lightblue",label="seaweedfs-application",shape="box",style="rounded,filled"]; - n12[fillcolor="lightblue",label="snapshot-controller",shape="box",style="rounded,filled"]; - n21[fillcolor="lightblue",label="tcp-balancer-application",shape="box",style="rounded,filled"]; - n33[fillcolor="lightblue",label="telepresence",shape="box",style="rounded,filled"]; - n57[fillcolor="lightblue",label="tenant-application",shape="box",style="rounded,filled"]; - n44[fillcolor="lightblue",label="velero",shape="box",style="rounded,filled"]; - n38[fillcolor="lightblue",label="vertical-pod-autoscaler",shape="box",style="rounded,filled"]; - n49[fillcolor="lightblue",label="victoria-metrics-operator",shape="box",style="rounded,filled"]; - n34[fillcolor="lightblue",label="virtual-machine-application",shape="box",style="rounded,filled"]; - n6[fillcolor="lightblue",label="virtualprivatecloud-application",shape="box",style="rounded,filled"]; - n63[fillcolor="lightblue",label="vm-disk-application",shape="box",style="rounded,filled"]; - n68[fillcolor="lightblue",label="vm-instance-application",shape="box",style="rounded,filled"]; - n60[fillcolor="lightblue",label="vpn-application",shape="box",style="rounded,filled"]; - n40->n28; - n40->n45; - n45->n28; - n64->n28; - n64->n29; - n17->n28; - n65->n28; - n65->n17; - n1->n28; - n1->n17; - n58->n28; - n58->n17; - n58->n41; - n22->n28; - n22->n17; - n22->n61; - n13->n28; - n51->n50; - n50->n28; - n50->n35; - n50->n36; - n52->n28; - n9->n28; - n9->n28; - n9->n10; - n7->n28; - n18->n28; - n18->n13; - n53->n28; - n46->n28; - n8->n28; - n23->n28; - n23->n14; - n14->n28; - n14->n13; - n37->n28; - n37->n24; - n42->n28; - n30->n28; - n48->n28; - n2->n28; - n66->n28; - n59->n28; - n4->n28; - n4->n3; - n3->n28; - n3->n35; - n41->n28; - n10->n28; - n10->n43; - n54->n28; - n15->n28; - n15->n17; - n15->n65; - n15->n1; - n15->n58; - n15->n22; - n61->n28; - n61->n35; - n31->n28; - n55->n28; - n55->n13; - n55->n35; - n55->n19; - n56->n28; - n56->n35; - n56->n13; - n62->n28; - n24->n28; - n24->n35; - n24->n37; - n24->n49; - n24->n38; - n47->n28; - n32->n28; - n39->n28; - n39->n56; - n20->n28; - n28->n13; - n28->n13; - n25->n28; - n29->n28; - n11->n28; - n16->n28; - n16->n5; - n5->n28; - n26->n28; - n26->n27; - n27->n28; - n19->n28; - n67->n28; - n12->n28; - n12->n13; - n21->n28; - n33->n28; - n57->n28; - n57->n59; - n57->n67; - n57->n66; - n57->n47; - n57->n45; - n57->n7; - n44->n28; - n44->n24; - n38->n28; - n38->n24; - n49->n28; - n49->n13; - n34->n28; - n34->n61; - n34->n31; - n6->n28; - n6->n32; - n63->n28; - n63->n31; - n68->n28; - n68->n61; - n60->n28; - -} diff --git a/packages/core/platform/psds/dependencies.svg b/packages/core/platform/psds/dependencies.svg deleted file mode 100644 index 9b6d7003..00000000 --- a/packages/core/platform/psds/dependencies.svg +++ /dev/null @@ -1,1128 +0,0 @@ - - - - - - - - - -n40 - -bootbox - - - -n45 - -bootbox-application - - - -n40->n45 - - - - - -n28 - -networking - - - -n40->n28 - - - - - -n45->n28 - - - - - -n64 - -bucket-application - - - -n64->n28 - - - - - -n29 - -objectstorage-controller - - - -n64->n29 - - - - - -n17 - -capi-operator - - - -n17->n28 - - - - - -n65 - -capi-providers-bootstrap - - - -n65->n17 - - - - - -n65->n28 - - - - - -n1 - -capi-providers-core - - - -n1->n17 - - - - - -n1->n28 - - - - - -n58 - -capi-providers-cpprovider - - - -n58->n17 - - - - - -n41 - -kamaji - - - -n58->n41 - - - - - -n58->n28 - - - - - -n22 - -capi-providers-infraprovider - - - -n22->n17 - - - - - -n61 - -kubevirt - - - -n22->n61 - - - - - -n22->n28 - - - - - -n13 - -cert-manager - - - -n13->n28 - - - - - -n51 - -clickhouse-application - - - -n50 - -clickhouse-operator - - - -n51->n50 - - - - - -n36 - -cozystack-core - - - -n50->n36 - - - - - -n35 - -monitoring - - - -n50->n35 - - - - - -n50->n28 - - - - - -n52 - -cozy-proxy - - - -n52->n28 - - - - - -n9 - -cozystack - - - -n10 - -keycloak - - - -n9->n10 - - - - - -n9->n28 - - - - - -n9->n28 - - - - - -n7 - -etcd-application - - - -n7->n28 - - - - - -n18 - -etcd-operator - - - -n18->n13 - - - - - -n18->n28 - - - - - -n53 - -external-dns - - - -n53->n28 - - - - - -n46 - -external-secrets-operator - - - -n46->n28 - - - - - -n8 - -ferretdb-application - - - -n8->n28 - - - - - -n23 - -foundationdb-application - - - -n14 - -foundationdb-operator - - - -n23->n14 - - - - - -n23->n28 - - - - - -n14->n13 - - - - - -n14->n28 - - - - - -n37 - -goldpinger - - - -n24 - -monitoring-agents - - - -n37->n24 - - - - - -n37->n28 - - - - - -n42 - -gpu-operator - - - -n42->n28 - - - - - -n30 - -grafana-operator - - - -n30->n28 - - - - - -n48 - -hetzner-robotlb - - - -n48->n28 - - - - - -n2 - -http-cache-application - - - -n2->n28 - - - - - -n66 - -info-application - - - -n66->n28 - - - - - -n59 - -ingress-application - - - -n59->n28 - - - - - -n4 - -kafka-application - - - -n3 - -kafka-operator - - - -n4->n3 - - - - - -n4->n28 - - - - - -n3->n35 - - - - - -n3->n28 - - - - - -n41->n28 - - - - - -n10->n28 - - - - - -n43 - -postgres-operator - - - -n10->n43 - - - - - -n54 - -keycloak-operator - - - -n54->n28 - - - - - -n15 - -kubernetes-application - - - -n15->n17 - - - - - -n15->n65 - - - - - -n15->n1 - - - - - -n15->n58 - - - - - -n15->n22 - - - - - -n15->n28 - - - - - -n61->n35 - - - - - -n61->n28 - - - - - -n31 - -kubevirt-cdi - - - -n31->n28 - - - - - -n55 - -linstor - - - -n55->n13 - - - - - -n55->n35 - - - - - -n55->n28 - - - - - -n19 - -reloader - - - -n55->n19 - - - - - -n56 - -mariadb-operator - - - -n56->n13 - - - - - -n56->n35 - - - - - -n56->n28 - - - - - -n62 - -metallb - - - -n62->n28 - - - - - -n24->n37 - - - - - -n24->n35 - - - - - -n24->n28 - - - - - -n38 - -vertical-pod-autoscaler - - - -n24->n38 - - - - - -n49 - -victoria-metrics-operator - - - -n24->n49 - - - - - -n47 - -monitoring-application - - - -n47->n28 - - - - - -n32 - -multus - - - -n32->n28 - - - - - -n39 - -mysql-application - - - -n39->n56 - - - - - -n39->n28 - - - - - -n20 - -nats-application - - - -n20->n28 - - - - - -n28->n13 - - - - - -n28->n13 - - - - - -n25 - -nfs-driver - - - -n25->n28 - - - - - -n29->n28 - - - - - -n11 - -postgres-application - - - -n11->n28 - - - - - -n16 - -rabbitmq-application - - - -n16->n28 - - - - - -n5 - -rabbitmq-operator - - - -n16->n5 - - - - - -n5->n28 - - - - - -n26 - -redis-application - - - -n26->n28 - - - - - -n27 - -redis-operator - - - -n26->n27 - - - - - -n27->n28 - - - - - -n19->n28 - - - - - -n67 - -seaweedfs-application - - - -n67->n28 - - - - - -n12 - -snapshot-controller - - - -n12->n13 - - - - - -n12->n28 - - - - - -n21 - -tcp-balancer-application - - - -n21->n28 - - - - - -n33 - -telepresence - - - -n33->n28 - - - - - -n57 - -tenant-application - - - -n57->n45 - - - - - -n57->n7 - - - - - -n57->n66 - - - - - -n57->n59 - - - - - -n57->n47 - - - - - -n57->n28 - - - - - -n57->n67 - - - - - -n44 - -velero - - - -n44->n24 - - - - - -n44->n28 - - - - - -n38->n24 - - - - - -n38->n28 - - - - - -n49->n13 - - - - - -n49->n28 - - - - - -n34 - -virtual-machine-application - - - -n34->n61 - - - - - -n34->n31 - - - - - -n34->n28 - - - - - -n6 - -virtualprivatecloud-application - - - -n6->n32 - - - - - -n6->n28 - - - - - -n63 - -vm-disk-application - - - -n63->n31 - - - - - -n63->n28 - - - - - -n68 - -vm-instance-application - - - -n68->n61 - - - - - -n68->n28 - - - - - -n60 - -vpn-application - - - -n60->n28 - - - - - diff --git a/packages/core/platform/templates/_helpers.tpl b/packages/core/platform/templates/_helpers.tpl deleted file mode 100644 index c656c7f8..00000000 --- a/packages/core/platform/templates/_helpers.tpl +++ /dev/null @@ -1,108 +0,0 @@ -{{/* -Get IP-addresses of master nodes -*/}} -{{- define "cozystack.master-node-ips" -}} -{{- $nodes := lookup "v1" "Node" "" "" -}} -{{- $ips := list -}} -{{- range $node := $nodes.items -}} - {{- if eq (index $node.metadata.labels "node-role.kubernetes.io/control-plane") "" -}} - {{- range $address := $node.status.addresses -}} - {{- if eq $address.type "InternalIP" -}} - {{- $ips = append $ips $address.address -}} - {{- break -}} - {{- end -}} - {{- end -}} - {{- end -}} -{{- end -}} -{{ join "," $ips }} -{{- end -}} - -{{/* -Get Kubernetes API Endpoint from cozystack deployment -Returns host:port format -*/}} -{{- define "cozystack.kubernetesAPIEndpoint" -}} -{{- $cozyDeployment := lookup "apps/v1" "Deployment" "cozy-system" "cozystack" }} -{{- $cozyContainers := dig "spec" "template" "spec" "containers" list $cozyDeployment }} -{{- $kubernetesServiceHost := "" }} -{{- $kubernetesServicePort := "" }} -{{- range $cozyContainers }} -{{- if eq .name "cozystack" }} -{{- range .env }} -{{- if eq .name "KUBERNETES_SERVICE_HOST" }} -{{- $kubernetesServiceHost = .value }} -{{- end }} -{{- if eq .name "KUBERNETES_SERVICE_PORT" }} -{{- $kubernetesServicePort = .value }} -{{- end }} -{{- end }} -{{- end }} -{{- end }} -{{- if eq $kubernetesServiceHost "" }} -{{- $kubernetesServiceHost = "kubernetes.default.svc" }} -{{- end }} -{{- if eq $kubernetesServicePort "" }} -{{- $kubernetesServicePort = "443" }} -{{- end }} -{{- printf "%s:%s" $kubernetesServiceHost $kubernetesServicePort }} -{{- end -}} - -{{- define "cozystack.defaultDashboardValues" -}} -kubeapps: -{{- if .Capabilities.APIVersions.Has "source.toolkit.fluxcd.io/v1" }} -{{- with (lookup "source.toolkit.fluxcd.io/v1" "HelmRepository" "cozy-public" "").items }} - redis: - master: - podAnnotations: - {{- range $index, $repo := . }} - {{- with (($repo.status).artifact).revision }} - repository.cozystack.io/{{ $repo.metadata.name }}: {{ quote . }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} - frontend: - resourcesPreset: "none" - dashboard: - resourcesPreset: "none" - {{- $cozystackBranding:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }} - {{- $branding := dig "data" "branding" "" $cozystackBranding }} - {{- if $branding }} - customLocale: - "Kubeapps": {{ $branding }} - {{- end }} - customStyle: | - {{- $logoImage := dig "data" "logo" "" $cozystackBranding }} - {{- if $logoImage }} - .kubeapps-logo { - background-image: {{ $logoImage }} - } - {{- end }} - #serviceaccount-selector { - display: none; - } - .login-moreinfo { - display: none; - } - a[href="#/docs"] { - display: none; - } - .login-group .clr-form-control .clr-control-label { - display: none; - } - .appview-separator div.appview-first-row div.center { - display: none; - } - .appview-separator div.appview-first-row section[aria-labelledby="app-secrets"] { - display: none; - } - .appview-first-row section[aria-labelledby="access-urls-title"] { - width: 100%; - } - .header-version { - display: none; - } - .label.label-info-secondary { - display: none; - } -{{- end }} diff --git a/packages/core/platform/templates/apps.yaml b/packages/core/platform/templates/apps.yaml deleted file mode 100644 index 514dcffb..00000000 --- a/packages/core/platform/templates/apps.yaml +++ /dev/null @@ -1,67 +0,0 @@ -{{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} -{{- $bundleName := index $cozyConfig.data "bundle-name" }} -{{- $bundle := tpl (.Files.Get (printf "bundles/%s.yaml" $bundleName)) . | fromYaml }} -{{- $host := "example.org" }} -{{- $host := "example.org" }} -{{- if $cozyConfig.data }} - {{- if hasKey $cozyConfig.data "root-host" }} - {{- $host = index $cozyConfig.data "root-host" }} - {{- end }} -{{- end }} -{{- $tenantRoot := dict }} -{{- if .Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }} -{{- $tenantRoot = lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" "tenant-root" "tenant-root" }} -{{- end }} -{{- if and $tenantRoot $tenantRoot.spec $tenantRoot.spec.values $tenantRoot.spec.values.host }} -{{- $host = $tenantRoot.spec.values.host }} -{{- else }} -{{- end }} ---- -apiVersion: v1 -kind: Namespace -metadata: - annotations: - helm.sh/resource-policy: keep - namespace.cozystack.io/etcd: tenant-root - namespace.cozystack.io/monitoring: tenant-root - namespace.cozystack.io/ingress: tenant-root - namespace.cozystack.io/seaweedfs: tenant-root - namespace.cozystack.io/host: "{{ $host }}" - name: tenant-root ---- -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: tenant-root - namespace: tenant-root - labels: - cozystack.io/ui: "true" - apps.cozystack.io/application.kind: Tenant - apps.cozystack.io/application.group: apps.cozystack.io - apps.cozystack.io/application.name: tenant-root -spec: - interval: 0s - releaseName: tenant-root - install: - remediation: - retries: -1 - upgrade: - remediation: - retries: -1 - chart: - spec: - chart: tenant - version: '>= 0.0.0-0' - sourceRef: - kind: HelmRepository - name: cozystack-apps - namespace: cozy-public - values: - host: "{{ $host }}" - dependsOn: - {{- range $x := $bundle.releases }} - {{- if has $x.name (list "cilium" "kubeovn") }} - - name: {{ $x.name }} - namespace: {{ $x.namespace }} - {{- end }} - {{- end }} diff --git a/packages/core/platform/templates/config.yaml b/packages/core/platform/templates/config.yaml new file mode 100644 index 00000000..6dff8c30 --- /dev/null +++ b/packages/core/platform/templates/config.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: cozystack + namespace: cozy-system +data: + root-host: {{ .Values.publishing.host | quote }} + api-server-endpoint: {{ .Values.publishing.apiServerEndpoint | quote }} + expose-services: {{ (join "," .Values.publishing.exposedServices) | quote }} + expose-ingress: {{ .Values.publishing.ingressName | quote }} + expose-external-ips: {{ (join "," .Values.publishing.externalIPs) | quote }} + cluster-domain: {{ .Values.networking.clusterDomain | quote }} + ipv4-pod-cidr: {{ .Values.networking.podCIDR | quote }} + ipv4-pod-gateway: {{ .Values.networking.podGateway | quote }} + ipv4-svc-cidr: {{ .Values.networking.serviceCIDR | quote }} + ipv4-join-cidr: {{ .Values.networking.joinCIDR | quote }} + clusterissuer: {{ .Values.publishing.certificates.issuerType | quote }} + oidc-enabled: {{ .Values.authentication.oidc.enabled | toString | quote }} + extra-keycloak-redirect-uri-for-dashboard: {{ (join "," .Values.authentication.oidc.dashboard.extraRedirectUris) | quote }} + cpu-allocation-ratio: {{ .Values.resources.cpuAllocationRatio | toString | quote }} + memory-allocation-ratio: {{ .Values.resources.memoryAllocationRatio | toString | quote }} + ephemeral-storage-allocation-ratio: {{ .Values.resources.ephemeralStorageAllocationRatio | toString | quote }} + management-kubeconfig-endpoint: {{ .Values.publishing.apiServerEndpoint | quote }} \ No newline at end of file diff --git a/packages/core/platform/templates/containerd-registry-secret.yaml b/packages/core/platform/templates/containerd-registry-secret.yaml new file mode 100644 index 00000000..6e9fb640 --- /dev/null +++ b/packages/core/platform/templates/containerd-registry-secret.yaml @@ -0,0 +1,35 @@ +{{- if .Values.registries.mirrors }} +apiVersion: v1 +kind: Secret +metadata: + name: patch-containerd + namespace: cozy-system +type: Opaque +stringData: +{{- range $registry, $mirror := .Values.registries.mirrors }} +{{- if $mirror.endpoints }} + {{ $registry }}.toml: | + server = "https://{{ $registry }}" +{{- range $endpoint := $mirror.endpoints }} + [host."{{ $endpoint }}"] + capabilities = ["pull", "resolve"] +{{- $endpointConfig := index $.Values.registries.config $endpoint }} +{{- if $endpointConfig }} +{{- if $endpointConfig.tls }} +{{- if $endpointConfig.tls.insecureSkipVerify }} + skip_verify = true +{{- end }} +{{- end }} +{{- if $endpointConfig.auth }} + [host."{{ $endpoint }}".auth] + username = "{{ $endpointConfig.auth.username }}" + password = "{{ $endpointConfig.auth.password }}" +{{- end }} +{{- else }} + skip_verify = true +{{- end }} +{{- end }} +{{- end }} +{{- end }} +{{- end }} + diff --git a/packages/core/platform/templates/cozystack-assets.yaml b/packages/core/platform/templates/cozystack-assets.yaml deleted file mode 100644 index 61ab8dca..00000000 --- a/packages/core/platform/templates/cozystack-assets.yaml +++ /dev/null @@ -1,73 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: cozystack-assets - namespace: cozy-system - labels: - app: cozystack-assets -spec: - serviceName: cozystack-assets - replicas: 1 - selector: - matchLabels: - app: cozystack-assets - template: - metadata: - labels: - app: cozystack-assets - spec: - hostNetwork: true - containers: - - name: assets-server - image: "{{ .Values.assets.image }}" - args: - - "-dir=/cozystack/assets" - - "-address=:8123" - ports: - - name: http - containerPort: 8123 - hostPort: 8123 - tolerations: - - operator: Exists ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: cozystack-assets-reader - namespace: cozy-system -rules: - - apiGroups: [""] - resources: - - pods/proxy - resourceNames: - - cozystack-assets-0 - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: cozystack-assets-reader - namespace: cozy-system -subjects: - - kind: User - name: cozystack-assets-reader - apiGroup: rbac.authorization.k8s.io -roleRef: - kind: Role - name: cozystack-assets-reader - apiGroup: rbac.authorization.k8s.io ---- -apiVersion: v1 -kind: Service -metadata: - name: cozystack-assets - namespace: cozy-system -spec: - ports: - - name: http - port: 80 - targetPort: 8123 - selector: - app: cozystack-assets - type: ClusterIP diff --git a/packages/core/platform/templates/helmreleases.yaml b/packages/core/platform/templates/helmreleases.yaml deleted file mode 100644 index 6ed61ed8..00000000 --- a/packages/core/platform/templates/helmreleases.yaml +++ /dev/null @@ -1,97 +0,0 @@ -{{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} -{{- $bundleName := index $cozyConfig.data "bundle-name" }} -{{- $bundle := tpl (.Files.Get (printf "bundles/%s.yaml" $bundleName)) . | fromYaml }} -{{- $dependencyNamespaces := dict }} -{{- $disabledComponents := splitList "," ((index $cozyConfig.data "bundle-disable") | default "") }} -{{- $enabledComponents := splitList "," ((index $cozyConfig.data "bundle-enable") | default "") }} -{{- $oidcEnabled := (index (default dict $cozyConfig.data) "oidc-enabled") | default "false" | eq "true" }} - -{{/* collect dependency namespaces from releases */}} -{{- range $x := $bundle.releases }} -{{- $_ := set $dependencyNamespaces $x.name $x.namespace }} -{{- end }} - -{{- range $x := $bundle.releases }} - -{{- $shouldInstall := true }} -{{- $shouldDelete := false }} -{{- $notEnabledOptionalComponent := and ($x.optional) (not (has $x.name $enabledComponents)) }} -{{- $disabledComponent := has $x.name $disabledComponents }} -{{- $isKeycloakComponent := or (eq $x.name "keycloak") (eq $x.name "keycloak-operator") (eq $x.name "keycloak-configure") }} - -{{- if and $isKeycloakComponent (not $oidcEnabled) }} -{{- $shouldInstall = false }} -{{- if $.Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }} -{{- if lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" $x.namespace $x.name }} -{{- $shouldDelete = true }} -{{- end }} -{{- end }} -{{- else if or $disabledComponent $notEnabledOptionalComponent }} -{{- $shouldInstall = false }} -{{- if $.Capabilities.APIVersions.Has "helm.toolkit.fluxcd.io/v2" }} -{{- if lookup "helm.toolkit.fluxcd.io/v2" "HelmRelease" $x.namespace $x.name }} -{{- $shouldDelete = true }} -{{- end }} -{{- end }} -{{- end }} - -{{- if or $shouldInstall $shouldDelete }} ---- -apiVersion: helm.toolkit.fluxcd.io/v2 -kind: HelmRelease -metadata: - name: {{ $x.name }} - namespace: {{ $x.namespace }} - labels: - cozystack.io/repository: system - cozystack.io/system-app: "true" - {{- if $shouldDelete }} - cozystack.io/marked-for-deletion: "true" - {{- end }} -spec: - interval: 5m - releaseName: {{ $x.releaseName | default $x.name }} - install: - crds: CreateReplace - remediation: - retries: -1 - upgrade: - crds: CreateReplace - remediation: - retries: -1 - chart: - spec: - chart: {{ $x.chart }} - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' - {{- with $x.valuesFiles }} - valuesFiles: - {{- toYaml $x.valuesFiles | nindent 6 }} - {{- end }} - {{- $values := dict }} - {{- with $x.values }} - {{- $values = merge . $values }} - {{- end }} - {{- with index $cozyConfig.data (printf "values-%s" $x.name) }} - {{- $values = mergeOverwrite $values (fromYaml .) }} - {{- end }} - {{- with $values }} - values: - {{- toYaml . | nindent 4}} - {{- end }} - - {{- with $x.dependsOn }} - dependsOn: - {{- range $dep := . }} - {{- if not (has $dep $disabledComponents) }} - - name: {{ $dep }} - namespace: {{ index $dependencyNamespaces $dep }} - {{- end }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} diff --git a/packages/core/platform/templates/helmrepos.yaml b/packages/core/platform/templates/helmrepos.yaml deleted file mode 100644 index 47954869..00000000 --- a/packages/core/platform/templates/helmrepos.yaml +++ /dev/null @@ -1,40 +0,0 @@ ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: cozystack-system - namespace: cozy-system - labels: - cozystack.io/repository: system -spec: - interval: 5m0s - url: https://{{ include "cozystack.kubernetesAPIEndpoint" . }}/api/v1/namespaces/cozy-system/pods/cozystack-assets-0/proxy/repos/system - certSecretRef: - name: cozystack-assets-tls ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: cozystack-apps - namespace: cozy-public - labels: - cozystack.io/ui: "true" - cozystack.io/repository: apps -spec: - interval: 5m0s - url: https://{{ include "cozystack.kubernetesAPIEndpoint" . }}/api/v1/namespaces/cozy-system/pods/cozystack-assets-0/proxy/repos/apps - certSecretRef: - name: cozystack-assets-tls ---- -apiVersion: source.toolkit.fluxcd.io/v1 -kind: HelmRepository -metadata: - name: cozystack-extra - namespace: cozy-public - labels: - cozystack.io/repository: extra -spec: - interval: 5m0s - url: https://{{ include "cozystack.kubernetesAPIEndpoint" . }}/api/v1/namespaces/cozy-system/pods/cozystack-assets-0/proxy/repos/extra - certSecretRef: - name: cozystack-assets-tls diff --git a/packages/core/platform/templates/migration-hook.yaml b/packages/core/platform/templates/migration-hook.yaml new file mode 100644 index 00000000..d4b3869e --- /dev/null +++ b/packages/core/platform/templates/migration-hook.yaml @@ -0,0 +1,68 @@ +{{- $shouldRunMigrationHook := false }} +{{- $currentVersion := 0 }} +{{- $targetVersion := .Values.migrations.targetVersion | int }} +{{- $configMap := lookup "v1" "ConfigMap" .Release.Namespace "cozystack-version" }} +{{- if $configMap }} + {{- $currentVersion = dig "data" "version" "0" $configMap | int }} + {{- if lt $currentVersion $targetVersion }} + {{- $shouldRunMigrationHook = true }} + {{- end }} +{{- end }} + +{{- if $shouldRunMigrationHook }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: cozystack-migration-hook + annotations: + helm.sh/hook: pre-upgrade + helm.sh/hook-weight: "1" + helm.sh/hook-delete-policy: before-hook-creation +spec: + backoffLimit: 3 + template: + metadata: + labels: + policy.cozystack.io/allow-to-apiserver: "true" + spec: + serviceAccountName: cozystack-migration-hook + containers: + - name: migration + image: {{ .Values.migrations.image }} + env: + - name: NAMESPACE + value: {{ .Release.Namespace | quote }} + - name: CURRENT_VERSION + value: {{ $currentVersion | quote }} + - name: TARGET_VERSION + value: {{ $targetVersion | quote }} + restartPolicy: Never +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + annotations: + helm.sh/hook: pre-upgrade + helm.sh/hook-weight: "1" + helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation + name: cozystack-migration-hook +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: cluster-admin +subjects: + - kind: ServiceAccount + name: cozystack-migration-hook + namespace: {{ .Release.Namespace | quote }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: cozystack-migration-hook + annotations: + helm.sh/hook: pre-upgrade + helm.sh/hook-weight: "1" + helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation +{{- end }} + diff --git a/packages/core/platform/templates/namespaces.yaml b/packages/core/platform/templates/namespaces.yaml deleted file mode 100644 index 11d00553..00000000 --- a/packages/core/platform/templates/namespaces.yaml +++ /dev/null @@ -1,40 +0,0 @@ -{{- $cozyConfig := lookup "v1" "ConfigMap" "cozy-system" "cozystack" }} -{{- $bundleName := index $cozyConfig.data "bundle-name" }} -{{- $bundle := tpl (.Files.Get (printf "bundles/%s.yaml" $bundleName)) . | fromYaml }} -{{- $disabledComponents := splitList "," ((index $cozyConfig.data "bundle-disable") | default "") }} -{{- $enabledComponents := splitList "," ((index $cozyConfig.data "bundle-enable") | default "") }} -{{- $namespaces := dict }} - -{{/* collect namespaces from releases */}} -{{- range $x := $bundle.releases }} - {{- if not (hasKey $namespaces $x.namespace) }} - {{- if not (has $x.name $disabledComponents) }} - {{- if or (not $x.optional) (and ($x.optional) (has $x.name $enabledComponents)) }} - {{- $_ := set $namespaces $x.namespace false }} - {{- end }} - {{- end }} - {{- end }} - {{/* if at least one release requires a privileged namespace, then it should be privileged */}} - {{- if or $x.privileged (index $namespaces $x.namespace) }} - {{- $_ := set $namespaces $x.namespace true }} - {{- end }} -{{- end }} - -{{/* Add extra namespaces */}} -{{- $_ := set $namespaces "cozy-system" true }} -{{- $_ := set $namespaces "cozy-public" false }} - -{{- range $namespace, $privileged := $namespaces }} ---- -apiVersion: v1 -kind: Namespace -metadata: - annotations: - "helm.sh/resource-policy": keep - labels: - cozystack.io/system: "true" - {{- if $privileged }} - pod-security.kubernetes.io/enforce: privileged - {{- end }} - name: {{ $namespace }} -{{- end }} diff --git a/packages/core/platform/templates/packages/isp-full.yaml b/packages/core/platform/templates/packages/isp-full.yaml new file mode 100644 index 00000000..d2e5c237 --- /dev/null +++ b/packages/core/platform/templates/packages/isp-full.yaml @@ -0,0 +1,215 @@ +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.networking +spec: + variant: kubeovn-cilium + components: + kubeovn: + values: + kube-ovn: + ipv4: + POD_CIDR: "{{ .Values.networking.podCIDR }}" + POD_GATEWAY: "{{ .Values.networking.podGateway }}" + SVC_CIDR: "{{ .Values.networking.serviceCIDR }}" + JOIN_CIDR: "{{ .Values.networking.joinCIDR }}" +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.cozystack-engine +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.cert-manager +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.kubeovn-webhook +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.kubeovn-plunger +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.victoria-metrics-operator +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.cozy-proxy +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.multus +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.tenant-application +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.ingress-application +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.seaweedfs-application +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.info-application +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.monitoring-application +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.etcd-application +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.cozystack-basics +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.backup-controller +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.velero +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.vertical-pod-autoscaler +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.metallb +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.gpu-operator +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.reloader +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.linstor +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.monitoring-agents +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.goldpinger +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.snapshot-controller +spec: + variant: default + components: {} +--- +apiVersion: cozystack.io/v1alpha1 +kind: Package +metadata: + name: cozystack.prometheus-operator-crds +spec: + variant: default + components: {} diff --git a/packages/core/platform/templates/repository.yaml b/packages/core/platform/templates/repository.yaml new file mode 100644 index 00000000..9bd9f5a1 --- /dev/null +++ b/packages/core/platform/templates/repository.yaml @@ -0,0 +1,17 @@ +{{- $sourceRef := .Values.sourceRef }} +{{- $apiVersion := "source.toolkit.fluxcd.io/v1" }} +{{- $kind := $sourceRef.kind }} +{{- $name := $sourceRef.name }} +{{- $namespace := $sourceRef.namespace }} +{{- $sourceRepo := lookup $apiVersion $kind $namespace $name }} +{{- if not $sourceRepo }} +{{- fail (printf "Source repository %s/%s of kind %s not found in namespace %s" $namespace $name $kind $namespace) }} +{{- end }} +--- +apiVersion: {{ $apiVersion }} +kind: {{ $kind }} +metadata: + name: cozystack-packages + namespace: cozy-system +spec: +{{- $sourceRepo.spec | toYaml | nindent 2 }} diff --git a/packages/core/platform/templates/scheduling.yaml b/packages/core/platform/templates/scheduling.yaml new file mode 100644 index 00000000..4486155a --- /dev/null +++ b/packages/core/platform/templates/scheduling.yaml @@ -0,0 +1,11 @@ +{{- if .Values.scheduling.globalAppTopologySpreadConstraints }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: cozystack-scheduling + namespace: cozy-system +data: + globalAppTopologySpreadConstraints: | + {{- toYaml .Values.scheduling.globalAppTopologySpreadConstraints | nindent 4 }} +{{- end }} diff --git a/packages/core/platform/templates/sources/backup-controller.yaml b/packages/core/platform/templates/sources/backup-controller.yaml new file mode 100644 index 00000000..f68e168b --- /dev/null +++ b/packages/core/platform/templates/sources/backup-controller.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.backup-controller +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + components: + - name: backup-controller + path: system/backup-controller + install: + privileged: true + namespace: cozy-backup-controller + releaseName: backup-controller diff --git a/packages/core/platform/psds/bootbox-application.yaml b/packages/core/platform/templates/sources/bootbox-application.yaml similarity index 100% rename from packages/core/platform/psds/bootbox-application.yaml rename to packages/core/platform/templates/sources/bootbox-application.yaml diff --git a/packages/core/platform/psds/bootbox.yaml b/packages/core/platform/templates/sources/bootbox.yaml similarity index 100% rename from packages/core/platform/psds/bootbox.yaml rename to packages/core/platform/templates/sources/bootbox.yaml diff --git a/packages/core/platform/psds/bucket-application.yaml b/packages/core/platform/templates/sources/bucket-application.yaml similarity index 100% rename from packages/core/platform/psds/bucket-application.yaml rename to packages/core/platform/templates/sources/bucket-application.yaml diff --git a/packages/core/platform/psds/capi-operator.yaml b/packages/core/platform/templates/sources/capi-operator.yaml similarity index 100% rename from packages/core/platform/psds/capi-operator.yaml rename to packages/core/platform/templates/sources/capi-operator.yaml diff --git a/packages/core/platform/psds/capi-providers-bootstrap.yaml b/packages/core/platform/templates/sources/capi-providers-bootstrap.yaml similarity index 100% rename from packages/core/platform/psds/capi-providers-bootstrap.yaml rename to packages/core/platform/templates/sources/capi-providers-bootstrap.yaml diff --git a/packages/core/platform/psds/capi-providers-core.yaml b/packages/core/platform/templates/sources/capi-providers-core.yaml similarity index 100% rename from packages/core/platform/psds/capi-providers-core.yaml rename to packages/core/platform/templates/sources/capi-providers-core.yaml diff --git a/packages/core/platform/psds/capi-providers-cpprovider.yaml b/packages/core/platform/templates/sources/capi-providers-cpprovider.yaml similarity index 100% rename from packages/core/platform/psds/capi-providers-cpprovider.yaml rename to packages/core/platform/templates/sources/capi-providers-cpprovider.yaml diff --git a/packages/core/platform/psds/capi-providers-infraprovider.yaml b/packages/core/platform/templates/sources/capi-providers-infraprovider.yaml similarity index 100% rename from packages/core/platform/psds/capi-providers-infraprovider.yaml rename to packages/core/platform/templates/sources/capi-providers-infraprovider.yaml diff --git a/packages/core/platform/psds/cert-manager.yaml b/packages/core/platform/templates/sources/cert-manager.yaml similarity index 100% rename from packages/core/platform/psds/cert-manager.yaml rename to packages/core/platform/templates/sources/cert-manager.yaml diff --git a/packages/core/platform/psds/clickhouse-application.yaml b/packages/core/platform/templates/sources/clickhouse-application.yaml similarity index 100% rename from packages/core/platform/psds/clickhouse-application.yaml rename to packages/core/platform/templates/sources/clickhouse-application.yaml diff --git a/packages/core/platform/psds/clickhouse-operator.yaml b/packages/core/platform/templates/sources/clickhouse-operator.yaml similarity index 90% rename from packages/core/platform/psds/clickhouse-operator.yaml rename to packages/core/platform/templates/sources/clickhouse-operator.yaml index 881c6639..c49ff9ab 100644 --- a/packages/core/platform/psds/clickhouse-operator.yaml +++ b/packages/core/platform/templates/sources/clickhouse-operator.yaml @@ -21,5 +21,3 @@ spec: install: namespace: cozy-clickhouse-operator releaseName: clickhouse-operator - dependsOn: - - victoria-metrics-operator diff --git a/packages/core/platform/psds/cozy-proxy.yaml b/packages/core/platform/templates/sources/cozy-proxy.yaml similarity index 100% rename from packages/core/platform/psds/cozy-proxy.yaml rename to packages/core/platform/templates/sources/cozy-proxy.yaml diff --git a/packages/core/platform/templates/sources/cozystack-basics.yaml b/packages/core/platform/templates/sources/cozystack-basics.yaml new file mode 100644 index 00000000..a3fbbad1 --- /dev/null +++ b/packages/core/platform/templates/sources/cozystack-basics.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.cozystack-basics +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.tenant-application + components: + - name: cozystack-basics + path: system/cozystack-basics + install: + namespace: cozy-system + releaseName: cozystack-basics diff --git a/packages/core/platform/psds/cozystack-engine.yaml b/packages/core/platform/templates/sources/cozystack-engine.yaml similarity index 74% rename from packages/core/platform/psds/cozystack-engine.yaml rename to packages/core/platform/templates/sources/cozystack-engine.yaml index 710b4350..ce06b9d8 100644 --- a/packages/core/platform/psds/cozystack-engine.yaml +++ b/packages/core/platform/templates/sources/cozystack-engine.yaml @@ -17,12 +17,18 @@ spec: - name: cozy-lib path: library/cozy-lib components: + - name: cozystack-resource-definition-crd + path: system/cozystack-resource-definition-crd + install: + namespace: cozy-system + releaseName: cozystack-resource-definition-crd - name: cozystack-controller path: system/cozystack-controller install: namespace: cozy-system releaseName: cozystack-controller - dependsOn: [] + dependsOn: + - cozystack-resource-definition-crd - name: cozystack-api path: system/cozystack-api install: @@ -30,6 +36,7 @@ spec: releaseName: cozystack-api dependsOn: - cozystack-controller + - cozystack-resource-definition-crd - name: lineage-controller-webhook path: system/lineage-controller-webhook install: @@ -37,6 +44,7 @@ spec: releaseName: lineage-controller-webhook dependsOn: - cozystack-controller + - cozystack-resource-definition-crd - name: dashboard path: system/dashboard install: @@ -45,6 +53,7 @@ spec: dependsOn: - cozystack-api - cozystack-controller + - cozystack-resource-definition-crd - name: oidc dependsOn: - cozystack.networking @@ -53,12 +62,18 @@ spec: - name: cozy-lib path: library/cozy-lib components: + - name: cozystack-resource-definition-crd + path: system/cozystack-resource-definition-crd + install: + namespace: cozy-system + releaseName: cozystack-resource-definition-crd - name: cozystack-controller path: system/cozystack-controller install: namespace: cozy-system releaseName: cozystack-controller - dependsOn: [] + dependsOn: + - cozystack-resource-definition-crd - name: cozystack-api path: system/cozystack-api install: @@ -66,6 +81,7 @@ spec: releaseName: cozystack-api dependsOn: - cozystack-controller + - cozystack-resource-definition-crd - name: lineage-controller-webhook path: system/lineage-controller-webhook install: @@ -73,6 +89,7 @@ spec: releaseName: lineage-controller-webhook dependsOn: - cozystack-controller + - cozystack-resource-definition-crd - name: dashboard path: system/dashboard install: @@ -82,6 +99,7 @@ spec: - cozystack-api - cozystack-controller - keycloak-configure + - cozystack-resource-definition-crd - name: keycloak-configure path: system/keycloak-configure install: diff --git a/packages/core/platform/psds/etcd-application.yaml b/packages/core/platform/templates/sources/etcd-application.yaml similarity index 100% rename from packages/core/platform/psds/etcd-application.yaml rename to packages/core/platform/templates/sources/etcd-application.yaml diff --git a/packages/core/platform/psds/etcd-operator.yaml b/packages/core/platform/templates/sources/etcd-operator.yaml similarity index 100% rename from packages/core/platform/psds/etcd-operator.yaml rename to packages/core/platform/templates/sources/etcd-operator.yaml diff --git a/packages/core/platform/psds/external-dns.yaml b/packages/core/platform/templates/sources/external-dns.yaml similarity index 100% rename from packages/core/platform/psds/external-dns.yaml rename to packages/core/platform/templates/sources/external-dns.yaml diff --git a/packages/core/platform/psds/external-secrets-operator.yaml b/packages/core/platform/templates/sources/external-secrets-operator.yaml similarity index 100% rename from packages/core/platform/psds/external-secrets-operator.yaml rename to packages/core/platform/templates/sources/external-secrets-operator.yaml diff --git a/packages/core/platform/psds/ferretdb-application.yaml b/packages/core/platform/templates/sources/ferretdb-application.yaml similarity index 100% rename from packages/core/platform/psds/ferretdb-application.yaml rename to packages/core/platform/templates/sources/ferretdb-application.yaml diff --git a/packages/core/platform/psds/foundationdb-application.yaml b/packages/core/platform/templates/sources/foundationdb-application.yaml similarity index 100% rename from packages/core/platform/psds/foundationdb-application.yaml rename to packages/core/platform/templates/sources/foundationdb-application.yaml diff --git a/packages/core/platform/psds/foundationdb-operator.yaml b/packages/core/platform/templates/sources/foundationdb-operator.yaml similarity index 100% rename from packages/core/platform/psds/foundationdb-operator.yaml rename to packages/core/platform/templates/sources/foundationdb-operator.yaml diff --git a/packages/core/platform/psds/goldpinger.yaml b/packages/core/platform/templates/sources/goldpinger.yaml similarity index 84% rename from packages/core/platform/psds/goldpinger.yaml rename to packages/core/platform/templates/sources/goldpinger.yaml index 307dac85..975ad138 100644 --- a/packages/core/platform/psds/goldpinger.yaml +++ b/packages/core/platform/templates/sources/goldpinger.yaml @@ -13,7 +13,7 @@ spec: - name: default dependsOn: - cozystack.networking - - cozystack.monitoring-agents + - cozystack.prometheus-operator-crds components: - name: goldpinger path: system/goldpinger @@ -21,5 +21,3 @@ spec: privileged: true namespace: cozy-goldpinger releaseName: goldpinger - dependsOn: - - monitoring-agents diff --git a/packages/core/platform/psds/gpu-operator.yaml b/packages/core/platform/templates/sources/gpu-operator.yaml similarity index 100% rename from packages/core/platform/psds/gpu-operator.yaml rename to packages/core/platform/templates/sources/gpu-operator.yaml diff --git a/packages/core/platform/psds/grafana-operator.yaml b/packages/core/platform/templates/sources/grafana-operator.yaml similarity index 100% rename from packages/core/platform/psds/grafana-operator.yaml rename to packages/core/platform/templates/sources/grafana-operator.yaml diff --git a/packages/core/platform/psds/hetzner-robotlb.yaml b/packages/core/platform/templates/sources/hetzner-robotlb.yaml similarity index 100% rename from packages/core/platform/psds/hetzner-robotlb.yaml rename to packages/core/platform/templates/sources/hetzner-robotlb.yaml diff --git a/packages/core/platform/psds/http-cache-application.yaml b/packages/core/platform/templates/sources/http-cache-application.yaml similarity index 100% rename from packages/core/platform/psds/http-cache-application.yaml rename to packages/core/platform/templates/sources/http-cache-application.yaml diff --git a/packages/core/platform/psds/info-application.yaml b/packages/core/platform/templates/sources/info-application.yaml similarity index 100% rename from packages/core/platform/psds/info-application.yaml rename to packages/core/platform/templates/sources/info-application.yaml diff --git a/packages/core/platform/psds/ingress-application.yaml b/packages/core/platform/templates/sources/ingress-application.yaml similarity index 100% rename from packages/core/platform/psds/ingress-application.yaml rename to packages/core/platform/templates/sources/ingress-application.yaml diff --git a/packages/core/platform/psds/kafka-application.yaml b/packages/core/platform/templates/sources/kafka-application.yaml similarity index 100% rename from packages/core/platform/psds/kafka-application.yaml rename to packages/core/platform/templates/sources/kafka-application.yaml diff --git a/packages/core/platform/psds/kafka-operator.yaml b/packages/core/platform/templates/sources/kafka-operator.yaml similarity index 100% rename from packages/core/platform/psds/kafka-operator.yaml rename to packages/core/platform/templates/sources/kafka-operator.yaml diff --git a/packages/core/platform/psds/kamaji.yaml b/packages/core/platform/templates/sources/kamaji.yaml similarity index 100% rename from packages/core/platform/psds/kamaji.yaml rename to packages/core/platform/templates/sources/kamaji.yaml diff --git a/packages/core/platform/psds/keycloak-operator.yaml b/packages/core/platform/templates/sources/keycloak-operator.yaml similarity index 100% rename from packages/core/platform/psds/keycloak-operator.yaml rename to packages/core/platform/templates/sources/keycloak-operator.yaml diff --git a/packages/core/platform/psds/keycloak.yaml b/packages/core/platform/templates/sources/keycloak.yaml similarity index 100% rename from packages/core/platform/psds/keycloak.yaml rename to packages/core/platform/templates/sources/keycloak.yaml diff --git a/packages/core/platform/templates/sources/kubeovn-plunger.yaml b/packages/core/platform/templates/sources/kubeovn-plunger.yaml new file mode 100644 index 00000000..bdd8f1c8 --- /dev/null +++ b/packages/core/platform/templates/sources/kubeovn-plunger.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.kubeovn-plunger +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.cert-manager + - cozystack.networking + - cozystack.victoria-metrics-operator + components: + - name: kubeovn-plunger + path: system/kubeovn-plunger + install: + namespace: cozy-kubeovn + releaseName: kubeovn-plunger diff --git a/packages/core/platform/templates/sources/kubeovn-webhook.yaml b/packages/core/platform/templates/sources/kubeovn-webhook.yaml new file mode 100644 index 00000000..3125b692 --- /dev/null +++ b/packages/core/platform/templates/sources/kubeovn-webhook.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.kubeovn-webhook +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.cert-manager + components: + - name: kubeovn-webhook + path: system/kubeovn-webhook + install: + privileged: true + namespace: cozy-kubeovn + releaseName: kubeovn-webhook diff --git a/packages/core/platform/psds/kubernetes-application.yaml b/packages/core/platform/templates/sources/kubernetes-application.yaml similarity index 100% rename from packages/core/platform/psds/kubernetes-application.yaml rename to packages/core/platform/templates/sources/kubernetes-application.yaml diff --git a/packages/core/platform/psds/kubevirt-cdi.yaml b/packages/core/platform/templates/sources/kubevirt-cdi.yaml similarity index 100% rename from packages/core/platform/psds/kubevirt-cdi.yaml rename to packages/core/platform/templates/sources/kubevirt-cdi.yaml diff --git a/packages/core/platform/psds/kubevirt.yaml b/packages/core/platform/templates/sources/kubevirt.yaml similarity index 100% rename from packages/core/platform/psds/kubevirt.yaml rename to packages/core/platform/templates/sources/kubevirt.yaml diff --git a/packages/core/platform/psds/linstor.yaml b/packages/core/platform/templates/sources/linstor.yaml similarity index 81% rename from packages/core/platform/psds/linstor.yaml rename to packages/core/platform/templates/sources/linstor.yaml index 32288cab..f440affe 100644 --- a/packages/core/platform/psds/linstor.yaml +++ b/packages/core/platform/templates/sources/linstor.yaml @@ -14,17 +14,15 @@ spec: dependsOn: - cozystack.networking - cozystack.cert-manager - - cozystack.monitoring + - cozystack.victoria-metrics-operator - cozystack.reloader + - cozystack.snapshot-controller components: - name: piraeus-operator path: system/piraeus-operator install: namespace: cozy-linstor releaseName: piraeus-operator - dependsOn: - - cert-manager - - victoria-metrics-operator - name: linstor path: system/linstor install: @@ -33,5 +31,3 @@ spec: releaseName: linstor dependsOn: - piraeus-operator - - cert-manager - - snapshot-controller diff --git a/packages/core/platform/psds/mariadb-operator.yaml b/packages/core/platform/templates/sources/mariadb-operator.yaml similarity index 100% rename from packages/core/platform/psds/mariadb-operator.yaml rename to packages/core/platform/templates/sources/mariadb-operator.yaml diff --git a/packages/core/platform/psds/metallb.yaml b/packages/core/platform/templates/sources/metallb.yaml similarity index 100% rename from packages/core/platform/psds/metallb.yaml rename to packages/core/platform/templates/sources/metallb.yaml diff --git a/packages/core/platform/psds/monitoring-agents.yaml b/packages/core/platform/templates/sources/monitoring-agents.yaml similarity index 90% rename from packages/core/platform/psds/monitoring-agents.yaml rename to packages/core/platform/templates/sources/monitoring-agents.yaml index 75832fd3..9585c5aa 100644 --- a/packages/core/platform/psds/monitoring-agents.yaml +++ b/packages/core/platform/templates/sources/monitoring-agents.yaml @@ -13,8 +13,6 @@ spec: - name: default dependsOn: - cozystack.networking - - cozystack.monitoring - - cozystack.goldpinger - cozystack.victoria-metrics-operator - cozystack.vertical-pod-autoscaler components: diff --git a/packages/core/platform/psds/monitoring-application.yaml b/packages/core/platform/templates/sources/monitoring-application.yaml similarity index 100% rename from packages/core/platform/psds/monitoring-application.yaml rename to packages/core/platform/templates/sources/monitoring-application.yaml diff --git a/packages/core/platform/psds/multus.yaml b/packages/core/platform/templates/sources/multus.yaml similarity index 100% rename from packages/core/platform/psds/multus.yaml rename to packages/core/platform/templates/sources/multus.yaml diff --git a/packages/core/platform/psds/mysql-application.yaml b/packages/core/platform/templates/sources/mysql-application.yaml similarity index 100% rename from packages/core/platform/psds/mysql-application.yaml rename to packages/core/platform/templates/sources/mysql-application.yaml diff --git a/packages/core/platform/psds/nats-application.yaml b/packages/core/platform/templates/sources/nats-application.yaml similarity index 100% rename from packages/core/platform/psds/nats-application.yaml rename to packages/core/platform/templates/sources/nats-application.yaml diff --git a/packages/core/platform/psds/networking.yaml b/packages/core/platform/templates/sources/networking.yaml similarity index 73% rename from packages/core/platform/psds/networking.yaml rename to packages/core/platform/templates/sources/networking.yaml index 5a443e25..57fff6fc 100644 --- a/packages/core/platform/psds/networking.yaml +++ b/packages/core/platform/templates/sources/networking.yaml @@ -13,8 +13,7 @@ spec: - name: noop components: [] - name: cilium - dependsOn: - - cozystack.cert-manager + dependsOn: [] components: - name: cilium path: system/cilium @@ -35,8 +34,7 @@ spec: dependsOn: - cilium - name: kubeovn-cilium - dependsOn: - - cozystack.cert-manager + dependsOn: [] components: - name: cilium path: system/cilium @@ -65,20 +63,3 @@ spec: releaseName: kubeovn dependsOn: - cilium - - name: kubeovn-plunger - path: system/kubeovn-plunger - install: - namespace: cozy-kubeovn - releaseName: kubeovn-plunger - dependsOn: - - cilium - - kubeovn - - name: kubeovn-webhook - path: system/kubeovn-webhook - install: - privileged: true - namespace: cozy-kubeovn - releaseName: kubeovn-webhook - dependsOn: - - cilium - - kubeovn diff --git a/packages/core/platform/psds/nfs-driver.yaml b/packages/core/platform/templates/sources/nfs-driver.yaml similarity index 100% rename from packages/core/platform/psds/nfs-driver.yaml rename to packages/core/platform/templates/sources/nfs-driver.yaml diff --git a/packages/core/platform/psds/objectstorage-controller.yaml b/packages/core/platform/templates/sources/objectstorage-controller.yaml similarity index 100% rename from packages/core/platform/psds/objectstorage-controller.yaml rename to packages/core/platform/templates/sources/objectstorage-controller.yaml diff --git a/packages/core/platform/psds/postgres-application.yaml b/packages/core/platform/templates/sources/postgres-application.yaml similarity index 100% rename from packages/core/platform/psds/postgres-application.yaml rename to packages/core/platform/templates/sources/postgres-application.yaml diff --git a/packages/core/platform/templates/sources/postgres-operator.yaml b/packages/core/platform/templates/sources/postgres-operator.yaml new file mode 100644 index 00000000..158ab5a2 --- /dev/null +++ b/packages/core/platform/templates/sources/postgres-operator.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.postgres-operator +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: + - cozystack.networking + - cozystack.monitoring + - cozystack.cert-manager + components: + - name: postgres-operator + path: system/postgres-operator + install: + namespace: cozy-postgres-operator + releaseName: postgres-operator + dependsOn: + - cert-manager + - victoria-metrics-operator diff --git a/packages/core/platform/templates/sources/prometheus-operator-crds.yaml b/packages/core/platform/templates/sources/prometheus-operator-crds.yaml new file mode 100644 index 00000000..4ab9ad98 --- /dev/null +++ b/packages/core/platform/templates/sources/prometheus-operator-crds.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: cozystack.io/v1alpha1 +kind: PackageSource +metadata: + name: cozystack.prometheus-operator-crds +spec: + sourceRef: + kind: OCIRepository + name: cozystack-packages + namespace: cozy-system + path: / + variants: + - name: default + dependsOn: [] + components: + - name: prometheus-operator-crds + path: system/prometheus-operator-crds + install: + namespace: cozy-victoria-metrics-operator + releaseName: prometheus-operator-crds diff --git a/packages/core/platform/psds/rabbitmq-application.yaml b/packages/core/platform/templates/sources/rabbitmq-application.yaml similarity index 100% rename from packages/core/platform/psds/rabbitmq-application.yaml rename to packages/core/platform/templates/sources/rabbitmq-application.yaml diff --git a/packages/core/platform/psds/rabbitmq-operator.yaml b/packages/core/platform/templates/sources/rabbitmq-operator.yaml similarity index 100% rename from packages/core/platform/psds/rabbitmq-operator.yaml rename to packages/core/platform/templates/sources/rabbitmq-operator.yaml diff --git a/packages/core/platform/psds/redis-application.yaml b/packages/core/platform/templates/sources/redis-application.yaml similarity index 100% rename from packages/core/platform/psds/redis-application.yaml rename to packages/core/platform/templates/sources/redis-application.yaml diff --git a/packages/core/platform/psds/redis-operator.yaml b/packages/core/platform/templates/sources/redis-operator.yaml similarity index 100% rename from packages/core/platform/psds/redis-operator.yaml rename to packages/core/platform/templates/sources/redis-operator.yaml diff --git a/packages/core/platform/psds/reloader.yaml b/packages/core/platform/templates/sources/reloader.yaml similarity index 100% rename from packages/core/platform/psds/reloader.yaml rename to packages/core/platform/templates/sources/reloader.yaml diff --git a/packages/core/platform/psds/seaweedfs-application.yaml b/packages/core/platform/templates/sources/seaweedfs-application.yaml similarity index 100% rename from packages/core/platform/psds/seaweedfs-application.yaml rename to packages/core/platform/templates/sources/seaweedfs-application.yaml diff --git a/packages/core/platform/psds/snapshot-controller.yaml b/packages/core/platform/templates/sources/snapshot-controller.yaml similarity index 90% rename from packages/core/platform/psds/snapshot-controller.yaml rename to packages/core/platform/templates/sources/snapshot-controller.yaml index 11add6c8..3d4342a4 100644 --- a/packages/core/platform/psds/snapshot-controller.yaml +++ b/packages/core/platform/templates/sources/snapshot-controller.yaml @@ -20,5 +20,3 @@ spec: install: namespace: cozy-snapshot-controller releaseName: snapshot-controller - dependsOn: - - cert-manager-issuers diff --git a/packages/core/platform/psds/tcp-balancer-application.yaml b/packages/core/platform/templates/sources/tcp-balancer-application.yaml similarity index 100% rename from packages/core/platform/psds/tcp-balancer-application.yaml rename to packages/core/platform/templates/sources/tcp-balancer-application.yaml diff --git a/packages/core/platform/psds/telepresence.yaml b/packages/core/platform/templates/sources/telepresence.yaml similarity index 100% rename from packages/core/platform/psds/telepresence.yaml rename to packages/core/platform/templates/sources/telepresence.yaml diff --git a/packages/core/platform/psds/tenant-application.yaml b/packages/core/platform/templates/sources/tenant-application.yaml similarity index 95% rename from packages/core/platform/psds/tenant-application.yaml rename to packages/core/platform/templates/sources/tenant-application.yaml index 13f00978..d95cfd44 100644 --- a/packages/core/platform/psds/tenant-application.yaml +++ b/packages/core/platform/templates/sources/tenant-application.yaml @@ -17,7 +17,6 @@ spec: - cozystack.seaweedfs-application - cozystack.info-application - cozystack.monitoring-application - - cozystack.bootbox-application - cozystack.etcd-application libraries: - name: cozy-lib diff --git a/packages/core/platform/psds/velero.yaml b/packages/core/platform/templates/sources/velero.yaml similarity index 90% rename from packages/core/platform/psds/velero.yaml rename to packages/core/platform/templates/sources/velero.yaml index ac40db3a..2374e847 100644 --- a/packages/core/platform/psds/velero.yaml +++ b/packages/core/platform/templates/sources/velero.yaml @@ -21,5 +21,3 @@ spec: privileged: true namespace: cozy-velero releaseName: velero - dependsOn: - - monitoring-agents diff --git a/packages/core/platform/psds/vertical-pod-autoscaler.yaml b/packages/core/platform/templates/sources/vertical-pod-autoscaler.yaml similarity index 92% rename from packages/core/platform/psds/vertical-pod-autoscaler.yaml rename to packages/core/platform/templates/sources/vertical-pod-autoscaler.yaml index f90de53d..a4d827cc 100644 --- a/packages/core/platform/psds/vertical-pod-autoscaler.yaml +++ b/packages/core/platform/templates/sources/vertical-pod-autoscaler.yaml @@ -13,7 +13,6 @@ spec: - name: default dependsOn: - cozystack.networking - - cozystack.monitoring-agents components: - name: vertical-pod-autoscaler-crds path: system/vertical-pod-autoscaler-crds @@ -21,6 +20,8 @@ spec: privileged: true namespace: cozy-vertical-pod-autoscaler releaseName: vertical-pod-autoscaler-crds + - name: vpa-for-vpa + path: system/vertical-pod-autoscaler - name: vertical-pod-autoscaler path: system/vertical-pod-autoscaler install: diff --git a/packages/core/platform/psds/victoria-metrics-operator.yaml b/packages/core/platform/templates/sources/victoria-metrics-operator.yaml similarity index 100% rename from packages/core/platform/psds/victoria-metrics-operator.yaml rename to packages/core/platform/templates/sources/victoria-metrics-operator.yaml diff --git a/packages/core/platform/psds/virtual-machine-application.yaml b/packages/core/platform/templates/sources/virtual-machine-application.yaml similarity index 100% rename from packages/core/platform/psds/virtual-machine-application.yaml rename to packages/core/platform/templates/sources/virtual-machine-application.yaml diff --git a/packages/core/platform/psds/virtualprivatecloud-application.yaml b/packages/core/platform/templates/sources/virtualprivatecloud-application.yaml similarity index 100% rename from packages/core/platform/psds/virtualprivatecloud-application.yaml rename to packages/core/platform/templates/sources/virtualprivatecloud-application.yaml diff --git a/packages/core/platform/psds/vm-disk-application.yaml b/packages/core/platform/templates/sources/vm-disk-application.yaml similarity index 100% rename from packages/core/platform/psds/vm-disk-application.yaml rename to packages/core/platform/templates/sources/vm-disk-application.yaml diff --git a/packages/core/platform/psds/vm-instance-application.yaml b/packages/core/platform/templates/sources/vm-instance-application.yaml similarity index 100% rename from packages/core/platform/psds/vm-instance-application.yaml rename to packages/core/platform/templates/sources/vm-instance-application.yaml diff --git a/packages/core/platform/psds/vpn-application.yaml b/packages/core/platform/templates/sources/vpn-application.yaml similarity index 100% rename from packages/core/platform/psds/vpn-application.yaml rename to packages/core/platform/templates/sources/vpn-application.yaml diff --git a/packages/core/platform/templates/version.yaml b/packages/core/platform/templates/version.yaml new file mode 100644 index 00000000..ebc5738f --- /dev/null +++ b/packages/core/platform/templates/version.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: cozystack-version + namespace: cozy-system +data: + version: "{{ .Values.migrations.targetVersion }}" + diff --git a/packages/core/platform/values-isp-full.yaml b/packages/core/platform/values-isp-full.yaml new file mode 100644 index 00000000..af0997bc --- /dev/null +++ b/packages/core/platform/values-isp-full.yaml @@ -0,0 +1,12 @@ +migrations: + enabled: true +bundles: + system: + enabled: true + type: "full" + iaas: + enabled: true + paas: + enabled: true + naas: + enabled: true diff --git a/packages/core/platform/values-isp-hosted.yaml b/packages/core/platform/values-isp-hosted.yaml new file mode 100644 index 00000000..eb20159a --- /dev/null +++ b/packages/core/platform/values-isp-hosted.yaml @@ -0,0 +1,12 @@ +migrations: + enabled: true +bundles: + system: + enabled: true + type: "hosted" + iaas: + enabled: false + paas: + enabled: true + naas: + enabled: true diff --git a/packages/core/platform/values.yaml b/packages/core/platform/values.yaml index 363d1921..22d2f87d 100644 --- a/packages/core/platform/values.yaml +++ b/packages/core/platform/values.yaml @@ -1,2 +1,89 @@ -assets: - image: ghcr.io/cozystack/cozystack/cozystack-assets:latest@sha256:19b166819d0205293c85d8351a3e038dc4c146b876a8e2ae21dce1d54f0b9e33 +sourceRef: + kind: OCIRepository + name: cozystack-platform + namespace: cozy-system + path: / +migrations: + enabled: false + image: ghcr.io/cozystack/cozystack/platform-migrations:latest@sha256:390dff1ac16d99c7677a2b580e0dc41bcb2ffd50232ddf4adff81d6f86aae70b + targetVersion: 23 +# Bundle deployment configuration +bundles: + system: + enabled: false + type: "hosted" + iaas: + enabled: true + paas: + enabled: true + naas: + enabled: true +# Network configuration +networking: + clusterDomain: "cozy.local" + podCIDR: "10.244.0.0/16" + podGateway: "10.244.0.1" + serviceCIDR: "10.96.0.0/16" + joinCIDR: "100.64.0.0/16" +# Service publishing and ingress configuration +publishing: + host: "example.org" + ingressName: tenant-root + exposedServices: + - api + - dashboard + - vm-exportproxy + - cdi-uploadproxy + apiServerEndpoint: "" # example: "https://api.example.org" + externalIPs: [] + certificates: + issuerType: http01 # "http01" or "cloudflare" +# Authentication configuration +authentication: + oidc: + enabled: false + dashboard: + extraRedirectUris: [] +# Pod scheduling configuration +scheduling: + topologySpreadConstraints: [] +# UI branding configuration +branding: + dashboard: {} + keycloak: {} +# Container registry mirrors configuration +# +# Example: +# registries: +# mirrors: +# docker.io: +# endpoints: +# - http://10.0.0.1:8082 +# ghcr.io: +# endpoints: +# - http://10.0.0.1:8083 +# gcr.io: +# endpoints: +# - http://10.0.0.1:8084 +# registry.k8s.io: +# endpoints: +# - http://10.0.0.1:8085 +# quay.io: +# endpoints: +# - http://10.0.0.1:8086 +# cr.fluentbit.io: +# endpoints: +# - http://10.0.0.1:8087 +# docker-registry3.mariadb.com: +# endpoints: +# - http://10.0.0.1:8088 +# config: +# "10.0.0.1:8082": +# tls: +# insecureSkipVerify: true +registries: {} +# Resource allocation ratios +resources: + cpuAllocationRatio: 10 + memoryAllocationRatio: 1 + ephemeralStorageAllocationRatio: 40 diff --git a/packages/system/cozystack-basics/Chart.yaml b/packages/system/cozystack-basics/Chart.yaml new file mode 100644 index 00000000..8135baef --- /dev/null +++ b/packages/system/cozystack-basics/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: cozy-basics +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/cozystack-basics/Makefile b/packages/system/cozystack-basics/Makefile new file mode 100644 index 00000000..fe85b39b --- /dev/null +++ b/packages/system/cozystack-basics/Makefile @@ -0,0 +1,4 @@ +export NAME=tenant-root +export NAMESPACE=cozy-system + +include ../../../scripts/package.mk diff --git a/packages/system/cozystack-basics/templates/cozy-public.yaml b/packages/system/cozystack-basics/templates/cozy-public.yaml new file mode 100644 index 00000000..b76816b4 --- /dev/null +++ b/packages/system/cozystack-basics/templates/cozy-public.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: cozy-public diff --git a/packages/system/cozystack-basics/templates/tenant-root.yaml b/packages/system/cozystack-basics/templates/tenant-root.yaml new file mode 100644 index 00000000..42ca6199 --- /dev/null +++ b/packages/system/cozystack-basics/templates/tenant-root.yaml @@ -0,0 +1,25 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: tenant-root +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + cozystack.io/ui: "true" + apps.cozystack.io/application.kind: Tenant + apps.cozystack.io/application.group: apps.cozystack.io + apps.cozystack.io/application.name: tenant-root + name: tenant-root + namespace: tenant-root +spec: + chartRef: + kind: ExternalArtifact + name: cozystack-tenant-application-default-tenant + namespace: cozy-system + interval: 1m0s + timeout: 5m0s diff --git a/packages/system/cozystack-basics/values.yaml b/packages/system/cozystack-basics/values.yaml new file mode 100644 index 00000000..0967ef42 --- /dev/null +++ b/packages/system/cozystack-basics/values.yaml @@ -0,0 +1 @@ +{} diff --git a/packages/system/vertical-pod-autoscaler/templates/vpa-for-vpa.yaml b/packages/system/vertical-pod-autoscaler/templates/vpa-for-vpa.yaml index 5fb35fca..2df053b5 100644 --- a/packages/system/vertical-pod-autoscaler/templates/vpa-for-vpa.yaml +++ b/packages/system/vertical-pod-autoscaler/templates/vpa-for-vpa.yaml @@ -16,15 +16,10 @@ metadata: name: vpa-for-vpa namespace: cozy-vpa-for-vpa spec: - chart: - spec: - chart: cozy-vertical-pod-autoscaler - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-vertical-pod-autoscaler-default-vpa-for-vpa + namespace: cozy-system dependsOn: - name: monitoring-agents namespace: cozy-monitoring From e59784e01a1e0500eef026695cb1a0cf31fd5551 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Sun, 21 Dec 2025 09:53:44 +0100 Subject: [PATCH 12/15] add --- cmd/cozyctl/cmd/dependencies.go | 254 +++++++++++++++++++++++++ cmd/cozyctl/cmd/inspect.go | 33 ++++ cmd/cozyctl/cmd/install.go | 315 ++++++++++++++++++++++++++++++++ cmd/cozyctl/cmd/list.go | 167 +++++++++++++++++ cmd/cozyctl/cmd/root.go | 50 +++++ cmd/cozyctl/main.go | 30 +++ cmd/psds-graph/main.go | 293 ----------------------------- go.mod | 3 +- go.sum | 2 + 9 files changed, 853 insertions(+), 294 deletions(-) create mode 100644 cmd/cozyctl/cmd/dependencies.go create mode 100644 cmd/cozyctl/cmd/inspect.go create mode 100644 cmd/cozyctl/cmd/install.go create mode 100644 cmd/cozyctl/cmd/list.go create mode 100644 cmd/cozyctl/cmd/root.go create mode 100644 cmd/cozyctl/main.go delete mode 100644 cmd/psds-graph/main.go diff --git a/cmd/cozyctl/cmd/dependencies.go b/cmd/cozyctl/cmd/dependencies.go new file mode 100644 index 00000000..ccae733b --- /dev/null +++ b/cmd/cozyctl/cmd/dependencies.go @@ -0,0 +1,254 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 cmd + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/emicklei/dot" + "github.com/spf13/cobra" + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + _ "k8s.io/client-go/plugin/pkg/client/auth" +) + +var dependenciesCmdFlags struct { + installed bool + components bool + kubeconfig string +} + +var dependenciesCmd = &cobra.Command{ + Use: "dependencies [PACKAGE]", + Short: "Inspect PackageSource dependencies as graphviz graph.", + Long: `Inspect PackageSource dependencies as graphviz graph. + +Pipe the output of the command through the "dot" program (part of graphviz package) +to render the graph: + + cozyctl dependencies | dot -Tpng > graph.png + +If PACKAGE is specified, shows dependencies only for that PackageSource. +If -i flag is set, shows dependencies only for installed Package resources.`, + Args: cobra.MaximumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + var packageName string + if len(args) > 0 { + packageName = args[0] + } + + // packagesOnly is inverse of components flag (if components=false, then packagesOnly=true) + packagesOnly := !dependenciesCmdFlags.components + graph, allNodes, err := buildGraphFromCluster(ctx, dependenciesCmdFlags.kubeconfig, packagesOnly, dependenciesCmdFlags.installed, packageName) + if err != nil { + return fmt.Errorf("error getting PackageSource dependencies: %w", err) + } + + dotGraph := generateDOTGraph(graph, allNodes, packagesOnly) + dotGraph.Write(os.Stdout) + + return nil + }, +} + +func init() { + rootCmd.AddCommand(dependenciesCmd) + dependenciesCmd.Flags().BoolVarP(&dependenciesCmdFlags.installed, "installed", "i", false, "show dependencies only for installed Package resources") + dependenciesCmd.Flags().BoolVar(&dependenciesCmdFlags.components, "components", true, "show component-level dependencies (default: true)") + dependenciesCmd.Flags().StringVar(&dependenciesCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") +} + +var ( + dependenciesScheme = runtime.NewScheme() +) + +func init() { + utilruntime.Must(clientgoscheme.AddToScheme(dependenciesScheme)) + utilruntime.Must(cozyv1alpha1.AddToScheme(dependenciesScheme)) +} + +// buildGraphFromCluster builds a dependency graph from PackageSource resources in the cluster. +func buildGraphFromCluster(ctx context.Context, kubeconfig string, packagesOnly bool, installedOnly bool, packageName string) (map[string][]string, map[string]bool, error) { + // Create Kubernetes client config + var config *rest.Config + var err error + + if kubeconfig != "" { + // Load kubeconfig from explicit path + config, err = clientcmd.BuildConfigFromFlags("", kubeconfig) + if err != nil { + return nil, nil, fmt.Errorf("failed to load kubeconfig from %s: %w", kubeconfig, err) + } + } else { + // Use default kubeconfig loading (from env var or ~/.kube/config) + config, err = ctrl.GetConfig() + if err != nil { + return nil, nil, fmt.Errorf("failed to get kubeconfig: %w", err) + } + } + + k8sClient, err := client.New(config, client.Options{Scheme: dependenciesScheme}) + if err != nil { + return nil, nil, fmt.Errorf("failed to create k8s client: %w", err) + } + + // Get installed Packages if needed + installedPackages := make(map[string]bool) + if installedOnly || packageName != "" { + var packageList cozyv1alpha1.PackageList + if err := k8sClient.List(ctx, &packageList); err != nil { + return nil, nil, fmt.Errorf("failed to list Packages: %w", err) + } + for _, pkg := range packageList.Items { + installedPackages[pkg.Name] = true + } + } + + // List all PackageSource resources + var packageSourceList cozyv1alpha1.PackageSourceList + if err := k8sClient.List(ctx, &packageSourceList); err != nil { + return nil, nil, fmt.Errorf("failed to list PackageSources: %w", err) + } + + graph := make(map[string][]string) + allNodes := make(map[string]bool) + + // Process each PackageSource + for _, ps := range packageSourceList.Items { + psName := ps.Name + if psName == "" { + continue + } + + // Filter by package name if specified + if packageName != "" && psName != packageName { + continue + } + + // Filter by installed packages if flag is set + if installedOnly && !installedPackages[psName] { + continue + } + + allNodes[psName] = true + + // Extract dependencies from variants + for _, variant := range ps.Spec.Variants { + // Variant-level dependencies + for _, dep := range variant.DependsOn { + // If installedOnly is set, only include dependencies that are installed + if installedOnly && !installedPackages[dep] { + continue + } + graph[psName] = append(graph[psName], dep) + allNodes[dep] = true + } + + // Component-level dependencies + if !packagesOnly { + for _, component := range variant.Components { + componentName := fmt.Sprintf("%s.%s", psName, component.Name) + allNodes[componentName] = true + + if component.Install != nil { + for _, dep := range component.Install.DependsOn { + // Check if it's a local component dependency or external + if strings.Contains(dep, ".") { + graph[componentName] = append(graph[componentName], dep) + allNodes[dep] = true + } else { + // Local component dependency + localDep := fmt.Sprintf("%s.%s", psName, dep) + graph[componentName] = append(graph[componentName], localDep) + allNodes[localDep] = true + } + } + } + } + } + } + } + + return graph, allNodes, nil +} + +// generateDOTGraph generates a DOT graph from the dependency graph. +func generateDOTGraph(graph map[string][]string, allNodes map[string]bool, packagesOnly bool) *dot.Graph { + g := dot.NewGraph(dot.Directed) + g.Attr("rankdir", "LR") + g.Attr("nodesep", "0.5") + g.Attr("ranksep", "1.0") + + // Add nodes + for node := range allNodes { + if packagesOnly && strings.Contains(node, ".") && !strings.HasPrefix(node, "cozystack.") { + // Skip component nodes when packages-only is enabled + continue + } + + n := g.Node(node) + + // Style nodes based on type + if strings.Contains(node, ".") && !strings.HasPrefix(node, "cozystack.") { + // Component node + n.Attr("shape", "box") + n.Attr("style", "rounded,filled") + n.Attr("fillcolor", "lightyellow") + n.Attr("label", strings.Split(node, ".")[len(strings.Split(node, "."))-1]) + } else { + // Package node + n.Attr("shape", "box") + n.Attr("style", "rounded,filled") + n.Attr("fillcolor", "lightblue") + n.Attr("label", node) + } + } + + // Add edges + for source, targets := range graph { + if packagesOnly && strings.Contains(source, ".") && !strings.HasPrefix(source, "cozystack.") { + // Skip component edges when packages-only is enabled + continue + } + + for _, target := range targets { + if packagesOnly && strings.Contains(target, ".") && !strings.HasPrefix(target, "cozystack.") { + // Skip component edges when packages-only is enabled + continue + } + + // Only add edge if both nodes exist + if allNodes[source] && allNodes[target] { + g.Edge(g.Node(source), g.Node(target)) + } + } + } + + return g +} + diff --git a/cmd/cozyctl/cmd/inspect.go b/cmd/cozyctl/cmd/inspect.go new file mode 100644 index 00000000..72f9a265 --- /dev/null +++ b/cmd/cozyctl/cmd/inspect.go @@ -0,0 +1,33 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 cmd + +import ( + "github.com/spf13/cobra" +) + +// inspectCmd represents the inspect command. +var inspectCmd = &cobra.Command{ + Use: "inspect", + Short: "Inspect internals of Cozystack", + Long: ``, +} + +func init() { + // inspectCmd can be extended with other inspect subcommands in the future +} + diff --git a/cmd/cozyctl/cmd/install.go b/cmd/cozyctl/cmd/install.go new file mode 100644 index 00000000..2411f453 --- /dev/null +++ b/cmd/cozyctl/cmd/install.go @@ -0,0 +1,315 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 cmd + +import ( + "bufio" + "context" + "fmt" + "os" + "strconv" + "strings" + + "github.com/spf13/cobra" + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + _ "k8s.io/client-go/plugin/pkg/client/auth" +) + +var installCmdFlags struct { + kubeconfig string +} + +var installCmd = &cobra.Command{ + Use: "install PACKAGESOURCE", + Short: "Install a PackageSource and its dependencies interactively", + Long: `Install a PackageSource and its dependencies interactively. + +This command builds a dependency tree for the specified PackageSource and +prompts you to install all dependencies, starting from the root of the tree. +For each dependency, you'll be asked to choose a variant, even if only one is available. + +If a dependency is already installed, the variant selection will be skipped.`, + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + packageSourceName := args[0] + + // Create Kubernetes client config + var config *rest.Config + var err error + + if installCmdFlags.kubeconfig != "" { + config, err = clientcmd.BuildConfigFromFlags("", installCmdFlags.kubeconfig) + if err != nil { + return fmt.Errorf("failed to load kubeconfig from %s: %w", installCmdFlags.kubeconfig, err) + } + } else { + config, err = ctrl.GetConfig() + if err != nil { + return fmt.Errorf("failed to get kubeconfig: %w", err) + } + } + + scheme := runtime.NewScheme() + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(cozyv1alpha1.AddToScheme(scheme)) + + k8sClient, err := client.New(config, client.Options{Scheme: scheme}) + if err != nil { + return fmt.Errorf("failed to create k8s client: %w", err) + } + + // Get PackageSource + packageSource := &cozyv1alpha1.PackageSource{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: packageSourceName}, packageSource); err != nil { + return fmt.Errorf("failed to get PackageSource %s: %w", packageSourceName, err) + } + + // Build dependency tree + dependencyTree, err := buildDependencyTree(ctx, k8sClient, packageSourceName) + if err != nil { + return fmt.Errorf("failed to build dependency tree: %w", err) + } + + // Topological sort (install from root to leaves) + installOrder, err := topologicalSort(dependencyTree) + if err != nil { + return fmt.Errorf("failed to sort dependencies: %w", err) + } + + // Get all PackageSources for variant selection + var allPackageSources cozyv1alpha1.PackageSourceList + if err := k8sClient.List(ctx, &allPackageSources); err != nil { + return fmt.Errorf("failed to list PackageSources: %w", err) + } + + packageSourceMap := make(map[string]*cozyv1alpha1.PackageSource) + for i := range allPackageSources.Items { + packageSourceMap[allPackageSources.Items[i].Name] = &allPackageSources.Items[i] + } + + // Get all installed Packages + var installedPackages cozyv1alpha1.PackageList + if err := k8sClient.List(ctx, &installedPackages); err != nil { + return fmt.Errorf("failed to list Packages: %w", err) + } + + installedMap := make(map[string]*cozyv1alpha1.Package) + for i := range installedPackages.Items { + installedMap[installedPackages.Items[i].Name] = &installedPackages.Items[i] + } + + // Install dependencies in order + fmt.Fprintf(os.Stderr, "Installing %s and its dependencies...\n\n", packageSourceName) + for _, pkgName := range installOrder { + // Check if already installed + if installed, exists := installedMap[pkgName]; exists { + variant := installed.Spec.Variant + if variant == "" { + variant = "default" + } + fmt.Fprintf(os.Stderr, "✓ %s (already installed, variant: %s)\n", pkgName, variant) + continue + } + + // Get PackageSource for this dependency + ps, exists := packageSourceMap[pkgName] + if !exists { + fmt.Fprintf(os.Stderr, "⚠ Warning: PackageSource %s not found, skipping\n", pkgName) + continue + } + + // Select variant interactively + variant, err := selectVariantInteractive(ps) + if err != nil { + return fmt.Errorf("failed to select variant for %s: %w", pkgName, err) + } + + // Create Package + pkg := &cozyv1alpha1.Package{ + ObjectMeta: metav1.ObjectMeta{ + Name: pkgName, + }, + Spec: cozyv1alpha1.PackageSpec{ + Variant: variant, + }, + } + + if err := k8sClient.Create(ctx, pkg); err != nil { + return fmt.Errorf("failed to create Package %s: %w", pkgName, err) + } + + fmt.Fprintf(os.Stderr, "✓ Created Package %s with variant %s\n", pkgName, variant) + } + + fmt.Fprintf(os.Stderr, "\nInstallation complete!\n") + return nil + }, +} + +// buildDependencyTree builds a dependency tree starting from the root PackageSource +func buildDependencyTree(ctx context.Context, k8sClient client.Client, rootName string) (map[string][]string, error) { + tree := make(map[string][]string) + visited := make(map[string]bool) + + // Ensure root is in tree even if it has no dependencies + tree[rootName] = []string{} + + var buildTree func(string) error + buildTree = func(pkgName string) error { + if visited[pkgName] { + return nil + } + visited[pkgName] = true + + // Get PackageSource + ps := &cozyv1alpha1.PackageSource{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: pkgName}, ps); err != nil { + // If PackageSource doesn't exist, just skip it + return nil + } + + // Collect all dependencies from all variants + deps := make(map[string]bool) + for _, variant := range ps.Spec.Variants { + for _, dep := range variant.DependsOn { + deps[dep] = true + } + } + + // Add dependencies to tree + for dep := range deps { + if _, exists := tree[pkgName]; !exists { + tree[pkgName] = []string{} + } + tree[pkgName] = append(tree[pkgName], dep) + // Recursively build tree for dependencies + if err := buildTree(dep); err != nil { + return err + } + } + + return nil + } + + if err := buildTree(rootName); err != nil { + return nil, err + } + + return tree, nil +} + +// topologicalSort performs topological sort on the dependency tree +// Returns order from root to leaves (dependencies first) +func topologicalSort(tree map[string][]string) ([]string, error) { + // Build reverse graph (dependencies -> dependents) + reverseGraph := make(map[string][]string) + allNodes := make(map[string]bool) + + for node, deps := range tree { + allNodes[node] = true + for _, dep := range deps { + allNodes[dep] = true + reverseGraph[dep] = append(reverseGraph[dep], node) + } + } + + // Calculate in-degrees (how many dependencies a node has) + inDegree := make(map[string]int) + for node := range allNodes { + inDegree[node] = 0 + } + for node, deps := range tree { + inDegree[node] = len(deps) + } + + // Kahn's algorithm - start with nodes that have no dependencies + var queue []string + for node, degree := range inDegree { + if degree == 0 { + queue = append(queue, node) + } + } + + var result []string + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + result = append(result, node) + + // Process dependents (nodes that depend on this node) + for _, dependent := range reverseGraph[node] { + inDegree[dependent]-- + if inDegree[dependent] == 0 { + queue = append(queue, dependent) + } + } + } + + // Check for cycles + if len(result) != len(allNodes) { + return nil, fmt.Errorf("dependency cycle detected") + } + + return result, nil +} + +// selectVariantInteractive prompts user to select a variant +func selectVariantInteractive(ps *cozyv1alpha1.PackageSource) (string, error) { + if len(ps.Spec.Variants) == 0 { + return "", fmt.Errorf("no variants available for PackageSource %s", ps.Name) + } + + reader := bufio.NewReader(os.Stdin) + + fmt.Fprintf(os.Stderr, "\nPackageSource: %s\n", ps.Name) + fmt.Fprintf(os.Stderr, "Available variants:\n") + for i, variant := range ps.Spec.Variants { + fmt.Fprintf(os.Stderr, " %d. %s\n", i+1, variant.Name) + } + + for { + fmt.Fprintf(os.Stderr, "Select variant (1-%d): ", len(ps.Spec.Variants)) + input, err := reader.ReadString('\n') + if err != nil { + return "", fmt.Errorf("failed to read input: %w", err) + } + + input = strings.TrimSpace(input) + choice, err := strconv.Atoi(input) + if err != nil || choice < 1 || choice > len(ps.Spec.Variants) { + fmt.Fprintf(os.Stderr, "Invalid choice. Please enter a number between 1 and %d.\n", len(ps.Spec.Variants)) + continue + } + + return ps.Spec.Variants[choice-1].Name, nil + } +} + +func init() { + rootCmd.AddCommand(installCmd) + installCmd.Flags().StringVar(&installCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") +} + diff --git a/cmd/cozyctl/cmd/list.go b/cmd/cozyctl/cmd/list.go new file mode 100644 index 00000000..544429d1 --- /dev/null +++ b/cmd/cozyctl/cmd/list.go @@ -0,0 +1,167 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 cmd + +import ( + "context" + "fmt" + "os" + "strings" + + "github.com/spf13/cobra" + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + _ "k8s.io/client-go/plugin/pkg/client/auth" +) + +var listCmdFlags struct { + installed bool + kubeconfig string +} + +var listCmd = &cobra.Command{ + Use: "list", + Short: "List PackageSource or Package resources", + Long: `List PackageSource or Package resources in table format. + +By default, lists PackageSource resources. Use -i flag to list installed Package resources.`, + Args: cobra.NoArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + // Create Kubernetes client config + var config *rest.Config + var err error + + if listCmdFlags.kubeconfig != "" { + config, err = clientcmd.BuildConfigFromFlags("", listCmdFlags.kubeconfig) + if err != nil { + return fmt.Errorf("failed to load kubeconfig from %s: %w", listCmdFlags.kubeconfig, err) + } + } else { + config, err = ctrl.GetConfig() + if err != nil { + return fmt.Errorf("failed to get kubeconfig: %w", err) + } + } + + scheme := runtime.NewScheme() + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(cozyv1alpha1.AddToScheme(scheme)) + + k8sClient, err := client.New(config, client.Options{Scheme: scheme}) + if err != nil { + return fmt.Errorf("failed to create k8s client: %w", err) + } + + if listCmdFlags.installed { + return listPackages(ctx, k8sClient) + } + return listPackageSources(ctx, k8sClient) + }, +} + +func listPackageSources(ctx context.Context, k8sClient client.Client) error { + var psList cozyv1alpha1.PackageSourceList + if err := k8sClient.List(ctx, &psList); err != nil { + return fmt.Errorf("failed to list PackageSources: %w", err) + } + + // Print header + fmt.Fprintf(os.Stdout, "%-50s %-30s %-10s %s\n", "NAME", "VARIANTS", "READY", "STATUS") + fmt.Fprintf(os.Stdout, "%-50s %-30s %-10s %s\n", strings.Repeat("-", 50), strings.Repeat("-", 30), strings.Repeat("-", 10), strings.Repeat("-", 50)) + + // Print rows + for _, ps := range psList.Items { + // Get variants + var variants []string + for _, variant := range ps.Spec.Variants { + variants = append(variants, variant.Name) + } + variantsStr := strings.Join(variants, ",") + if len(variantsStr) > 28 { + variantsStr = variantsStr[:25] + "..." + } + + // Get Ready condition + ready := "Unknown" + status := "" + for _, condition := range ps.Status.Conditions { + if condition.Type == "Ready" { + ready = string(condition.Status) + status = condition.Message + if len(status) > 48 { + status = status[:45] + "..." + } + break + } + } + + fmt.Fprintf(os.Stdout, "%-50s %-30s %-10s %s\n", ps.Name, variantsStr, ready, status) + } + + return nil +} + +func listPackages(ctx context.Context, k8sClient client.Client) error { + var pkgList cozyv1alpha1.PackageList + if err := k8sClient.List(ctx, &pkgList); err != nil { + return fmt.Errorf("failed to list Packages: %w", err) + } + + // Print header + fmt.Fprintf(os.Stdout, "%-50s %-20s %-10s %s\n", "NAME", "VARIANT", "READY", "STATUS") + fmt.Fprintf(os.Stdout, "%-50s %-20s %-10s %s\n", strings.Repeat("-", 50), strings.Repeat("-", 20), strings.Repeat("-", 10), strings.Repeat("-", 50)) + + // Print rows + for _, pkg := range pkgList.Items { + variant := pkg.Spec.Variant + if variant == "" { + variant = "default" + } + + // Get Ready condition + ready := "Unknown" + status := "" + for _, condition := range pkg.Status.Conditions { + if condition.Type == "Ready" { + ready = string(condition.Status) + status = condition.Message + if len(status) > 48 { + status = status[:45] + "..." + } + break + } + } + + fmt.Fprintf(os.Stdout, "%-50s %-20s %-10s %s\n", pkg.Name, variant, ready, status) + } + + return nil +} + +func init() { + listCmd.Flags().BoolVarP(&listCmdFlags.installed, "installed", "i", false, "list installed Package resources instead of PackageSource resources") + listCmd.Flags().StringVar(&listCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") +} + diff --git a/cmd/cozyctl/cmd/root.go b/cmd/cozyctl/cmd/root.go new file mode 100644 index 00000000..fbe3def2 --- /dev/null +++ b/cmd/cozyctl/cmd/root.go @@ -0,0 +1,50 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" +) + +// rootCmd represents the base command when called without any subcommands. +var rootCmd = &cobra.Command{ + Use: "cozyctl", + Short: "A CLI for managing Cozystack", + Long: ``, + SilenceErrors: true, + SilenceUsage: true, + DisableAutoGenTag: true, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() error { + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err.Error()) + return err + } + return nil +} + +func init() { + rootCmd.AddCommand(inspectCmd) + rootCmd.AddCommand(listCmd) +} + diff --git a/cmd/cozyctl/main.go b/cmd/cozyctl/main.go new file mode 100644 index 00000000..6840b9ec --- /dev/null +++ b/cmd/cozyctl/main.go @@ -0,0 +1,30 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 main + +import ( + "os" + + "github.com/cozystack/cozystack/cmd/cozyctl/cmd" +) + +func main() { + if err := cmd.Execute(); err != nil { + os.Exit(1) + } +} + diff --git a/cmd/psds-graph/main.go b/cmd/psds-graph/main.go deleted file mode 100644 index 6b3e58e0..00000000 --- a/cmd/psds-graph/main.go +++ /dev/null @@ -1,293 +0,0 @@ -/* -Copyright 2025 The Cozystack Authors. - -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 main - -import ( - "fmt" - "os" - "os/exec" - "path/filepath" - "strings" - - "github.com/emicklei/dot" - "github.com/spf13/cobra" - "gopkg.in/yaml.v3" -) - -var ( - psdsDir string - outputFile string - packagesOnly bool - format string -) - -func main() { - rootCmd := &cobra.Command{ - Use: "psds-graph", - Short: "Generate dependency graph for PackageSource files", - Long: `Generate a dependency graph visualization for PackageSource files. - -The command scans all YAML files in the specified directory, extracts dependencies, -and generates a graph in DOT format (compatible with graphviz). - -Examples: - # Generate SVG graph - psds-graph --psds-dir packages/core/platform/psds --output dependencies.svg - - # Generate PNG (requires graphviz) - psds-graph --psds-dir packages/core/platform/psds --output dependencies.png --format png - - # Show only package-level dependencies - psds-graph --psds-dir packages/core/platform/psds --output dependencies.svg --packages-only`, - RunE: run, - } - - rootCmd.Flags().StringVar(&psdsDir, "psds-dir", "packages/core/platform/psds", "Directory containing PackageSource YAML files") - rootCmd.Flags().StringVar(&outputFile, "output", "dependencies.dot", "Output file path") - rootCmd.Flags().BoolVar(&packagesOnly, "packages-only", false, "Show only package-level dependencies, hide component dependencies") - rootCmd.Flags().StringVar(&format, "format", "dot", "Output format: dot, svg, png, pdf (requires graphviz for non-dot formats)") - - if err := rootCmd.Execute(); err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) - } -} - -func run(cmd *cobra.Command, args []string) error { - if psdsDir == "" { - return fmt.Errorf("--psds-dir is required") - } - - fmt.Fprintf(os.Stderr, "Scanning %s...\n", psdsDir) - - graph, allNodes, err := buildGraph(psdsDir, packagesOnly) - if err != nil { - return fmt.Errorf("failed to build graph: %w", err) - } - - fmt.Fprintf(os.Stderr, "Found %d nodes and %d edges\n", len(allNodes), countEdges(graph)) - - // Generate DOT graph - dotGraph := generateDOTGraph(graph, allNodes, packagesOnly) - - // Write DOT file first - dotFile := outputFile - if format != "dot" { - dotFile = strings.TrimSuffix(outputFile, filepath.Ext(outputFile)) + ".dot" - } - - if err := writeDOT(dotGraph, dotFile); err != nil { - return err - } - - // If format is not dot, try to render using graphviz - if format != "dot" { - return renderWithGraphviz(dotFile, outputFile, format) - } - - return nil -} - -type PackageSource struct { - APIVersion string `yaml:"apiVersion"` - Kind string `yaml:"kind"` - Metadata map[string]interface{} `yaml:"metadata"` - Spec Spec `yaml:"spec"` -} - -type Spec struct { - Variants []Variant `yaml:"variants"` -} - -type Variant struct { - Name string `yaml:"name"` - DependsOn []string `yaml:"dependsOn"` - Components []Component `yaml:"components"` -} - -type Component struct { - Name string `yaml:"name"` - Install Install `yaml:"install"` -} - -type Install struct { - DependsOn []string `yaml:"dependsOn"` -} - -func buildGraph(psdsDir string, packagesOnly bool) (map[string][]string, map[string]bool, error) { - graph := make(map[string][]string) - allNodes := make(map[string]bool) - - err := filepath.Walk(psdsDir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - - if !strings.HasSuffix(path, ".yaml") { - return nil - } - - data, err := os.ReadFile(path) - if err != nil { - fmt.Fprintf(os.Stderr, "Warning: failed to read %s: %v\n", path, err) - return nil - } - - var ps PackageSource - if err := yaml.Unmarshal(data, &ps); err != nil { - fmt.Fprintf(os.Stderr, "Warning: failed to parse %s: %v\n", path, err) - return nil - } - - packageName, ok := ps.Metadata["name"].(string) - if !ok || packageName == "" { - fmt.Fprintf(os.Stderr, "Warning: %s has no package name, skipping\n", path) - return nil - } - - allNodes[packageName] = true - - // Extract dependencies - for _, variant := range ps.Spec.Variants { - // Variant-level dependencies - for _, dep := range variant.DependsOn { - graph[packageName] = append(graph[packageName], dep) - allNodes[dep] = true - } - - // Component-level dependencies - if !packagesOnly { - for _, component := range variant.Components { - componentName := fmt.Sprintf("%s.%s", packageName, component.Name) - allNodes[componentName] = true - - for _, dep := range component.Install.DependsOn { - // Check if it's a local component dependency or external - if strings.Contains(dep, ".") { - graph[componentName] = append(graph[componentName], dep) - allNodes[dep] = true - } else { - // Local component dependency - localDep := fmt.Sprintf("%s.%s", packageName, dep) - graph[componentName] = append(graph[componentName], localDep) - allNodes[localDep] = true - } - } - } - } - } - - return nil - }) - - return graph, allNodes, err -} - -func countEdges(graph map[string][]string) int { - count := 0 - for _, deps := range graph { - count += len(deps) - } - return count -} - -func generateDOTGraph(graph map[string][]string, allNodes map[string]bool, packagesOnly bool) *dot.Graph { - g := dot.NewGraph(dot.Directed) - g.Attr("rankdir", "LR") - g.Attr("nodesep", "0.5") - g.Attr("ranksep", "1.0") - - // Add nodes - for node := range allNodes { - if packagesOnly && strings.Contains(node, ".") && !strings.HasPrefix(node, "cozystack.") { - // Skip component nodes when packages-only is enabled - continue - } - - n := g.Node(node) - - // Style nodes based on type - if strings.Contains(node, ".") && !strings.HasPrefix(node, "cozystack.") { - // Component node - n.Attr("shape", "box") - n.Attr("style", "rounded,filled") - n.Attr("fillcolor", "lightyellow") - n.Attr("label", strings.Split(node, ".")[len(strings.Split(node, "."))-1]) - } else { - // Package node - n.Attr("shape", "box") - n.Attr("style", "rounded,filled") - n.Attr("fillcolor", "lightblue") - label := node - if strings.HasPrefix(node, "cozystack.") { - label = strings.TrimPrefix(node, "cozystack.") - } - n.Attr("label", label) - } - } - - // Add edges - for source, targets := range graph { - if packagesOnly && strings.Contains(source, ".") && !strings.HasPrefix(source, "cozystack.") { - // Skip component edges when packages-only is enabled - continue - } - - for _, target := range targets { - if packagesOnly && strings.Contains(target, ".") && !strings.HasPrefix(target, "cozystack.") { - // Skip component edges when packages-only is enabled - continue - } - - // Only add edge if both nodes exist - if allNodes[source] && allNodes[target] { - g.Edge(g.Node(source), g.Node(target)) - } - } - } - - return g -} - -func writeDOT(g *dot.Graph, outputFile string) error { - file, err := os.Create(outputFile) - if err != nil { - return fmt.Errorf("failed to create output file: %w", err) - } - defer file.Close() - - g.Write(file) - - return nil -} - -func renderWithGraphviz(dotFile, outputFile, format string) error { - // Check if dot is available - dotPath, err := exec.LookPath("dot") - if err != nil { - return fmt.Errorf("graphviz 'dot' command not found. Install with: brew install graphviz\nGenerated DOT file: %s", dotFile) - } - - cmd := exec.Command(dotPath, "-T"+format, dotFile, "-o", outputFile) - if err := cmd.Run(); err != nil { - return fmt.Errorf("failed to render graph: %w\nGenerated DOT file: %s", err, dotFile) - } - - fmt.Fprintf(os.Stderr, "Generated %s\n", outputFile) - return nil -} - diff --git a/go.mod b/go.mod index ca558579..d03d9aff 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ module github.com/cozystack/cozystack go 1.25.0 require ( + github.com/emicklei/dot v1.10.0 github.com/fluxcd/helm-controller/api v1.4.3 github.com/fluxcd/source-controller/api v1.6.2 github.com/fluxcd/source-watcher/api/v2 v2.0.2 @@ -18,6 +19,7 @@ require ( github.com/spf13/cobra v1.9.1 go.uber.org/zap v1.27.0 gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 k8s.io/api v0.34.1 k8s.io/apiextensions-apiserver v0.34.1 k8s.io/apimachinery v0.34.1 @@ -119,7 +121,6 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/kms v0.34.1 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect diff --git a/go.sum b/go.sum index 9eec9d5c..6c466a99 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/emicklei/dot v1.10.0 h1:z17n0ce/FBMz3QbShSzVGhiW447Qhu7fljzvp3Gs6ig= +github.com/emicklei/dot v1.10.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= From 224da109e2daa371468d0393854c7f889613adc8 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 22 Dec 2025 08:20:22 +0100 Subject: [PATCH 13/15] 2 --- cmd/cozyctl/cmd/inspect.go | 33 - cmd/cozyctl/cmd/install.go | 315 ---------- cmd/cozypkg/cmd/add.go | 565 ++++++++++++++++++ cmd/cozypkg/cmd/del.go | 121 ++++ cmd/{cozyctl => cozypkg}/cmd/dependencies.go | 86 ++- cmd/{cozyctl => cozypkg}/cmd/list.go | 92 ++- cmd/{cozyctl => cozypkg}/cmd/root.go | 7 +- cmd/{cozyctl => cozypkg}/main.go | 2 +- packages/core/installer/example/platform.yaml | 6 +- .../platform/templates/sources/kubevirt.yaml | 2 +- 10 files changed, 823 insertions(+), 406 deletions(-) delete mode 100644 cmd/cozyctl/cmd/inspect.go delete mode 100644 cmd/cozyctl/cmd/install.go create mode 100644 cmd/cozypkg/cmd/add.go create mode 100644 cmd/cozypkg/cmd/del.go rename cmd/{cozyctl => cozypkg}/cmd/dependencies.go (70%) rename cmd/{cozyctl => cozypkg}/cmd/list.go (64%) rename cmd/{cozyctl => cozypkg}/cmd/root.go (88%) rename cmd/{cozyctl => cozypkg}/main.go (93%) diff --git a/cmd/cozyctl/cmd/inspect.go b/cmd/cozyctl/cmd/inspect.go deleted file mode 100644 index 72f9a265..00000000 --- a/cmd/cozyctl/cmd/inspect.go +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2025 The Cozystack Authors. - -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 cmd - -import ( - "github.com/spf13/cobra" -) - -// inspectCmd represents the inspect command. -var inspectCmd = &cobra.Command{ - Use: "inspect", - Short: "Inspect internals of Cozystack", - Long: ``, -} - -func init() { - // inspectCmd can be extended with other inspect subcommands in the future -} - diff --git a/cmd/cozyctl/cmd/install.go b/cmd/cozyctl/cmd/install.go deleted file mode 100644 index 2411f453..00000000 --- a/cmd/cozyctl/cmd/install.go +++ /dev/null @@ -1,315 +0,0 @@ -/* -Copyright 2025 The Cozystack Authors. - -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 cmd - -import ( - "bufio" - "context" - "fmt" - "os" - "strconv" - "strings" - - "github.com/spf13/cobra" - cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - clientgoscheme "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" - ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" - _ "k8s.io/client-go/plugin/pkg/client/auth" -) - -var installCmdFlags struct { - kubeconfig string -} - -var installCmd = &cobra.Command{ - Use: "install PACKAGESOURCE", - Short: "Install a PackageSource and its dependencies interactively", - Long: `Install a PackageSource and its dependencies interactively. - -This command builds a dependency tree for the specified PackageSource and -prompts you to install all dependencies, starting from the root of the tree. -For each dependency, you'll be asked to choose a variant, even if only one is available. - -If a dependency is already installed, the variant selection will be skipped.`, - Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - ctx := context.Background() - packageSourceName := args[0] - - // Create Kubernetes client config - var config *rest.Config - var err error - - if installCmdFlags.kubeconfig != "" { - config, err = clientcmd.BuildConfigFromFlags("", installCmdFlags.kubeconfig) - if err != nil { - return fmt.Errorf("failed to load kubeconfig from %s: %w", installCmdFlags.kubeconfig, err) - } - } else { - config, err = ctrl.GetConfig() - if err != nil { - return fmt.Errorf("failed to get kubeconfig: %w", err) - } - } - - scheme := runtime.NewScheme() - utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(cozyv1alpha1.AddToScheme(scheme)) - - k8sClient, err := client.New(config, client.Options{Scheme: scheme}) - if err != nil { - return fmt.Errorf("failed to create k8s client: %w", err) - } - - // Get PackageSource - packageSource := &cozyv1alpha1.PackageSource{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: packageSourceName}, packageSource); err != nil { - return fmt.Errorf("failed to get PackageSource %s: %w", packageSourceName, err) - } - - // Build dependency tree - dependencyTree, err := buildDependencyTree(ctx, k8sClient, packageSourceName) - if err != nil { - return fmt.Errorf("failed to build dependency tree: %w", err) - } - - // Topological sort (install from root to leaves) - installOrder, err := topologicalSort(dependencyTree) - if err != nil { - return fmt.Errorf("failed to sort dependencies: %w", err) - } - - // Get all PackageSources for variant selection - var allPackageSources cozyv1alpha1.PackageSourceList - if err := k8sClient.List(ctx, &allPackageSources); err != nil { - return fmt.Errorf("failed to list PackageSources: %w", err) - } - - packageSourceMap := make(map[string]*cozyv1alpha1.PackageSource) - for i := range allPackageSources.Items { - packageSourceMap[allPackageSources.Items[i].Name] = &allPackageSources.Items[i] - } - - // Get all installed Packages - var installedPackages cozyv1alpha1.PackageList - if err := k8sClient.List(ctx, &installedPackages); err != nil { - return fmt.Errorf("failed to list Packages: %w", err) - } - - installedMap := make(map[string]*cozyv1alpha1.Package) - for i := range installedPackages.Items { - installedMap[installedPackages.Items[i].Name] = &installedPackages.Items[i] - } - - // Install dependencies in order - fmt.Fprintf(os.Stderr, "Installing %s and its dependencies...\n\n", packageSourceName) - for _, pkgName := range installOrder { - // Check if already installed - if installed, exists := installedMap[pkgName]; exists { - variant := installed.Spec.Variant - if variant == "" { - variant = "default" - } - fmt.Fprintf(os.Stderr, "✓ %s (already installed, variant: %s)\n", pkgName, variant) - continue - } - - // Get PackageSource for this dependency - ps, exists := packageSourceMap[pkgName] - if !exists { - fmt.Fprintf(os.Stderr, "⚠ Warning: PackageSource %s not found, skipping\n", pkgName) - continue - } - - // Select variant interactively - variant, err := selectVariantInteractive(ps) - if err != nil { - return fmt.Errorf("failed to select variant for %s: %w", pkgName, err) - } - - // Create Package - pkg := &cozyv1alpha1.Package{ - ObjectMeta: metav1.ObjectMeta{ - Name: pkgName, - }, - Spec: cozyv1alpha1.PackageSpec{ - Variant: variant, - }, - } - - if err := k8sClient.Create(ctx, pkg); err != nil { - return fmt.Errorf("failed to create Package %s: %w", pkgName, err) - } - - fmt.Fprintf(os.Stderr, "✓ Created Package %s with variant %s\n", pkgName, variant) - } - - fmt.Fprintf(os.Stderr, "\nInstallation complete!\n") - return nil - }, -} - -// buildDependencyTree builds a dependency tree starting from the root PackageSource -func buildDependencyTree(ctx context.Context, k8sClient client.Client, rootName string) (map[string][]string, error) { - tree := make(map[string][]string) - visited := make(map[string]bool) - - // Ensure root is in tree even if it has no dependencies - tree[rootName] = []string{} - - var buildTree func(string) error - buildTree = func(pkgName string) error { - if visited[pkgName] { - return nil - } - visited[pkgName] = true - - // Get PackageSource - ps := &cozyv1alpha1.PackageSource{} - if err := k8sClient.Get(ctx, client.ObjectKey{Name: pkgName}, ps); err != nil { - // If PackageSource doesn't exist, just skip it - return nil - } - - // Collect all dependencies from all variants - deps := make(map[string]bool) - for _, variant := range ps.Spec.Variants { - for _, dep := range variant.DependsOn { - deps[dep] = true - } - } - - // Add dependencies to tree - for dep := range deps { - if _, exists := tree[pkgName]; !exists { - tree[pkgName] = []string{} - } - tree[pkgName] = append(tree[pkgName], dep) - // Recursively build tree for dependencies - if err := buildTree(dep); err != nil { - return err - } - } - - return nil - } - - if err := buildTree(rootName); err != nil { - return nil, err - } - - return tree, nil -} - -// topologicalSort performs topological sort on the dependency tree -// Returns order from root to leaves (dependencies first) -func topologicalSort(tree map[string][]string) ([]string, error) { - // Build reverse graph (dependencies -> dependents) - reverseGraph := make(map[string][]string) - allNodes := make(map[string]bool) - - for node, deps := range tree { - allNodes[node] = true - for _, dep := range deps { - allNodes[dep] = true - reverseGraph[dep] = append(reverseGraph[dep], node) - } - } - - // Calculate in-degrees (how many dependencies a node has) - inDegree := make(map[string]int) - for node := range allNodes { - inDegree[node] = 0 - } - for node, deps := range tree { - inDegree[node] = len(deps) - } - - // Kahn's algorithm - start with nodes that have no dependencies - var queue []string - for node, degree := range inDegree { - if degree == 0 { - queue = append(queue, node) - } - } - - var result []string - for len(queue) > 0 { - node := queue[0] - queue = queue[1:] - result = append(result, node) - - // Process dependents (nodes that depend on this node) - for _, dependent := range reverseGraph[node] { - inDegree[dependent]-- - if inDegree[dependent] == 0 { - queue = append(queue, dependent) - } - } - } - - // Check for cycles - if len(result) != len(allNodes) { - return nil, fmt.Errorf("dependency cycle detected") - } - - return result, nil -} - -// selectVariantInteractive prompts user to select a variant -func selectVariantInteractive(ps *cozyv1alpha1.PackageSource) (string, error) { - if len(ps.Spec.Variants) == 0 { - return "", fmt.Errorf("no variants available for PackageSource %s", ps.Name) - } - - reader := bufio.NewReader(os.Stdin) - - fmt.Fprintf(os.Stderr, "\nPackageSource: %s\n", ps.Name) - fmt.Fprintf(os.Stderr, "Available variants:\n") - for i, variant := range ps.Spec.Variants { - fmt.Fprintf(os.Stderr, " %d. %s\n", i+1, variant.Name) - } - - for { - fmt.Fprintf(os.Stderr, "Select variant (1-%d): ", len(ps.Spec.Variants)) - input, err := reader.ReadString('\n') - if err != nil { - return "", fmt.Errorf("failed to read input: %w", err) - } - - input = strings.TrimSpace(input) - choice, err := strconv.Atoi(input) - if err != nil || choice < 1 || choice > len(ps.Spec.Variants) { - fmt.Fprintf(os.Stderr, "Invalid choice. Please enter a number between 1 and %d.\n", len(ps.Spec.Variants)) - continue - } - - return ps.Spec.Variants[choice-1].Name, nil - } -} - -func init() { - rootCmd.AddCommand(installCmd) - installCmd.Flags().StringVar(&installCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") -} - diff --git a/cmd/cozypkg/cmd/add.go b/cmd/cozypkg/cmd/add.go new file mode 100644 index 00000000..dce99020 --- /dev/null +++ b/cmd/cozypkg/cmd/add.go @@ -0,0 +1,565 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 cmd + +import ( + "bufio" + "context" + "fmt" + "os" + "path/filepath" + "strconv" + "strings" + + "github.com/spf13/cobra" + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer/yaml" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + _ "k8s.io/client-go/plugin/pkg/client/auth" +) + +var addCmdFlags struct { + files []string + kubeconfig string +} + +var addCmd = &cobra.Command{ + Use: "add [package]...", + Short: "Install PackageSource and its dependencies interactively", + Long: `Install PackageSource and its dependencies interactively. + +You can specify packages as arguments or use -f flag to read from files. +Multiple -f flags can be specified, and they can point to files or directories.`, + Args: cobra.ArbitraryArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + // Collect package names from arguments and files + packageNames := make(map[string]bool) + packagesFromFiles := make(map[string]string) // packageName -> filePath + + for _, arg := range args { + packageNames[arg] = true + } + + // Read packages from files + for _, filePath := range addCmdFlags.files { + packages, err := readPackagesFromFile(filePath) + if err != nil { + return fmt.Errorf("failed to read packages from %s: %w", filePath, err) + } + for _, pkg := range packages { + packageNames[pkg] = true + packagesFromFiles[pkg] = filePath + } + } + + if len(packageNames) == 0 { + return fmt.Errorf("no packages specified") + } + + // Create Kubernetes client config + var config *rest.Config + var err error + + if addCmdFlags.kubeconfig != "" { + config, err = clientcmd.BuildConfigFromFlags("", addCmdFlags.kubeconfig) + if err != nil { + return fmt.Errorf("failed to load kubeconfig from %s: %w", addCmdFlags.kubeconfig, err) + } + } else { + config, err = ctrl.GetConfig() + if err != nil { + return fmt.Errorf("failed to get kubeconfig: %w", err) + } + } + + scheme := runtime.NewScheme() + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(cozyv1alpha1.AddToScheme(scheme)) + + k8sClient, err := client.New(config, client.Options{Scheme: scheme}) + if err != nil { + return fmt.Errorf("failed to create k8s client: %w", err) + } + + // Process each package + for packageName := range packageNames { + // Check if package comes from a file + if filePath, fromFile := packagesFromFiles[packageName]; fromFile { + // Try to create Package directly from file + if err := createPackageFromFile(ctx, k8sClient, filePath, packageName); err == nil { + fmt.Fprintf(os.Stderr, "✓ Added Package %s\n", packageName) + continue + } + // If failed, fall back to interactive installation + } + + // Interactive installation from PackageSource + if err := installPackage(ctx, k8sClient, packageName); err != nil { + return err + } + } + + return nil + }, +} + +func readPackagesFromFile(filePath string) ([]string, error) { + info, err := os.Stat(filePath) + if err != nil { + return nil, err + } + + var packages []string + + if info.IsDir() { + // Read all YAML files from directory + err := filepath.Walk(filePath, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() || !strings.HasSuffix(path, ".yaml") && !strings.HasSuffix(path, ".yml") { + return nil + } + + pkgs, err := readPackagesFromYAMLFile(path) + if err != nil { + return fmt.Errorf("failed to read %s: %w", path, err) + } + packages = append(packages, pkgs...) + return nil + }) + if err != nil { + return nil, err + } + } else { + packages, err = readPackagesFromYAMLFile(filePath) + if err != nil { + return nil, err + } + } + + return packages, nil +} + +func readPackagesFromYAMLFile(filePath string) ([]string, error) { + data, err := os.ReadFile(filePath) + if err != nil { + return nil, err + } + + var packages []string + + // Split YAML documents (in case of multiple resources) + documents := strings.Split(string(data), "---") + + for _, doc := range documents { + doc = strings.TrimSpace(doc) + if doc == "" { + continue + } + + // Parse using Kubernetes decoder + decoder := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) + obj := &unstructured.Unstructured{} + _, _, err := decoder.Decode([]byte(doc), nil, obj) + if err != nil { + continue + } + + // Check if it's a Package + if obj.GetKind() == "Package" { + name := obj.GetName() + if name != "" { + packages = append(packages, name) + } + continue + } + + // Check if it's a PackageSource + if obj.GetKind() == "PackageSource" { + name := obj.GetName() + if name != "" { + packages = append(packages, name) + } + continue + } + + // Try to parse as PackageList + if obj.GetKind() == "PackageList" { + items, found, err := unstructured.NestedSlice(obj.Object, "items") + if err == nil && found { + for _, item := range items { + if itemMap, ok := item.(map[string]interface{}); ok { + if metadata, ok := itemMap["metadata"].(map[string]interface{}); ok { + if name, ok := metadata["name"].(string); ok && name != "" { + packages = append(packages, name) + } + } + } + } + } + continue + } + + // Try to parse as PackageSourceList + if obj.GetKind() == "PackageSourceList" { + items, found, err := unstructured.NestedSlice(obj.Object, "items") + if err == nil && found { + for _, item := range items { + if itemMap, ok := item.(map[string]interface{}); ok { + if metadata, ok := itemMap["metadata"].(map[string]interface{}); ok { + if name, ok := metadata["name"].(string); ok && name != "" { + packages = append(packages, name) + } + } + } + } + } + continue + } + } + + if len(packages) == 0 { + return nil, fmt.Errorf("no valid packages found in file") + } + + return packages, nil +} + +// buildDependencyTree builds a dependency tree starting from the root PackageSource +// Returns both the dependency tree and a map of dependencies to their requesters +func buildDependencyTree(ctx context.Context, k8sClient client.Client, rootName string) (map[string][]string, map[string]string, error) { + tree := make(map[string][]string) + dependencyRequesters := make(map[string]string) // dep -> requester + visited := make(map[string]bool) + + // Ensure root is in tree even if it has no dependencies + tree[rootName] = []string{} + + var buildTree func(string) error + buildTree = func(pkgName string) error { + if visited[pkgName] { + return nil + } + visited[pkgName] = true + + // Get PackageSource + ps := &cozyv1alpha1.PackageSource{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: pkgName}, ps); err != nil { + // If PackageSource doesn't exist, just skip it + return nil + } + + // Collect all dependencies from all variants + deps := make(map[string]bool) + for _, variant := range ps.Spec.Variants { + for _, dep := range variant.DependsOn { + deps[dep] = true + } + } + + // Add dependencies to tree + for dep := range deps { + if _, exists := tree[pkgName]; !exists { + tree[pkgName] = []string{} + } + tree[pkgName] = append(tree[pkgName], dep) + // Track who requested this dependency + dependencyRequesters[dep] = pkgName + // Recursively build tree for dependencies + if err := buildTree(dep); err != nil { + return err + } + } + + return nil + } + + if err := buildTree(rootName); err != nil { + return nil, nil, err + } + + return tree, dependencyRequesters, nil +} + +// topologicalSort performs topological sort on the dependency tree +// Returns order from root to leaves (dependencies first) +func topologicalSort(tree map[string][]string) ([]string, error) { + // Build reverse graph (dependencies -> dependents) + reverseGraph := make(map[string][]string) + allNodes := make(map[string]bool) + + for node, deps := range tree { + allNodes[node] = true + for _, dep := range deps { + allNodes[dep] = true + reverseGraph[dep] = append(reverseGraph[dep], node) + } + } + + // Calculate in-degrees (how many dependencies a node has) + inDegree := make(map[string]int) + for node := range allNodes { + inDegree[node] = 0 + } + for node, deps := range tree { + inDegree[node] = len(deps) + } + + // Kahn's algorithm - start with nodes that have no dependencies + var queue []string + for node, degree := range inDegree { + if degree == 0 { + queue = append(queue, node) + } + } + + var result []string + for len(queue) > 0 { + node := queue[0] + queue = queue[1:] + result = append(result, node) + + // Process dependents (nodes that depend on this node) + for _, dependent := range reverseGraph[node] { + inDegree[dependent]-- + if inDegree[dependent] == 0 { + queue = append(queue, dependent) + } + } + } + + // Check for cycles + if len(result) != len(allNodes) { + return nil, fmt.Errorf("dependency cycle detected") + } + + return result, nil +} + +// createPackageFromFile creates a Package resource directly from a YAML file +func createPackageFromFile(ctx context.Context, k8sClient client.Client, filePath string, packageName string) error { + data, err := os.ReadFile(filePath) + if err != nil { + return err + } + + // Split YAML documents + documents := strings.Split(string(data), "---") + + for _, doc := range documents { + doc = strings.TrimSpace(doc) + if doc == "" { + continue + } + + // Parse using Kubernetes decoder + decoder := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) + obj := &unstructured.Unstructured{} + _, _, err := decoder.Decode([]byte(doc), nil, obj) + if err != nil { + continue + } + + // Check if it's a Package with matching name + if obj.GetKind() == "Package" && obj.GetName() == packageName { + // Convert to Package + var pkg cozyv1alpha1.Package + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &pkg); err != nil { + return fmt.Errorf("failed to convert Package: %w", err) + } + + // Create Package + if err := k8sClient.Create(ctx, &pkg); err != nil { + return fmt.Errorf("failed to create Package: %w", err) + } + + return nil + } + } + + return fmt.Errorf("Package %s not found in file", packageName) +} + +func installPackage(ctx context.Context, k8sClient client.Client, packageSourceName string) error { + // Get PackageSource + packageSource := &cozyv1alpha1.PackageSource{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: packageSourceName}, packageSource); err != nil { + return fmt.Errorf("failed to get PackageSource %s: %w", packageSourceName, err) + } + + // Build dependency tree + dependencyTree, dependencyRequesters, err := buildDependencyTree(ctx, k8sClient, packageSourceName) + if err != nil { + return fmt.Errorf("failed to build dependency tree: %w", err) + } + + // Topological sort (install from root to leaves) + installOrder, err := topologicalSort(dependencyTree) + if err != nil { + return fmt.Errorf("failed to sort dependencies: %w", err) + } + + // Get all PackageSources for variant selection + var allPackageSources cozyv1alpha1.PackageSourceList + if err := k8sClient.List(ctx, &allPackageSources); err != nil { + return fmt.Errorf("failed to list PackageSources: %w", err) + } + + packageSourceMap := make(map[string]*cozyv1alpha1.PackageSource) + for i := range allPackageSources.Items { + packageSourceMap[allPackageSources.Items[i].Name] = &allPackageSources.Items[i] + } + + // Get all installed Packages + var installedPackages cozyv1alpha1.PackageList + if err := k8sClient.List(ctx, &installedPackages); err != nil { + return fmt.Errorf("failed to list Packages: %w", err) + } + + installedMap := make(map[string]*cozyv1alpha1.Package) + for i := range installedPackages.Items { + installedMap[installedPackages.Items[i].Name] = &installedPackages.Items[i] + } + + // First, collect all variant selections + fmt.Fprintf(os.Stderr, "Installing %s and its dependencies...\n\n", packageSourceName) + packageVariants := make(map[string]string) // packageName -> variant + + for _, pkgName := range installOrder { + // Check if already installed + if installed, exists := installedMap[pkgName]; exists { + variant := installed.Spec.Variant + if variant == "" { + variant = "default" + } + fmt.Fprintf(os.Stderr, "✓ %s (already installed, variant: %s)\n", pkgName, variant) + packageVariants[pkgName] = variant + continue + } + + // Get PackageSource for this dependency + ps, exists := packageSourceMap[pkgName] + if !exists { + requester := dependencyRequesters[pkgName] + if requester != "" { + return fmt.Errorf("PackageSource %s not found (required by %s)", pkgName, requester) + } + return fmt.Errorf("PackageSource %s not found", pkgName) + } + + // Select variant interactively + variant, err := selectVariantInteractive(ps) + if err != nil { + return fmt.Errorf("failed to select variant for %s: %w", pkgName, err) + } + + packageVariants[pkgName] = variant + } + + // Now create all Package resources + for _, pkgName := range installOrder { + // Skip if already installed + if _, exists := installedMap[pkgName]; exists { + continue + } + + variant := packageVariants[pkgName] + + // Create Package + pkg := &cozyv1alpha1.Package{ + ObjectMeta: metav1.ObjectMeta{ + Name: pkgName, + }, + Spec: cozyv1alpha1.PackageSpec{ + Variant: variant, + }, + } + + if err := k8sClient.Create(ctx, pkg); err != nil { + return fmt.Errorf("failed to create Package %s: %w", pkgName, err) + } + + fmt.Fprintf(os.Stderr, "✓ Added Package %s\n", pkgName) + } + + return nil +} + +// selectVariantInteractive prompts user to select a variant +func selectVariantInteractive(ps *cozyv1alpha1.PackageSource) (string, error) { + if len(ps.Spec.Variants) == 0 { + return "", fmt.Errorf("no variants available for PackageSource %s", ps.Name) + } + + reader := bufio.NewReader(os.Stdin) + + fmt.Fprintf(os.Stderr, "\nPackageSource: %s\n", ps.Name) + fmt.Fprintf(os.Stderr, "Available variants:\n") + for i, variant := range ps.Spec.Variants { + fmt.Fprintf(os.Stderr, " %d. %s\n", i+1, variant.Name) + } + + // If only one variant, use it as default + defaultVariant := ps.Spec.Variants[0].Name + var prompt string + if len(ps.Spec.Variants) == 1 { + prompt = "Select variant [1]: " + } else { + prompt = fmt.Sprintf("Select variant (1-%d): ", len(ps.Spec.Variants)) + } + + for { + fmt.Fprintf(os.Stderr, prompt) + input, err := reader.ReadString('\n') + if err != nil { + return "", fmt.Errorf("failed to read input: %w", err) + } + + input = strings.TrimSpace(input) + + // If input is empty and there's a default variant, use it + if input == "" && len(ps.Spec.Variants) == 1 { + return defaultVariant, nil + } + + choice, err := strconv.Atoi(input) + if err != nil || choice < 1 || choice > len(ps.Spec.Variants) { + fmt.Fprintf(os.Stderr, "Invalid choice. Please enter a number between 1 and %d.\n", len(ps.Spec.Variants)) + continue + } + + return ps.Spec.Variants[choice-1].Name, nil + } +} + +func init() { + rootCmd.AddCommand(addCmd) + addCmd.Flags().StringArrayVarP(&addCmdFlags.files, "file", "f", []string{}, "Read packages from file or directory (can be specified multiple times)") + addCmd.Flags().StringVar(&addCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") +} + diff --git a/cmd/cozypkg/cmd/del.go b/cmd/cozypkg/cmd/del.go new file mode 100644 index 00000000..ed4a74c2 --- /dev/null +++ b/cmd/cozypkg/cmd/del.go @@ -0,0 +1,121 @@ +/* +Copyright 2025 The Cozystack Authors. + +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 cmd + +import ( + "context" + "fmt" + "os" + + "github.com/spf13/cobra" + cozyv1alpha1 "github.com/cozystack/cozystack/api/v1alpha1" + "k8s.io/apimachinery/pkg/runtime" + utilruntime "k8s.io/apimachinery/pkg/util/runtime" + clientgoscheme "k8s.io/client-go/kubernetes/scheme" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + _ "k8s.io/client-go/plugin/pkg/client/auth" +) + +var delCmdFlags struct { + files []string + kubeconfig string +} + +var delCmd = &cobra.Command{ + Use: "del [package]...", + Short: "Delete Package resources", + Long: `Delete Package resources. + +You can specify packages as arguments or use -f flag to read from files. +Multiple -f flags can be specified, and they can point to files or directories.`, + Args: cobra.ArbitraryArgs, + RunE: func(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + // Collect package names from arguments and files + packageNames := make(map[string]bool) + for _, arg := range args { + packageNames[arg] = true + } + + // Read packages from files (reuse function from add.go) + for _, filePath := range delCmdFlags.files { + packages, err := readPackagesFromFile(filePath) + if err != nil { + return fmt.Errorf("failed to read packages from %s: %w", filePath, err) + } + for _, pkg := range packages { + packageNames[pkg] = true + } + } + + if len(packageNames) == 0 { + return fmt.Errorf("no packages specified") + } + + // Create Kubernetes client config + var config *rest.Config + var err error + + if delCmdFlags.kubeconfig != "" { + config, err = clientcmd.BuildConfigFromFlags("", delCmdFlags.kubeconfig) + if err != nil { + return fmt.Errorf("failed to load kubeconfig from %s: %w", delCmdFlags.kubeconfig, err) + } + } else { + config, err = ctrl.GetConfig() + if err != nil { + return fmt.Errorf("failed to get kubeconfig: %w", err) + } + } + + scheme := runtime.NewScheme() + utilruntime.Must(clientgoscheme.AddToScheme(scheme)) + utilruntime.Must(cozyv1alpha1.AddToScheme(scheme)) + + k8sClient, err := client.New(config, client.Options{Scheme: scheme}) + if err != nil { + return fmt.Errorf("failed to create k8s client: %w", err) + } + + // Delete each package + for packageName := range packageNames { + pkg := &cozyv1alpha1.Package{} + pkg.Name = packageName + if err := k8sClient.Delete(ctx, pkg); err != nil { + if client.IgnoreNotFound(err) == nil { + fmt.Fprintf(os.Stderr, "⚠ Package %s not found, skipping\n", packageName) + continue + } + return fmt.Errorf("failed to delete Package %s: %w", packageName, err) + } + fmt.Fprintf(os.Stderr, "✓ Deleted Package %s\n", packageName) + } + + return nil + }, +} + +func init() { + rootCmd.AddCommand(delCmd) + delCmd.Flags().StringArrayVarP(&delCmdFlags.files, "file", "f", []string{}, "Read packages from file or directory (can be specified multiple times)") + delCmd.Flags().StringVar(&delCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") +} + diff --git a/cmd/cozyctl/cmd/dependencies.go b/cmd/cozypkg/cmd/dependencies.go similarity index 70% rename from cmd/cozyctl/cmd/dependencies.go rename to cmd/cozypkg/cmd/dependencies.go index ccae733b..b7a8c17b 100644 --- a/cmd/cozyctl/cmd/dependencies.go +++ b/cmd/cozypkg/cmd/dependencies.go @@ -35,36 +35,67 @@ import ( _ "k8s.io/client-go/plugin/pkg/client/auth" ) -var dependenciesCmdFlags struct { +var dotCmdFlags struct { installed bool components bool + files []string kubeconfig string } -var dependenciesCmd = &cobra.Command{ - Use: "dependencies [PACKAGE]", - Short: "Inspect PackageSource dependencies as graphviz graph.", - Long: `Inspect PackageSource dependencies as graphviz graph. +var dotCmd = &cobra.Command{ + Use: "dot [package]...", + Short: "Generate dependency graph as graphviz DOT format", + Long: `Generate dependency graph as graphviz DOT format. -Pipe the output of the command through the "dot" program (part of graphviz package) -to render the graph: +Pipe the output through the "dot" program (part of graphviz package) to render the graph: - cozyctl dependencies | dot -Tpng > graph.png + cozypkg dot | dot -Tpng > graph.png -If PACKAGE is specified, shows dependencies only for that PackageSource. -If -i flag is set, shows dependencies only for installed Package resources.`, - Args: cobra.MaximumNArgs(1), +By default, shows dependencies for all PackageSource resources. +Use --installed to show only installed Package resources. +Specify packages as arguments or use -f flag to read from files.`, + Args: cobra.ArbitraryArgs, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() + // Collect package names from arguments and files + packageNames := make(map[string]bool) + for _, arg := range args { + packageNames[arg] = true + } + + // Read packages from files (reuse function from add.go) + for _, filePath := range dotCmdFlags.files { + packages, err := readPackagesFromFile(filePath) + if err != nil { + return fmt.Errorf("failed to read packages from %s: %w", filePath, err) + } + for _, pkg := range packages { + packageNames[pkg] = true + } + } + + // Convert to slice, empty means all packages + var selectedPackages []string + if len(packageNames) > 0 { + for pkg := range packageNames { + selectedPackages = append(selectedPackages, pkg) + } + } + + // If multiple packages specified, show graph for all of them + // If single package, use packageName for backward compatibility var packageName string - if len(args) > 0 { - packageName = args[0] + if len(selectedPackages) == 1 { + packageName = selectedPackages[0] + } else if len(selectedPackages) > 1 { + // Multiple packages - pass empty string to packageName, use selectedPackages + packageName = "" } // packagesOnly is inverse of components flag (if components=false, then packagesOnly=true) - packagesOnly := !dependenciesCmdFlags.components - graph, allNodes, err := buildGraphFromCluster(ctx, dependenciesCmdFlags.kubeconfig, packagesOnly, dependenciesCmdFlags.installed, packageName) + packagesOnly := !dotCmdFlags.components + graph, allNodes, err := buildGraphFromCluster(ctx, dotCmdFlags.kubeconfig, packagesOnly, dotCmdFlags.installed, packageName, selectedPackages) if err != nil { return fmt.Errorf("error getting PackageSource dependencies: %w", err) } @@ -77,10 +108,11 @@ If -i flag is set, shows dependencies only for installed Package resources.`, } func init() { - rootCmd.AddCommand(dependenciesCmd) - dependenciesCmd.Flags().BoolVarP(&dependenciesCmdFlags.installed, "installed", "i", false, "show dependencies only for installed Package resources") - dependenciesCmd.Flags().BoolVar(&dependenciesCmdFlags.components, "components", true, "show component-level dependencies (default: true)") - dependenciesCmd.Flags().StringVar(&dependenciesCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") + rootCmd.AddCommand(dotCmd) + dotCmd.Flags().BoolVarP(&dotCmdFlags.installed, "installed", "i", false, "show dependencies only for installed Package resources") + dotCmd.Flags().BoolVar(&dotCmdFlags.components, "components", true, "show component-level dependencies (default: true)") + dotCmd.Flags().StringArrayVarP(&dotCmdFlags.files, "file", "f", []string{}, "Read packages from file or directory (can be specified multiple times)") + dotCmd.Flags().StringVar(&dotCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") } var ( @@ -93,7 +125,7 @@ func init() { } // buildGraphFromCluster builds a dependency graph from PackageSource resources in the cluster. -func buildGraphFromCluster(ctx context.Context, kubeconfig string, packagesOnly bool, installedOnly bool, packageName string) (map[string][]string, map[string]bool, error) { +func buildGraphFromCluster(ctx context.Context, kubeconfig string, packagesOnly bool, installedOnly bool, packageName string, selectedPackages []string) (map[string][]string, map[string]bool, error) { // Create Kubernetes client config var config *rest.Config var err error @@ -150,6 +182,20 @@ func buildGraphFromCluster(ctx context.Context, kubeconfig string, packagesOnly continue } + // Filter by selected packages if specified + if len(selectedPackages) > 0 { + found := false + for _, selected := range selectedPackages { + if psName == selected { + found = true + break + } + } + if !found { + continue + } + } + // Filter by installed packages if flag is set if installedOnly && !installedPackages[psName] { continue diff --git a/cmd/cozyctl/cmd/list.go b/cmd/cozypkg/cmd/list.go similarity index 64% rename from cmd/cozyctl/cmd/list.go rename to cmd/cozypkg/cmd/list.go index 544429d1..faa898b1 100644 --- a/cmd/cozyctl/cmd/list.go +++ b/cmd/cozypkg/cmd/list.go @@ -36,6 +36,7 @@ import ( var listCmdFlags struct { installed bool + components bool kubeconfig string } @@ -44,7 +45,8 @@ var listCmd = &cobra.Command{ Short: "List PackageSource or Package resources", Long: `List PackageSource or Package resources in table format. -By default, lists PackageSource resources. Use -i flag to list installed Package resources.`, +By default, lists PackageSource resources. Use --installed flag to list installed Package resources. +Use --components flag to show components on separate lines.`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -75,13 +77,13 @@ By default, lists PackageSource resources. Use -i flag to list installed Package } if listCmdFlags.installed { - return listPackages(ctx, k8sClient) + return listPackages(ctx, k8sClient, listCmdFlags.components) } - return listPackageSources(ctx, k8sClient) + return listPackageSources(ctx, k8sClient, listCmdFlags.components) }, } -func listPackageSources(ctx context.Context, k8sClient client.Client) error { +func listPackageSources(ctx context.Context, k8sClient client.Client, showComponents bool) error { var psList cozyv1alpha1.PackageSourceList if err := k8sClient.List(ctx, &psList); err != nil { return fmt.Errorf("failed to list PackageSources: %w", err) @@ -91,39 +93,50 @@ func listPackageSources(ctx context.Context, k8sClient client.Client) error { fmt.Fprintf(os.Stdout, "%-50s %-30s %-10s %s\n", "NAME", "VARIANTS", "READY", "STATUS") fmt.Fprintf(os.Stdout, "%-50s %-30s %-10s %s\n", strings.Repeat("-", 50), strings.Repeat("-", 30), strings.Repeat("-", 10), strings.Repeat("-", 50)) - // Print rows - for _, ps := range psList.Items { - // Get variants - var variants []string - for _, variant := range ps.Spec.Variants { - variants = append(variants, variant.Name) - } - variantsStr := strings.Join(variants, ",") - if len(variantsStr) > 28 { - variantsStr = variantsStr[:25] + "..." - } + // Print rows + for _, ps := range psList.Items { + // Get variants + var variants []string + for _, variant := range ps.Spec.Variants { + variants = append(variants, variant.Name) + } + variantsStr := strings.Join(variants, ",") + if len(variantsStr) > 28 { + variantsStr = variantsStr[:25] + "..." + } - // Get Ready condition - ready := "Unknown" - status := "" - for _, condition := range ps.Status.Conditions { - if condition.Type == "Ready" { - ready = string(condition.Status) - status = condition.Message - if len(status) > 48 { - status = status[:45] + "..." + // Get Ready condition + ready := "Unknown" + status := "" + for _, condition := range ps.Status.Conditions { + if condition.Type == "Ready" { + ready = string(condition.Status) + status = condition.Message + if len(status) > 48 { + status = status[:45] + "..." + } + break + } + } + + fmt.Fprintf(os.Stdout, "%-50s %-30s %-10s %s\n", ps.Name, variantsStr, ready, status) + + // Show components if requested + if showComponents { + for _, variant := range ps.Spec.Variants { + for _, component := range variant.Components { + fmt.Fprintf(os.Stdout, " %-48s %-30s %-10s %s\n", + fmt.Sprintf("%s.%s", ps.Name, component.Name), + variant.Name, "", "") + } } - break } } - fmt.Fprintf(os.Stdout, "%-50s %-30s %-10s %s\n", ps.Name, variantsStr, ready, status) - } - return nil } -func listPackages(ctx context.Context, k8sClient client.Client) error { +func listPackages(ctx context.Context, k8sClient client.Client, showComponents bool) error { var pkgList cozyv1alpha1.PackageList if err := k8sClient.List(ctx, &pkgList); err != nil { return fmt.Errorf("failed to list Packages: %w", err) @@ -155,13 +168,34 @@ func listPackages(ctx context.Context, k8sClient client.Client) error { } fmt.Fprintf(os.Stdout, "%-50s %-20s %-10s %s\n", pkg.Name, variant, ready, status) + + // Show components if requested + if showComponents { + // Get PackageSource to show components + ps := &cozyv1alpha1.PackageSource{} + if err := k8sClient.Get(ctx, client.ObjectKey{Name: pkg.Name}, ps); err == nil { + // Find the variant + for _, v := range ps.Spec.Variants { + if v.Name == variant { + for _, component := range v.Components { + fmt.Fprintf(os.Stdout, " %-48s %-20s %-10s %s\n", + fmt.Sprintf("%s.%s", pkg.Name, component.Name), + variant, "", "") + } + break + } + } + } + } } return nil } func init() { + rootCmd.AddCommand(listCmd) listCmd.Flags().BoolVarP(&listCmdFlags.installed, "installed", "i", false, "list installed Package resources instead of PackageSource resources") + listCmd.Flags().BoolVar(&listCmdFlags.components, "components", false, "show components on separate lines") listCmd.Flags().StringVar(&listCmdFlags.kubeconfig, "kubeconfig", "", "Path to kubeconfig file (defaults to ~/.kube/config or KUBECONFIG env var)") } diff --git a/cmd/cozyctl/cmd/root.go b/cmd/cozypkg/cmd/root.go similarity index 88% rename from cmd/cozyctl/cmd/root.go rename to cmd/cozypkg/cmd/root.go index fbe3def2..62bd54aa 100644 --- a/cmd/cozyctl/cmd/root.go +++ b/cmd/cozypkg/cmd/root.go @@ -25,8 +25,8 @@ import ( // rootCmd represents the base command when called without any subcommands. var rootCmd = &cobra.Command{ - Use: "cozyctl", - Short: "A CLI for managing Cozystack", + Use: "cozypkg", + Short: "A CLI for managing Cozystack packages", Long: ``, SilenceErrors: true, SilenceUsage: true, @@ -44,7 +44,6 @@ func Execute() error { } func init() { - rootCmd.AddCommand(inspectCmd) - rootCmd.AddCommand(listCmd) + // Commands are registered in their respective init() functions } diff --git a/cmd/cozyctl/main.go b/cmd/cozypkg/main.go similarity index 93% rename from cmd/cozyctl/main.go rename to cmd/cozypkg/main.go index 6840b9ec..7f6b9ead 100644 --- a/cmd/cozyctl/main.go +++ b/cmd/cozypkg/main.go @@ -19,7 +19,7 @@ package main import ( "os" - "github.com/cozystack/cozystack/cmd/cozyctl/cmd" + "github.com/cozystack/cozystack/cmd/cozypkg/cmd" ) func main() { diff --git a/packages/core/installer/example/platform.yaml b/packages/core/installer/example/platform.yaml index 689e5f00..6ec544aa 100644 --- a/packages/core/installer/example/platform.yaml +++ b/packages/core/installer/example/platform.yaml @@ -12,9 +12,9 @@ spec: host: "dev5.infra.aenix.org" apiServerEndpoint: "https://api.dev5.infra.aenix.org" externalIPs: - - 10.4.0.246 - - 10.4.0.180 - - 10.4.0.46 + - 10.4.0.94 + - 10.4.0.179 + - 10.4.0.26 authentication: oidc: enabled: true diff --git a/packages/core/platform/templates/sources/kubevirt.yaml b/packages/core/platform/templates/sources/kubevirt.yaml index d8ebce0f..3b41854b 100644 --- a/packages/core/platform/templates/sources/kubevirt.yaml +++ b/packages/core/platform/templates/sources/kubevirt.yaml @@ -13,7 +13,7 @@ spec: - name: default dependsOn: - cozystack.networking - - cozystack.monitoring + - cozystack.victoria-metrics-operator components: - name: kubevirt-operator path: system/kubevirt-operator From a80917ac1f1d39871763a1417c76bd9210fcc889 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 22 Dec 2025 08:37:04 +0100 Subject: [PATCH 14/15] 123 --- .../apps/bucket/templates/helmrelease.yaml | 13 +++------- .../helmreleases/cert-manager-crds.yaml | 13 +++------- .../templates/helmreleases/cert-manager.yaml | 13 +++------- .../templates/helmreleases/cilium.yaml | 13 +++------- .../templates/helmreleases/coredns.yaml | 13 +++------- .../templates/helmreleases/csi.yaml | 13 +++------- .../templates/helmreleases/fluxcd.yaml | 26 ++++++------------- .../helmreleases/gateway-api-crds.yaml | 13 +++------- .../templates/helmreleases/gpu-operator.yaml | 13 +++------- .../templates/helmreleases/ingress-nginx.yaml | 13 +++------- .../helmreleases/metrics-server.yaml | 13 +++------- .../helmreleases/monitoring-agents.yaml | 13 +++------- .../prometheus-operator-crds.yaml | 13 +++------- .../templates/helmreleases/velero.yaml | 13 +++------- .../vertical-pod-autoscaler-crds.yaml | 13 +++------- .../helmreleases/vertical-pod-autoscaler.yaml | 13 +++------- .../victoria-metrics-operator.yaml | 13 +++------- .../helmreleases/volumesnapshot-crd.yaml | 13 +++------- packages/apps/nats/templates/nats.yaml | 13 +++------- packages/apps/tenant/templates/etcd.yaml | 13 +++------- packages/apps/tenant/templates/info.yaml | 13 +++------- packages/apps/tenant/templates/ingress.yaml | 13 +++------- .../apps/tenant/templates/monitoring.yaml | 13 +++------- packages/apps/tenant/templates/seaweedfs.yaml | 13 +++------- .../sources/bootbox-application.yaml | 4 +-- .../sources/kubernetes-application.yaml | 4 +++ .../system/bootbox/templates/bootbox.yaml | 13 +++------- 27 files changed, 110 insertions(+), 236 deletions(-) diff --git a/packages/apps/bucket/templates/helmrelease.yaml b/packages/apps/bucket/templates/helmrelease.yaml index 45959572..01e7dfb2 100644 --- a/packages/apps/bucket/templates/helmrelease.yaml +++ b/packages/apps/bucket/templates/helmrelease.yaml @@ -3,15 +3,10 @@ kind: HelmRelease metadata: name: {{ .Release.Name }}-system spec: - chart: - spec: - chart: cozy-bucket - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-bucket-application-default-bucket-system + namespace: cozy-system interval: 5m timeout: 10m install: diff --git a/packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml b/packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml index 73954e12..0a14d0f3 100644 --- a/packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/cert-manager-crds.yaml @@ -8,15 +8,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: cert-manager-crds - chart: - spec: - chart: cozy-cert-manager-crds - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-cert-manager-crds + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/cert-manager.yaml b/packages/apps/kubernetes/templates/helmreleases/cert-manager.yaml index e0caf4cb..1114cd75 100644 --- a/packages/apps/kubernetes/templates/helmreleases/cert-manager.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/cert-manager.yaml @@ -8,15 +8,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: cert-manager - chart: - spec: - chart: cozy-cert-manager - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-cert-manager + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/cilium.yaml b/packages/apps/kubernetes/templates/helmreleases/cilium.yaml index c356dc79..c5482735 100644 --- a/packages/apps/kubernetes/templates/helmreleases/cilium.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/cilium.yaml @@ -22,15 +22,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: cilium - chart: - spec: - chart: cozy-cilium - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-cilium + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/coredns.yaml b/packages/apps/kubernetes/templates/helmreleases/coredns.yaml index 37a09a0b..da14661a 100644 --- a/packages/apps/kubernetes/templates/helmreleases/coredns.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/coredns.yaml @@ -13,15 +13,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: coredns - chart: - spec: - chart: cozy-coredns - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-coredns + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/csi.yaml b/packages/apps/kubernetes/templates/helmreleases/csi.yaml index 3ecbf1eb..06d48980 100644 --- a/packages/apps/kubernetes/templates/helmreleases/csi.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/csi.yaml @@ -8,15 +8,10 @@ metadata: spec: interval: 5m releaseName: csi - chart: - spec: - chart: cozy-kubevirt-csi-node - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-kubevirt-csi-node + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/fluxcd.yaml b/packages/apps/kubernetes/templates/helmreleases/fluxcd.yaml index 7518601b..793cb070 100644 --- a/packages/apps/kubernetes/templates/helmreleases/fluxcd.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/fluxcd.yaml @@ -8,15 +8,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: fluxcd-operator - chart: - spec: - chart: cozy-fluxcd-operator - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-fluxcd-operator + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig @@ -56,15 +51,10 @@ metadata: spec: interval: 5m releaseName: fluxcd - chart: - spec: - chart: cozy-fluxcd - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-fluxcd + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/gateway-api-crds.yaml b/packages/apps/kubernetes/templates/helmreleases/gateway-api-crds.yaml index 48a20c5a..16683f02 100644 --- a/packages/apps/kubernetes/templates/helmreleases/gateway-api-crds.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/gateway-api-crds.yaml @@ -8,15 +8,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: gateway-api-crds - chart: - spec: - chart: cozy-gateway-api-crds - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-gateway-api-crds + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/gpu-operator.yaml b/packages/apps/kubernetes/templates/helmreleases/gpu-operator.yaml index fbee1724..0b7953bb 100644 --- a/packages/apps/kubernetes/templates/helmreleases/gpu-operator.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/gpu-operator.yaml @@ -8,15 +8,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: gpu-operator - chart: - spec: - chart: cozy-gpu-operator - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-gpu-operator + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/ingress-nginx.yaml b/packages/apps/kubernetes/templates/helmreleases/ingress-nginx.yaml index f80dd7ae..0f147798 100644 --- a/packages/apps/kubernetes/templates/helmreleases/ingress-nginx.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/ingress-nginx.yaml @@ -27,15 +27,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: ingress-nginx - chart: - spec: - chart: cozy-ingress-nginx - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-ingress-nginx + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/metrics-server.yaml b/packages/apps/kubernetes/templates/helmreleases/metrics-server.yaml index 394e6bb4..8f99c62c 100644 --- a/packages/apps/kubernetes/templates/helmreleases/metrics-server.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/metrics-server.yaml @@ -7,15 +7,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: metrics-server - chart: - spec: - chart: cozy-metrics-server - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-metrics-server + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml b/packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml index cf93f233..565fc5a9 100644 --- a/packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/monitoring-agents.yaml @@ -10,15 +10,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: cozy-monitoring-agents - chart: - spec: - chart: cozy-monitoring-agents - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-monitoring-agents + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yaml b/packages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yaml index 63972126..6f9ef87d 100644 --- a/packages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/prometheus-operator-crds.yaml @@ -7,15 +7,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: prometheus-operator-crds - chart: - spec: - chart: cozy-prometheus-operator-crds - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-prometheus-operator-crds + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/velero.yaml b/packages/apps/kubernetes/templates/helmreleases/velero.yaml index 0c918da6..29abc286 100644 --- a/packages/apps/kubernetes/templates/helmreleases/velero.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/velero.yaml @@ -8,15 +8,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: velero - chart: - spec: - chart: cozy-velero - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-velero + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml b/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml index 71bdc9ee..89393b7f 100644 --- a/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler-crds.yaml @@ -9,15 +9,10 @@ metadata: spec: interval: 5m releaseName: vertical-pod-autoscaler-crds - chart: - spec: - chart: cozy-vertical-pod-autoscaler-crds - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-vertical-pod-autoscaler-crds + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml b/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml index 8b615c9c..bee264a2 100644 --- a/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/vertical-pod-autoscaler.yaml @@ -36,15 +36,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: vertical-pod-autoscaler - chart: - spec: - chart: cozy-vertical-pod-autoscaler - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-vertical-pod-autoscaler + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/victoria-metrics-operator.yaml b/packages/apps/kubernetes/templates/helmreleases/victoria-metrics-operator.yaml index dbb4d8dc..da53ea8d 100644 --- a/packages/apps/kubernetes/templates/helmreleases/victoria-metrics-operator.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/victoria-metrics-operator.yaml @@ -8,15 +8,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: cozy-victoria-metrics-operator - chart: - spec: - chart: cozy-victoria-metrics-operator - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-victoria-metrics-operator + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yaml b/packages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yaml index 83fa32d1..74105e5b 100644 --- a/packages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yaml +++ b/packages/apps/kubernetes/templates/helmreleases/volumesnapshot-crd.yaml @@ -7,15 +7,10 @@ metadata: cozystack.io/target-cluster-name: {{ .Release.Name }} spec: releaseName: vsnap-crd - chart: - spec: - chart: cozy-vsnap-crd - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-kubernetes-application-kubevirt-kubernetes-volumesnapshot-crd + namespace: cozy-system kubeConfig: secretRef: name: {{ .Release.Name }}-admin-kubeconfig diff --git a/packages/apps/nats/templates/nats.yaml b/packages/apps/nats/templates/nats.yaml index b05c87b5..0d66c8e8 100644 --- a/packages/apps/nats/templates/nats.yaml +++ b/packages/apps/nats/templates/nats.yaml @@ -35,15 +35,10 @@ kind: HelmRelease metadata: name: {{ .Release.Name }}-system spec: - chart: - spec: - chart: cozy-nats - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-system - namespace: cozy-system - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-nats-application-default-nats-system + namespace: cozy-system interval: 5m timeout: 10m install: diff --git a/packages/apps/tenant/templates/etcd.yaml b/packages/apps/tenant/templates/etcd.yaml index 8cd720cc..2af6e9df 100644 --- a/packages/apps/tenant/templates/etcd.yaml +++ b/packages/apps/tenant/templates/etcd.yaml @@ -13,15 +13,10 @@ metadata: apps.cozystack.io/application.group: apps.cozystack.io apps.cozystack.io/application.name: etcd spec: - chart: - spec: - chart: etcd - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-extra - namespace: cozy-public - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-etcd-application-default-etcd + namespace: cozy-system interval: 5m timeout: 10m install: diff --git a/packages/apps/tenant/templates/info.yaml b/packages/apps/tenant/templates/info.yaml index 4a66e422..a2b9488f 100644 --- a/packages/apps/tenant/templates/info.yaml +++ b/packages/apps/tenant/templates/info.yaml @@ -12,15 +12,10 @@ metadata: apps.cozystack.io/application.group: apps.cozystack.io apps.cozystack.io/application.name: info spec: - chart: - spec: - chart: info - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-extra - namespace: cozy-public - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-info-application-default-info + namespace: cozy-system interval: 5m timeout: 10m install: diff --git a/packages/apps/tenant/templates/ingress.yaml b/packages/apps/tenant/templates/ingress.yaml index beb07342..b9c853c2 100644 --- a/packages/apps/tenant/templates/ingress.yaml +++ b/packages/apps/tenant/templates/ingress.yaml @@ -13,15 +13,10 @@ metadata: apps.cozystack.io/application.group: apps.cozystack.io apps.cozystack.io/application.name: ingress spec: - chart: - spec: - chart: ingress - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-extra - namespace: cozy-public - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-ingress-application-default-ingress + namespace: cozy-system interval: 5m timeout: 10m install: diff --git a/packages/apps/tenant/templates/monitoring.yaml b/packages/apps/tenant/templates/monitoring.yaml index 4986fc21..440ea790 100644 --- a/packages/apps/tenant/templates/monitoring.yaml +++ b/packages/apps/tenant/templates/monitoring.yaml @@ -13,15 +13,10 @@ metadata: apps.cozystack.io/application.group: apps.cozystack.io apps.cozystack.io/application.name: monitoring spec: - chart: - spec: - chart: monitoring - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-extra - namespace: cozy-public - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-monitoring-application-default-monitoring + namespace: cozy-system interval: 5m timeout: 10m install: diff --git a/packages/apps/tenant/templates/seaweedfs.yaml b/packages/apps/tenant/templates/seaweedfs.yaml index 9a714b79..c7b565b2 100644 --- a/packages/apps/tenant/templates/seaweedfs.yaml +++ b/packages/apps/tenant/templates/seaweedfs.yaml @@ -13,15 +13,10 @@ metadata: apps.cozystack.io/application.group: apps.cozystack.io apps.cozystack.io/application.name: seaweedfs spec: - chart: - spec: - chart: seaweedfs - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-extra - namespace: cozy-public - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-seaweedfs-application-default-seaweedfs + namespace: cozy-system interval: 5m timeout: 10m install: diff --git a/packages/core/platform/templates/sources/bootbox-application.yaml b/packages/core/platform/templates/sources/bootbox-application.yaml index 86f1fa6e..a1c8a481 100644 --- a/packages/core/platform/templates/sources/bootbox-application.yaml +++ b/packages/core/platform/templates/sources/bootbox-application.yaml @@ -17,12 +17,12 @@ spec: - name: cozy-lib path: library/cozy-lib components: - - name: bootbox + - name: bootbox-system path: system/bootbox install: releaseName: bootbox-application namespace: cozy-system - - name: bootbox-app + - name: bootbox path: extra/bootbox libraries: ["cozy-lib"] - name: bootbox-rd diff --git a/packages/core/platform/templates/sources/kubernetes-application.yaml b/packages/core/platform/templates/sources/kubernetes-application.yaml index 93e4d68b..0acde1c4 100644 --- a/packages/core/platform/templates/sources/kubernetes-application.yaml +++ b/packages/core/platform/templates/sources/kubernetes-application.yaml @@ -54,6 +54,10 @@ spec: path: system/gpu-operator - name: kubernetes-vertical-pod-autoscaler path: system/vertical-pod-autoscaler + - name: kubernetes-prometheus-operator-crds + path: system/prometheus-operator-crds + - name: kubernetes-metrics-server + path: system/metrics-server - name: kubernetes path: apps/kubernetes libraries: ["cozy-lib"] diff --git a/packages/system/bootbox/templates/bootbox.yaml b/packages/system/bootbox/templates/bootbox.yaml index 45cd07ce..a29b4461 100644 --- a/packages/system/bootbox/templates/bootbox.yaml +++ b/packages/system/bootbox/templates/bootbox.yaml @@ -11,14 +11,9 @@ metadata: name: bootbox namespace: tenant-root spec: - chart: - spec: - chart: bootbox - reconcileStrategy: Revision - sourceRef: - kind: HelmRepository - name: cozystack-extra - namespace: cozy-public - version: '>= 0.0.0-0' + chartRef: + kind: ExternalArtifact + name: cozystack-bootbox-application-default-bootbox + namespace: cozy-system interval: 1m0s timeout: 5m0s From 43cef5d50e31aaf21c7cdf39d741dabd959096f3 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Mon, 22 Dec 2025 08:46:02 +0100 Subject: [PATCH 15/15] api --- hack/update-codegen.sh | 5 +++++ .../installer}/crds/cozystack.io_packages.yaml | 0 .../installer}/crds/cozystack.io_packagesources.yaml | 0 packages/core/installer/templates/crds.yaml | 6 ++++++ 4 files changed, 11 insertions(+) rename packages/{system/cozystack-controller => core/installer}/crds/cozystack.io_packages.yaml (100%) rename packages/{system/cozystack-controller => core/installer}/crds/cozystack.io_packagesources.yaml (100%) create mode 100644 packages/core/installer/templates/crds.yaml diff --git a/hack/update-codegen.sh b/hack/update-codegen.sh index 0e43f717..4c2f8786 100755 --- a/hack/update-codegen.sh +++ b/hack/update-codegen.sh @@ -24,6 +24,8 @@ API_KNOWN_VIOLATIONS_DIR="${API_KNOWN_VIOLATIONS_DIR:-"${SCRIPT_ROOT}/api/api-ru UPDATE_API_KNOWN_VIOLATIONS="${UPDATE_API_KNOWN_VIOLATIONS:-true}" CONTROLLER_GEN="go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.16.4" TMPDIR=$(mktemp -d) +OPERATOR_CRDDIR=packages/core/installer/crds +BACKUPSTRATEGY_CRDDIR=packages/system/backupstrategy-controller/definitions COZY_CONTROLLER_CRDDIR=packages/system/cozystack-controller/crds COZY_RD_CRDDIR=packages/system/cozystack-resource-definition-crd/definition BACKUPS_CORE_CRDDIR=packages/system/backup-controller/definitions @@ -62,6 +64,9 @@ kube::codegen::gen_openapi \ $CONTROLLER_GEN object:headerFile="hack/boilerplate.go.txt" paths="./api/..." $CONTROLLER_GEN rbac:roleName=manager-role crd paths="./api/..." output:crd:artifacts:config=${TMPDIR} +mv ${TMPDIR}/cozystack.io_packages.yaml ${OPERATOR_CRDDIR}/cozystack.io_packages.yaml +mv ${TMPDIR}/cozystack.io_packagesources.yaml ${OPERATOR_CRDDIR}/cozystack.io_packagesources.yaml + mv ${TMPDIR}/cozystack.io_cozystackresourcedefinitions.yaml \ ${COZY_RD_CRDDIR}/cozystack.io_cozystackresourcedefinitions.yaml diff --git a/packages/system/cozystack-controller/crds/cozystack.io_packages.yaml b/packages/core/installer/crds/cozystack.io_packages.yaml similarity index 100% rename from packages/system/cozystack-controller/crds/cozystack.io_packages.yaml rename to packages/core/installer/crds/cozystack.io_packages.yaml diff --git a/packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml b/packages/core/installer/crds/cozystack.io_packagesources.yaml similarity index 100% rename from packages/system/cozystack-controller/crds/cozystack.io_packagesources.yaml rename to packages/core/installer/crds/cozystack.io_packagesources.yaml diff --git a/packages/core/installer/templates/crds.yaml b/packages/core/installer/templates/crds.yaml new file mode 100644 index 00000000..9ff44d13 --- /dev/null +++ b/packages/core/installer/templates/crds.yaml @@ -0,0 +1,6 @@ +{{/* +{{- range $path, $_ := .Files.Glob "crds/*.yaml" }} +--- +{{ $.Files.Get $path }} +{{- end }} +*/}}