mirror of
https://github.com/dokku/dokku.git
synced 2026-05-18 05:05:46 +02:00
The new config and pull secret helm releases need to honor user-set annotations and labels for `--resource-type secret` so existing scheduler-k3s annotation tests keep passing. The dedicated charts now render `.Values.global.annotations` and `.Values.global.labels` onto their Secret manifest, and the deploy trigger plumbs `SecretAnnotations` and `SecretLabels` from the global annotation/label config. The rollback regression bats test now uses `dokku ps:rebuild` for its second deploy because git push of an unchanged ref is rejected by the dokku remote.
189 lines
5.4 KiB
Go
189 lines
5.4 KiB
Go
package scheduler_k3s
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/dokku/dokku/plugins/common"
|
|
)
|
|
|
|
// ConfigSecretValues contains the values for the config secret helm chart
|
|
type ConfigSecretValues struct {
|
|
Global ConfigSecretGlobalValues `yaml:"global"`
|
|
}
|
|
|
|
// ConfigSecretGlobalValues contains the global values for the config secret chart
|
|
type ConfigSecretGlobalValues struct {
|
|
Annotations map[string]string `yaml:"annotations,omitempty"`
|
|
AppName string `yaml:"app_name"`
|
|
Labels map[string]string `yaml:"labels,omitempty"`
|
|
Namespace string `yaml:"namespace"`
|
|
Secrets map[string]string `yaml:"secrets,omitempty"`
|
|
}
|
|
|
|
// GetConfigSecretReleaseName returns the helm release name for the config secret
|
|
func GetConfigSecretReleaseName(appName string) string {
|
|
return fmt.Sprintf("config-%s", appName)
|
|
}
|
|
|
|
// GetConfigSecretName returns the kubernetes secret name for the config env
|
|
func GetConfigSecretName(appName string) string {
|
|
return fmt.Sprintf("config-%s", appName)
|
|
}
|
|
|
|
// CreateOrUpdateConfigSecretInput contains the inputs to CreateOrUpdateConfigSecret
|
|
type CreateOrUpdateConfigSecretInput struct {
|
|
AppName string
|
|
Env map[string]string
|
|
Annotations map[string]string
|
|
Labels map[string]string
|
|
}
|
|
|
|
// CreateOrUpdateConfigSecret creates or updates the config env secret helm chart for an app
|
|
func CreateOrUpdateConfigSecret(ctx context.Context, input CreateOrUpdateConfigSecretInput) error {
|
|
appName := input.AppName
|
|
if err := isKubernetesAvailable(); err != nil {
|
|
common.LogDebug("kubernetes not available, skipping config secret creation")
|
|
return nil
|
|
}
|
|
|
|
scheduler := common.PropertyGetDefault("scheduler", appName, "selected", "")
|
|
globalScheduler := common.PropertyGetDefault("scheduler", "--global", "selected", "docker-local")
|
|
if scheduler == "" {
|
|
scheduler = globalScheduler
|
|
}
|
|
if scheduler != "k3s" {
|
|
common.LogDebug("app does not use k3s scheduler, skipping config secret creation")
|
|
return nil
|
|
}
|
|
|
|
chartDir, err := os.MkdirTemp("", "dokku-config-secret-chart-")
|
|
if err != nil {
|
|
return fmt.Errorf("error creating chart directory: %w", err)
|
|
}
|
|
defer os.RemoveAll(chartDir)
|
|
|
|
if err := os.MkdirAll(filepath.Join(chartDir, "templates"), os.FileMode(0755)); err != nil {
|
|
return fmt.Errorf("error creating chart templates directory: %w", err)
|
|
}
|
|
|
|
namespace := getComputedNamespace(appName)
|
|
releaseName := GetConfigSecretReleaseName(appName)
|
|
|
|
chart := &Chart{
|
|
ApiVersion: "v2",
|
|
AppVersion: "1.0.0",
|
|
Name: releaseName,
|
|
Icon: "https://dokku.com/assets/dokku-logo.svg",
|
|
Version: "0.0.1",
|
|
}
|
|
|
|
err = writeYaml(WriteYamlInput{
|
|
Object: chart,
|
|
Path: filepath.Join(chartDir, "Chart.yaml"),
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("error writing chart: %w", err)
|
|
}
|
|
|
|
b, err := templates.ReadFile("templates/config-secret-chart/templates/config-secret.yaml")
|
|
if err != nil {
|
|
return fmt.Errorf("error reading config-secret template: %w", err)
|
|
}
|
|
|
|
filename := filepath.Join(chartDir, "templates", "config-secret.yaml")
|
|
err = os.WriteFile(filename, b, os.FileMode(0644))
|
|
if err != nil {
|
|
return fmt.Errorf("error writing config-secret template: %w", err)
|
|
}
|
|
|
|
if os.Getenv("DOKKU_TRACE") == "1" {
|
|
common.CatFile(filename)
|
|
}
|
|
|
|
encodedSecrets := map[string]string{}
|
|
for key, value := range input.Env {
|
|
encodedSecrets[key] = base64.StdEncoding.EncodeToString([]byte(value))
|
|
}
|
|
|
|
values := &ConfigSecretValues{
|
|
Global: ConfigSecretGlobalValues{
|
|
Annotations: input.Annotations,
|
|
AppName: appName,
|
|
Labels: input.Labels,
|
|
Namespace: namespace,
|
|
Secrets: encodedSecrets,
|
|
},
|
|
}
|
|
|
|
err = writeYaml(WriteYamlInput{
|
|
Object: values,
|
|
Path: filepath.Join(chartDir, "values.yaml"),
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("error writing values: %w", err)
|
|
}
|
|
|
|
if err := createKubernetesNamespace(ctx, namespace); err != nil {
|
|
return fmt.Errorf("error creating namespace: %w", err)
|
|
}
|
|
|
|
helmAgent, err := NewHelmAgent(namespace, DeployLogPrinter)
|
|
if err != nil {
|
|
return fmt.Errorf("error creating helm agent: %w", err)
|
|
}
|
|
|
|
chartPath, err := filepath.Abs(chartDir)
|
|
if err != nil {
|
|
return fmt.Errorf("error getting chart path: %w", err)
|
|
}
|
|
|
|
common.LogVerboseQuiet(fmt.Sprintf("Installing config secret for %s", appName))
|
|
err = helmAgent.InstallOrUpgradeChart(ctx, ChartInput{
|
|
ChartPath: chartPath,
|
|
Namespace: namespace,
|
|
ReleaseName: releaseName,
|
|
Wait: false,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("error installing config secret chart: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// DeleteConfigSecret deletes the config env secret helm chart for an app
|
|
func DeleteConfigSecret(ctx context.Context, appName string) error {
|
|
if err := isKubernetesAvailable(); err != nil {
|
|
common.LogDebug("kubernetes not available, skipping config secret deletion")
|
|
return nil
|
|
}
|
|
|
|
namespace := getComputedNamespace(appName)
|
|
releaseName := GetConfigSecretReleaseName(appName)
|
|
|
|
helmAgent, err := NewHelmAgent(namespace, DeployLogPrinter)
|
|
if err != nil {
|
|
return fmt.Errorf("error creating helm agent: %w", err)
|
|
}
|
|
|
|
exists, err := helmAgent.ChartExists(releaseName)
|
|
if err != nil {
|
|
return fmt.Errorf("error checking if config secret chart exists: %w", err)
|
|
}
|
|
|
|
if !exists {
|
|
return nil
|
|
}
|
|
|
|
common.LogVerboseQuiet(fmt.Sprintf("Removing config secret for %s", appName))
|
|
if err := helmAgent.UninstallChart(releaseName); err != nil {
|
|
return fmt.Errorf("error uninstalling config secret chart: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|