Repository navigation
fix: address shubham's review feedback on DPT CACertRef handling #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -347,7 +347,7 @@ aws_secret_access_key = test-secret | |
| }, | ||
| } | ||
|
|
||
| cp, err := reconciler.initializeProvider(ctx, spec) | ||
| cp, err := reconciler.initializeProvider(ctx, spec, nil) | ||
|
|
||
| if tt.expectError { | ||
| require.Error(t, err) | ||
|
|
@@ -1391,6 +1391,32 @@ func TestRetrieveCAData(t *testing.T) { | |
| }, | ||
| expectBytes: []byte("more bad ca data"), | ||
| }, | ||
| { | ||
| name: "ca cert ref takes precedence over inline ca cert", | ||
| bsl: &velerov1.BackupStorageLocationSpec{ | ||
| StorageType: velerov1.StorageType{ | ||
| ObjectStorage: &velerov1.ObjectStorageLocation{ | ||
| CACert: []byte("inline ca data"), | ||
| CACertRef: &corev1.SecretKeySelector{ | ||
| Key: "ca", | ||
| LocalObjectReference: corev1.LocalObjectReference{ | ||
| Name: "casecret", | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| startingSecret: &corev1.Secret{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: "casecret", | ||
| Namespace: namespace, | ||
| }, | ||
| Data: map[string][]byte{ | ||
| "ca": []byte("secret ca data"), | ||
| }, | ||
| }, | ||
| expectBytes: []byte("secret ca data"), | ||
| }, | ||
| { | ||
| name: "missing ca cert ref secret", | ||
| bsl: &velerov1.BackupStorageLocationSpec{ | ||
|
|
@@ -1489,3 +1515,96 @@ func TestRetrieveCAData(t *testing.T) { | |
| } | ||
|
|
||
| } | ||
|
|
||
| func TestResolveCAData(t *testing.T) { | ||
| scheme := runtime.NewScheme() | ||
| require.NoError(t, oadpv1alpha1.AddToScheme(scheme)) | ||
| require.NoError(t, corev1.AddToScheme(scheme)) | ||
|
|
||
| namespace := "dpt-test" | ||
|
|
||
| refBSL := func(provider string) *velerov1.BackupStorageLocationSpec { | ||
| return &velerov1.BackupStorageLocationSpec{ | ||
| Provider: provider, | ||
| StorageType: velerov1.StorageType{ | ||
| ObjectStorage: &velerov1.ObjectStorageLocation{ | ||
| CACertRef: &corev1.SecretKeySelector{ | ||
| Key: "ca", | ||
| LocalObjectReference: corev1.LocalObjectReference{Name: "casecret"}, | ||
| }, | ||
| }, | ||
| }, | ||
| } | ||
| } | ||
| caSecret := &corev1.Secret{ | ||
| ObjectMeta: metav1.ObjectMeta{Name: "casecret", Namespace: namespace}, | ||
| Data: map[string][]byte{"ca": []byte("secret ca data")}, | ||
| } | ||
|
|
||
| tests := []struct { | ||
| name string | ||
| skipTLSVerify bool | ||
| bsl *velerov1.BackupStorageLocationSpec | ||
| startingSecret *corev1.Secret | ||
| expectErr bool | ||
| expectBytes []byte | ||
| }{ | ||
| { | ||
| name: "aws resolves the referenced secret", | ||
| bsl: refBSL("aws"), | ||
| startingSecret: caSecret, | ||
| expectBytes: []byte("secret ca data"), | ||
| }, | ||
| { | ||
| name: "skipTLSVerify does not read a missing ca secret", | ||
| skipTLSVerify: true, | ||
| bsl: refBSL("aws"), | ||
| }, | ||
| { | ||
| name: "aws with a missing ca secret still errors when verification is on", | ||
| bsl: refBSL("aws"), | ||
| // no secret created | ||
| expectErr: true, | ||
| }, | ||
| { | ||
| name: "gcp does not add a secret dependency", | ||
| bsl: refBSL("gcp"), | ||
| // no secret created: must not be looked up | ||
| }, | ||
| { | ||
| name: "azure does not add a secret dependency", | ||
| bsl: refBSL("azure"), | ||
| }, | ||
| { | ||
| name: "nil spec", | ||
| }, | ||
| } | ||
|
|
||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| builder := fake.NewClientBuilder().WithScheme(scheme) | ||
| if tt.startingSecret != nil { | ||
| builder = builder.WithObjects(tt.startingSecret) | ||
| } | ||
| fakeClient := builder.Build() | ||
|
|
||
| reconciler := &DataProtectionTestReconciler{ | ||
| Client: fakeClient, | ||
| Log: logr.Discard(), | ||
| NamespacedName: types.NamespacedName{Namespace: namespace, Name: "test-obj"}, | ||
| Context: context.Background(), | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be t.Context(). I'll submit a commit to fix this.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks |
||
| dpt: &oadpv1alpha1.DataProtectionTest{ | ||
| Spec: oadpv1alpha1.DataProtectionTestSpec{SkipTLSVerify: tt.skipTLSVerify}, | ||
| }, | ||
| } | ||
|
|
||
| caData, err := reconciler.resolveCAData(context.Background(), tt.bsl) | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here. |
||
| if tt.expectErr { | ||
| require.Error(t, err) | ||
| } else { | ||
| require.NoError(t, err) | ||
| } | ||
| require.Equal(t, tt.expectBytes, caData) | ||
| }) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,5 +86,11 @@ func CreateDPTAndAssertComplete(c client.Client, namespace, bslName string) erro | |
| if dpt.Status.Phase != "Complete" { | ||
| return fmt.Errorf("DataProtectionTest %s reached phase %q (error: %s)", dpt.Name, dpt.Status.Phase, dpt.Status.ErrorMessage) | ||
| } | ||
| // The reconciler marks the DPT Complete even when the upload itself failed | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there is ever a DPTv2 I would ask this to change. One expects when the phase is "Completed" all parts were successful and otherwise either PartialFailed or PartialComplete or PartialSuccess or similar. With a condition array added to explain.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @@shubham-pampattiwar thoughts? |
||
| // and records the outcome in status.uploadTest, so phase alone is not | ||
| // enough: a TLS failure reaching the bucket would otherwise pass here. | ||
| if !dpt.Status.UploadTest.Success { | ||
| return fmt.Errorf("DataProtectionTest %s completed but the upload test failed: %s", dpt.Name, dpt.Status.UploadTest.ErrorMessage) | ||
| } | ||
| return nil | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Azure/GCP plugins don't respect providing custom CAs anyways.
I don't see how this helps, anyone doing so is configuring the object incorrectly. But I don't see this hurting to force ignoring for anything other than aws.