From d91f6ff9b7e3cfdcb6923aa98207553fa508fbd5 Mon Sep 17 00:00:00 2001 From: Ashok Siyani Date: Wed, 22 Nov 2023 11:48:50 +0000 Subject: [PATCH 1/4] setup SB even if no local encrypted file found --- decrypt.go | 8 ++-- decrypt_test.go | 116 +++++++++++++++++++++++++++++++----------------- 2 files changed, 80 insertions(+), 44 deletions(-) diff --git a/decrypt.go b/decrypt.go index 54df99f..e031787 100644 --- a/decrypt.go +++ b/decrypt.go @@ -24,12 +24,12 @@ func ensureDecryption(ctx context.Context, cwd string, app applicationInfo) erro return fmt.Errorf("unable to check if app source folder has encrypted files err:%s", err) } - if !found { - return nil - } - d, err := getKeyRingData(ctx, app.destinationNamespace, app.keyringSecret) if err != nil { + // if there are no local secret file and secret is not found then its not an error + if !found == errors.Is(err, errNotFound) { + return nil + } return err } diff --git a/decrypt_test.go b/decrypt_test.go index 7373a34..f67b9b2 100644 --- a/decrypt_test.go +++ b/decrypt_test.go @@ -151,6 +151,15 @@ func Test_ensureDecryption(t *testing.T) { } kubeClient = fake.NewSimpleClientset( + &v1.Secret{ + ObjectMeta: metaV1.ObjectMeta{ + Name: "strongbox-secret", + Namespace: "bar", + }, + Data: map[string][]byte{ + "keyring": kr, + }, + }, &v1.Secret{ ObjectMeta: metaV1.ObjectMeta{ Name: "strongbox-secret", @@ -174,7 +183,7 @@ func Test_ensureDecryption(t *testing.T) { }, ) - // withRemoteBase doesn't have enc files so it should not look for "missing-secrets" secret + // withRemoteBase doesn't have encrypted files so it should not error for "missing-secrets" secret bar := applicationInfo{ name: "bar", destinationNamespace: "bar", @@ -183,12 +192,35 @@ func Test_ensureDecryption(t *testing.T) { key: "invalid", }, } - err = ensureDecryption(context.Background(), withRemoteBaseTestDir, bar) - if err != nil { - t.Fatal(err) + t.Run("no-encrypted-files-no-secret", func(t *testing.T) { + err = ensureDecryption(context.Background(), withRemoteBaseTestDir, bar) + if err != nil { + t.Fatal(err) + } + }) + + // withRemoteBase doesn't have encrypted files but namespace contains secret so it should setup + // strongbox for remote base's encrypted secrets + bar2 := applicationInfo{ + name: "bar", + destinationNamespace: "bar", + keyringSecret: secretInfo{ + name: "strongbox-secret", + key: "keyring", + }, } + t.Run("no-encrypted-files-with-secret", func(t *testing.T) { + err = ensureDecryption(context.Background(), withRemoteBaseTestDir, bar2) + if err != nil { + t.Fatal(err) + } + // make sure .strongbox_keyring file exists with correct keyring data + if !bytes.Contains(getFileContent(t, withRemoteBaseTestDir+"/.strongbox_keyring"), kr) { + t.Error(withRemoteBaseTestDir + "/.strongbox_keyring should contain keyring data") + } + }) - // encryptedTestDir1 has enc files so it should look for secret and then decrypt content + // encryptedTestDir1 has encrypted files so it should look for secret and then decrypt content // keyring secret in app's destination NS foo := applicationInfo{ name: "foo", @@ -198,29 +230,31 @@ func Test_ensureDecryption(t *testing.T) { key: "keyring", }, } - err = ensureDecryption(context.Background(), encryptedTestDir1, foo) - if err != nil { - t.Fatal(err) - } + t.Run("encrypted-files-with-secret", func(t *testing.T) { + err = ensureDecryption(context.Background(), encryptedTestDir1, foo) + if err != nil { + t.Fatal(err) + } - if !bytes.Contains(getFileContent(t, encryptedTestDir1+"/secrets/strongbox-keyring"), kr) { - t.Error(encryptedTestDir1 + "/secrets/strongbox-keyring should contain keyring data") - } + if !bytes.Contains(getFileContent(t, encryptedTestDir1+"/secrets/strongbox-keyring"), kr) { + t.Error(encryptedTestDir1 + "/secrets/strongbox-keyring should contain keyring data") + } - encryptedFiles := []string{ - encryptedTestDir1 + "/app/secrets/env_secrets", - encryptedTestDir1 + "/app/secrets/kube_secret.yaml", - encryptedTestDir1 + "/app/secrets/s1.json", - encryptedTestDir1 + "/app/secrets/s2.yaml", - } + encryptedFiles := []string{ + encryptedTestDir1 + "/app/secrets/env_secrets", + encryptedTestDir1 + "/app/secrets/kube_secret.yaml", + encryptedTestDir1 + "/app/secrets/s1.json", + encryptedTestDir1 + "/app/secrets/s2.yaml", + } - for _, f := range encryptedFiles { - if !bytes.Contains(getFileContent(t, f), []byte("PlainText")) { - t.Errorf("%s should be decrypted", f) + for _, f := range encryptedFiles { + if !bytes.Contains(getFileContent(t, f), []byte("PlainText")) { + t.Errorf("%s should be decrypted", f) + } } - } + }) - // encryptedTestDir2 has enc files so it should look for secret and then decrypt content + // encryptedTestDir2 has encrypted files so it should look for secret and then decrypt content // keyring secret in different namespace then app's destination NS baz := applicationInfo{ name: "foo", @@ -231,26 +265,28 @@ func Test_ensureDecryption(t *testing.T) { key: "keyring", }, } - err = ensureDecryption(context.Background(), encryptedTestDir2, baz) - if err != nil { - t.Fatal(err) - } + t.Run("encrypted-files-with-secret-from-diff-ns", func(t *testing.T) { + err = ensureDecryption(context.Background(), encryptedTestDir2, baz) + if err != nil { + t.Fatal(err) + } - if !bytes.Contains(getFileContent(t, encryptedTestDir2+"/secrets/strongbox-keyring"), kr) { - t.Error(encryptedTestDir2 + "/secrets/strongbox-keyring should contain keyring data") - } + if !bytes.Contains(getFileContent(t, encryptedTestDir2+"/secrets/strongbox-keyring"), kr) { + t.Error(encryptedTestDir2 + "/secrets/strongbox-keyring should contain keyring data") + } - encryptedFiles = []string{ - encryptedTestDir2 + "/app/secrets/env_secrets", - encryptedTestDir2 + "/app/secrets/kube_secret.yaml", - encryptedTestDir2 + "/app/secrets/s1.json", - encryptedTestDir2 + "/app/secrets/s2.yaml", - } + encryptedFiles := []string{ + encryptedTestDir2 + "/app/secrets/env_secrets", + encryptedTestDir2 + "/app/secrets/kube_secret.yaml", + encryptedTestDir2 + "/app/secrets/s1.json", + encryptedTestDir2 + "/app/secrets/s2.yaml", + } - for _, f := range encryptedFiles { - if !bytes.Contains(getFileContent(t, f), []byte("PlainText")) { - t.Errorf("%s should be decrypted", f) + for _, f := range encryptedFiles { + if !bytes.Contains(getFileContent(t, f), []byte("PlainText")) { + t.Errorf("%s should be decrypted", f) + } } - } + }) } From fd7759c67631d886cbc60217a35470e3a28f93ba Mon Sep 17 00:00:00 2001 From: Ashok Siyani Date: Wed, 22 Nov 2023 11:49:28 +0000 Subject: [PATCH 2/4] updated go dependencies --- go.mod | 24 ++++++++++++------------ go.sum | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index 68d2574..d231ff6 100644 --- a/go.mod +++ b/go.mod @@ -6,9 +6,9 @@ require ( github.com/google/go-cmp v0.6.0 github.com/hashicorp/go-hclog v1.5.0 github.com/urfave/cli/v2 v2.25.7 - k8s.io/api v0.28.3 - k8s.io/apimachinery v0.28.3 - k8s.io/client-go v0.28.3 + k8s.io/api v0.28.4 + k8s.io/apimachinery v0.28.4 + k8s.io/client-go v0.28.4 ) require ( @@ -16,7 +16,7 @@ require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect - github.com/fatih/color v1.15.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/go-logr/logr v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.20.0 // indirect github.com/go-openapi/jsonreference v0.20.2 // indirect @@ -37,20 +37,20 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/oauth2 v0.13.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect - golang.org/x/time v0.3.0 // indirect + golang.org/x/net v0.18.0 // indirect + golang.org/x/oauth2 v0.14.0 // indirect + golang.org/x/sys v0.14.0 // indirect + golang.org/x/term v0.14.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.4.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect - k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e // indirect + k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 515751b..be4ab8d 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= @@ -121,8 +123,12 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= +golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY= golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0= +golang.org/x/oauth2 v0.14.0 h1:P0Vrf/2538nmC0H+pEQ3MNFRRnVR7RlqyVw+bvm26z0= +golang.org/x/oauth2 v0.14.0/go.mod h1:lAtNWgaWfL4cm7j2OV8TxGi9Qb7ECORx8DktCY74OwM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -143,18 +149,26 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= +golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.4.0 h1:Z81tqI5ddIoXDPvVQ7/7CC9TnLM7ubaFG2qXYd5BbYY= +golang.org/x/time v0.4.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -185,16 +199,26 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.28.3 h1:Gj1HtbSdB4P08C8rs9AR94MfSGpRhJgsS+GF9V26xMM= k8s.io/api v0.28.3/go.mod h1:MRCV/jr1dW87/qJnZ57U5Pak65LGmQVkKTzf3AtKFHc= +k8s.io/api v0.28.4 h1:8ZBrLjwosLl/NYgv1P7EQLqoO8MGQApnbgH8tu3BMzY= +k8s.io/api v0.28.4/go.mod h1:axWTGrY88s/5YE+JSt4uUi6NMM+gur1en2REMR7IRj0= k8s.io/apimachinery v0.28.3 h1:B1wYx8txOaCQG0HmYF6nbpU8dg6HvA06x5tEffvOe7A= k8s.io/apimachinery v0.28.3/go.mod h1:uQTKmIqs+rAYaq+DFaoD2X7pcjLOqbQX2AOiO0nIpb8= +k8s.io/apimachinery v0.28.4 h1:zOSJe1mc+GxuMnFzD4Z/U1wst50X28ZNsn5bhgIIao8= +k8s.io/apimachinery v0.28.4/go.mod h1:wI37ncBvfAoswfq626yPTe6Bz1c22L7uaJ8dho83mgg= k8s.io/client-go v0.28.3 h1:2OqNb72ZuTZPKCl+4gTKvqao0AMOl9f3o2ijbAj3LI4= k8s.io/client-go v0.28.3/go.mod h1:LTykbBp9gsA7SwqirlCXBWtK0guzfhpoW4qSm7i9dxo= +k8s.io/client-go v0.28.4 h1:Np5ocjlZcTrkyRJ3+T3PkXDpe4UpatQxj85+xjaD2wY= +k8s.io/client-go v0.28.4/go.mod h1:0VDZFpgoZfelyP5Wqu0/r/TRYcLYuJ2U1KEeoaPa1N4= k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 h1:aVUu9fTY98ivBPKR9Y5w/AuzbMm96cd3YHRTU83I780= k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= +k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e h1:snPmy96t93RredGRjKfMFt+gvxuVAncqSAyBveJtr4Q= +k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf h1:iTzha1p7Fi83476ypNSz8nV9iR9932jIIs26F7gNLsU= +k8s.io/utils v0.0.0-20231121161247-cf03d44ff3cf/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= From fa0c7bf26a7e74aab1405219a99bc9a927eff3c8 Mon Sep 17 00:00:00 2001 From: Ashok Siyani Date: Wed, 22 Nov 2023 11:56:36 +0000 Subject: [PATCH 3/4] Update kustomize to version v5.2.1 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 58564cb..30d2fab 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM golang:1.21-alpine AS build ENV \ STRONGBOX_VERSION=1.1.0 \ - KUSTOMIZE_VERSION=v5.1.0 + KUSTOMIZE_VERSION=v5.2.1 RUN os=$(go env GOOS) && arch=$(go env GOARCH) \ && apk --no-cache add curl \ From b8e8562a06a96b7a6c8c2f117c9a09a3ff6e2582 Mon Sep 17 00:00:00 2001 From: Ashok Siyani Date: Wed, 22 Nov 2023 12:02:32 +0000 Subject: [PATCH 4/4] make exp redable --- decrypt.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/decrypt.go b/decrypt.go index e031787..9fdf216 100644 --- a/decrypt.go +++ b/decrypt.go @@ -27,7 +27,7 @@ func ensureDecryption(ctx context.Context, cwd string, app applicationInfo) erro d, err := getKeyRingData(ctx, app.destinationNamespace, app.keyringSecret) if err != nil { // if there are no local secret file and secret is not found then its not an error - if !found == errors.Is(err, errNotFound) { + if !found && errors.Is(err, errNotFound) { return nil } return err