Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
d3986cc
feat: add Velero plugin configuration schema and validation
banjoh Nov 7, 2025
43ac598
Additional unit tests for image format validation
banjoh Nov 7, 2025
18cdd40
Add container name to Velero plugin configuration
banjoh Nov 7, 2025
e40e253
feat: add support for custom Velero plugins via EC config
banjoh Nov 7, 2025
4f59d2a
Use oras-go to validate image format
banjoh Nov 10, 2025
697e1e0
Better test name
banjoh Nov 10, 2025
344c049
Fix failing tests
banjoh Nov 11, 2025
11ad835
Remove unsupported example from config_types.go
banjoh Nov 11, 2025
e7a6b8d
Merge remote-tracking branch 'origin/main' into evansmungai/sc-131045…
banjoh Nov 12, 2025
241fc9e
Remove unnecessary comments
banjoh Nov 12, 2025
7f73213
Additional comment to explain to copilot
banjoh Nov 12, 2025
5ad9daa
feat: add support for custom Velero plugins via EC config
banjoh Nov 7, 2025
4988b54
Merge branch 'evansmungai/sc-131045/add-inject-velero-plugin-to-helm-…
banjoh Nov 12, 2025
6eecff1
Show velero chart values in EC metadata subcommand output
banjoh Nov 12, 2025
e995653
Do not process image names
banjoh Nov 12, 2025
cfa0ea1
Add velero plugins to allEC config
banjoh Nov 12, 2025
6f62453
Use ReferenceRegexp to validate image format
banjoh Nov 12, 2025
b806b60
feat: add support for custom Velero plugins via EC config
banjoh Nov 7, 2025
a22af11
Show velero chart values in EC metadata subcommand output
banjoh Nov 12, 2025
6380e99
Do not process image names
banjoh Nov 12, 2025
83e3729
Add velero plugins to allEC config
banjoh Nov 12, 2025
dc6ed98
Merge branch 'evansmungai/sc-131045/add-inject-velero-plugin-to-helm-…
banjoh Nov 12, 2025
d079c0f
Fix failing unit test
banjoh Nov 12, 2025
b385ae3
Fix lint errors
banjoh Nov 12, 2025
47a2a75
Merge branch 'evansmungai/sc-131045/add-ec-config-to-add-velero-plugi…
banjoh Nov 12, 2025
9777103
Add dry run tests for velero plugin feature
banjoh Nov 12, 2025
c375455
Use separate cluster config for velero plugin test
banjoh Nov 12, 2025
cc589e2
Merge remote-tracking branch 'origin/main' into evansmungai/sc-131045…
banjoh Nov 13, 2025
dd4a0dd
Fix test and rename plugin
banjoh Nov 13, 2025
2c3b53f
Remove Velero plugin configuration from test configs
banjoh Nov 13, 2025
86d7e7d
Reinstate change accidentally removed in previous commit
banjoh Nov 13, 2025
d42d0e9
Remove unnecessary changes
banjoh Nov 13, 2025
0985f8a
Some more cleanup
banjoh Nov 13, 2025
3d51c8e
Remove unecessarry change
banjoh Nov 13, 2025
3db5fd6
Remove unnecessary change and add builtInExtensions to cluster-config…
banjoh Nov 13, 2025
7a2c52f
Refactor dry run tests
banjoh Nov 13, 2025
af3f231
Fix failing tests
banjoh Nov 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 8 additions & 6 deletions pkg/addons/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,10 @@ func GetAddOnsForInstall(opts InstallOptions) []types.AddOn {

if opts.DisasterRecoveryEnabled {
addOns = append(addOns, &velero.Velero{
Proxy: opts.ProxySpec,
HostCABundlePath: opts.HostCABundlePath,
K0sDataDir: opts.K0sDataDir,
Proxy: opts.ProxySpec,
HostCABundlePath: opts.HostCABundlePath,
K0sDataDir: opts.K0sDataDir,
EmbeddedConfigSpec: opts.EmbeddedConfigSpec,
})
}

Expand Down Expand Up @@ -206,9 +207,10 @@ func GetAddOnsForRestore(opts RestoreOptions) []types.AddOn {
OpenEBSDataDir: opts.OpenEBSDataDir,
},
&velero.Velero{
Proxy: opts.ProxySpec,
HostCABundlePath: opts.HostCABundlePath,
K0sDataDir: opts.K0sDataDir,
Proxy: opts.ProxySpec,
HostCABundlePath: opts.HostCABundlePath,
K0sDataDir: opts.K0sDataDir,
EmbeddedConfigSpec: opts.EmbeddedConfigSpec,
},
}
return addOns
Expand Down
7 changes: 6 additions & 1 deletion pkg/addons/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/replicatedhq/embedded-cluster/pkg/addons/registry"
"github.com/replicatedhq/embedded-cluster/pkg/addons/seaweedfs"
"github.com/replicatedhq/embedded-cluster/pkg/addons/velero"
"github.com/replicatedhq/embedded-cluster/pkg/release"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down Expand Up @@ -78,7 +79,11 @@ func GenerateChartConfigs(ctx context.Context, kcli client.Client) ([]ecv1beta1.
repositories = append(repositories, repos...)

// velero
chart, repos, err = velero.GenerateChartConfig()
var ecConfig *ecv1beta1.ConfigSpec
if ecCfg := release.GetEmbeddedClusterConfig(); ecCfg != nil {
ecConfig = &ecCfg.Spec
}
chart, repos, err = velero.GenerateChartConfig(ecConfig)
if err != nil {
return nil, nil, errors.Wrap(err, "generate chart config for velero")
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/addons/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,9 +136,10 @@ func (a *AddOns) getAddOnsForUpgrade(meta *ectypes.ReleaseMetadata, opts Upgrade

if opts.DisasterRecoveryEnabled {
addOns = append(addOns, &velero.Velero{
Proxy: opts.ProxySpec,
HostCABundlePath: opts.HostCABundlePath,
K0sDataDir: opts.K0sDataDir,
Proxy: opts.ProxySpec,
HostCABundlePath: opts.HostCABundlePath,
K0sDataDir: opts.K0sDataDir,
EmbeddedConfigSpec: opts.EmbeddedConfigSpec,
})
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/addons/velero/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ func GetAdditionalImages() []string {
return images
}

func GenerateChartConfig() ([]ecv1beta1.Chart, []k0sv1beta1.Repository, error) {
hv, err := helmValues()
func GenerateChartConfig(ecConfig *ecv1beta1.ConfigSpec) ([]ecv1beta1.Chart, []k0sv1beta1.Repository, error) {
hv, err := helmValues(ecConfig)
if err != nil {
return nil, nil, errors.Wrap(err, "get helm values")
}
Expand Down
56 changes: 54 additions & 2 deletions pkg/addons/velero/values.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var (
)

func (v *Velero) GenerateHelmValues(ctx context.Context, kcli client.Client, domains ecv1beta1.Domains, overrides []string) (map[string]interface{}, error) {
hv, err := helmValues()
hv, err := helmValues(v.EmbeddedConfigSpec)
if err != nil {
return nil, errors.Wrap(err, "get helm values")
}
Expand Down Expand Up @@ -112,11 +112,63 @@ func (v *Velero) GenerateHelmValues(ctx context.Context, kcli client.Client, dom
return copiedValues, nil
}

func helmValues() (map[string]interface{}, error) {
func helmValues(ecConfig *ecv1beta1.ConfigSpec) (map[string]interface{}, error) {
hv, err := release.RenderHelmValues(rawvalues, Metadata)
if err != nil {
return nil, errors.Wrap(err, "render helm values")
}

// Inject custom Velero plugins from ConfigSpec if available
if err := injectPluginInitContainers(hv, ecConfig); err != nil {
return nil, errors.Wrap(err, "inject plugin init containers")
}

return hv, nil
}

// injectPluginInitContainers injects custom Velero plugin initContainers from ConfigSpec
func injectPluginInitContainers(values map[string]interface{}, ecConfig *ecv1beta1.ConfigSpec) error {
if ecConfig == nil || len(ecConfig.Extensions.Velero.Plugins) == 0 {
return nil
}

allPlugins := ecConfig.Extensions.Velero.Plugins

// Get existing initContainers or create empty slice
var existingInitContainers []any
if existing, ok := values["initContainers"]; ok {
if containers, ok := existing.([]any); ok {
existingInitContainers = containers
}
}

// Process each plugin and create initContainer
for _, plugin := range allPlugins {
imagePullPolicy := plugin.ImagePullPolicy
if imagePullPolicy == "" {
imagePullPolicy = "IfNotPresent" // Default to match AWS plugin
}

initContainer := generatePluginContainer(plugin.Name, plugin.Image, imagePullPolicy)
existingInitContainers = append(existingInitContainers, initContainer)
}

// Update values with merged initContainers
values["initContainers"] = existingInitContainers
return nil
}

// generatePluginContainer creates an initContainer spec for a Velero plugin
func generatePluginContainer(name, image, imagePullPolicy string) map[string]interface{} {
return map[string]interface{}{
"name": name,
"image": image,
"imagePullPolicy": imagePullPolicy,
"volumeMounts": []map[string]interface{}{
{
"mountPath": "/target",
"name": "plugins",
},
},
}
}
Loading