Skip to content

Commit d38d4f9

Browse files
committed
Remove error constant strings
To avoid doing a whole bunch of string comparison in unit tests, we also switch to using cmpopts.EquateErrors. Signed-off-by: Nic Cope <[email protected]>
1 parent db81395 commit d38d4f9

39 files changed

+375
-440
lines changed

pkg/certificates/certificates.go

+3-9
Original file line numberDiff line numberDiff line change
@@ -26,30 +26,24 @@ import (
2626
"github.com/crossplane/crossplane-runtime/pkg/errors"
2727
)
2828

29-
const (
30-
errLoadCert = "cannot load certificate"
31-
errLoadCA = "cannot load CA certificate"
32-
errInvalidCA = "invalid CA certificate"
33-
)
34-
3529
// LoadMTLSConfig loads TLS certificates in the given folder using well-defined filenames for certificates in a Kubernetes environment.
3630
func LoadMTLSConfig(caPath, certPath, keyPath string, isServer bool) (*tls.Config, error) {
3731
tlsCertFilePath := filepath.Clean(certPath)
3832
tlsKeyFilePath := filepath.Clean(keyPath)
3933
certificate, err := tls.LoadX509KeyPair(tlsCertFilePath, tlsKeyFilePath)
4034
if err != nil {
41-
return nil, errors.Wrap(err, errLoadCert)
35+
return nil, errors.Wrap(err, "cannot load certificate")
4236
}
4337

4438
caCertFilePath := filepath.Clean(caPath)
4539
ca, err := os.ReadFile(caCertFilePath)
4640
if err != nil {
47-
return nil, errors.Wrap(err, errLoadCA)
41+
return nil, errors.Wrap(err, "cannot load CA certificate")
4842
}
4943

5044
pool := x509.NewCertPool()
5145
if !pool.AppendCertsFromPEM(ca) {
52-
return nil, errors.New(errInvalidCA)
46+
return nil, errors.New("invalid CA certificate")
5347
}
5448

5549
tlsConfig := &tls.Config{

pkg/certificates/certificates_test.go

+8-12
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,12 @@ package certificates
22

33
import (
44
"crypto/tls"
5+
"os"
56
"path/filepath"
67
"testing"
78

89
"github.com/google/go-cmp/cmp"
9-
10-
"github.com/crossplane/crossplane-runtime/pkg/errors"
11-
"github.com/crossplane/crossplane-runtime/pkg/test"
12-
)
13-
14-
var (
15-
errNoSuchFile = errors.New("open invalid/path/tls.crt: no such file or directory")
16-
errNoCAFile = errors.New("open test-data/no-ca/ca.crt: no such file or directory")
10+
"github.com/google/go-cmp/cmp/cmpopts"
1711
)
1812

1913
const (
@@ -42,7 +36,7 @@ func TestLoad(t *testing.T) {
4236
certsFolderPath: "invalid/path",
4337
},
4438
want: want{
45-
err: errors.Wrap(errNoSuchFile, errLoadCert),
39+
err: os.ErrNotExist,
4640
out: nil,
4741
},
4842
},
@@ -52,7 +46,7 @@ func TestLoad(t *testing.T) {
5246
certsFolderPath: "test-data/no-ca",
5347
},
5448
want: want{
55-
err: errors.Wrap(errNoCAFile, errLoadCA),
49+
err: os.ErrNotExist,
5650
out: nil,
5751
},
5852
},
@@ -62,7 +56,9 @@ func TestLoad(t *testing.T) {
6256
certsFolderPath: "test-data/invalid-certs/",
6357
},
6458
want: want{
65-
err: errors.New(errInvalidCA),
59+
// TODO(negz): Can we be more specific? Should we use a sentinel
60+
// error?
61+
err: cmpopts.AnyError,
6662
out: nil,
6763
},
6864
},
@@ -96,7 +92,7 @@ func TestLoad(t *testing.T) {
9692
requireClient := tc.args.requireClientValidation
9793

9894
cfg, err := LoadMTLSConfig(filepath.Join(certsFolderPath, caCertFileName), filepath.Join(certsFolderPath, tlsCertFileName), filepath.Join(certsFolderPath, tlsKeyFileName), requireClient)
99-
if diff := cmp.Diff(tc.want.err, err, test.EquateErrors()); diff != "" {
95+
if diff := cmp.Diff(tc.want.err, err, cmpopts.EquateErrors()); diff != "" {
10096
t.Errorf("\n%s\nLoad(...): -want error, +got error:\n%s", tc.reason, diff)
10197
}
10298

pkg/connection/manager.go

+13-25
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,6 @@ import (
3333
"github.com/crossplane/crossplane-runtime/pkg/resource"
3434
)
3535

36-
// Error strings.
37-
const (
38-
errConnectStore = "cannot connect to secret store"
39-
errWriteStore = "cannot write to secret store"
40-
errReadStore = "cannot read from secret store"
41-
errDeleteFromStore = "cannot delete from secret store"
42-
errGetStoreConfig = "cannot get store config"
43-
errSecretConflict = "cannot establish control of existing connection secret"
44-
45-
errFmtNotOwnedBy = "existing secret is not owned by UID %q"
46-
)
47-
4836
// StoreBuilderFn is a function that builds and returns a Store with a given
4937
// store config.
5038
type StoreBuilderFn func(ctx context.Context, local client.Client, tcfg *tls.Config, cfg v1.SecretStoreConfig) (Store, error)
@@ -110,11 +98,11 @@ func (m *DetailsManager) PublishConnection(ctx context.Context, so resource.Conn
11098

11199
ss, err := m.connectStore(ctx, p)
112100
if err != nil {
113-
return false, errors.Wrap(err, errConnectStore)
101+
return false, errors.Wrap(err, "cannot connect to secret store")
114102
}
115103

116104
changed, err := ss.WriteKeyValues(ctx, store.NewSecret(so, store.KeyValues(conn)), SecretToWriteMustBeOwnedBy(so))
117-
return changed, errors.Wrap(err, errWriteStore)
105+
return changed, errors.Wrap(err, "cannot write to secret store")
118106
}
119107

120108
// UnpublishConnection deletes connection details secret to the configured
@@ -128,10 +116,10 @@ func (m *DetailsManager) UnpublishConnection(ctx context.Context, so resource.Co
128116

129117
ss, err := m.connectStore(ctx, p)
130118
if err != nil {
131-
return errors.Wrap(err, errConnectStore)
119+
return errors.Wrap(err, "cannot connect to secret store")
132120
}
133121

134-
return errors.Wrap(ss.DeleteKeyValues(ctx, store.NewSecret(so, store.KeyValues(conn)), SecretToDeleteMustBeOwnedBy(so)), errDeleteFromStore)
122+
return errors.Wrap(ss.DeleteKeyValues(ctx, store.NewSecret(so, store.KeyValues(conn)), SecretToDeleteMustBeOwnedBy(so)), "cannot delete from secret store")
135123
}
136124

137125
// FetchConnection fetches connection details of a given ConnectionSecretOwner.
@@ -144,11 +132,11 @@ func (m *DetailsManager) FetchConnection(ctx context.Context, so resource.Connec
144132

145133
ss, err := m.connectStore(ctx, p)
146134
if err != nil {
147-
return nil, errors.Wrap(err, errConnectStore)
135+
return nil, errors.Wrap(err, "cannot connect to secret store")
148136
}
149137

150138
s := &store.Secret{}
151-
return managed.ConnectionDetails(s.Data), errors.Wrap(ss.ReadKeyValues(ctx, store.ScopedName{Name: p.Name, Scope: so.GetNamespace()}, s), errReadStore)
139+
return managed.ConnectionDetails(s.Data), errors.Wrap(ss.ReadKeyValues(ctx, store.ScopedName{Name: p.Name, Scope: so.GetNamespace()}, s), "cannot read from secret store")
152140
}
153141

154142
// PropagateConnection propagate connection details from one resource to another.
@@ -160,37 +148,37 @@ func (m *DetailsManager) PropagateConnection(ctx context.Context, to resource.Lo
160148

161149
ssFrom, err := m.connectStore(ctx, from.GetPublishConnectionDetailsTo())
162150
if err != nil {
163-
return false, errors.Wrap(err, errConnectStore)
151+
return false, errors.Wrap(err, "cannot connect to secret store")
164152
}
165153

166154
sFrom := &store.Secret{}
167155
if err = ssFrom.ReadKeyValues(ctx, store.ScopedName{
168156
Name: from.GetPublishConnectionDetailsTo().Name,
169157
Scope: from.GetNamespace(),
170158
}, sFrom); err != nil {
171-
return false, errors.Wrap(err, errReadStore)
159+
return false, errors.Wrap(err, "cannot read from secret store")
172160
}
173161

174162
// Make sure 'from' is the controller of the connection secret it references
175163
// before we propagate it. This ensures a resource cannot use Crossplane to
176164
// circumvent RBAC by propagating a secret it does not own.
177165
if sFrom.GetOwner() != string(from.GetUID()) {
178-
return false, errors.New(errSecretConflict)
166+
return false, errors.New("cannot establish control of existing connection secret")
179167
}
180168

181169
ssTo, err := m.connectStore(ctx, to.GetPublishConnectionDetailsTo())
182170
if err != nil {
183-
return false, errors.Wrap(err, errConnectStore)
171+
return false, errors.Wrap(err, "cannot connect to secret store")
184172
}
185173

186174
changed, err := ssTo.WriteKeyValues(ctx, store.NewSecret(to, sFrom.Data), SecretToWriteMustBeOwnedBy(to))
187-
return changed, errors.Wrap(err, errWriteStore)
175+
return changed, errors.Wrap(err, "cannot write to secret store")
188176
}
189177

190178
func (m *DetailsManager) connectStore(ctx context.Context, p *v1.PublishConnectionDetailsTo) (Store, error) {
191179
sc := m.newConfig()
192180
if err := m.client.Get(ctx, types.NamespacedName{Name: p.SecretStoreConfigRef.Name}, sc); err != nil {
193-
return nil, errors.Wrap(err, errGetStoreConfig)
181+
return nil, errors.Wrap(err, "cannot get store config")
194182
}
195183

196184
return m.storeBuilder(ctx, m.client, m.tcfg, sc.GetStoreConfig())
@@ -214,7 +202,7 @@ func SecretToDeleteMustBeOwnedBy(so metav1.Object) store.DeleteOption {
214202

215203
func secretMustBeOwnedBy(so metav1.Object, secret *store.Secret) error {
216204
if secret.Metadata == nil || secret.Metadata.GetOwnerUID() != string(so.GetUID()) {
217-
return errors.Errorf(errFmtNotOwnedBy, string(so.GetUID()))
205+
return errors.Errorf("existing secret is not woned by UID %q", string(so.GetUID()))
218206
}
219207
return nil
220208
}

0 commit comments

Comments
 (0)