mirror of
https://github.com/cozystack/cozystack.git
synced 2026-03-03 21:48:57 +00:00
Compare commits
59 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1f056ff4e | ||
|
|
181fc3cc40 | ||
|
|
3d403205ca | ||
|
|
3b027a7da9 | ||
|
|
68718b9bf4 | ||
|
|
32b12ceefa | ||
|
|
c1ec2a2fc3 | ||
|
|
71c32d91a7 | ||
|
|
65ea7116ce | ||
|
|
d7b5636f23 | ||
|
|
b0beb6edf9 | ||
|
|
7058e404cf | ||
|
|
25edc1f54b | ||
|
|
36a52277f6 | ||
|
|
0e5aad8588 | ||
|
|
70cb6b586a | ||
|
|
90b29c7d4d | ||
|
|
82e5a0d403 | ||
|
|
520cfd2526 | ||
|
|
39db2c141a | ||
|
|
42c94cfebd | ||
|
|
9fae1b17b8 | ||
|
|
5d232bef97 | ||
|
|
19d2f43bf5 | ||
|
|
7f646d84bb | ||
|
|
83505f50c7 | ||
|
|
46de1f311b | ||
|
|
682a933156 | ||
|
|
6d402ecff9 | ||
|
|
2cb80079d1 | ||
|
|
b8604b8ec5 | ||
|
|
f645a5d8fc | ||
|
|
31d87671a1 | ||
|
|
13b294c9a7 | ||
|
|
2ee2bf55ed | ||
|
|
39f51f7fba | ||
|
|
0c50253e2c | ||
|
|
cfab053c66 | ||
|
|
67a8fa91e8 | ||
|
|
5703e16a80 | ||
|
|
297ddf853b | ||
|
|
62f80f85b4 | ||
|
|
a5cdaddbb4 | ||
|
|
0e4fe7a33e | ||
|
|
ee95353342 | ||
|
|
9506c58926 | ||
|
|
ffcc55c588 | ||
|
|
cbf67cd30e | ||
|
|
1b46ff3f6b | ||
|
|
674b3963a7 | ||
|
|
f71f914fe6 | ||
|
|
a09ed799e9 | ||
|
|
8e35d6ae4e | ||
|
|
2f8c6b72fe | ||
|
|
5a679e12ad | ||
|
|
0176ba5e95 | ||
|
|
b474c07c80 | ||
|
|
5dbdd0eafa | ||
|
|
21715c02bc |
1
Makefile
1
Makefile
@@ -15,6 +15,7 @@ build: build-deps
|
||||
make -C packages/extra/monitoring image
|
||||
make -C packages/system/cozystack-api image
|
||||
make -C packages/system/cozystack-controller image
|
||||
make -C packages/system/lineage-controller-webhook image
|
||||
make -C packages/system/cilium image
|
||||
make -C packages/system/kubeovn image
|
||||
make -C packages/system/kubeovn-webhook image
|
||||
|
||||
@@ -39,7 +39,6 @@ import (
|
||||
cozystackiov1alpha1 "github.com/cozystack/cozystack/api/v1alpha1"
|
||||
"github.com/cozystack/cozystack/internal/controller"
|
||||
"github.com/cozystack/cozystack/internal/controller/dashboard"
|
||||
lcw "github.com/cozystack/cozystack/internal/lineagecontrollerwebhook"
|
||||
"github.com/cozystack/cozystack/internal/telemetry"
|
||||
|
||||
helmv2 "github.com/fluxcd/helm-controller/api/v2"
|
||||
@@ -222,20 +221,6 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// special one that's both a webhook and a reconciler
|
||||
lineageControllerWebhook := &lcw.LineageControllerWebhook{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: mgr.GetScheme(),
|
||||
}
|
||||
if err := lineageControllerWebhook.SetupWithManagerAsController(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to setup controller", "controller", "LineageController")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := lineageControllerWebhook.SetupWithManagerAsWebhook(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to setup webhook", "webhook", "LineageWebhook")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// +kubebuilder:scaffold:builder
|
||||
|
||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||
|
||||
179
cmd/lineage-controller-webhook/main.go
Normal file
179
cmd/lineage-controller-webhook/main.go
Normal file
@@ -0,0 +1,179 @@
|
||||
/*
|
||||
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 main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"os"
|
||||
|
||||
// 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"
|
||||
|
||||
"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/healthz"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
|
||||
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
||||
"sigs.k8s.io/controller-runtime/pkg/webhook"
|
||||
|
||||
cozystackiov1alpha1 "github.com/cozystack/cozystack/api/v1alpha1"
|
||||
lcw "github.com/cozystack/cozystack/internal/lineagecontrollerwebhook"
|
||||
// +kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
var (
|
||||
scheme = runtime.NewScheme()
|
||||
setupLog = ctrl.Log.WithName("setup")
|
||||
)
|
||||
|
||||
func init() {
|
||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||
|
||||
utilruntime.Must(cozystackiov1alpha1.AddToScheme(scheme))
|
||||
// +kubebuilder:scaffold:scheme
|
||||
}
|
||||
|
||||
func main() {
|
||||
var metricsAddr string
|
||||
var enableLeaderElection bool
|
||||
var probeAddr string
|
||||
var secureMetrics bool
|
||||
var enableHTTP2 bool
|
||||
var tlsOpts []func(*tls.Config)
|
||||
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
|
||||
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
|
||||
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", true,
|
||||
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
|
||||
flag.BoolVar(&enableHTTP2, "enable-http2", false,
|
||||
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
|
||||
opts := zap.Options{
|
||||
Development: false,
|
||||
}
|
||||
opts.BindFlags(flag.CommandLine)
|
||||
flag.Parse()
|
||||
|
||||
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
|
||||
|
||||
// if the enable-http2 flag is false (the default), http/2 should be disabled
|
||||
// due to its vulnerabilities. More specifically, disabling http/2 will
|
||||
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
|
||||
// Rapid Reset CVEs. For more information see:
|
||||
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
|
||||
// - https://github.com/advisories/GHSA-4374-p667-p6c8
|
||||
disableHTTP2 := func(c *tls.Config) {
|
||||
setupLog.Info("disabling http/2")
|
||||
c.NextProtos = []string{"http/1.1"}
|
||||
}
|
||||
|
||||
if !enableHTTP2 {
|
||||
tlsOpts = append(tlsOpts, disableHTTP2)
|
||||
}
|
||||
|
||||
webhookServer := webhook.NewServer(webhook.Options{
|
||||
TLSOpts: tlsOpts,
|
||||
})
|
||||
|
||||
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
|
||||
// More info:
|
||||
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/server
|
||||
// - https://book.kubebuilder.io/reference/metrics.html
|
||||
metricsServerOptions := metricsserver.Options{
|
||||
BindAddress: metricsAddr,
|
||||
SecureServing: secureMetrics,
|
||||
TLSOpts: tlsOpts,
|
||||
}
|
||||
|
||||
if secureMetrics {
|
||||
// FilterProvider is used to protect the metrics endpoint with authn/authz.
|
||||
// These configurations ensure that only authorized users and service accounts
|
||||
// can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
|
||||
// https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/filters#WithAuthenticationAndAuthorization
|
||||
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
|
||||
|
||||
// TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically
|
||||
// generate self-signed certificates for the metrics server. While convenient for development and testing,
|
||||
// this setup is not recommended for production.
|
||||
}
|
||||
|
||||
// Configure rate limiting for the Kubernetes client
|
||||
config := ctrl.GetConfigOrDie()
|
||||
config.QPS = 50.0 // Increased from default 5.0
|
||||
config.Burst = 100 // Increased from default 10
|
||||
|
||||
mgr, err := ctrl.NewManager(config, ctrl.Options{
|
||||
Scheme: scheme,
|
||||
Metrics: metricsServerOptions,
|
||||
WebhookServer: webhookServer,
|
||||
HealthProbeBindAddress: probeAddr,
|
||||
LeaderElection: enableLeaderElection,
|
||||
LeaderElectionID: "8796f12d.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, this setting is unsafe. 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)
|
||||
}
|
||||
|
||||
lineageControllerWebhook := &lcw.LineageControllerWebhook{
|
||||
Client: mgr.GetClient(),
|
||||
Scheme: mgr.GetScheme(),
|
||||
}
|
||||
if err := lineageControllerWebhook.SetupWithManagerAsController(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to setup controller", "controller", "LineageController")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := lineageControllerWebhook.SetupWithManagerAsWebhook(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to setup webhook", "webhook", "LineageWebhook")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// +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 manager")
|
||||
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
|
||||
setupLog.Error(err, "problem running manager")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
3
docs/changelogs/unreleased.md
Normal file
3
docs/changelogs/unreleased.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Changes after v0.37.0
|
||||
|
||||
* [lineage] Break webhook out into a separate daemonset. Reduce unnecessary webhook calls by marking handled resources and excluding them from consideration by the webhook's object selector (@lllamnyp in #1515).
|
||||
@@ -64,19 +64,19 @@ spec:
|
||||
EOF
|
||||
# Wait for the tenant-test namespace to be active
|
||||
kubectl wait namespace tenant-test --timeout=20s --for=jsonpath='{.status.phase}'=Active
|
||||
|
||||
|
||||
# Wait for the Kamaji control plane to be created (retry for up to 10 seconds)
|
||||
timeout 10 sh -ec 'until kubectl get kamajicontrolplane -n tenant-test kubernetes-'"${test_name}"'; do sleep 1; done'
|
||||
|
||||
# Wait for the tenant control plane to be fully created (timeout after 4 minutes)
|
||||
kubectl wait --for=condition=TenantControlPlaneCreated kamajicontrolplane -n tenant-test kubernetes-${test_name} --timeout=4m
|
||||
|
||||
|
||||
# Wait for Kubernetes resources to be ready (timeout after 2 minutes)
|
||||
kubectl wait tcp -n tenant-test kubernetes-${test_name} --timeout=2m --for=jsonpath='{.status.kubernetesResources.version.status}'=Ready
|
||||
|
||||
|
||||
# Wait for all required deployments to be available (timeout after 4 minutes)
|
||||
kubectl wait deploy --timeout=4m --for=condition=available -n tenant-test kubernetes-${test_name} kubernetes-${test_name}-cluster-autoscaler kubernetes-${test_name}-kccm kubernetes-${test_name}-kcsi-controller
|
||||
|
||||
|
||||
# Wait for the machine deployment to scale to 2 replicas (timeout after 1 minute)
|
||||
kubectl wait machinedeployment kubernetes-${test_name}-md0 -n tenant-test --timeout=1m --for=jsonpath='{.status.replicas}'=2
|
||||
# Get the admin kubeconfig and save it to a file
|
||||
@@ -87,14 +87,14 @@ EOF
|
||||
|
||||
|
||||
# Set up port forwarding to the Kubernetes API server for a 200 second timeout
|
||||
bash -c 'timeout 200s kubectl port-forward service/kubernetes-'"${test_name}"' -n tenant-test '"${port}"':6443 > /dev/null 2>&1 &'
|
||||
bash -c 'timeout 300s kubectl port-forward service/kubernetes-'"${test_name}"' -n tenant-test '"${port}"':6443 > /dev/null 2>&1 &'
|
||||
# Verify the Kubernetes version matches what we expect (retry for up to 20 seconds)
|
||||
timeout 20 sh -ec 'until kubectl --kubeconfig tenantkubeconfig version 2>/dev/null | grep -Fq "Server Version: ${k8s_version}"; do sleep 5; done'
|
||||
|
||||
# Wait for the nodes to be ready (timeout after 2 minutes)
|
||||
timeout 2m bash -c '
|
||||
timeout 3m bash -c '
|
||||
until [ "$(kubectl --kubeconfig tenantkubeconfig get nodes -o jsonpath="{.items[*].metadata.name}" | wc -w)" -eq 2 ]; do
|
||||
sleep 3
|
||||
sleep 2
|
||||
done
|
||||
'
|
||||
# Verify the nodes are ready
|
||||
@@ -105,9 +105,11 @@ EOF
|
||||
versions=$(kubectl --kubeconfig tenantkubeconfig get nodes -o jsonpath='{.items[*].status.nodeInfo.kubeletVersion}')
|
||||
node_ok=true
|
||||
|
||||
if [[ "$k8s_version" == v1.32* ]]; then
|
||||
echo "⚠️ TODO: Temporary stub — allowing nodes with v1.33 while k8s_version is v1.32"
|
||||
fi
|
||||
case "$k8s_version" in
|
||||
v1.32*)
|
||||
echo "⚠️ TODO: Temporary stub — allowing nodes with v1.33 while k8s_version is v1.32"
|
||||
;;
|
||||
esac
|
||||
|
||||
for v in $versions; do
|
||||
case "$k8s_version" in
|
||||
@@ -134,7 +136,7 @@ EOF
|
||||
esac
|
||||
done
|
||||
|
||||
if ! $node_ok; then
|
||||
if [ "$node_ok" != true ]; then
|
||||
echo "Kubelet versions did not match expected ${k8s_version}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -132,7 +132,6 @@ machine:
|
||||
- usermode_helper=disabled
|
||||
- name: zfs
|
||||
- name: spl
|
||||
- name: lldpd
|
||||
registries:
|
||||
mirrors:
|
||||
docker.io:
|
||||
|
||||
@@ -30,10 +30,6 @@ func (m *Manager) ensureCustomColumnsOverride(ctx context.Context, crd *cozyv1al
|
||||
name := fmt.Sprintf("stock-namespace-%s.%s.%s", g, v, plural)
|
||||
id := fmt.Sprintf("stock-namespace-/%s/%s/%s", g, v, plural)
|
||||
|
||||
// Badge content & color derived from kind
|
||||
badgeText := initialsFromKind(kind) // e.g., "VirtualMachine" -> "VM", "Bucket" -> "B"
|
||||
badgeColor := hexColorForKind(kind) // deterministic, dark enough for white text
|
||||
|
||||
obj := &dashv1alpha1.CustomColumnsOverride{}
|
||||
obj.SetName(name)
|
||||
|
||||
@@ -62,25 +58,11 @@ func (m *Manager) ensureCustomColumnsOverride(ctx context.Context, crd *cozyv1al
|
||||
},
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "antdText",
|
||||
"type": "ResourceBadge",
|
||||
"data": map[string]any{
|
||||
"id": "header-badge",
|
||||
"text": badgeText,
|
||||
"title": strings.ToLower(kind), // optional tooltip
|
||||
"style": map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
"borderRadius": "20px",
|
||||
"color": "#fff",
|
||||
"display": "inline-block",
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": "15px",
|
||||
"fontWeight": 400,
|
||||
"lineHeight": "24px",
|
||||
"minWidth": 24,
|
||||
"padding": "0 9px",
|
||||
"textAlign": "center",
|
||||
"whiteSpace": "nowrap",
|
||||
},
|
||||
"value": kind,
|
||||
// abbreviation auto-generated by ResourceBadge from value
|
||||
},
|
||||
},
|
||||
map[string]any{
|
||||
|
||||
@@ -53,7 +53,6 @@ func (m *Manager) ensureFactory(ctx context.Context, crd *cozyv1alpha1.Cozystack
|
||||
Kind: kind,
|
||||
Plural: plural,
|
||||
Title: strings.ToLower(plural),
|
||||
Size: BadgeSizeLarge,
|
||||
}
|
||||
|
||||
spec := createUnifiedFactory(config, tabs, []any{resourceFetch})
|
||||
@@ -115,7 +114,7 @@ func detailsTab(kind, endpoint, schemaJSON string, keysOrder [][]string) map[str
|
||||
"gap": float64(6),
|
||||
},
|
||||
"children": []any{
|
||||
createUnifiedBadgeFromKind("ns-badge", "Namespace", "namespace", BadgeSizeMedium),
|
||||
createUnifiedBadgeFromKind("ns-badge", "Namespace"),
|
||||
antdLink("namespace-link",
|
||||
"{reqsJsonPath[0]['.metadata.namespace']['-']}",
|
||||
"/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace",
|
||||
@@ -324,6 +323,7 @@ func yamlTab(plural string) map[string]any {
|
||||
"type": "builtin",
|
||||
"typeName": plural,
|
||||
"prefillValuesRequestIndex": float64(0),
|
||||
"readOnly": true,
|
||||
"substractHeight": float64(400),
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package dashboard
|
||||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
@@ -57,97 +54,6 @@ func pickPlural(kind string, crd *cozyv1alpha1.CozystackResourceDefinition) stri
|
||||
return k + "s"
|
||||
}
|
||||
|
||||
// initialsFromKind splits CamelCase and returns the first letters in upper case.
|
||||
// "VirtualMachine" -> "VM"; "Bucket" -> "B".
|
||||
func initialsFromKind(kind string) string {
|
||||
parts := splitCamel(kind)
|
||||
if len(parts) == 0 {
|
||||
return strings.ToUpper(kind)
|
||||
}
|
||||
var b strings.Builder
|
||||
for _, p := range parts {
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
b.WriteString(strings.ToUpper(string(p[0])))
|
||||
// Limit to 3 chars to keep the badge compact (VM, PVC, etc.)
|
||||
if b.Len() >= 3 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// hexColorForKind returns a dark, saturated color (hex) derived from a stable hash of the kind.
|
||||
// We map the hash to an HSL hue; fix S/L for consistent readability with white text.
|
||||
func hexColorForKind(kind string) string {
|
||||
// Stable short hash (sha1 → bytes → hue)
|
||||
sum := sha1.Sum([]byte(kind))
|
||||
// Use first two bytes for hue [0..359]
|
||||
hue := int(sum[0])<<8 | int(sum[1])
|
||||
hue = hue % 360
|
||||
|
||||
// Fixed S/L chosen to contrast with white text:
|
||||
// S = 80%, L = 35% (dark enough so #fff is readable)
|
||||
r, g, b := hslToRGB(float64(hue), 0.80, 0.35)
|
||||
|
||||
return fmt.Sprintf("#%02x%02x%02x", r, g, b)
|
||||
}
|
||||
|
||||
// hslToRGB converts HSL (0..360, 0..1, 0..1) to sRGB (0..255).
|
||||
func hslToRGB(h float64, s float64, l float64) (uint8, uint8, uint8) {
|
||||
c := (1 - absFloat(2*l-1)) * s
|
||||
hp := h / 60.0
|
||||
x := c * (1 - absFloat(modFloat(hp, 2)-1))
|
||||
var r1, g1, b1 float64
|
||||
switch {
|
||||
case 0 <= hp && hp < 1:
|
||||
r1, g1, b1 = c, x, 0
|
||||
case 1 <= hp && hp < 2:
|
||||
r1, g1, b1 = x, c, 0
|
||||
case 2 <= hp && hp < 3:
|
||||
r1, g1, b1 = 0, c, x
|
||||
case 3 <= hp && hp < 4:
|
||||
r1, g1, b1 = 0, x, c
|
||||
case 4 <= hp && hp < 5:
|
||||
r1, g1, b1 = x, 0, c
|
||||
default:
|
||||
r1, g1, b1 = c, 0, x
|
||||
}
|
||||
m := l - c/2
|
||||
r := uint8(clamp01(r1+m) * 255.0)
|
||||
g := uint8(clamp01(g1+m) * 255.0)
|
||||
b := uint8(clamp01(b1+m) * 255.0)
|
||||
return r, g, b
|
||||
}
|
||||
|
||||
func absFloat(v float64) float64 {
|
||||
if v < 0 {
|
||||
return -v
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func modFloat(a, b float64) float64 {
|
||||
return a - b*float64(int(a/b))
|
||||
}
|
||||
|
||||
func clamp01(v float64) float64 {
|
||||
if v < 0 {
|
||||
return 0
|
||||
}
|
||||
if v > 1 {
|
||||
return 1
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// optional: tiny helper to expose the compact color hash (useful for debugging)
|
||||
func shortHashHex(s string) string {
|
||||
sum := sha1.Sum([]byte(s))
|
||||
return hex.EncodeToString(sum[:4])
|
||||
}
|
||||
|
||||
// ----------------------- Helpers (OpenAPI → values) -----------------------
|
||||
|
||||
// defaultOrZero returns the schema default if present; otherwise a reasonable zero value.
|
||||
@@ -295,12 +201,6 @@ func normalizeJSON(v any) any {
|
||||
}
|
||||
}
|
||||
|
||||
var camelSplitter = regexp.MustCompile(`(?m)([A-Z]+[a-z0-9]*|[a-z0-9]+)`)
|
||||
|
||||
func splitCamel(s string) []string {
|
||||
return camelSplitter.FindAllString(s, -1)
|
||||
}
|
||||
|
||||
// --- helpers for schema inspection ---
|
||||
|
||||
func isScalarType(n map[string]any) bool {
|
||||
|
||||
@@ -531,7 +531,6 @@ func createBreadcrumbItem(key, label string, link ...string) map[string]any {
|
||||
|
||||
// createCustomColumn creates a custom column with factory type and badge
|
||||
func createCustomColumn(name, kind, plural, href string) map[string]any {
|
||||
badge := createUnifiedBadgeFromKind("header-badge", kind, plural, BadgeSizeMedium)
|
||||
link := antdLink("name-link", "{reqsJsonPath[0]['.metadata.name']['-']}", href)
|
||||
|
||||
return map[string]any{
|
||||
@@ -541,8 +540,18 @@ func createCustomColumn(name, kind, plural, href string) map[string]any {
|
||||
"disableEventBubbling": true,
|
||||
"items": []any{
|
||||
map[string]any{
|
||||
"children": []any{badge, link},
|
||||
"type": "antdFlex",
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": kind,
|
||||
// abbreviation auto-generated by ResourceBadge from value
|
||||
},
|
||||
},
|
||||
link,
|
||||
},
|
||||
"type": "antdFlex",
|
||||
"data": map[string]any{
|
||||
"align": "center",
|
||||
"gap": float64(6),
|
||||
@@ -554,16 +563,16 @@ func createCustomColumn(name, kind, plural, href string) map[string]any {
|
||||
}
|
||||
|
||||
// createCustomColumnWithBadge creates a custom column with a specific badge
|
||||
func createCustomColumnWithBadge(name, badgeText, badgeColor, title, href string) map[string]any {
|
||||
config := BadgeConfig{
|
||||
Text: badgeText,
|
||||
Color: badgeColor,
|
||||
Title: title,
|
||||
Size: BadgeSizeMedium,
|
||||
}
|
||||
badge := createUnifiedBadge("header-badge", config)
|
||||
// badgeValue should be the kind in PascalCase (e.g., "Service", "Pod")
|
||||
// abbreviation is auto-generated by ResourceBadge from badgeValue
|
||||
func createCustomColumnWithBadge(name, badgeValue, href string) map[string]any {
|
||||
link := antdLink("name-link", "{reqsJsonPath[0]['.metadata.name']['-']}", href)
|
||||
|
||||
badgeData := map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": badgeValue,
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
"type": "factory",
|
||||
@@ -571,8 +580,14 @@ func createCustomColumnWithBadge(name, badgeText, badgeColor, title, href string
|
||||
"disableEventBubbling": true,
|
||||
"items": []any{
|
||||
map[string]any{
|
||||
"children": []any{badge, link},
|
||||
"type": "antdFlex",
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": badgeData,
|
||||
},
|
||||
link,
|
||||
},
|
||||
"type": "antdFlex",
|
||||
"data": map[string]any{
|
||||
"align": "center",
|
||||
"gap": float64(6),
|
||||
@@ -583,17 +598,22 @@ func createCustomColumnWithBadge(name, badgeText, badgeColor, title, href string
|
||||
}
|
||||
}
|
||||
|
||||
// createCustomColumnWithSpecificColor creates a custom column with a specific color
|
||||
func createCustomColumnWithSpecificColor(name, kind, title, color, href string) map[string]any {
|
||||
config := BadgeConfig{
|
||||
Text: initialsFromKind(kind),
|
||||
Color: color,
|
||||
Title: title,
|
||||
Size: BadgeSizeMedium,
|
||||
}
|
||||
badge := createUnifiedBadge("header-badge", config)
|
||||
// createCustomColumnWithSpecificColor creates a custom column with a specific kind and optional color
|
||||
// badgeValue should be the kind in PascalCase (e.g., "Service", "Pod")
|
||||
func createCustomColumnWithSpecificColor(name, kind, color, href string) map[string]any {
|
||||
link := antdLink("name-link", "{reqsJsonPath[0]['.metadata.name']['-']}", href)
|
||||
|
||||
badgeData := map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": kind,
|
||||
}
|
||||
// Add custom color if specified
|
||||
if color != "" {
|
||||
badgeData["style"] = map[string]any{
|
||||
"backgroundColor": color,
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
"type": "factory",
|
||||
@@ -602,8 +622,14 @@ func createCustomColumnWithSpecificColor(name, kind, title, color, href string)
|
||||
"disableEventBubbling": true,
|
||||
"items": []any{
|
||||
map[string]any{
|
||||
"children": []any{badge, link},
|
||||
"type": "antdFlex",
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": badgeData,
|
||||
},
|
||||
link,
|
||||
},
|
||||
"type": "antdFlex",
|
||||
"data": map[string]any{
|
||||
"align": "center",
|
||||
"gap": float64(6),
|
||||
@@ -668,7 +694,7 @@ func createTimestampColumn(name, jsonPath string) map[string]any {
|
||||
// createFactoryHeader creates a header for factory resources
|
||||
func createFactoryHeader(kind, plural string) map[string]any {
|
||||
lowerKind := strings.ToLower(kind)
|
||||
badge := createUnifiedBadgeFromKind("badge-"+lowerKind, kind, plural, BadgeSizeLarge)
|
||||
badge := createUnifiedBadgeFromKind("badge-"+lowerKind, kind)
|
||||
nameText := parsedText(lowerKind+"-name", "{reqsJsonPath[0]['.metadata.name']['-']}", map[string]any{
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": float64(20),
|
||||
@@ -718,13 +744,26 @@ func createFactorySpec(key string, sidebarTags []any, urlsToFetch []any, header
|
||||
}
|
||||
|
||||
// createCustomColumnWithJsonPath creates a column with a custom badge and link using jsonPath
|
||||
func createCustomColumnWithJsonPath(name, jsonPath, badgeText, badgeTitle, badgeColor, linkHref string) map[string]any {
|
||||
// badgeValue should be the kind in PascalCase (e.g., "Service", "VirtualMachine")
|
||||
// abbreviation is auto-generated by ResourceBadge from badgeValue
|
||||
func createCustomColumnWithJsonPath(name, jsonPath, badgeValue, badgeColor, linkHref string) map[string]any {
|
||||
// Determine link ID based on jsonPath
|
||||
linkId := "name-link"
|
||||
if jsonPath == ".metadata.namespace" {
|
||||
linkId = "namespace-link"
|
||||
}
|
||||
|
||||
badgeData := map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": badgeValue,
|
||||
}
|
||||
// Add custom color if specified
|
||||
if badgeColor != "" {
|
||||
badgeData["style"] = map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
"type": "factory",
|
||||
@@ -741,26 +780,8 @@ func createCustomColumnWithJsonPath(name, jsonPath, badgeText, badgeTitle, badge
|
||||
},
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "antdText",
|
||||
"data": map[string]any{
|
||||
"id": "header-badge",
|
||||
"text": badgeText,
|
||||
"title": badgeTitle,
|
||||
"style": map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
"borderRadius": "20px",
|
||||
"color": "#fff",
|
||||
"display": "inline-block",
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": "15px",
|
||||
"fontWeight": 400,
|
||||
"lineHeight": "24px",
|
||||
"minWidth": 24,
|
||||
"padding": "0 9px",
|
||||
"textAlign": "center",
|
||||
"whiteSpace": "nowrap",
|
||||
},
|
||||
},
|
||||
"type": "ResourceBadge",
|
||||
"data": badgeData,
|
||||
},
|
||||
map[string]any{
|
||||
"type": "antdLink",
|
||||
@@ -778,7 +799,20 @@ func createCustomColumnWithJsonPath(name, jsonPath, badgeText, badgeTitle, badge
|
||||
}
|
||||
|
||||
// createCustomColumnWithoutJsonPath creates a column with a custom badge and link without jsonPath
|
||||
func createCustomColumnWithoutJsonPath(name, badgeText, badgeTitle, badgeColor, linkHref string) map[string]any {
|
||||
// badgeValue should be the kind in PascalCase (e.g., "Node", "Pod")
|
||||
// abbreviation is auto-generated by ResourceBadge from badgeValue
|
||||
func createCustomColumnWithoutJsonPath(name, badgeValue, badgeColor, linkHref string) map[string]any {
|
||||
badgeData := map[string]any{
|
||||
"id": "header-badge",
|
||||
"value": badgeValue,
|
||||
}
|
||||
// Add custom color if specified
|
||||
if badgeColor != "" {
|
||||
badgeData["style"] = map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"name": name,
|
||||
"type": "factory",
|
||||
@@ -794,26 +828,8 @@ func createCustomColumnWithoutJsonPath(name, badgeText, badgeTitle, badgeColor,
|
||||
},
|
||||
"children": []any{
|
||||
map[string]any{
|
||||
"type": "antdText",
|
||||
"data": map[string]any{
|
||||
"id": "header-badge",
|
||||
"text": badgeText,
|
||||
"title": badgeTitle,
|
||||
"style": map[string]any{
|
||||
"backgroundColor": badgeColor,
|
||||
"borderRadius": "20px",
|
||||
"color": "#fff",
|
||||
"display": "inline-block",
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": "15px",
|
||||
"fontWeight": 400,
|
||||
"lineHeight": "24px",
|
||||
"minWidth": 24,
|
||||
"padding": "0 9px",
|
||||
"textAlign": "center",
|
||||
"whiteSpace": "nowrap",
|
||||
},
|
||||
},
|
||||
"type": "ResourceBadge",
|
||||
"data": badgeData,
|
||||
},
|
||||
map[string]any{
|
||||
"type": "antdLink",
|
||||
|
||||
@@ -132,7 +132,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
return []*dashboardv1alpha1.CustomColumnsOverride{
|
||||
// Factory details v1 services
|
||||
createCustomColumnsOverride("factory-details-v1.services", []any{
|
||||
createCustomColumnWithSpecificColor("Name", "Service", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithSpecificColor("Name", "Service", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("ClusterIP", ".spec.clusterIP"),
|
||||
createStringColumn("LoadbalancerIP", ".spec.loadBalancerIP"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
@@ -140,15 +140,15 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock namespace v1 services
|
||||
createCustomColumnsOverride("stock-namespace-/v1/services", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Service", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("ClusterIP", ".spec.clusterIP"),
|
||||
createStringColumn("LoadbalancerIP", ".spec.loadBalancerIP"),
|
||||
createStringColumn("LoadbalancerIP", ".status.loadBalancer.ingress[0].ip"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Stock namespace core cozystack io v1alpha1 tenantmodules
|
||||
createCustomColumnsOverride("stock-namespace-/core.cozystack.io/v1alpha1/tenantmodules", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "M", "module", getColorForType("module"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/{reqsJsonPath[0]['.metadata.name']['-']}-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Module", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/{reqsJsonPath[0]['.metadata.name']['-']}-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createReadyColumn(),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
createStringColumn("Version", ".status.version"),
|
||||
@@ -164,7 +164,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Factory details v1alpha1 cozystack io workloadmonitors
|
||||
createCustomColumnsOverride("factory-details-v1alpha1.cozystack.io.workloadmonitors", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "W", "workloadmonitor", getColorForType("workloadmonitor"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/workloadmonitor-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "WorkloadMonitor", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/workloadmonitor-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("TYPE", ".spec.type"),
|
||||
createStringColumn("VERSION", ".spec.version"),
|
||||
createStringColumn("REPLICAS", ".spec.replicas"),
|
||||
@@ -175,7 +175,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Factory details v1alpha1 core cozystack io tenantsecretstables
|
||||
createCustomColumnsOverride("factory-details-v1alpha1.core.cozystack.io.tenantsecretstables", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", getColorForType("secret"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Secret", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("Key", ".data.key"),
|
||||
createSecretBase64Column("Value", ".data.value"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
@@ -184,7 +184,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
// Factory ingress details rules
|
||||
createCustomColumnsOverride("factory-kube-ingress-details-rules", []any{
|
||||
createStringColumn("Host", ".host"),
|
||||
createCustomColumnWithJsonPath("Service", ".http.paths[0].backend.service.name", "S", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.http.paths[0].backend.service.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Service", ".http.paths[0].backend.service.name", "Service", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.http.paths[0].backend.service.name']['-']}"),
|
||||
createStringColumn("Port", ".http.paths[0].backend.service.port.number"),
|
||||
createStringColumn("Path", ".http.paths[0].path"),
|
||||
}),
|
||||
@@ -250,7 +250,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Factory details networking k8s io v1 ingresses
|
||||
createCustomColumnsOverride("factory-details-networking.k8s.io.v1.ingresses", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "I", "ingress", getColorForType("ingress"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Ingress", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("Hosts", ".spec.rules[*].host"),
|
||||
createStringColumn("Address", ".status.loadBalancer.ingress[0].ip"),
|
||||
createStringColumn("Port", ".spec.defaultBackend.service.port.number"),
|
||||
@@ -259,7 +259,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock namespace networking k8s io v1 ingresses
|
||||
createCustomColumnsOverride("stock-namespace-/networking.k8s.io/v1/ingresses", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "I", "ingress", getColorForType("ingress"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Ingress", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-ingress-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("Hosts", ".spec.rules[*].host"),
|
||||
createStringColumn("Address", ".status.loadBalancer.ingress[0].ip"),
|
||||
createStringColumn("Port", ".spec.defaultBackend.service.port.number"),
|
||||
@@ -268,34 +268,34 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock cluster v1 configmaps
|
||||
createCustomColumnsOverride("stock-cluster-/v1/configmaps", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "ConfigMap", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Stock namespace v1 configmaps
|
||||
createCustomColumnsOverride("stock-namespace-/v1/configmaps", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "ConfigMap", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Cluster v1 configmaps
|
||||
createCustomColumnsOverride("cluster-/v1/configmaps", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "CM", "configmap", getColorForType("configmap"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "ConfigMap", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/configmap-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Stock cluster v1 nodes
|
||||
createCustomColumnsOverride("stock-cluster-/v1/nodes", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "N", "node", getColorForType("node"), "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Node", "", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createSimpleStatusColumn("Status", "node-status"),
|
||||
}),
|
||||
|
||||
// Factory node details v1 pods
|
||||
createCustomColumnsOverride("factory-node-details-v1.pods", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", getColorForType("pod"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", getColorForType("namespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Pod", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace"),
|
||||
createStringColumn("Restart Policy", ".spec.restartPolicy"),
|
||||
createStringColumn("Pod IP", ".status.podIP"),
|
||||
createStringColumn("QOS", ".status.qosClass"),
|
||||
@@ -304,8 +304,8 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Factory v1 pods
|
||||
createCustomColumnsOverride("factory-v1.pods", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", getColorForType("pod"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithoutJsonPath("Node", "N", "node", getColorForType("node"), "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Pod", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithoutJsonPath("Node", "Node", "", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createStringColumn("Restart Policy", ".spec.restartPolicy"),
|
||||
createStringColumn("Pod IP", ".status.podIP"),
|
||||
createStringColumn("QOS", ".status.qosClass"),
|
||||
@@ -314,9 +314,9 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock cluster v1 pods
|
||||
createCustomColumnsOverride("stock-cluster-/v1/pods", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
|
||||
createCustomColumnWithJsonPath("Node", ".spec.nodeName", "N", "node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
|
||||
createCustomColumnWithJsonPath("Node", ".spec.nodeName", "Node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createStringColumn("Restart Policy", ".spec.restartPolicy"),
|
||||
createStringColumn("Pod IP", ".status.podIP"),
|
||||
createStringColumn("QOS", ".status.qosClass"),
|
||||
@@ -325,8 +325,8 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock namespace v1 pods
|
||||
createCustomColumnsOverride("stock-namespace-/v1/pods", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "P", "pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithoutJsonPath("Node", "N", "node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Pod", "#009596", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/pod-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithoutJsonPath("Node", "Node", "#8476d1", "/openapi-ui/{2}/factory/node-details/{reqsJsonPath[0]['.spec.nodeName']['-']}"),
|
||||
createStringColumn("Restart Policy", ".spec.restartPolicy"),
|
||||
createStringColumn("Pod IP", ".status.podIP"),
|
||||
createStringColumn("QOS", ".status.qosClass"),
|
||||
@@ -335,15 +335,15 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock cluster v1 secrets
|
||||
createCustomColumnsOverride("stock-cluster-/v1/secrets", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "NS", "namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Namespace", ".metadata.namespace", "Namespace", "#a25792ff", "/openapi-ui/{2}/factory/tenantnamespace/{reqsJsonPath[0]['.metadata.namespace']['-']}"),
|
||||
createStringColumn("Type", ".type"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
|
||||
// Stock namespace v1 secrets
|
||||
createCustomColumnsOverride("stock-namespace-/v1/secrets", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "Secret", "#c46100", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-secret-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
|
||||
createStringColumn("Type", ".type"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
@@ -360,7 +360,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
|
||||
|
||||
// Stock cluster core cozystack io v1alpha1 tenantnamespaces
|
||||
createCustomColumnsOverride("stock-cluster-/core.cozystack.io/v1alpha1/tenantnamespaces", []any{
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "TN", "tenantnamespace", getColorForType("tenantnamespace"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.name']['-']}/factory/marketplace"),
|
||||
createCustomColumnWithJsonPath("Name", ".metadata.name", "TenantNamespace", "", "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.name']['-']}/factory/marketplace"),
|
||||
createTimestampColumn("Created", ".metadata.creationTimestamp"),
|
||||
}),
|
||||
}
|
||||
@@ -496,7 +496,6 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
|
||||
Kind: "Namespace",
|
||||
Plural: "namespaces",
|
||||
Title: "namespace",
|
||||
Size: BadgeSizeLarge,
|
||||
}
|
||||
namespaceSpec := createUnifiedFactory(namespaceConfig, nil, []any{"/api/clusters/{2}/k8s/api/v1/namespaces/{5}"})
|
||||
|
||||
@@ -796,6 +795,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
|
||||
"substractHeight": float64(400),
|
||||
"type": "builtin",
|
||||
"typeName": "secrets",
|
||||
"readOnly": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1201,7 +1201,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
|
||||
"gap": 6,
|
||||
},
|
||||
"children": []any{
|
||||
createUnifiedBadgeFromKind("ns-badge", "Namespace", "namespace", BadgeSizeMedium),
|
||||
createUnifiedBadgeFromKind("ns-badge", "Namespace"),
|
||||
antdLink("namespace-link",
|
||||
"{reqsJsonPath[0]['.metadata.namespace']['-']}",
|
||||
"/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/marketplace",
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package dashboard
|
||||
|
||||
import "strings"
|
||||
|
||||
// ---------------- UI helpers (use float64 for numeric fields) ----------------
|
||||
|
||||
func contentCard(id string, style map[string]any, children []any) map[string]any {
|
||||
@@ -200,10 +198,10 @@ func createBadge(id, text, color, title string) map[string]any {
|
||||
|
||||
// createBadgeFromKind creates a badge using the existing badge generation functions
|
||||
func createBadgeFromKind(id, kind, title string) map[string]any {
|
||||
return createUnifiedBadgeFromKind(id, kind, title, BadgeSizeMedium)
|
||||
return createUnifiedBadgeFromKind(id, kind)
|
||||
}
|
||||
|
||||
// createHeaderBadge creates a badge specifically for headers with consistent styling
|
||||
func createHeaderBadge(id, kind, plural string) map[string]any {
|
||||
return createUnifiedBadgeFromKind(id, kind, strings.ToLower(plural), BadgeSizeLarge)
|
||||
return createUnifiedBadgeFromKind(id, kind)
|
||||
}
|
||||
|
||||
@@ -81,86 +81,47 @@ func isAlphanumeric(c byte) bool {
|
||||
|
||||
// BadgeConfig holds configuration for badge generation
|
||||
type BadgeConfig struct {
|
||||
Text string
|
||||
Color string
|
||||
Title string
|
||||
Size BadgeSize
|
||||
Kind string // Resource kind in PascalCase (e.g., "VirtualMachine") - used for value and auto-generation
|
||||
Text string // Optional abbreviation override (if empty, ResourceBadge auto-generates from Kind)
|
||||
Color string // Optional custom backgroundColor override
|
||||
}
|
||||
|
||||
// BadgeSize represents the size of the badge
|
||||
type BadgeSize int
|
||||
|
||||
const (
|
||||
BadgeSizeSmall BadgeSize = iota
|
||||
BadgeSizeMedium
|
||||
BadgeSizeLarge
|
||||
)
|
||||
|
||||
// generateBadgeConfig creates a BadgeConfig from kind and optional custom values
|
||||
func generateBadgeConfig(kind string, customText, customColor, customTitle string) BadgeConfig {
|
||||
config := BadgeConfig{
|
||||
Text: initialsFromKind(kind),
|
||||
Color: hexColorForKind(kind),
|
||||
Title: strings.ToLower(kind),
|
||||
Size: BadgeSizeMedium,
|
||||
}
|
||||
|
||||
// Override with custom values if provided
|
||||
if customText != "" {
|
||||
config.Text = customText
|
||||
}
|
||||
if customColor != "" {
|
||||
config.Color = customColor
|
||||
}
|
||||
if customTitle != "" {
|
||||
config.Title = customTitle
|
||||
}
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
// createUnifiedBadge creates a badge using the unified BadgeConfig
|
||||
// createUnifiedBadge creates a badge using the unified BadgeConfig with ResourceBadge component
|
||||
func createUnifiedBadge(id string, config BadgeConfig) map[string]any {
|
||||
fontSize := "15px"
|
||||
if config.Size == BadgeSizeLarge {
|
||||
fontSize = "20px"
|
||||
} else if config.Size == BadgeSizeSmall {
|
||||
fontSize = "12px"
|
||||
data := map[string]any{
|
||||
"id": id,
|
||||
"value": config.Kind,
|
||||
}
|
||||
|
||||
// Add abbreviation override if specified (otherwise ResourceBadge auto-generates from Kind)
|
||||
if config.Text != "" {
|
||||
data["abbreviation"] = config.Text
|
||||
}
|
||||
|
||||
// Add custom color if specified
|
||||
if config.Color != "" {
|
||||
data["style"] = map[string]any{
|
||||
"backgroundColor": config.Color,
|
||||
}
|
||||
}
|
||||
|
||||
return map[string]any{
|
||||
"type": "antdText",
|
||||
"data": map[string]any{
|
||||
"id": id,
|
||||
"text": config.Text,
|
||||
"title": config.Title,
|
||||
"style": map[string]any{
|
||||
"backgroundColor": config.Color,
|
||||
"borderRadius": "20px",
|
||||
"color": "#fff",
|
||||
"display": "inline-block",
|
||||
"fontFamily": "RedHatDisplay, Overpass, overpass, helvetica, arial, sans-serif",
|
||||
"fontSize": fontSize,
|
||||
"fontWeight": float64(400),
|
||||
"lineHeight": "24px",
|
||||
"minWidth": float64(24),
|
||||
"padding": "0 9px",
|
||||
"textAlign": "center",
|
||||
"whiteSpace": "nowrap",
|
||||
},
|
||||
},
|
||||
"type": "ResourceBadge",
|
||||
"data": data,
|
||||
}
|
||||
}
|
||||
|
||||
// createUnifiedBadgeFromKind creates a badge from kind with automatic color generation
|
||||
func createUnifiedBadgeFromKind(id, kind, title string, size BadgeSize) map[string]any {
|
||||
config := BadgeConfig{
|
||||
Text: initialsFromKind(kind),
|
||||
Color: hexColorForKind(kind),
|
||||
Title: title,
|
||||
Size: size,
|
||||
// createUnifiedBadgeFromKind creates a badge from kind with ResourceBadge component
|
||||
// Abbreviation is auto-generated by ResourceBadge from kind, but can be customized if needed
|
||||
func createUnifiedBadgeFromKind(id, kind string) map[string]any {
|
||||
return map[string]any{
|
||||
"type": "ResourceBadge",
|
||||
"data": map[string]any{
|
||||
"id": id,
|
||||
"value": kind,
|
||||
// abbreviation is optional - ResourceBadge auto-generates from value
|
||||
},
|
||||
}
|
||||
return createUnifiedBadge(id, config)
|
||||
}
|
||||
|
||||
// ---------------- Resource creation helpers with unified approach ----------------
|
||||
@@ -183,7 +144,9 @@ func createResourceConfig(components []string, kind, title string) ResourceConfi
|
||||
metadataName := generateMetadataName(specID)
|
||||
|
||||
// Generate badge config
|
||||
badgeConfig := generateBadgeConfig(kind, "", "", title)
|
||||
badgeConfig := BadgeConfig{
|
||||
Kind: kind,
|
||||
}
|
||||
|
||||
return ResourceConfig{
|
||||
SpecID: specID,
|
||||
@@ -196,35 +159,6 @@ func createResourceConfig(components []string, kind, title string) ResourceConfi
|
||||
|
||||
// ---------------- Enhanced color generation ----------------
|
||||
|
||||
// getColorForKind returns a color for a specific kind with improved distribution
|
||||
func getColorForKind(kind string) string {
|
||||
// Use existing hexColorForKind function
|
||||
return hexColorForKind(kind)
|
||||
}
|
||||
|
||||
// getColorForType returns a color for a specific type (like "namespace", "service", etc.)
|
||||
func getColorForType(typeName string) string {
|
||||
// Map common types to specific colors for consistency
|
||||
colorMap := map[string]string{
|
||||
"namespace": "#a25792ff",
|
||||
"service": "#6ca100",
|
||||
"pod": "#009596",
|
||||
"node": "#8476d1",
|
||||
"secret": "#c46100",
|
||||
"configmap": "#b48c78ff",
|
||||
"ingress": "#2e7dff",
|
||||
"workloadmonitor": "#c46100",
|
||||
"module": "#8b5cf6",
|
||||
}
|
||||
|
||||
if color, exists := colorMap[strings.ToLower(typeName)]; exists {
|
||||
return color
|
||||
}
|
||||
|
||||
// Fall back to hash-based color generation
|
||||
return hexColorForKind(typeName)
|
||||
}
|
||||
|
||||
// ---------------- Automatic ID generation for UI elements ----------------
|
||||
|
||||
// generateElementID creates an ID for UI elements based on context and type
|
||||
@@ -282,7 +216,6 @@ type UnifiedResourceConfig struct {
|
||||
Title string
|
||||
Color string
|
||||
BadgeText string
|
||||
Size BadgeSize
|
||||
}
|
||||
|
||||
// createUnifiedFactory creates a factory using unified approach
|
||||
@@ -292,16 +225,9 @@ func createUnifiedFactory(config UnifiedResourceConfig, tabs []any, urlsToFetch
|
||||
|
||||
// Create header with unified badge
|
||||
badgeConfig := BadgeConfig{
|
||||
Kind: config.Kind,
|
||||
Text: config.BadgeText,
|
||||
Color: config.Color,
|
||||
Title: config.Title,
|
||||
Size: config.Size,
|
||||
}
|
||||
if badgeConfig.Text == "" {
|
||||
badgeConfig.Text = initialsFromKind(config.Kind)
|
||||
}
|
||||
if badgeConfig.Color == "" {
|
||||
badgeConfig.Color = getColorForKind(config.Kind)
|
||||
}
|
||||
|
||||
badge := createUnifiedBadge(generateBadgeID("header", config.Kind), badgeConfig)
|
||||
@@ -348,7 +274,9 @@ func createUnifiedFactory(config UnifiedResourceConfig, tabs []any, urlsToFetch
|
||||
|
||||
// createUnifiedCustomColumn creates a custom column using unified approach
|
||||
func createUnifiedCustomColumn(name, jsonPath, kind, title, href string) map[string]any {
|
||||
badgeConfig := generateBadgeConfig(kind, "", "", title)
|
||||
badgeConfig := BadgeConfig{
|
||||
Kind: kind,
|
||||
}
|
||||
badge := createUnifiedBadge(generateBadgeID("column", kind), badgeConfig)
|
||||
|
||||
linkID := generateLinkID("column", "name")
|
||||
|
||||
@@ -38,6 +38,9 @@ func (l *LineageControllerWebhook) Map(hr *helmv2.HelmRelease) (string, string,
|
||||
if !ok {
|
||||
return "", "", "", fmt.Errorf("failed to load chart-app mapping from config")
|
||||
}
|
||||
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 {
|
||||
|
||||
@@ -26,6 +26,13 @@ var (
|
||||
AncestryAmbiguous = fmt.Errorf("object ancestry is ambiguous")
|
||||
)
|
||||
|
||||
const (
|
||||
ManagedObjectKey = "internal.cozystack.io/managed-by-cozystack"
|
||||
ManagerGroupKey = "apps.cozystack.io/application.group"
|
||||
ManagerKindKey = "apps.cozystack.io/application.kind"
|
||||
ManagerNameKey = "apps.cozystack.io/application.name"
|
||||
)
|
||||
|
||||
// getResourceSelectors returns the appropriate CozystackResourceDefinitionResources for a given GroupKind
|
||||
func (h *LineageControllerWebhook) getResourceSelectors(gk schema.GroupKind, crd *cozyv1alpha1.CozystackResourceDefinition) *cozyv1alpha1.CozystackResourceDefinitionResources {
|
||||
switch {
|
||||
@@ -91,7 +98,7 @@ func (h *LineageControllerWebhook) Handle(ctx context.Context, req admission.Req
|
||||
labels, err := h.computeLabels(ctx, obj)
|
||||
for {
|
||||
if err != nil && errors.Is(err, NoAncestors) {
|
||||
return admission.Allowed("object not managed by app")
|
||||
break // not a problem, mark object as unmanaged
|
||||
}
|
||||
if err != nil && errors.Is(err, AncestryAmbiguous) {
|
||||
warn = append(warn, "object ancestry ambiguous, using first ancestor found")
|
||||
@@ -119,7 +126,7 @@ func (h *LineageControllerWebhook) Handle(ctx context.Context, req admission.Req
|
||||
func (h *LineageControllerWebhook) computeLabels(ctx context.Context, o *unstructured.Unstructured) (map[string]string, error) {
|
||||
owners := lineage.WalkOwnershipGraph(ctx, h.dynClient, h.mapper, h, o)
|
||||
if len(owners) == 0 {
|
||||
return nil, NoAncestors
|
||||
return map[string]string{ManagedObjectKey: "false"}, NoAncestors
|
||||
}
|
||||
obj, err := owners[0].GetUnstructured(ctx, h.dynClient, h.mapper)
|
||||
if err != nil {
|
||||
@@ -135,7 +142,8 @@ func (h *LineageControllerWebhook) computeLabels(ctx context.Context, o *unstruc
|
||||
}
|
||||
labels := map[string]string{
|
||||
// truncate apigroup to first 63 chars
|
||||
"apps.cozystack.io/application.group": func(s string) string {
|
||||
ManagedObjectKey: "true",
|
||||
ManagerGroupKey: func(s string) string {
|
||||
if len(s) < 63 {
|
||||
return s
|
||||
}
|
||||
@@ -145,8 +153,8 @@ func (h *LineageControllerWebhook) computeLabels(ctx context.Context, o *unstruc
|
||||
}
|
||||
return s
|
||||
}(gv.Group),
|
||||
"apps.cozystack.io/application.kind": obj.GetKind(),
|
||||
"apps.cozystack.io/application.name": obj.GetName(),
|
||||
ManagerKindKey: obj.GetKind(),
|
||||
ManagerNameKey: obj.GetName(),
|
||||
}
|
||||
templateLabels := map[string]string{
|
||||
"kind": strings.ToLower(obj.GetKind()),
|
||||
|
||||
@@ -1 +1 @@
|
||||
ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:50ac1581e3100bd6c477a71161cb455a341ffaf9e5e2f6086802e4e25271e8af
|
||||
ghcr.io/cozystack/cozystack/nginx-cache:0.0.0@sha256:b7633717cd7449c0042ae92d8ca9b36e4d69566561f5c7d44e21058e7d05c6d5
|
||||
|
||||
@@ -1 +1 @@
|
||||
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:c8b08084a86251cdd18e237de89b695bca0e4f7eb1f1f6ddc2b903b4d74ea5ff
|
||||
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:e7c575b0068cf78fae8730fe8d1919799e93356b14f0b645789645bd975878b9
|
||||
|
||||
@@ -147,7 +147,7 @@ spec:
|
||||
podAdditionalMetadata:
|
||||
labels:
|
||||
policy.cozystack.io/allow-to-etcd: "true"
|
||||
replicas: 2
|
||||
replicas: {{ .Values.controlPlane.replicas }}
|
||||
version: {{ include "kubernetes.versionMap" $ }}
|
||||
---
|
||||
apiVersion: cozystack.io/v1alpha1
|
||||
|
||||
74
packages/apps/mysql/templates/hooks/cleanup-pvc.yaml
Normal file
74
packages/apps/mysql/templates/hooks/cleanup-pvc.yaml
Normal file
@@ -0,0 +1,74 @@
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-delete
|
||||
"helm.sh/hook-weight": "10"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
policy.cozystack.io/allow-to-apiserver: "true"
|
||||
spec:
|
||||
serviceAccountName: {{ .Release.Name }}-cleanup
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: cleanup
|
||||
image: docker.io/clastix/kubectl:v1.32
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
echo "Deleting orphaned PVCs for {{ .Release.Name }}..."
|
||||
kubectl delete pvc -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} || true
|
||||
echo "PVC cleanup complete."
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-delete
|
||||
helm.sh/hook-weight: "0"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-delete
|
||||
"helm.sh/hook-weight": "5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["persistentvolumeclaims"]
|
||||
verbs: ["get", "list", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
labels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
annotations:
|
||||
"helm.sh/hook": post-delete
|
||||
helm.sh/hook-weight: "5"
|
||||
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ .Release.Name }}-cleanup
|
||||
@@ -47,18 +47,14 @@ spec:
|
||||
retries: -1
|
||||
values:
|
||||
nats:
|
||||
podTemplate:
|
||||
container:
|
||||
merge:
|
||||
spec:
|
||||
containers:
|
||||
- name: nats
|
||||
image: nats:2.10.17-alpine
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 22 }}
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 12 }}
|
||||
fullnameOverride: {{ .Release.Name }}
|
||||
config:
|
||||
{{- if or (gt (len $passwords) 0) (gt (len .Values.config.merge) 0) }}
|
||||
{{- if or $passwords .Values.config.merge }}
|
||||
merge:
|
||||
{{- if gt (len $passwords) 0 }}
|
||||
{{- if $passwords }}
|
||||
accounts:
|
||||
A:
|
||||
users:
|
||||
@@ -67,13 +63,13 @@ spec:
|
||||
password: "{{ $password }}"
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and .Values.config (hasKey .Values.config "merge") }}
|
||||
{{ toYaml .Values.config.merge | nindent 12 }}
|
||||
{{- with .Values.config.merge }}
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and .Values.config (hasKey .Values.config "resolver") }}
|
||||
{{- with .Values.config.resolver }}
|
||||
resolver:
|
||||
{{ toYaml .Values.config.resolver | nindent 12 }}
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
cluster:
|
||||
enabled: true
|
||||
|
||||
@@ -27,6 +27,7 @@ spec:
|
||||
replicas: 3
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 6 }}
|
||||
redis:
|
||||
image: "redis:8.2.0"
|
||||
resources: {{- include "cozy-lib.resources.defaultingSanitize" (list .Values.resourcesPreset .Values.resources $) | nindent 6 }}
|
||||
replicas: {{ .Values.replicas }}
|
||||
{{- with .Values.size }}
|
||||
|
||||
@@ -28,6 +28,7 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups:
|
||||
- core.cozystack.io
|
||||
@@ -113,6 +114,7 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
---
|
||||
kind: RoleBinding
|
||||
@@ -184,6 +186,7 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups:
|
||||
- core.cozystack.io
|
||||
@@ -282,6 +285,7 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups:
|
||||
- core.cozystack.io
|
||||
@@ -356,6 +360,7 @@ rules:
|
||||
- cozystack.io
|
||||
resources:
|
||||
- workloadmonitors
|
||||
- workloads
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups:
|
||||
- core.cozystack.io
|
||||
|
||||
@@ -5,7 +5,7 @@ set -u
|
||||
TMPDIR=$(mktemp -d)
|
||||
PROFILES="initramfs kernel iso installer nocloud metal"
|
||||
FIRMWARES="amd-ucode amdgpu bnx2-bnx2x i915 intel-ice-firmware intel-ucode qlogic-firmware"
|
||||
EXTENSIONS="drbd zfs lldpd"
|
||||
EXTENSIONS="drbd zfs"
|
||||
|
||||
mkdir -p images/talos/profiles
|
||||
|
||||
@@ -90,7 +90,6 @@ input:
|
||||
- imageRef: ${QLOGIC_FIRMWARE_IMAGE}
|
||||
- imageRef: ${DRBD_IMAGE}
|
||||
- imageRef: ${ZFS_IMAGE}
|
||||
- imageRef: ${LLDPD_IMAGE}
|
||||
output:
|
||||
kind: ${kind}
|
||||
imageOptions: ${image_options}
|
||||
|
||||
@@ -21,7 +21,6 @@ input:
|
||||
- imageRef: ghcr.io/siderolabs/qlogic-firmware:20250708@sha256:97124ee3594ab1529c8153b633f85f2d2de1252ee8222a77f81904dcabd76815
|
||||
- imageRef: ghcr.io/siderolabs/drbd:9.2.14-v1.10.6@sha256:ca7fba878c5acb8fdfe130a39472a6c0a5c9dd74d65ba7507c09780a873b29c7
|
||||
- imageRef: ghcr.io/siderolabs/zfs:2.3.3-v1.10.6@sha256:4952ef7306cf014823b6a66cf6d29840f4c6b7b362e36f9d6e853846c7dd0025
|
||||
- imageRef: ghcr.io/siderolabs/lldpd:1.0.19@sha256:73caa3c3a6c325970d0f527963f982698154d5f39c8c045b0fc2eb51d7da7b85
|
||||
output:
|
||||
kind: initramfs
|
||||
imageOptions: {}
|
||||
|
||||
@@ -21,7 +21,6 @@ input:
|
||||
- imageRef: ghcr.io/siderolabs/qlogic-firmware:20250708@sha256:97124ee3594ab1529c8153b633f85f2d2de1252ee8222a77f81904dcabd76815
|
||||
- imageRef: ghcr.io/siderolabs/drbd:9.2.14-v1.10.6@sha256:ca7fba878c5acb8fdfe130a39472a6c0a5c9dd74d65ba7507c09780a873b29c7
|
||||
- imageRef: ghcr.io/siderolabs/zfs:2.3.3-v1.10.6@sha256:4952ef7306cf014823b6a66cf6d29840f4c6b7b362e36f9d6e853846c7dd0025
|
||||
- imageRef: ghcr.io/siderolabs/lldpd:1.0.19@sha256:73caa3c3a6c325970d0f527963f982698154d5f39c8c045b0fc2eb51d7da7b85
|
||||
output:
|
||||
kind: installer
|
||||
imageOptions: {}
|
||||
|
||||
@@ -21,7 +21,6 @@ input:
|
||||
- imageRef: ghcr.io/siderolabs/qlogic-firmware:20250708@sha256:97124ee3594ab1529c8153b633f85f2d2de1252ee8222a77f81904dcabd76815
|
||||
- imageRef: ghcr.io/siderolabs/drbd:9.2.14-v1.10.6@sha256:ca7fba878c5acb8fdfe130a39472a6c0a5c9dd74d65ba7507c09780a873b29c7
|
||||
- imageRef: ghcr.io/siderolabs/zfs:2.3.3-v1.10.6@sha256:4952ef7306cf014823b6a66cf6d29840f4c6b7b362e36f9d6e853846c7dd0025
|
||||
- imageRef: ghcr.io/siderolabs/lldpd:1.0.19@sha256:73caa3c3a6c325970d0f527963f982698154d5f39c8c045b0fc2eb51d7da7b85
|
||||
output:
|
||||
kind: iso
|
||||
imageOptions: {}
|
||||
|
||||
@@ -21,7 +21,6 @@ input:
|
||||
- imageRef: ghcr.io/siderolabs/qlogic-firmware:20250708@sha256:97124ee3594ab1529c8153b633f85f2d2de1252ee8222a77f81904dcabd76815
|
||||
- imageRef: ghcr.io/siderolabs/drbd:9.2.14-v1.10.6@sha256:ca7fba878c5acb8fdfe130a39472a6c0a5c9dd74d65ba7507c09780a873b29c7
|
||||
- imageRef: ghcr.io/siderolabs/zfs:2.3.3-v1.10.6@sha256:4952ef7306cf014823b6a66cf6d29840f4c6b7b362e36f9d6e853846c7dd0025
|
||||
- imageRef: ghcr.io/siderolabs/lldpd:1.0.19@sha256:73caa3c3a6c325970d0f527963f982698154d5f39c8c045b0fc2eb51d7da7b85
|
||||
output:
|
||||
kind: kernel
|
||||
imageOptions: {}
|
||||
|
||||
@@ -21,7 +21,6 @@ input:
|
||||
- imageRef: ghcr.io/siderolabs/qlogic-firmware:20250708@sha256:97124ee3594ab1529c8153b633f85f2d2de1252ee8222a77f81904dcabd76815
|
||||
- imageRef: ghcr.io/siderolabs/drbd:9.2.14-v1.10.6@sha256:ca7fba878c5acb8fdfe130a39472a6c0a5c9dd74d65ba7507c09780a873b29c7
|
||||
- imageRef: ghcr.io/siderolabs/zfs:2.3.3-v1.10.6@sha256:4952ef7306cf014823b6a66cf6d29840f4c6b7b362e36f9d6e853846c7dd0025
|
||||
- imageRef: ghcr.io/siderolabs/lldpd:1.0.19@sha256:73caa3c3a6c325970d0f527963f982698154d5f39c8c045b0fc2eb51d7da7b85
|
||||
output:
|
||||
kind: image
|
||||
imageOptions: { diskSize: 1306525696, diskFormat: raw }
|
||||
|
||||
@@ -21,7 +21,6 @@ input:
|
||||
- imageRef: ghcr.io/siderolabs/qlogic-firmware:20250708@sha256:97124ee3594ab1529c8153b633f85f2d2de1252ee8222a77f81904dcabd76815
|
||||
- imageRef: ghcr.io/siderolabs/drbd:9.2.14-v1.10.6@sha256:ca7fba878c5acb8fdfe130a39472a6c0a5c9dd74d65ba7507c09780a873b29c7
|
||||
- imageRef: ghcr.io/siderolabs/zfs:2.3.3-v1.10.6@sha256:4952ef7306cf014823b6a66cf6d29840f4c6b7b362e36f9d6e853846c7dd0025
|
||||
- imageRef: ghcr.io/siderolabs/lldpd:1.0.19@sha256:73caa3c3a6c325970d0f527963f982698154d5f39c8c045b0fc2eb51d7da7b85
|
||||
output:
|
||||
kind: image
|
||||
imageOptions: { diskSize: 1306525696, diskFormat: raw }
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
cozystack:
|
||||
image: ghcr.io/cozystack/cozystack/installer:v0.37.0@sha256:256c5a0f0ae2fc3ad6865b9fda74c42945b38a5384240fa29554617185b60556
|
||||
image: ghcr.io/cozystack/cozystack/installer:v0.37.5@sha256:b821a5375271a4192af8d63da5281f8f994831085bd99155665742a13da0c35e
|
||||
|
||||
@@ -68,6 +68,12 @@ releases:
|
||||
disableTelemetry: true
|
||||
{{- end }}
|
||||
|
||||
- name: lineage-controller-webhook
|
||||
releaseName: lineage-controller-webhook
|
||||
chart: cozy-lineage-controller-webhook
|
||||
namespace: cozy-system
|
||||
dependsOn: [cozystack-controller,cilium,cert-manager]
|
||||
|
||||
- name: cert-manager
|
||||
releaseName: cert-manager
|
||||
chart: cozy-cert-manager
|
||||
|
||||
@@ -36,6 +36,12 @@ releases:
|
||||
disableTelemetry: true
|
||||
{{- end }}
|
||||
|
||||
- name: lineage-controller-webhook
|
||||
releaseName: lineage-controller-webhook
|
||||
chart: cozy-lineage-controller-webhook
|
||||
namespace: cozy-system
|
||||
dependsOn: [cozystack-controller,cert-manager]
|
||||
|
||||
- name: cert-manager
|
||||
releaseName: cert-manager
|
||||
chart: cozy-cert-manager
|
||||
|
||||
@@ -105,6 +105,12 @@ releases:
|
||||
disableTelemetry: true
|
||||
{{- end }}
|
||||
|
||||
- name: lineage-controller-webhook
|
||||
releaseName: lineage-controller-webhook
|
||||
chart: cozy-lineage-controller-webhook
|
||||
namespace: cozy-system
|
||||
dependsOn: [cozystack-controller,cilium,kubeovn,cert-manager]
|
||||
|
||||
- name: cozystack-resource-definition-crd
|
||||
releaseName: cozystack-resource-definition-crd
|
||||
chart: cozystack-resource-definition-crd
|
||||
|
||||
@@ -52,6 +52,12 @@ releases:
|
||||
disableTelemetry: true
|
||||
{{- end }}
|
||||
|
||||
- name: lineage-controller-webhook
|
||||
releaseName: lineage-controller-webhook
|
||||
chart: cozy-lineage-controller-webhook
|
||||
namespace: cozy-system
|
||||
dependsOn: [cozystack-controller,cert-manager]
|
||||
|
||||
- name: cozystack-resource-definition-crd
|
||||
releaseName: cozystack-resource-definition-crd
|
||||
chart: cozystack-resource-definition-crd
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
e2e:
|
||||
image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.37.0@sha256:10afd0a6c39248ec41d0e59ff1bc6c29bd0075b7cc9a512b01cf603ef39c33ea
|
||||
image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.37.5@sha256:16c3c05956cb5a69bcff4f18fff9ba0d19b41b88c1cb01c013877ba90f613dc6
|
||||
|
||||
@@ -1 +1 @@
|
||||
ghcr.io/cozystack/cozystack/matchbox:v0.37.0@sha256:5cca5f56b755285aefa11b1052fe55e1aa83b25bae34aef80cdb77ff63091044
|
||||
ghcr.io/cozystack/cozystack/matchbox:v0.37.5@sha256:6a53b95bc53ed79d7f5bb4fe1c4f3f4f789238e7e91ec2ce8df66ce3b4970891
|
||||
|
||||
@@ -72,6 +72,8 @@
|
||||
| `alerta.alerts.telegram.token` | Telegram token for your bot | `string` | `""` |
|
||||
| `alerta.alerts.telegram.chatID` | Specify multiple ID's separated by comma. Get yours in https://t.me/chatid_echo_bot | `string` | `""` |
|
||||
| `alerta.alerts.telegram.disabledSeverity` | List of severity without alerts, separated by comma like: "informational,warning" | `string` | `""` |
|
||||
| `alerta.alerts.slack` | Configuration for Slack alerts | `*object` | `null` |
|
||||
| `alerta.alerts.slack.url` | Configuration uri for Slack alerts | `*string` | `""` |
|
||||
|
||||
|
||||
### Grafana configuration
|
||||
|
||||
@@ -109,9 +109,20 @@ spec:
|
||||
- name: AUTH_REQUIRED
|
||||
value: "True"
|
||||
|
||||
{{- $plugins := list }}
|
||||
{{- if and .Values.alerta.alerts.telegram.chatID .Values.alerta.alerts.telegram.token }}
|
||||
{{- $plugins = append $plugins "telegram" }}
|
||||
{{- end }}
|
||||
{{- if .Values.alerta.alerts.slack.url }}
|
||||
{{- $plugins = append $plugins "slack" }}
|
||||
{{- end }}
|
||||
|
||||
{{- if gt (len $plugins) 0 }}
|
||||
- name: "PLUGINS"
|
||||
value: "telegram"
|
||||
value: "{{ default "" (join "," $plugins) }}"
|
||||
{{- end }}
|
||||
|
||||
{{- if and .Values.alerta.alerts.telegram.chatID .Values.alerta.alerts.telegram.token }}
|
||||
- name: TELEGRAM_CHAT_ID
|
||||
value: "{{ .Values.alerta.alerts.telegram.chatID }}"
|
||||
- name: TELEGRAM_TOKEN
|
||||
@@ -122,6 +133,11 @@ spec:
|
||||
value: "{{ .Values.alerta.alerts.telegram.disabledSeverity }}"
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.alerta.alerts.slack.url }}
|
||||
- name: "SLACK_WEBHOOK_URL"
|
||||
value: "{{ .Values.alerta.alerts.slack.url }}"
|
||||
{{- end }}
|
||||
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
|
||||
@@ -12,6 +12,17 @@
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"slack": {
|
||||
"description": "Configuration for Slack alerts",
|
||||
"type": "object",
|
||||
"default": {},
|
||||
"properties": {
|
||||
"url": {
|
||||
"description": "Configuration uri for Slack alerts",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"telegram": {
|
||||
"description": "Configuration for Telegram alerts",
|
||||
"type": "object",
|
||||
|
||||
@@ -90,6 +90,8 @@ logsStorages:
|
||||
## @field telegramAlerts.token {string} Telegram token for your bot
|
||||
## @field telegramAlerts.chatID {string} Specify multiple ID's separated by comma. Get yours in https://t.me/chatid_echo_bot
|
||||
## @field telegramAlerts.disabledSeverity {string} List of severity without alerts, separated by comma like: "informational,warning"
|
||||
## @field alerts.slack {*slackAlerts} Configuration for Slack alerts
|
||||
## @field slackAlerts.url {*string} Configuration uri for Slack alerts
|
||||
alerta:
|
||||
storage: 10Gi
|
||||
storageClassName: ""
|
||||
@@ -112,6 +114,9 @@ alerta:
|
||||
chatID: ""
|
||||
disabledSeverity: ""
|
||||
|
||||
slack:
|
||||
url: ""
|
||||
|
||||
## @section Grafana configuration
|
||||
|
||||
## @param grafana {grafana} Configuration for Grafana
|
||||
|
||||
@@ -1 +1 @@
|
||||
ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.37.0@sha256:f166f09cdc9cdbb758209883819ab8261a3793bc1d7a6b6685efd5a2b2930847
|
||||
ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.37.5@sha256:ac6380462d791bae88a1dc842ec5b2e6d7e1054c2255614e573c3997df64b463
|
||||
|
||||
@@ -1 +1 @@
|
||||
ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:7348bec610f08bd902c88c9a9f28fdd644727e2728a1e4103f88f0c99febd5e7
|
||||
ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:a5bb5014842d3deb551c707552721c2cfe8f6211f9fc8bc060f1bbf79a36e47e
|
||||
|
||||
@@ -10,6 +10,7 @@ metadata:
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/backend-protocol: HTTPS
|
||||
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
|
||||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
name: kubernetes
|
||||
namespace: default
|
||||
spec:
|
||||
|
||||
@@ -6,6 +6,9 @@ rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["namespaces", "secrets"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["rolebindings"]
|
||||
verbs: ["get", "watch", "list"]
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["create", "update", "patch", "delete"]
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
cozystackAPI:
|
||||
image: ghcr.io/cozystack/cozystack/cozystack-api:v0.37.0@sha256:19d89e8afb90ce38ab7e42ecedfc28402f7c0b56f30957db957c5415132ff6ca
|
||||
image: ghcr.io/cozystack/cozystack/cozystack-api:v0.37.5@sha256:1166252a96f14f4bcf4369577151aa3c372dabf171da9a8dbd28bab81889ac87
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: cozystack-controller-webhook-selfsigned
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
selfSigned: {}
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: cozystack-controller-webhook-ca
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
secretName: cozystack-controller-webhook-ca
|
||||
duration: 43800h # 5 years
|
||||
commonName: cozystack-controller-webhook-ca
|
||||
issuerRef:
|
||||
name: cozystack-controller-webhook-selfsigned
|
||||
isCA: true
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: cozystack-controller-webhook-ca
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
ca:
|
||||
secretName: cozystack-controller-webhook-ca
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: cozystack-controller-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
secretName: cozystack-controller-webhook-cert
|
||||
duration: 8760h
|
||||
renewBefore: 720h
|
||||
issuerRef:
|
||||
name: cozystack-controller-webhook-ca
|
||||
commonName: cozystack-controller
|
||||
dnsNames:
|
||||
- cozystack-controller
|
||||
- cozystack-controller.{{ .Release.Namespace }}.svc
|
||||
@@ -28,15 +28,3 @@ spec:
|
||||
{{- if .Values.cozystackController.disableTelemetry }}
|
||||
- --disable-telemetry
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: webhook
|
||||
containerPort: 9443
|
||||
volumeMounts:
|
||||
- name: webhook-certs
|
||||
mountPath: /tmp/k8s-webhook-server/serving-certs
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: webhook-certs
|
||||
secret:
|
||||
secretName: cozystack-controller-webhook-cert
|
||||
defaultMode: 0400
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cozystackController:
|
||||
image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.37.0@sha256:845b8e68cbc277c2303080bcd55597e4334610d396dad258ad56fd906530acc3
|
||||
image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.37.5@sha256:0d339b30ce2d07634dd19176e6966c5bd722872b12e47176b4243abb5704a11f
|
||||
debug: false
|
||||
disableTelemetry: false
|
||||
cozystackVersion: "v0.37.0"
|
||||
cozystackVersion: "v0.37.5"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -32,3 +32,8 @@ spec:
|
||||
secrets:
|
||||
exclude: []
|
||||
include: []
|
||||
services:
|
||||
exclude: []
|
||||
include:
|
||||
- resourceNames:
|
||||
- virtual-machine-{{ .name }}
|
||||
|
||||
@@ -4,7 +4,7 @@ FROM node:${NODE_VERSION}-alpine AS builder
|
||||
RUN apk add git
|
||||
WORKDIR /src
|
||||
|
||||
ARG COMMIT_REF=22f9143f5109fb90332651c857d70b51bffccd9b
|
||||
ARG COMMIT_REF=88531ed6881b4ce4808e56c00905951d7ba8031c
|
||||
RUN wget -O- https://github.com/PRO-Robotech/openapi-ui-k8s-bff/archive/${COMMIT_REF}.tar.gz | tar xzf - --strip-components=1
|
||||
|
||||
COPY patches /patches
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
diff --git a/src/endpoints/forms/formPrepare/formPrepare.ts b/src/endpoints/forms/formPrepare/formPrepare.ts
|
||||
diff --git a/src/endpoints/forms/prepareFormProps/prepareFormProps.ts b/src/endpoints/forms/prepareFormProps/prepareFormProps.ts
|
||||
index 7e437db..90c40f6 100644
|
||||
--- a/src/endpoints/forms/formPrepare/formPrepare.ts
|
||||
+++ b/src/endpoints/forms/formPrepare/formPrepare.ts
|
||||
--- a/src/endpoints/forms/prepareFormProps/prepareFormProps.ts
|
||||
+++ b/src/endpoints/forms/prepareFormProps/prepareFormProps.ts
|
||||
@@ -15,6 +15,7 @@ export const prepareFormProps: RequestHandler = async (req: TPrepareFormReq, res
|
||||
|
||||
const filteredHeaders = { ...req.headers }
|
||||
|
||||
@@ -3,9 +3,14 @@ ARG NODE_VERSION=20.18.1
|
||||
# openapi-k8s-toolkit
|
||||
# imported from https://github.com/cozystack/openapi-k8s-toolkit
|
||||
FROM node:${NODE_VERSION}-alpine AS openapi-k8s-toolkit-builder
|
||||
RUN apk add git
|
||||
WORKDIR /src
|
||||
ARG COMMIT=4f57ab295b2a886eb294b0b987554194fbe67dcd
|
||||
ARG COMMIT=e5f16b45de19f892de269cc4ef27e74aa62f4c92
|
||||
RUN wget -O- https://github.com/cozystack/openapi-k8s-toolkit/archive/${COMMIT}.tar.gz | tar -xzvf- --strip-components=1
|
||||
|
||||
COPY openapi-k8s-toolkit/patches /patches
|
||||
RUN git apply /patches/*.diff
|
||||
|
||||
RUN npm install
|
||||
RUN npm install --build-from-source @swc/core
|
||||
RUN npm run build
|
||||
@@ -17,10 +22,10 @@ FROM node:${NODE_VERSION}-alpine AS builder
|
||||
RUN apk add git
|
||||
WORKDIR /src
|
||||
|
||||
ARG COMMIT_REF=65e7fa8b3dc530a36e94c8435622bb09961aef97
|
||||
ARG COMMIT_REF=9ce4367657f49c0032d8016b1d9491f8abbd2b15
|
||||
RUN wget -O- https://github.com/PRO-Robotech/openapi-ui/archive/${COMMIT_REF}.tar.gz | tar xzf - --strip-components=1
|
||||
|
||||
COPY patches /patches
|
||||
COPY openapi-ui/patches /patches
|
||||
RUN git apply /patches/*.diff
|
||||
|
||||
ENV PATH=/src/node_modules/.bin:$PATH
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
diff --git a/src/components/molecules/EnrichedTable/organisms/EnrichedTable/utils.tsx b/src/components/molecules/EnrichedTable/organisms/EnrichedTable/utils.tsx
|
||||
index 8bcef4d..2551e92 100644
|
||||
--- a/src/components/molecules/EnrichedTable/organisms/EnrichedTable/utils.tsx
|
||||
+++ b/src/components/molecules/EnrichedTable/organisms/EnrichedTable/utils.tsx
|
||||
@@ -22,6 +22,15 @@ import { TableFactory } from '../../molecules'
|
||||
import { ShortenedTextWithTooltip, FilterDropdown, TrimmedTags, TextAlignContainer, TinyButton } from './atoms'
|
||||
import { TInternalDataForControls } from './types'
|
||||
|
||||
+const getPluralForm = (singular: string): string => {
|
||||
+ // If already ends with 's', add 'es'
|
||||
+ if (singular.endsWith('s')) {
|
||||
+ return `${singular}es`
|
||||
+ }
|
||||
+ // Otherwise just add 's'
|
||||
+ return `${singular}s`
|
||||
+}
|
||||
+
|
||||
export const getCellRender = ({
|
||||
value,
|
||||
record,
|
||||
@@ -255,7 +264,7 @@ export const getEnrichedColumnsWithControls = ({
|
||||
key: 'controls',
|
||||
className: 'controls',
|
||||
width: 60,
|
||||
- render: (value: TInternalDataForControls) => {
|
||||
+ render: (value: TInternalDataForControls, record: unknown) => {
|
||||
return (
|
||||
// <TextAlignContainer $align="right" className="hideable">
|
||||
<TextAlignContainer $align="center">
|
||||
@@ -279,10 +288,19 @@ export const getEnrichedColumnsWithControls = ({
|
||||
domEvent.stopPropagation()
|
||||
domEvent.preventDefault()
|
||||
if (key === 'edit') {
|
||||
+ // Special case: redirect tenantmodules from core.cozystack.io to apps.cozystack.io with plural form
|
||||
+ let apiGroupAndVersion = value.apiGroupAndVersion
|
||||
+ let typeName = value.typeName
|
||||
+ if (apiGroupAndVersion?.startsWith('core.cozystack.io/') && typeName === 'tenantmodules') {
|
||||
+ const appsApiVersion = apiGroupAndVersion.replace('core.cozystack.io/', 'apps.cozystack.io/')
|
||||
+ const pluralTypeName = getPluralForm(value.entryName)
|
||||
+ apiGroupAndVersion = appsApiVersion
|
||||
+ typeName = pluralTypeName
|
||||
+ }
|
||||
navigate(
|
||||
`${baseprefix}/${value.cluster}${value.namespace ? `/${value.namespace}` : ''}${
|
||||
value.syntheticProject ? `/${value.syntheticProject}` : ''
|
||||
- }/${value.pathPrefix}/${value.apiGroupAndVersion}/${value.typeName}/${value.entryName}?backlink=${
|
||||
+ }/${value.pathPrefix}/${apiGroupAndVersion}/${typeName}/${value.entryName}?backlink=${
|
||||
value.backlink
|
||||
}`,
|
||||
)
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx b/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx
|
||||
index 577ba0f..018df9c 100644
|
||||
index b6fb99f..965bac0 100644
|
||||
--- a/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx
|
||||
+++ b/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx
|
||||
@@ -1,11 +1,16 @@
|
||||
@@ -26,16 +26,16 @@ index 577ba0f..018df9c 100644
|
||||
|
||||
- const namespacesData = useBuiltinResources({
|
||||
+ const namespacesData = useApiResources({
|
||||
clusterName: cluster,
|
||||
clusterName: selectedCluster || '',
|
||||
- typeName: 'namespaces',
|
||||
+ apiGroup: BASE_PROJECTS_API_GROUP,
|
||||
+ apiVersion: BASE_PROJECTS_VERSION,
|
||||
+ typeName: BASE_PROJECTS_RESOURCE_NAME,
|
||||
limit: null,
|
||||
isEnabled: selectedCluster !== undefined,
|
||||
})
|
||||
|
||||
diff --git a/src/hooks/useNavSelectorInside.ts b/src/hooks/useNavSelectorInside.ts
|
||||
index d69405e..5adbd5d 100644
|
||||
index 5736e2b..1ec0f71 100644
|
||||
--- a/src/hooks/useNavSelectorInside.ts
|
||||
+++ b/src/hooks/useNavSelectorInside.ts
|
||||
@@ -1,6 +1,11 @@
|
||||
@@ -63,8 +63,8 @@ index d69405e..5adbd5d 100644
|
||||
+ apiVersion: BASE_PROJECTS_VERSION,
|
||||
+ typeName: BASE_PROJECTS_RESOURCE_NAME,
|
||||
limit: null,
|
||||
isEnabled: Boolean(clusterName),
|
||||
})
|
||||
|
||||
diff --git a/src/utils/getBacklink.ts b/src/utils/getBacklink.ts
|
||||
index a862354..f24e2bc 100644
|
||||
--- a/src/utils/getBacklink.ts
|
||||
@@ -0,0 +1,15 @@
|
||||
diff --git a/src/components/organisms/Header/organisms/User/User.tsx b/src/components/organisms/Header/organisms/User/User.tsx
|
||||
index efe7ac3..80b715c 100644
|
||||
--- a/src/components/organisms/Header/organisms/User/User.tsx
|
||||
+++ b/src/components/organisms/Header/organisms/User/User.tsx
|
||||
@@ -23,10 +23,6 @@ export const User: FC = () => {
|
||||
// key: '1',
|
||||
// label: <ThemeSelector />,
|
||||
// },
|
||||
- {
|
||||
- key: '2',
|
||||
- label: <div onClick={() => navigate(`${baseprefix}/inside/clusters`)}>Inside</div>,
|
||||
- },
|
||||
{
|
||||
key: '3',
|
||||
label: (
|
||||
@@ -1,6 +1,6 @@
|
||||
{{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }}
|
||||
|
||||
{{- $tenantText := "v0.37.0" }}
|
||||
{{- $tenantText := "v0.37.5" }}
|
||||
{{- $footerText := "Cozystack" }}
|
||||
{{- $titleText := "Cozystack Dashboard" }}
|
||||
{{- $logoText := "false" }}
|
||||
|
||||
@@ -55,6 +55,8 @@ spec:
|
||||
- --http-address=0.0.0.0:8000
|
||||
- --redirect-url=https://dashboard.{{ $host }}/oauth2/callback
|
||||
- --oidc-issuer-url=https://keycloak.{{ $host }}/realms/cozy
|
||||
- --backend-logout-url=https://keycloak.{{ $host }}/realms/cozy/protocol/openid-connect/logout?id_token_hint={id_token}
|
||||
- --whitelist-domain=keycloak.{{ $host }}
|
||||
- --email-domain=*
|
||||
- --pass-access-token=true
|
||||
- --pass-authorization-header=true
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
openapiUI:
|
||||
image: ghcr.io/cozystack/cozystack/openapi-ui:v0.37.0@sha256:13f38cf56830e899eb5e3d9dc8184965dd8dba9f8cd3c5ca10df0970355842d6
|
||||
image: ghcr.io/cozystack/cozystack/openapi-ui:v0.37.5@sha256:5c66e9aebbf6b435b75f1607ab800028a22d0e99a1acc5cf405f07581ce414f8
|
||||
openapiUIK8sBff:
|
||||
image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.37.0@sha256:2b626dbbf87241e8621ac5b0285f402edbc2c2069ba254ca2ace2dd5c9248ac8
|
||||
image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.37.5@sha256:194ff92c584a950f22067220436e6d8705e614422227e9cac7e889a704b709de
|
||||
tokenProxy:
|
||||
image: ghcr.io/cozystack/cozystack/token-proxy:v0.37.0@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b
|
||||
image: ghcr.io/cozystack/cozystack/token-proxy:v0.37.5@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b
|
||||
|
||||
@@ -10,3 +10,4 @@ update:
|
||||
rm -rf charts
|
||||
helm pull oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator --untar --untardir charts
|
||||
patch --no-backup-if-mismatch -p1 < patches/kubernetesEnvs.diff
|
||||
patch --no-backup-if-mismatch -p1 < patches/networkPolicy.diff
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Capabilities.APIVersions.Has "cilium.io/v2/CiliumClusterwideNetworkPolicy" }}
|
||||
---
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumClusterwideNetworkPolicy
|
||||
metadata:
|
||||
name: {{ include "flux-operator.fullname" . }}-restrict
|
||||
spec:
|
||||
nodeSelector: {}
|
||||
ingressDeny:
|
||||
- fromEntities:
|
||||
- world
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8080"
|
||||
protocol: TCP
|
||||
- port: "8081"
|
||||
protocol: TCP
|
||||
ingress:
|
||||
- fromEntities:
|
||||
- cluster
|
||||
{{- end }}
|
||||
25
packages/system/fluxcd-operator/patches/networkPolicy.diff
Normal file
25
packages/system/fluxcd-operator/patches/networkPolicy.diff
Normal file
@@ -0,0 +1,25 @@
|
||||
diff --git a/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml b/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml
|
||||
new file mode 100644
|
||||
--- /dev/null (revision 52a23eacfc32430d8b008b765c64a81526521bae)
|
||||
+++ b/packages/system/fluxcd-operator/charts/flux-operator/templates/network-policy.yaml (revision 52a23eacfc32430d8b008b765c64a81526521bae)
|
||||
@@ -0,0 +1,18 @@
|
||||
+{{- if .Capabilities.APIVersions.Has "cilium.io/v2/CiliumClusterwideNetworkPolicy" }}
|
||||
+apiVersion: cilium.io/v2
|
||||
+kind: CiliumClusterwideNetworkPolicy
|
||||
+metadata:
|
||||
+ name: {{ include "flux-operator.fullname" . }}-restrict
|
||||
+spec:
|
||||
+ nodeSelector: {}
|
||||
+ ingressDeny:
|
||||
+ - fromEntities:
|
||||
+ - world
|
||||
+ toPorts:
|
||||
+ - ports:
|
||||
+ - port: "8080"
|
||||
+ protocol: TCP
|
||||
+ - port: "8081"
|
||||
+ protocol: TCP
|
||||
+ ingress:
|
||||
+ - fromEntities:
|
||||
+ - cluster
|
||||
+{{- end }}
|
||||
156
packages/system/kamaji/images/kamaji/patches/992.diff
Normal file
156
packages/system/kamaji/images/kamaji/patches/992.diff
Normal file
@@ -0,0 +1,156 @@
|
||||
diff --git a/internal/resources/api_server_certificate.go b/internal/resources/api_server_certificate.go
|
||||
index 436cdf9..4702b6c 100644
|
||||
--- a/internal/resources/api_server_certificate.go
|
||||
+++ b/internal/resources/api_server_certificate.go
|
||||
@@ -108,6 +108,7 @@ func (r *APIServerCertificate) mutate(ctx context.Context, tenantControlPlane *k
|
||||
}
|
||||
|
||||
r.resource.SetLabels(utilities.MergeMaps(
|
||||
+ r.resource.GetLabels(),
|
||||
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
|
||||
map[string]string{
|
||||
constants.ControllerLabelResource: "x509",
|
||||
diff --git a/internal/resources/api_server_kubelet_client_certificate.go b/internal/resources/api_server_kubelet_client_certificate.go
|
||||
index 85b4d42..da18db4 100644
|
||||
--- a/internal/resources/api_server_kubelet_client_certificate.go
|
||||
+++ b/internal/resources/api_server_kubelet_client_certificate.go
|
||||
@@ -95,6 +95,7 @@ func (r *APIServerKubeletClientCertificate) mutate(ctx context.Context, tenantCo
|
||||
}
|
||||
|
||||
r.resource.SetLabels(utilities.MergeMaps(
|
||||
+ r.resource.GetLabels(),
|
||||
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
|
||||
map[string]string{
|
||||
constants.ControllerLabelResource: "x509",
|
||||
diff --git a/internal/resources/ca_certificate.go b/internal/resources/ca_certificate.go
|
||||
index 5425b0b..625273f 100644
|
||||
--- a/internal/resources/ca_certificate.go
|
||||
+++ b/internal/resources/ca_certificate.go
|
||||
@@ -137,7 +137,7 @@ func (r *CACertificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1
|
||||
corev1.TLSPrivateKeyKey: ca.PrivateKey,
|
||||
}
|
||||
|
||||
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
|
||||
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
|
||||
|
||||
utilities.SetObjectChecksum(r.resource, r.resource.Data)
|
||||
|
||||
diff --git a/internal/resources/datastore/datastore_certificate.go b/internal/resources/datastore/datastore_certificate.go
|
||||
index dea45ae..8492a5e 100644
|
||||
--- a/internal/resources/datastore/datastore_certificate.go
|
||||
+++ b/internal/resources/datastore/datastore_certificate.go
|
||||
@@ -94,6 +94,7 @@ func (r *Certificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1al
|
||||
r.resource.Data["ca.crt"] = ca
|
||||
|
||||
r.resource.SetLabels(utilities.MergeMaps(
|
||||
+ r.resource.GetLabels(),
|
||||
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
|
||||
map[string]string{
|
||||
constants.ControllerLabelResource: "x509",
|
||||
diff --git a/internal/resources/datastore/datastore_storage_config.go b/internal/resources/datastore/datastore_storage_config.go
|
||||
index 7d03420..4ea9e64 100644
|
||||
--- a/internal/resources/datastore/datastore_storage_config.go
|
||||
+++ b/internal/resources/datastore/datastore_storage_config.go
|
||||
@@ -181,7 +181,7 @@ func (r *Config) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.
|
||||
|
||||
utilities.SetObjectChecksum(r.resource, r.resource.Data)
|
||||
|
||||
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
|
||||
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
|
||||
|
||||
return ctrl.SetControllerReference(tenantControlPlane, r.resource, r.Client.Scheme())
|
||||
}
|
||||
diff --git a/internal/resources/front-proxy-client-certificate.go b/internal/resources/front-proxy-client-certificate.go
|
||||
index f5ed67c..2dd4eda 100644
|
||||
--- a/internal/resources/front-proxy-client-certificate.go
|
||||
+++ b/internal/resources/front-proxy-client-certificate.go
|
||||
@@ -95,6 +95,7 @@ func (r *FrontProxyClientCertificate) mutate(ctx context.Context, tenantControlP
|
||||
}
|
||||
|
||||
r.resource.SetLabels(utilities.MergeMaps(
|
||||
+ r.resource.GetLabels(),
|
||||
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
|
||||
map[string]string{
|
||||
constants.ControllerLabelResource: "x509",
|
||||
diff --git a/internal/resources/front_proxy_ca_certificate.go b/internal/resources/front_proxy_ca_certificate.go
|
||||
index d410720..ccadc70 100644
|
||||
--- a/internal/resources/front_proxy_ca_certificate.go
|
||||
+++ b/internal/resources/front_proxy_ca_certificate.go
|
||||
@@ -114,7 +114,7 @@ func (r *FrontProxyCACertificate) mutate(ctx context.Context, tenantControlPlane
|
||||
kubeadmconstants.FrontProxyCAKeyName: ca.PrivateKey,
|
||||
}
|
||||
|
||||
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
|
||||
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
|
||||
|
||||
utilities.SetObjectChecksum(r.resource, r.resource.Data)
|
||||
|
||||
diff --git a/internal/resources/k8s_ingress_resource.go b/internal/resources/k8s_ingress_resource.go
|
||||
index f2e014f..e1aef59 100644
|
||||
--- a/internal/resources/k8s_ingress_resource.go
|
||||
+++ b/internal/resources/k8s_ingress_resource.go
|
||||
@@ -147,7 +147,7 @@ func (r *KubernetesIngressResource) Define(_ context.Context, tenantControlPlane
|
||||
|
||||
func (r *KubernetesIngressResource) mutate(tenantControlPlane *kamajiv1alpha1.TenantControlPlane) controllerutil.MutateFn {
|
||||
return func() error {
|
||||
- labels := utilities.MergeMaps(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()), tenantControlPlane.Spec.ControlPlane.Ingress.AdditionalMetadata.Labels)
|
||||
+ labels := utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()), tenantControlPlane.Spec.ControlPlane.Ingress.AdditionalMetadata.Labels)
|
||||
r.resource.SetLabels(labels)
|
||||
|
||||
annotations := utilities.MergeMaps(r.resource.GetAnnotations(), tenantControlPlane.Spec.ControlPlane.Ingress.AdditionalMetadata.Annotations)
|
||||
diff --git a/internal/resources/k8s_service_resource.go b/internal/resources/k8s_service_resource.go
|
||||
index 7e7f11f..9c30145 100644
|
||||
--- a/internal/resources/k8s_service_resource.go
|
||||
+++ b/internal/resources/k8s_service_resource.go
|
||||
@@ -76,7 +76,12 @@ func (r *KubernetesServiceResource) mutate(ctx context.Context, tenantControlPla
|
||||
address, _ := tenantControlPlane.DeclaredControlPlaneAddress(ctx, r.Client)
|
||||
|
||||
return func() error {
|
||||
- labels := utilities.MergeMaps(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Labels)
|
||||
+ labels := utilities.MergeMaps(
|
||||
+ r.resource.GetLabels(),
|
||||
+ utilities.KamajiLabels(
|
||||
+ tenantControlPlane.GetName(), r.GetName()),
|
||||
+ tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Labels,
|
||||
+ )
|
||||
r.resource.SetLabels(labels)
|
||||
|
||||
annotations := utilities.MergeMaps(r.resource.GetAnnotations(), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Annotations)
|
||||
diff --git a/internal/resources/kubeadm_config.go b/internal/resources/kubeadm_config.go
|
||||
index ae4cfc0..98dc36d 100644
|
||||
--- a/internal/resources/kubeadm_config.go
|
||||
+++ b/internal/resources/kubeadm_config.go
|
||||
@@ -89,7 +89,7 @@ func (r *KubeadmConfigResource) mutate(ctx context.Context, tenantControlPlane *
|
||||
return err
|
||||
}
|
||||
|
||||
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
|
||||
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
|
||||
|
||||
params := kubeadm.Parameters{
|
||||
TenantControlPlaneAddress: address,
|
||||
diff --git a/internal/resources/kubeconfig.go b/internal/resources/kubeconfig.go
|
||||
index a87da7f..bd77676 100644
|
||||
--- a/internal/resources/kubeconfig.go
|
||||
+++ b/internal/resources/kubeconfig.go
|
||||
@@ -163,6 +163,7 @@ func (r *KubeconfigResource) mutate(ctx context.Context, tenantControlPlane *kam
|
||||
}
|
||||
|
||||
r.resource.SetLabels(utilities.MergeMaps(
|
||||
+ r.resource.GetLabels(),
|
||||
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
|
||||
map[string]string{
|
||||
constants.ControllerLabelResource: "kubeconfig",
|
||||
diff --git a/internal/resources/sa_certificate.go b/internal/resources/sa_certificate.go
|
||||
index b53c7b0..4001eca 100644
|
||||
--- a/internal/resources/sa_certificate.go
|
||||
+++ b/internal/resources/sa_certificate.go
|
||||
@@ -113,7 +113,7 @@ func (r *SACertificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1
|
||||
kubeadmconstants.ServiceAccountPrivateKeyName: sa.PrivateKey,
|
||||
}
|
||||
|
||||
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
|
||||
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
|
||||
|
||||
utilities.SetObjectChecksum(r.resource, r.resource.Data)
|
||||
|
||||
@@ -3,7 +3,7 @@ kamaji:
|
||||
deploy: false
|
||||
image:
|
||||
pullPolicy: IfNotPresent
|
||||
tag: v0.37.0@sha256:9f4fd5045ede2909fbaf2572e4138fcbd8921071ecf8f08446257fddd0e6f655
|
||||
tag: v0.37.5@sha256:9d076f9a6cfcf25a22a1d366ff7129439688ae8cb07f5a81eab77df3968155ef
|
||||
repository: ghcr.io/cozystack/cozystack/kamaji
|
||||
resources:
|
||||
limits:
|
||||
@@ -13,4 +13,4 @@ kamaji:
|
||||
cpu: 100m
|
||||
memory: 100Mi
|
||||
extraArgs:
|
||||
- --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.37.0@sha256:9f4fd5045ede2909fbaf2572e4138fcbd8921071ecf8f08446257fddd0e6f655
|
||||
- --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.37.5@sha256:9d076f9a6cfcf25a22a1d366ff7129439688ae8cb07f5a81eab77df3968155ef
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
portSecurity: true
|
||||
routes: ""
|
||||
image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.37.0@sha256:9950614571ea77a55925eba0839b6b12c8e5a7a30b8858031a8c6050f261af1a
|
||||
image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.37.5@sha256:3443a6ddc9a1e087b27f21937385f40699cdf1763ae7e2350f13610fecb1195c
|
||||
ovnCentralName: ovn-central
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
portSecurity: true
|
||||
routes: ""
|
||||
image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.37.0@sha256:7e63205708e607ce2cedfe2a2cafd323ca51e3ebc71244a21ff6f9016c6c87bc
|
||||
image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.37.5@sha256:7e63205708e607ce2cedfe2a2cafd323ca51e3ebc71244a21ff6f9016c6c87bc
|
||||
|
||||
@@ -2,6 +2,7 @@ kube-ovn:
|
||||
namespace: cozy-kubeovn
|
||||
func:
|
||||
ENABLE_NP: false
|
||||
ENABLE_LB: false
|
||||
ipv4:
|
||||
POD_CIDR: "10.244.0.0/16"
|
||||
POD_GATEWAY: "10.244.0.1"
|
||||
@@ -64,4 +65,4 @@ global:
|
||||
images:
|
||||
kubeovn:
|
||||
repository: kubeovn
|
||||
tag: v1.14.5@sha256:af10da442a0c6dc7df47a0ef752e2eb5c247bb0b43069fdfcb2aa51511185ea2
|
||||
tag: v1.14.5@sha256:0bbd4688ea73c6e9e08b1b3fecec39a051395fa50bf7afedbc93254cb1216df1
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
storageClass: replicated
|
||||
csiDriver:
|
||||
image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:c8b08084a86251cdd18e237de89b695bca0e4f7eb1f1f6ddc2b903b4d74ea5ff
|
||||
image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:e7c575b0068cf78fae8730fe8d1919799e93356b14f0b645789645bd975878b9
|
||||
|
||||
@@ -10,7 +10,7 @@ spec:
|
||||
expr: |
|
||||
max_over_time(
|
||||
kubevirt_vm_info{
|
||||
status!="Running",
|
||||
status!="running",
|
||||
exported_namespace=~".+",
|
||||
name=~".+"
|
||||
}[10m]
|
||||
@@ -27,7 +27,7 @@ spec:
|
||||
expr: |
|
||||
max_over_time(
|
||||
kubevirt_vmi_info{
|
||||
phase!="running",
|
||||
phase!="Running",
|
||||
exported_namespace=~".+",
|
||||
name=~".+"
|
||||
}[10m]
|
||||
|
||||
27
packages/system/lineage-controller-webhook/.gitignore
vendored
Normal file
27
packages/system/lineage-controller-webhook/.gitignore
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
bin/*
|
||||
Dockerfile.cross
|
||||
|
||||
# Test binary, built with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Go workspace file
|
||||
go.work
|
||||
|
||||
# Kubernetes Generated files - skip generated files, except for vendored files
|
||||
!vendor/**/zz_generated.*
|
||||
|
||||
# editor and IDE paraphernalia
|
||||
.idea
|
||||
.vscode
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
3
packages/system/lineage-controller-webhook/Chart.yaml
Normal file
3
packages/system/lineage-controller-webhook/Chart.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
apiVersion: v2
|
||||
name: cozy-lineage-controller-webhook
|
||||
version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process
|
||||
18
packages/system/lineage-controller-webhook/Makefile
Normal file
18
packages/system/lineage-controller-webhook/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
NAME=lineage-controller-webhook
|
||||
NAMESPACE=cozy-system
|
||||
|
||||
include ../../../scripts/common-envs.mk
|
||||
include ../../../scripts/package.mk
|
||||
|
||||
image: image-lineage-controller-webhook
|
||||
|
||||
image-lineage-controller-webhook:
|
||||
docker buildx build -f images/lineage-controller-webhook/Dockerfile ../../.. \
|
||||
--tag $(REGISTRY)/lineage-controller-webhook:$(call settag,$(TAG)) \
|
||||
--cache-from type=registry,ref=$(REGISTRY)/lineage-controller-webhook:latest \
|
||||
--cache-to type=inline \
|
||||
--metadata-file images/lineage-controller-webhook.json \
|
||||
$(BUILDX_ARGS)
|
||||
IMAGE="$(REGISTRY)/lineage-controller-webhook:$(call settag,$(TAG))@$$(yq e '."containerimage.digest"' images/lineage-controller-webhook.json -o json -r)" \
|
||||
yq -i '.lineageControllerWebhook.image = strenv(IMAGE)' values.yaml
|
||||
rm -f images/lineage-controller-webhook.json
|
||||
@@ -0,0 +1,23 @@
|
||||
FROM golang:1.24-alpine AS builder
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
COPY go.mod go.sum ./
|
||||
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go mod download
|
||||
|
||||
COPY api api/
|
||||
COPY pkg pkg/
|
||||
COPY cmd cmd/
|
||||
COPY internal internal/
|
||||
|
||||
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -ldflags="-extldflags=-static" -o /lineage-controller-webhook cmd/lineage-controller-webhook/main.go
|
||||
|
||||
FROM scratch
|
||||
|
||||
COPY --from=builder /lineage-controller-webhook /lineage-controller-webhook
|
||||
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
ENTRYPOINT ["/lineage-controller-webhook"]
|
||||
@@ -0,0 +1,45 @@
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: lineage-controller-webhook-selfsigned
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
selfSigned: {}
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: lineage-controller-webhook-ca
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
secretName: lineage-controller-webhook-ca
|
||||
duration: 43800h # 5 years
|
||||
commonName: lineage-controller-webhook-ca
|
||||
issuerRef:
|
||||
name: lineage-controller-webhook-selfsigned
|
||||
isCA: true
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: lineage-controller-webhook-ca
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
ca:
|
||||
secretName: lineage-controller-webhook-ca
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
name: lineage-controller-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
spec:
|
||||
secretName: lineage-controller-webhook-cert
|
||||
duration: 8760h
|
||||
renewBefore: 720h
|
||||
issuerRef:
|
||||
name: lineage-controller-webhook-ca
|
||||
commonName: lineage-controller-webhook
|
||||
dnsNames:
|
||||
- lineage-controller-webhook
|
||||
- lineage-controller-webhook.{{ .Release.Namespace }}.svc
|
||||
@@ -0,0 +1,46 @@
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: lineage-controller-webhook
|
||||
labels:
|
||||
app: lineage-controller-webhook
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: lineage-controller-webhook
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: lineage-controller-webhook
|
||||
spec:
|
||||
nodeSelector:
|
||||
node-role.kubernetes.io/control-plane: ""
|
||||
tolerations:
|
||||
- key: "node-role.kubernetes.io/control-plane"
|
||||
operator: "Exists"
|
||||
effect: "NoSchedule"
|
||||
- key: "node-role.kubernetes.io/master"
|
||||
operator: "Exists"
|
||||
effect: "NoSchedule"
|
||||
serviceAccountName: lineage-controller-webhook
|
||||
containers:
|
||||
- name: lineage-controller-webhook
|
||||
image: "{{ .Values.lineageControllerWebhook.image }}"
|
||||
args:
|
||||
{{- if .Values.lineageControllerWebhook.debug }}
|
||||
- --zap-log-level=debug
|
||||
{{- else }}
|
||||
- --zap-log-level=info
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: webhook
|
||||
containerPort: 9443
|
||||
volumeMounts:
|
||||
- name: webhook-certs
|
||||
mountPath: /tmp/k8s-webhook-server/serving-certs
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: webhook-certs
|
||||
secret:
|
||||
secretName: lineage-controller-webhook-cert
|
||||
defaultMode: 0400
|
||||
@@ -3,7 +3,7 @@ kind: MutatingWebhookConfiguration
|
||||
metadata:
|
||||
name: lineage
|
||||
annotations:
|
||||
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/cozystack-controller-webhook
|
||||
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/lineage-controller-webhook
|
||||
labels:
|
||||
app: cozystack-controller
|
||||
webhooks:
|
||||
@@ -12,7 +12,7 @@ webhooks:
|
||||
sideEffects: None
|
||||
clientConfig:
|
||||
service:
|
||||
name: cozystack-controller
|
||||
name: lineage-controller-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
path: /mutate-lineage
|
||||
rules:
|
||||
@@ -40,3 +40,7 @@ webhooks:
|
||||
values:
|
||||
- kube-system
|
||||
- default
|
||||
objectSelector:
|
||||
matchExpressions:
|
||||
- key: internal.cozystack.io/managed-by-cozystack
|
||||
operator: DoesNotExist
|
||||
@@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: lineage-controller-webhook
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: lineage-controller-webhook
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: lineage-controller-webhook
|
||||
namespace: {{ .Release.Namespace }}
|
||||
@@ -0,0 +1,8 @@
|
||||
kind: ClusterRole
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: lineage-controller-webhook
|
||||
rules:
|
||||
- apiGroups: ['*']
|
||||
resources: ['*']
|
||||
verbs: ["get", "list", "watch"]
|
||||
@@ -0,0 +1,4 @@
|
||||
kind: ServiceAccount
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: lineage-controller-webhook
|
||||
@@ -1,10 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: cozystack-controller
|
||||
name: lineage-controller-webhook
|
||||
labels:
|
||||
app: cozystack-controller
|
||||
app: lineage-controller-webhook
|
||||
spec:
|
||||
internalTrafficPolicy: Local
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 443
|
||||
@@ -12,4 +13,4 @@ spec:
|
||||
protocol: TCP
|
||||
name: webhook
|
||||
selector:
|
||||
app: cozystack-controller
|
||||
app: lineage-controller-webhook
|
||||
3
packages/system/lineage-controller-webhook/values.yaml
Normal file
3
packages/system/lineage-controller-webhook/values.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
lineageControllerWebhook:
|
||||
image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.37.5@sha256:df3bd847e9a733a9e9e4b4ebb6a48a95405c68c663837a72f613ace2904242bd
|
||||
debug: false
|
||||
@@ -1,3 +1,3 @@
|
||||
objectstorage:
|
||||
controller:
|
||||
image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.37.0@sha256:5f2eed05d19ba971806374834cb16ca49282aac76130194c00b213c79ce3e10d"
|
||||
image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.37.5@sha256:7ee2109d9279c33507505f6b1a12173018749ead39229b642043b25621e63455"
|
||||
|
||||
@@ -3,8 +3,8 @@ name: piraeus
|
||||
description: |
|
||||
The Piraeus Operator manages software defined storage clusters using LINSTOR in Kubernetes.
|
||||
type: application
|
||||
version: 2.9.0
|
||||
appVersion: "v2.9.0"
|
||||
version: 2.9.1
|
||||
appVersion: "v2.9.1"
|
||||
maintainers:
|
||||
- name: Piraeus Datastore
|
||||
url: https://piraeus.io
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# DO NOT EDIT; Automatically created by hack/copy-image-config-to-chart.sh
|
||||
# DO NOT EDIT; Automatically created by tools/copy-image-config-to-chart.sh
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
@@ -17,16 +17,16 @@ data:
|
||||
# quay.io/piraeusdatastore/piraeus-server:v1.24.2
|
||||
components:
|
||||
linstor-controller:
|
||||
tag: v1.31.3
|
||||
tag: v1.32.3
|
||||
image: piraeus-server
|
||||
linstor-satellite:
|
||||
tag: v1.31.3
|
||||
tag: v1.32.3
|
||||
image: piraeus-server
|
||||
linstor-csi:
|
||||
tag: v1.8.0
|
||||
tag: v1.9.0
|
||||
image: piraeus-csi
|
||||
drbd-reactor:
|
||||
tag: v1.8.0
|
||||
tag: v1.9.0
|
||||
image: drbd-reactor
|
||||
ha-controller:
|
||||
tag: v1.3.0
|
||||
@@ -35,45 +35,45 @@ data:
|
||||
tag: v1.0.0
|
||||
image: drbd-shutdown-guard
|
||||
ktls-utils:
|
||||
tag: v1.1.0
|
||||
tag: v1.2.1
|
||||
image: ktls-utils
|
||||
drbd-module-loader:
|
||||
tag: v9.2.14
|
||||
tag: v9.2.15
|
||||
# The special "match" attribute is used to select an image based on the node's reported OS.
|
||||
# The operator will first check the k8s node's ".status.nodeInfo.osImage" field, and compare it against the list
|
||||
# here. If one matches, that specific image name will be used instead of the fallback image.
|
||||
image: drbd9-noble # Fallback image: chose a recent kernel, which can hopefully compile whatever config is actually in use
|
||||
match:
|
||||
- osImage: Red Hat Enterprise Linux Server 7\.
|
||||
image: drbd9-centos7
|
||||
- osImage: Red Hat Enterprise Linux 8\.
|
||||
image: drbd9-almalinux8
|
||||
- osImage: Red Hat Enterprise Linux 9\.
|
||||
image: drbd9-almalinux9
|
||||
- osImage: Red Hat Enterprise Linux 10\.
|
||||
image: drbd9-almalinux10
|
||||
- osImage: "Red Hat Enterprise Linux CoreOS 41[3-9]"
|
||||
image: drbd9-almalinux9
|
||||
- osImage: Red Hat Enterprise Linux CoreOS
|
||||
image: drbd9-almalinux8
|
||||
- osImage: CentOS Linux 7
|
||||
image: drbd9-centos7
|
||||
- osImage: CentOS Linux 8
|
||||
image: drbd9-almalinux8
|
||||
- osImage: AlmaLinux 8
|
||||
image: drbd9-almalinux8
|
||||
- osImage: AlmaLinux 9
|
||||
image: drbd9-almalinux9
|
||||
- osImage: AlmaLinux 10
|
||||
image: drbd9-almalinux10
|
||||
- osImage: Oracle Linux Server 8\.
|
||||
image: drbd9-almalinux8
|
||||
- osImage: Oracle Linux Server 9\.
|
||||
image: drbd9-almalinux9
|
||||
- osImage: Oracle Linux Server 10\.
|
||||
image: drbd9-almalinux10
|
||||
- osImage: Rocky Linux 8
|
||||
image: drbd9-almalinux8
|
||||
- osImage: Rocky Linux 9
|
||||
image: drbd9-almalinux9
|
||||
- osImage: Ubuntu 18\.04
|
||||
image: drbd9-bionic
|
||||
- osImage: Ubuntu 20\.04
|
||||
image: drbd9-focal
|
||||
- osImage: Rocky Linux 10
|
||||
image: drbd9-almalinux10
|
||||
- osImage: Ubuntu 22\.04
|
||||
image: drbd9-jammy
|
||||
- osImage: Ubuntu 24\.04
|
||||
@@ -82,32 +82,30 @@ data:
|
||||
image: drbd9-bookworm
|
||||
- osImage: Debian GNU/Linux 11
|
||||
image: drbd9-bullseye
|
||||
- osImage: Debian GNU/Linux 10
|
||||
image: drbd9-buster
|
||||
0_sig_storage_images.yaml: |
|
||||
---
|
||||
base: registry.k8s.io/sig-storage
|
||||
components:
|
||||
csi-attacher:
|
||||
tag: v4.9.0
|
||||
tag: v4.10.0
|
||||
image: csi-attacher
|
||||
csi-livenessprobe:
|
||||
tag: v2.16.0
|
||||
tag: v2.17.0
|
||||
image: livenessprobe
|
||||
csi-provisioner:
|
||||
tag: v5.3.0
|
||||
image: csi-provisioner
|
||||
csi-snapshotter:
|
||||
tag: v8.2.1
|
||||
tag: v8.3.0
|
||||
image: csi-snapshotter
|
||||
csi-resizer:
|
||||
tag: v1.13.2
|
||||
tag: v1.14.0
|
||||
image: csi-resizer
|
||||
csi-external-health-monitor-controller:
|
||||
tag: v0.15.0
|
||||
tag: v0.16.0
|
||||
image: csi-external-health-monitor-controller
|
||||
csi-node-driver-registrar:
|
||||
tag: v2.14.0
|
||||
tag: v2.15.0
|
||||
image: csi-node-driver-registrar
|
||||
{{- range $idx, $value := .Values.imageConfigOverride }}
|
||||
{{ add $idx 1 }}_helm_override.yaml: |
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
{{ if .Values.serviceAccount.create }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
# DO NOT EDIT; Automatically created by tools/copy-rbac-config-to-chart.sh
|
||||
{{ if .Values.rbac.create }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
@@ -14,448 +8,288 @@ metadata:
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- events
|
||||
- persistentvolumes
|
||||
- secrets
|
||||
- serviceaccounts
|
||||
- services
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- pods
|
||||
- secrets
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims/status
|
||||
verbs:
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- delete
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/eviction
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- replicasets
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- cert-manager.io
|
||||
resources:
|
||||
- certificates
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- events.k8s.io
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- internal.linstor.linbit.com
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorclusters
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorclusters/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorclusters/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstornodeconnections
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstornodeconnections/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstornodeconnections/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorsatelliteconfigurations
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorsatelliteconfigurations/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorsatellites
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorsatellites/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorsatellites/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- clusterrolebindings
|
||||
- clusterroles
|
||||
- rolebindings
|
||||
- roles
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- security.openshift.io
|
||||
resourceNames:
|
||||
- privileged
|
||||
resources:
|
||||
- securitycontextconstraints
|
||||
verbs:
|
||||
- use
|
||||
- apiGroups:
|
||||
- snapshot.storage.k8s.io
|
||||
resources:
|
||||
- volumesnapshotclasses
|
||||
- volumesnapshots
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- snapshot.storage.k8s.io
|
||||
resources:
|
||||
- volumesnapshotcontents
|
||||
verbs:
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- snapshot.storage.k8s.io
|
||||
resources:
|
||||
- volumesnapshotcontents/status
|
||||
verbs:
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- csidrivers
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- csinodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- csistoragecapacities
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- storageclasses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- volumeattachments
|
||||
verbs:
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- volumeattachments/status
|
||||
verbs:
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.fullname" . }}-manager-rolebinding
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: '{{ include "piraeus-operator.fullname" . }}-controller-manager'
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: '{{ include "piraeus-operator.serviceAccountName" . }}'
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
{{ end }}
|
||||
{{ if.Values.rbac.create }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.fullname" . }}-proxy-role
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- authentication.k8s.io
|
||||
resources:
|
||||
- tokenreviews
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- authorization.k8s.io
|
||||
resources:
|
||||
- subjectaccessreviews
|
||||
verbs:
|
||||
- create
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.fullname" . }}-proxy-rolebinding
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: '{{ include "piraeus-operator.fullname" . }}-proxy-role'
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "piraeus-operator.serviceAccountName" . }}
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
- events
|
||||
- persistentvolumes
|
||||
- pods
|
||||
- secrets
|
||||
- serviceaccounts
|
||||
- services
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- nodes
|
||||
- persistentvolumeclaims
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- persistentvolumeclaims/status
|
||||
verbs:
|
||||
- patch
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- pods/eviction
|
||||
verbs:
|
||||
- create
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- daemonsets
|
||||
- deployments
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- replicasets
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- cert-manager.io
|
||||
resources:
|
||||
- certificates
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- events.k8s.io
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- internal.linstor.linbit.com
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- deletecollection
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorclusters
|
||||
- linstornodeconnections
|
||||
- linstorsatellites
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorclusters/finalizers
|
||||
- linstornodeconnections/finalizers
|
||||
- linstorsatellites/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorclusters/status
|
||||
- linstornodeconnections/status
|
||||
- linstorsatelliteconfigurations/status
|
||||
- linstorsatellites/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- piraeus.io
|
||||
resources:
|
||||
- linstorsatelliteconfigurations
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- rbac.authorization.k8s.io
|
||||
resources:
|
||||
- clusterrolebindings
|
||||
- clusterroles
|
||||
- rolebindings
|
||||
- roles
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- security.openshift.io
|
||||
resourceNames:
|
||||
- privileged
|
||||
resources:
|
||||
- securitycontextconstraints
|
||||
verbs:
|
||||
- use
|
||||
- apiGroups:
|
||||
- snapshot.storage.k8s.io
|
||||
resources:
|
||||
- volumesnapshotclasses
|
||||
- volumesnapshots
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- snapshot.storage.k8s.io
|
||||
resources:
|
||||
- volumesnapshotcontents
|
||||
verbs:
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- snapshot.storage.k8s.io
|
||||
resources:
|
||||
- volumesnapshotcontents/status
|
||||
verbs:
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- csidrivers
|
||||
- csistoragecapacities
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- csinodes
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- storageclasses
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- volumeattachments
|
||||
verbs:
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- storage.k8s.io
|
||||
resources:
|
||||
- volumeattachments/status
|
||||
verbs:
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.fullname" . }}-leader-election-role
|
||||
name: {{ include "piraeus-operator.fullname" . }}-leader-election
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
resources:
|
||||
- leases
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.fullname" . }}-leader-election-rolebinding
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: '{{ include "piraeus-operator.fullname" . }}-leader-election-role'
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "piraeus-operator.serviceAccountName" . }}
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- coordination.k8s.io
|
||||
resources:
|
||||
- leases
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- create
|
||||
- update
|
||||
- patch
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ""
|
||||
resources:
|
||||
- events
|
||||
verbs:
|
||||
- create
|
||||
- patch
|
||||
{{ end }}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
{{ if .Values.rbac.create }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.fullname" . }}-leader-election
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ include "piraeus-operator.fullname" . }}-leader-election
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "piraeus-operator.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.fullname" . }}-controller-manager
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ include "piraeus-operator.fullname" . }}-controller-manager
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "piraeus-operator.serviceAccountName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,9 @@
|
||||
{{ if .Values.serviceAccount.create }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "piraeus-operator.serviceAccountName" . }}
|
||||
labels:
|
||||
{{- include "piraeus-operator.labels" . | nindent 4 }}
|
||||
{{ end }}
|
||||
@@ -1,6 +1,8 @@
|
||||
REDIS_OPERATOR_TAG=$(shell grep -F 'ARG VERSION=' images/redis-operator/Dockerfile | cut -f2 -d=)
|
||||
export NAME=redis-operator
|
||||
export NAMESPACE=cozy-$(NAME)
|
||||
|
||||
include ../../../scripts/common-envs.mk
|
||||
include ../../../scripts/package.mk
|
||||
|
||||
update:
|
||||
@@ -9,3 +11,16 @@ update:
|
||||
helm repo update redis-operator
|
||||
helm pull redis-operator/redis-operator --untar --untardir charts
|
||||
sed -i '/{{/d' charts/redis-operator/crds/databases.spotahome.com_redisfailovers.yaml
|
||||
|
||||
image:
|
||||
docker buildx build images/redis-operator \
|
||||
--tag $(REGISTRY)/redis-operator:$(REDIS_OPERATOR_TAG) \
|
||||
--cache-from type=registry,ref=$(REGISTRY)/redis-operator:latest \
|
||||
--cache-to type=inline \
|
||||
--metadata-file images/redis-operator.json \
|
||||
$(BUILDX_ARGS)
|
||||
REPOSITORY="$(REGISTRY)/redis-operator" \
|
||||
yq -i '.redis-operator.image.repository = strenv(REPOSITORY)' values.yaml
|
||||
TAG=$(REDIS_OPERATOR_TAG)@$$(yq e '."containerimage.digest"' images/redis-operator.json -o json -r) \
|
||||
yq -i '.redis-operator.image.tag = strenv(TAG)' values.yaml
|
||||
rm -f images/redis-operator.json
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
FROM golang:1.20 AS builder
|
||||
|
||||
ARG VERSION=v1.3.0-rc1
|
||||
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
||||
WORKDIR /workspace
|
||||
|
||||
RUN curl -sSL https://github.com/spotahome/redis-operator/archive/refs/tags/${VERSION}.tar.gz | tar -xzvf- --strip=1
|
||||
|
||||
COPY patches /patches
|
||||
RUN git apply /patches/*.diff
|
||||
|
||||
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH VERSION=$VERSION ./scripts/build.sh
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk --no-cache add \
|
||||
ca-certificates
|
||||
COPY --from=builder /workspace/bin/redis-operator /usr/local/bin
|
||||
RUN addgroup -g 1000 rf && \
|
||||
adduser -D -u 1000 -G rf rf && \
|
||||
chown rf:rf /usr/local/bin/redis-operator
|
||||
USER rf
|
||||
|
||||
ENTRYPOINT ["/usr/local/bin/redis-operator"]
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
diff --git a/service/k8s/service.go b/service/k8s/service.go
|
||||
index 712cc4c0..e84afc92 100644
|
||||
--- a/service/k8s/service.go
|
||||
+++ b/service/k8s/service.go
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
"github.com/spotahome/redis-operator/log"
|
||||
"github.com/spotahome/redis-operator/metrics"
|
||||
+ "github.com/spotahome/redis-operator/operator/redisfailover/util"
|
||||
)
|
||||
|
||||
// Service the ServiceAccount service that knows how to interact with k8s to manage them
|
||||
@@ -95,6 +96,10 @@ func (s *ServiceService) CreateOrUpdateService(namespace string, service *corev1
|
||||
// namespace is our spec(https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#concurrency-control-and-consistency),
|
||||
// we will replace the current namespace state.
|
||||
service.ResourceVersion = storedService.ResourceVersion
|
||||
+ newLabels := util.MergeLabels(storedService.GetLabels(), service.GetLabels())
|
||||
+ newAnnotations := util.MergeAnnotations(storedService.GetAnnotations(), service.GetAnnotations())
|
||||
+ service.SetLabels(newLabels)
|
||||
+ service.SetAnnotations(newAnnotations)
|
||||
return s.UpdateService(namespace, service)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
redis-operator:
|
||||
image:
|
||||
tag: v1.3.0-rc1
|
||||
repository: ghcr.io/cozystack/cozystack/redis-operator
|
||||
tag: v1.3.0-rc1@sha256:a4012e6a1b5daaedb57cc27edfdbff52124de4164b5ec0ee53c5ce5710ef4c25
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
NAME=seaweedfs-system
|
||||
export NAME=seaweedfs-system
|
||||
|
||||
include ../../../scripts/common-envs.mk
|
||||
include ../../../scripts/package.mk
|
||||
|
||||
update:
|
||||
rm -rf charts
|
||||
mkdir -p charts
|
||||
curl -sSL https://github.com/seaweedfs/seaweedfs/archive/refs/heads/master.tar.gz | \
|
||||
tar xzvf - --strip 3 -C charts seaweedfs-master/k8s/charts/seaweedfs
|
||||
version=$$(git ls-remote --tags --sort="v:refname" https://github.com/seaweedfs/seaweedfs | grep -v '\^{}' | grep 'refs/tags/[0-9]' | awk -F'/' 'END{print $$3}') && \
|
||||
curl -sSL https://github.com/seaweedfs/seaweedfs/archive/refs/tags/$${version}.tar.gz | \
|
||||
tar xzvf - --strip 3 -C charts seaweedfs-$${version}/k8s/charts/seaweedfs && \
|
||||
sed -i.bak "/ARG VERSION/ s|=.*|=$${version}|g" images/seaweedfs/Dockerfile && \
|
||||
rm -f images/seaweedfs/Dockerfile.bak
|
||||
patch --no-backup-if-mismatch -p4 < patches/resize-api-server-annotation.diff
|
||||
patch --no-backup-if-mismatch -p4 < patches/fix-volume-servicemonitor.patch
|
||||
#patch --no-backup-if-mismatch -p4 < patches/retention-policy-delete.yaml
|
||||
|
||||
image:
|
||||
docker buildx build images/seaweedfs \
|
||||
--tag $(REGISTRY)/seaweedfs:$(call settag,$(TAG)) \
|
||||
--cache-from type=registry,ref=$(REGISTRY)/seaweedfs:latest \
|
||||
--cache-to type=inline \
|
||||
--metadata-file images/seaweedfs.json \
|
||||
$(BUILDX_ARGS)
|
||||
REGISTRY="$(REGISTRY)" \
|
||||
yq -i '.seaweedfs.image.registry = strenv(REGISTRY)' values.yaml
|
||||
TAG=$(TAG)@$$(yq e '."containerimage.digest"' images/seaweedfs.json -o json -r) \
|
||||
yq -i '.seaweedfs.image.tag = strenv(TAG)' values.yaml
|
||||
yq -i '.global.imageName = "seaweedfs"' values.yaml
|
||||
rm -f images/seaweedfs.json
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
apiVersion: v1
|
||||
description: SeaweedFS
|
||||
name: seaweedfs
|
||||
appVersion: "3.97"
|
||||
appVersion: "3.99"
|
||||
# Dev note: Trigger a helm chart release by `git tag -a helm-<version>`
|
||||
version: 4.0.397
|
||||
version: 4.0.399
|
||||
|
||||
@@ -79,6 +79,12 @@ spec:
|
||||
image: {{ template "master.image" . }}
|
||||
imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }}
|
||||
env:
|
||||
{{- /* Determine default cluster alias and the corresponding env var keys to avoid conflicts */}}
|
||||
{{- $envMerged := merge (.Values.global.extraEnvironmentVars | default dict) (.Values.allInOne.extraEnvironmentVars | default dict) }}
|
||||
{{- $clusterDefault := default "sw" (index $envMerged "WEED_CLUSTER_DEFAULT") }}
|
||||
{{- $clusterUpper := upper $clusterDefault }}
|
||||
{{- $clusterMasterKey := printf "WEED_CLUSTER_%s_MASTER" $clusterUpper }}
|
||||
{{- $clusterFilerKey := printf "WEED_CLUSTER_%s_FILER" $clusterUpper }}
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
@@ -95,6 +101,7 @@ spec:
|
||||
value: "{{ template "seaweedfs.name" . }}"
|
||||
{{- if .Values.allInOne.extraEnvironmentVars }}
|
||||
{{- range $key, $value := .Values.allInOne.extraEnvironmentVars }}
|
||||
{{- if and (ne $key $clusterMasterKey) (ne $key $clusterFilerKey) }}
|
||||
- name: {{ $key }}
|
||||
{{- if kindIs "string" $value }}
|
||||
value: {{ $value | quote }}
|
||||
@@ -104,8 +111,10 @@ spec:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.global.extraEnvironmentVars }}
|
||||
{{- range $key, $value := .Values.global.extraEnvironmentVars }}
|
||||
{{- if and (ne $key $clusterMasterKey) (ne $key $clusterFilerKey) }}
|
||||
- name: {{ $key }}
|
||||
{{- if kindIs "string" $value }}
|
||||
value: {{ $value | quote }}
|
||||
@@ -115,6 +124,12 @@ spec:
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
# Inject computed cluster endpoints for the default cluster
|
||||
- name: {{ $clusterMasterKey }}
|
||||
value: {{ include "seaweedfs.cluster.masterAddress" . | quote }}
|
||||
- name: {{ $clusterFilerKey }}
|
||||
value: {{ include "seaweedfs.cluster.filerAddress" . | quote }}
|
||||
command:
|
||||
- "/bin/sh"
|
||||
- "-ec"
|
||||
|
||||
@@ -15,7 +15,6 @@ spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/component: objectstorage-provisioner
|
||||
template:
|
||||
|
||||
@@ -28,8 +28,8 @@ spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /sw-filer/?(.*)
|
||||
pathType: ImplementationSpecific
|
||||
- path: {{ .Values.filer.ingress.path | quote }}
|
||||
pathType: {{ .Values.filer.ingress.pathType | quote }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
|
||||
@@ -28,8 +28,8 @@ spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /sw-master/?(.*)
|
||||
pathType: ImplementationSpecific
|
||||
- path: {{ .Values.master.ingress.path | quote }}
|
||||
pathType: {{ .Values.master.ingress.pathType | quote }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
|
||||
@@ -27,8 +27,8 @@ spec:
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: ImplementationSpecific
|
||||
- path: {{ .Values.s3.ingress.path | quote }}
|
||||
pathType: {{ .Values.s3.ingress.pathType | quote }}
|
||||
backend:
|
||||
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
|
||||
service:
|
||||
|
||||
@@ -96,13 +96,16 @@ Inject extra environment vars in the format key:value, if populated
|
||||
{{/* Computes the container image name for all components (if they are not overridden) */}}
|
||||
{{- define "common.image" -}}
|
||||
{{- $registryName := default .Values.image.registry .Values.global.registry | toString -}}
|
||||
{{- $repositoryName := .Values.image.repository | toString -}}
|
||||
{{- $repositoryName := default .Values.image.repository .Values.global.repository | toString -}}
|
||||
{{- $name := .Values.global.imageName | toString -}}
|
||||
{{- $tag := default .Chart.AppVersion .Values.image.tag | toString -}}
|
||||
{{- if $repositoryName -}}
|
||||
{{- $name = printf "%s/%s" (trimSuffix "/" $repositoryName) (base $name) -}}
|
||||
{{- end -}}
|
||||
{{- if $registryName -}}
|
||||
{{- printf "%s/%s%s:%s" $registryName $repositoryName $name $tag -}}
|
||||
{{- printf "%s/%s:%s" $registryName $name $tag -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s%s:%s" $repositoryName $name $tag -}}
|
||||
{{- printf "%s:%s" $name $tag -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -219,3 +222,27 @@ or generate a new random password if it doesn't exist.
|
||||
{{- randAlphaNum $length -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Compute the master service address to be used in cluster env vars.
|
||||
If allInOne is enabled, point to the all-in-one service; otherwise, point to the master service.
|
||||
*/}}
|
||||
{{- define "seaweedfs.cluster.masterAddress" -}}
|
||||
{{- $serviceNameSuffix := "-master" -}}
|
||||
{{- if .Values.allInOne.enabled -}}
|
||||
{{- $serviceNameSuffix = "-all-in-one" -}}
|
||||
{{- end -}}
|
||||
{{- printf "%s%s.%s:%d" (include "seaweedfs.name" .) $serviceNameSuffix .Release.Namespace (int .Values.master.port) -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Compute the filer service address to be used in cluster env vars.
|
||||
If allInOne is enabled, point to the all-in-one service; otherwise, point to the filer-client service.
|
||||
*/}}
|
||||
{{- define "seaweedfs.cluster.filerAddress" -}}
|
||||
{{- $serviceNameSuffix := "-filer-client" -}}
|
||||
{{- if .Values.allInOne.enabled -}}
|
||||
{{- $serviceNameSuffix = "-all-in-one" -}}
|
||||
{{- end -}}
|
||||
{{- printf "%s%s.%s:%d" (include "seaweedfs.name" .) $serviceNameSuffix .Release.Namespace (int .Values.filer.port) -}}
|
||||
{{- end -}}
|
||||
|
||||
@@ -21,9 +21,9 @@ metadata:
|
||||
{{- with $.Values.global.monitoring.additionalLabels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if $.Values.volume.annotations }}
|
||||
{{- with $volume.annotations }}
|
||||
annotations:
|
||||
{{- toYaml $.Values.volume.annotations | nindent 4 }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
endpoints:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user