Skip to content

Commit 77f195c

Browse files
authored
feat(install): store config values in a kube secret on install (#3272)
* feat(install): store config values in a kube secret on install * chore: address delete + recreate race condition
1 parent 37ac3e0 commit 77f195c

File tree

2 files changed

+491
-0
lines changed

2 files changed

+491
-0
lines changed

api/internal/managers/app/install/install.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import (
1010
"github.com/replicatedhq/embedded-cluster/pkg/netutils"
1111
"github.com/replicatedhq/embedded-cluster/pkg/runtimeconfig"
1212
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
13+
corev1 "k8s.io/api/core/v1"
14+
apierrors "k8s.io/apimachinery/pkg/api/errors"
15+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
"sigs.k8s.io/controller-runtime/pkg/client"
1317
kyaml "sigs.k8s.io/yaml"
1418
)
1519

@@ -29,6 +33,11 @@ func (m *appInstallManager) Install(ctx context.Context, configValues kotsv1beta
2933
return fmt.Errorf("get kotsadm namespace: %w", err)
3034
}
3135

36+
// Create or update secret with config values before installing
37+
if err := m.createConfigValuesSecret(ctx, configValues, kotsadmNamespace); err != nil {
38+
return fmt.Errorf("creating config values secret: %w", err)
39+
}
40+
3241
ecDomains := utils.GetDomains(m.releaseData)
3342

3443
installOpts := kotscli.InstallOptions{
@@ -79,3 +88,75 @@ func (m *appInstallManager) createConfigValuesFile(configValues kotsv1beta1.Conf
7988

8089
return configValuesFile.Name(), nil
8190
}
91+
92+
// createConfigValuesSecret creates or updates a Kubernetes secret with the config values.
93+
// TODO: Handle 1MB size limitation by storing large file data fields as pointers to other secrets
94+
// TODO: Consider maintaining history of config values for potential rollbacks
95+
func (m *appInstallManager) createConfigValuesSecret(ctx context.Context, configValues kotsv1beta1.ConfigValues, namespace string) error {
96+
// Get app slug and version from release data
97+
license := &kotsv1beta1.License{}
98+
if err := kyaml.Unmarshal(m.license, license); err != nil {
99+
return fmt.Errorf("parse license: %w", err)
100+
}
101+
102+
if m.releaseData == nil || m.releaseData.ChannelRelease == nil {
103+
return fmt.Errorf("release data is required for secret creation")
104+
}
105+
106+
// Marshal config values to YAML
107+
data, err := kyaml.Marshal(configValues)
108+
if err != nil {
109+
return fmt.Errorf("marshal config values: %w", err)
110+
}
111+
112+
secretName := fmt.Sprintf("%s-config-values", license.Spec.AppSlug)
113+
114+
// Create secret object
115+
secret := &corev1.Secret{
116+
TypeMeta: metav1.TypeMeta{
117+
Kind: "Secret",
118+
APIVersion: "v1",
119+
},
120+
ObjectMeta: metav1.ObjectMeta{
121+
Name: secretName,
122+
Namespace: namespace,
123+
Labels: map[string]string{
124+
"app.kubernetes.io/name": license.Spec.AppSlug,
125+
"app.kubernetes.io/version": m.releaseData.ChannelRelease.VersionLabel,
126+
"app.kubernetes.io/component": "config",
127+
"app.kubernetes.io/part-of": "embedded-cluster",
128+
"app.kubernetes.io/managed-by": "embedded-cluster-installer",
129+
},
130+
},
131+
Type: corev1.SecretTypeOpaque,
132+
Data: map[string][]byte{
133+
"config-values.yaml": data,
134+
},
135+
}
136+
137+
// Try to create the secret
138+
if err := m.kcli.Create(ctx, secret); err != nil {
139+
if !apierrors.IsAlreadyExists(err) {
140+
return fmt.Errorf("create config values secret: %w", err)
141+
}
142+
143+
// Secret exists, get and update it
144+
existingSecret := &corev1.Secret{}
145+
if err := m.kcli.Get(ctx, client.ObjectKey{
146+
Name: secretName,
147+
Namespace: namespace,
148+
}, existingSecret); err != nil {
149+
return fmt.Errorf("get existing config values secret: %w", err)
150+
}
151+
152+
// Update the existing secret's data and labels
153+
existingSecret.Data = secret.Data
154+
existingSecret.Labels = secret.Labels
155+
156+
if err := m.kcli.Update(ctx, existingSecret); err != nil {
157+
return fmt.Errorf("update config values secret: %w", err)
158+
}
159+
}
160+
161+
return nil
162+
}

0 commit comments

Comments
 (0)