Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions api/v1alpha1/dataprotectionapplication_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,14 @@ type VeleroConfig struct {
// Velero args are settings to customize velero server arguments. Overrides values in other fields.
// +optional
Args *VeleroServerArgs `json:"args,omitempty"`
// ExtraArgs are additional arguments to append to the Velero server.
// Keys are flag names (without leading --), values are flag values.
// These are merged additively on top of operator defaults and Args.
// If the unsupported-args annotation is set, it takes highest precedence
// and completely overrides all other args including ExtraArgs.
// Precedence: operator defaults / Args < ExtraArgs < unsupported-args annotation.
// +optional
ExtraArgs map[string]string `json:"extraArgs,omitempty"`
Comment thread
coderabbitai[bot] marked this conversation as resolved.
// LoadAffinityConfig is the config for data path load affinity.
// +optional
LoadAffinityConfig []*LoadAffinity `json:"loadAffinity,omitempty"`
Expand Down Expand Up @@ -598,6 +606,14 @@ type NodeAgentConfig struct {
// Embedding KopiaRepoOptions
// +optional
KopiaRepoOptions `json:",inline"`
// ExtraArgs are additional arguments to append to the node-agent server.
// Keys are flag names (without leading --), values are flag values.
// These are merged additively on top of operator defaults.
// If the unsupported-args annotation is set, it takes highest precedence
// and completely overrides all other args including ExtraArgs.
// Precedence: operator defaults < ExtraArgs < unsupported-args annotation.
// +optional
ExtraArgs map[string]string `json:"extraArgs,omitempty"`
}

type KopiaRepoOptions struct {
Expand Down
14 changes: 14 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions bundle/manifests/oadp.openshift.io_dataprotectionapplications.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,17 @@ spec:
enable defines a boolean pointer whether we want the daemonset to
exist or not
type: boolean
extraArgs:
additionalProperties:
type: string
description: |-
ExtraArgs are additional arguments to append to the node-agent server.
Keys are flag names (without leading --), values are flag values.
These are merged additively on top of operator defaults.
If the unsupported-args annotation is set, it takes highest precedence
and completely overrides all other args including ExtraArgs.
Precedence: operator defaults < ExtraArgs < unsupported-args annotation.
type: object
fullMaintenanceInterval:
description: |-
fullMaintenanceInterval determines the time between kopia full maintenance operations.
Expand Down Expand Up @@ -1274,6 +1285,17 @@ spec:
the 1-second polling interval for the first 10 seconds while waiting
for the snaphandle
type: boolean
extraArgs:
additionalProperties:
type: string
description: |-
ExtraArgs are additional arguments to append to the Velero server.
Keys are flag names (without leading --), values are flag values.
These are merged additively on top of operator defaults and Args.
If the unsupported-args annotation is set, it takes highest precedence
and completely overrides all other args including ExtraArgs.
Precedence: operator defaults / Args < ExtraArgs < unsupported-args annotation.
type: object
featureFlags:
description: featureFlags defines the list of features to enable for Velero instance
items:
Expand Down
22 changes: 22 additions & 0 deletions config/crd/bases/oadp.openshift.io_dataprotectionapplications.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,17 @@ spec:
enable defines a boolean pointer whether we want the daemonset to
exist or not
type: boolean
extraArgs:
additionalProperties:
type: string
description: |-
ExtraArgs are additional arguments to append to the node-agent server.
Keys are flag names (without leading --), values are flag values.
These are merged additively on top of operator defaults.
If the unsupported-args annotation is set, it takes highest precedence
and completely overrides all other args including ExtraArgs.
Precedence: operator defaults < ExtraArgs < unsupported-args annotation.
type: object
Comment thread
Shreyashxredhat marked this conversation as resolved.
fullMaintenanceInterval:
description: |-
fullMaintenanceInterval determines the time between kopia full maintenance operations.
Expand Down Expand Up @@ -1274,6 +1285,17 @@ spec:
the 1-second polling interval for the first 10 seconds while waiting
for the snaphandle
type: boolean
extraArgs:
additionalProperties:
type: string
description: |-
ExtraArgs are additional arguments to append to the Velero server.
Keys are flag names (without leading --), values are flag values.
These are merged additively on top of operator defaults and Args.
If the unsupported-args annotation is set, it takes highest precedence
and completely overrides all other args including ExtraArgs.
Precedence: operator defaults / Args < ExtraArgs < unsupported-args annotation.
type: object
featureFlags:
description: featureFlags defines the list of features to enable for Velero instance
items:
Expand Down
4 changes: 4 additions & 0 deletions internal/controller/nodeagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,10 @@ func (r *DataProtectionApplicationReconciler) customizeNodeAgentDaemonset(ds *ap
nodeAgentContainer.Args = append(nodeAgentContainer.Args, fmt.Sprintf("--log-format=%s", dpa.Spec.LogFormat))
}

if len(dpa.Spec.Configuration.NodeAgent.ExtraArgs) > 0 {
nodeAgentContainer.Args = common.MergeExtraArgs(nodeAgentContainer.Args, dpa.Spec.Configuration.NodeAgent.ExtraArgs)
}

// Apply unsupported server args from the specified ConfigMap.
// This will completely override any previously set args for the node-agent server.
// If the ConfigMap exists and is not empty, its key-value pairs will be used as the new CLI arguments.
Expand Down
87 changes: 87 additions & 0 deletions internal/controller/nodeagent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,93 @@ func TestDPAReconciler_buildNodeAgentDaemonset(t *testing.T) {
nodeAgentDaemonSet: testNodeAgentDaemonSet.DeepCopy(),
errorMessage: "configmaps \"missing-unsupported-node-agent-server-args-cm\" not found",
},
{
name: "valid DPA CR with NodeAgent ExtraArgs, DaemonSet is built with extra args appended",
dpa: createTestDpaWith(
nil,
oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{},
NodeAgent: &oadpv1alpha1.NodeAgentConfig{
NodeAgentCommonFields: oadpv1alpha1.NodeAgentCommonFields{},
UploaderType: "kopia",
ExtraArgs: map[string]string{
"custom-flag": "value1",
},
},
},
},
),
clientObjects: []client.Object{testGenericInfrastructure},
nodeAgentDaemonSet: testNodeAgentDaemonSet.DeepCopy(),
wantNodeAgentDaemonSet: createTestBuiltNodeAgentDaemonSet(TestBuiltNodeAgentDaemonSetOptions{
args: []string{
"--custom-flag=value1",
},
}),
},
{
name: "valid DPA CR with NodeAgent ExtraArgs overriding an existing arg, DaemonSet is built with overridden value",
dpa: createTestDpaWith(
nil,
oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{},
NodeAgent: &oadpv1alpha1.NodeAgentConfig{
NodeAgentCommonFields: oadpv1alpha1.NodeAgentCommonFields{},
DataMoverPrepareTimeout: &metav1.Duration{Duration: 10 * time.Second},
UploaderType: "kopia",
ExtraArgs: map[string]string{
"data-mover-prepare-timeout": "45m",
},
},
},
},
),
clientObjects: []client.Object{testGenericInfrastructure},
nodeAgentDaemonSet: testNodeAgentDaemonSet.DeepCopy(),
wantNodeAgentDaemonSet: createTestBuiltNodeAgentDaemonSet(TestBuiltNodeAgentDaemonSetOptions{
args: []string{
"--data-mover-prepare-timeout=45m",
},
}),
},
{
name: "valid DPA CR with NodeAgent ExtraArgs and Unsupported Server Args, annotation takes priority",
dpa: createTestDpaWith(
map[string]string{common.UnsupportedNodeAgentServerArgsAnnotation: "unsupported-node-agent-server-args-cm"},
oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{},
NodeAgent: &oadpv1alpha1.NodeAgentConfig{
NodeAgentCommonFields: oadpv1alpha1.NodeAgentCommonFields{},
UploaderType: "kopia",
ExtraArgs: map[string]string{
"custom-flag": "value1",
},
},
},
},
),
clientObjects: []client.Object{
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "unsupported-node-agent-server-args-cm",
Namespace: testNamespaceName,
},
Data: map[string]string{
"unsupported-arg": "value2",
},
},
testGenericInfrastructure,
},
nodeAgentDaemonSet: testNodeAgentDaemonSet.DeepCopy(),
wantNodeAgentDaemonSet: createTestBuiltNodeAgentDaemonSet(TestBuiltNodeAgentDaemonSetOptions{
args: []string{
"--unsupported-arg=value2",
},
}),
},
{
name: "valid DPA CR with NodeAgent resource allocations, NodeAgent DaemonSet is built with resource allocations",
dpa: createTestDpaWith(
Expand Down
12 changes: 5 additions & 7 deletions internal/controller/velero.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"strings"

"github.com/go-logr/logr"
"github.com/google/go-cmp/cmp"
"github.com/operator-framework/operator-lib/proxy"
"github.com/sirupsen/logrus"
"github.com/vmware-tanzu/velero/pkg/install"
Expand Down Expand Up @@ -89,11 +88,7 @@ func (r *DataProtectionApplicationReconciler) ReconcileVeleroDeployment(log logr
Namespace: dpa.Namespace,
},
}
var orig *appsv1.Deployment // for debugging purposes
op, err := controllerutil.CreateOrPatch(r.Context, r.Client, veleroDeployment, func() error {
if debugMode {
orig = veleroDeployment.DeepCopy() // for debugging purposes
}
// Setting Deployment selector if a new object is created as it is immutable
if veleroDeployment.ObjectMeta.CreationTimestamp.IsZero() {
veleroDeployment.Spec.Selector = &metav1.LabelSelector{
Expand All @@ -110,8 +105,8 @@ func (r *DataProtectionApplicationReconciler) ReconcileVeleroDeployment(log logr
// Setting controller owner reference on the velero deployment
return controllerutil.SetControllerReference(dpa, veleroDeployment, r.Scheme)
})
if debugMode && op != controllerutil.OperationResultNone { // for debugging purposes
fmt.Printf("DEBUG: There was a diff which resulted in an operation on Velero Deployment: %s\n", cmp.Diff(orig, veleroDeployment))
if debugMode && op != controllerutil.OperationResultNone {
log.Info("Velero Deployment reconciled with changes", "operation", op)
}

if err != nil {
Expand Down Expand Up @@ -480,6 +475,9 @@ func (r *DataProtectionApplicationReconciler) customizeVeleroDeployment(veleroDe
}
r.appendPluginSpecificSpecs(veleroDeployment, veleroContainer, providerNeedsDefaultCreds)
setPodTemplateSpecDefaults(&veleroDeployment.Spec.Template)
if dpa.Spec.Configuration.Velero != nil && len(dpa.Spec.Configuration.Velero.ExtraArgs) > 0 {
veleroContainer.Args = common.MergeExtraArgs(veleroContainer.Args, dpa.Spec.Configuration.Velero.ExtraArgs)
}
if configMapName, ok := dpa.Annotations[common.UnsupportedVeleroServerArgsAnnotation]; ok {
if configMapName != "" {
unsupportedServerArgsCM := corev1.ConfigMap{}
Expand Down
113 changes: 113 additions & 0 deletions internal/controller/velero_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,119 @@ func TestDPAReconciler_buildVeleroDeployment(t *testing.T) {
veleroDeployment: testVeleroDeployment.DeepCopy(),
errorMessage: "configmaps \"missing-unsupported-server-args-cm\" not found",
},
{
name: "valid DPA CR with ExtraArgs, Velero Deployment is built with extra args appended",
dpa: createTestDpaWith(
nil,
oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{
ExtraArgs: map[string]string{
"custom-timeout": "30m",
"another-flag": "value1",
},
},
},
},
),
veleroDeployment: testVeleroDeployment.DeepCopy(),
wantVeleroDeployment: createTestBuiltVeleroDeployment(TestBuiltVeleroDeploymentOptions{
args: []string{
defaultFileSystemBackupTimeout,
defaultRestoreResourcePriorities,
defaultDisableInformerCache,
"--another-flag=value1",
"--custom-timeout=30m",
},
}),
},
{
name: "valid DPA CR with ExtraArgs overriding a default, Velero Deployment is built with overridden value",
dpa: createTestDpaWith(
nil,
oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{
ExtraArgs: map[string]string{
"fs-backup-timeout": "8h",
},
},
},
},
),
veleroDeployment: testVeleroDeployment.DeepCopy(),
wantVeleroDeployment: createTestBuiltVeleroDeployment(TestBuiltVeleroDeploymentOptions{
args: []string{
"--fs-backup-timeout=8h",
defaultRestoreResourcePriorities,
defaultDisableInformerCache,
},
}),
},
{
name: "valid DPA CR with ExtraArgs and Unsupported Server Args, annotation takes priority",
dpa: createTestDpaWith(
map[string]string{common.UnsupportedVeleroServerArgsAnnotation: "unsupported-server-args-cm"},
oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{
ExtraArgs: map[string]string{
"custom-flag": "value1",
},
},
},
},
),
clientObjects: []client.Object{
&corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: "unsupported-server-args-cm",
Namespace: testNamespaceName,
},
Data: map[string]string{
"unsupported-arg": "value2",
},
},
},
veleroDeployment: testVeleroDeployment.DeepCopy(),
wantVeleroDeployment: createTestBuiltVeleroDeployment(TestBuiltVeleroDeploymentOptions{
args: []string{
"--unsupported-arg=value2",
},
}),
},
{
name: "valid DPA CR with Args and ExtraArgs, ExtraArgs adds on top of Args",
dpa: createTestDpaWith(
nil,
oadpv1alpha1.DataProtectionApplicationSpec{
Configuration: &oadpv1alpha1.ApplicationConfig{
Velero: &oadpv1alpha1.VeleroConfig{
Args: &oadpv1alpha1.VeleroServerArgs{
ServerFlags: oadpv1alpha1.ServerFlags{
MetricsAddress: fmt.Sprintf(":%v", argsMetricsPortTest),
},
},
ExtraArgs: map[string]string{
"custom-flag": "custom-value",
"disable-informer-cache": "true",
},
},
},
},
),
veleroDeployment: testVeleroDeployment.DeepCopy(),
wantVeleroDeployment: createTestBuiltVeleroDeployment(TestBuiltVeleroDeploymentOptions{
metricsPort: argsMetricsPortTest,
args: []string{
fmt.Sprintf("--metrics-address=:%v", argsMetricsPortTest),
"--fs-backup-timeout=4h0m0s",
defaultRestoreResourcePriorities,
"--disable-informer-cache=true",
"--custom-flag=custom-value",
},
}),
},
{
name: "valid DPA CR with ItemOperationSyncFrequency, Velero Deployment is built with ItemOperationSyncFrequency arg",
dpa: createTestDpaWith(
Expand Down
Loading