mirror of
https://github.com/project-zot/zot.git
synced 2026-06-16 20:38:08 +08:00
fix(tests): update imagetrust tests to use mock service (#1929)
- use secretsManagerMock and secretsManagerCacheMock to avoid failing because of "already exists" error when running multiple times image_trust_test on the same localstack instance Signed-off-by: Andreea-Lupu <andreealupu1470@yahoo.com>
This commit is contained in:
@@ -256,11 +256,11 @@ func (cloud *PublicKeyAWSStorage) StorePublicKey(name godigest.Digest, publicKey
|
||||
}
|
||||
|
||||
_, err := cloud.secretsManagerClient.CreateSecret(context.Background(), secretInputParam)
|
||||
if err != nil {
|
||||
return err
|
||||
if err != nil && IsResourceExistsException(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
func validatePublicKey(publicKeyContent []byte) (bool, error) {
|
||||
|
||||
@@ -9,13 +9,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/aws/transport/http"
|
||||
"github.com/aws/aws-sdk-go-v2/config"
|
||||
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
|
||||
"github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
|
||||
aws1 "github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/endpoints"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
smanager "github.com/aws/aws-sdk-go/service/secretsmanager"
|
||||
"github.com/aws/aws-secretsmanager-caching-go/secretcache"
|
||||
smithy "github.com/aws/smithy-go"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
@@ -140,6 +143,20 @@ func GetSecretsManagerRetrieval(region, endpoint string) *secretcache.Cache {
|
||||
return cache
|
||||
}
|
||||
|
||||
func IsResourceExistsException(err error) bool {
|
||||
if opErr, ok := err.(*smithy.OperationError); ok { //nolint: errorlint
|
||||
if resErr, ok := opErr.Err.(*http.ResponseError); ok { //nolint: errorlint
|
||||
if _, ok := resErr.Err.(*types.ResourceExistsException); ok { //nolint: errorlint
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (imgTrustStore *ImageTrustStore) VerifySignature(
|
||||
signatureType string, rawSignature []byte, sigKey string, manifestDigest godigest.Digest, manifestContent []byte,
|
||||
repo string,
|
||||
|
||||
@@ -16,8 +16,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"
|
||||
"github.com/aws/aws-sdk-go-v2/service/secretsmanager"
|
||||
"github.com/aws/aws-sdk-go-v2/service/secretsmanager/types"
|
||||
smithy "github.com/aws/smithy-go"
|
||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
||||
guuid "github.com/gofrs/uuid"
|
||||
"github.com/notaryproject/notation-go"
|
||||
notreg "github.com/notaryproject/notation-go/registry"
|
||||
@@ -661,7 +664,7 @@ func TestLocalTrustStore(t *testing.T) {
|
||||
func TestAWSTrustStore(t *testing.T) {
|
||||
tskip.SkipDynamo(t)
|
||||
|
||||
trustpolicy := "trustpolicy"
|
||||
trustpolicyDoc := "trustpolicy"
|
||||
|
||||
Convey("NewAWSImageTrustStore error", t, func() {
|
||||
_, err := imagetrust.NewAWSImageTrustStore("us-east-2", "wrong;endpoint")
|
||||
@@ -669,22 +672,7 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("InitTrustpolicy retry", t, func() {
|
||||
smanager, err := imagetrust.GetSecretsManagerClient("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
smCache := imagetrust.GetSecretsManagerRetrieval("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
|
||||
|
||||
description := "notation trustpolicy file"
|
||||
content := "trustpolicy content"
|
||||
|
||||
_, err = smanager.CreateSecret(context.Background(),
|
||||
&secretsmanager.CreateSecretInput{
|
||||
Name: &trustpolicy,
|
||||
Description: &description,
|
||||
SecretString: &content,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
secretsManagerMock := mocks.SecretsManagerMock{
|
||||
DeleteSecretFn: func(ctx context.Context, params *secretsmanager.DeleteSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
@@ -694,20 +682,25 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.CreateSecretOutput, error) {
|
||||
return smanager.CreateSecret(ctx, params, optFns...)
|
||||
return &secretsmanager.CreateSecretOutput{}, getResourceExistsException()
|
||||
},
|
||||
}
|
||||
|
||||
secretsManagerCacheMock := mocks.SecretsManagerCacheMock{
|
||||
GetSecretStringFn: func(secretID string) (string, error) {
|
||||
return "", errUnexpectedError
|
||||
},
|
||||
}
|
||||
|
||||
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
_, err := imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, smCache)
|
||||
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
|
||||
GetSecretStringFn: func(secretID string) (string, error) {
|
||||
return content, nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
secretsManagerMock = mocks.SecretsManagerMock{
|
||||
@@ -719,13 +712,15 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.CreateSecretOutput, error) {
|
||||
return smanager.CreateSecret(ctx, params, optFns...)
|
||||
return &secretsmanager.CreateSecretOutput{}, getResourceExistsException()
|
||||
},
|
||||
}
|
||||
|
||||
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, smCache)
|
||||
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
errVal := make(chan bool)
|
||||
|
||||
secretsManagerMock = mocks.SecretsManagerMock{
|
||||
DeleteSecretFn: func(ctx context.Context, params *secretsmanager.DeleteSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
@@ -733,7 +728,7 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
go func() {
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
smanager.DeleteSecret(ctx, params, optFns...) //nolint:errcheck
|
||||
errVal <- true
|
||||
}()
|
||||
|
||||
return &secretsmanager.DeleteSecretOutput{}, nil
|
||||
@@ -741,21 +736,53 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.CreateSecretOutput, error) {
|
||||
return smanager.CreateSecret(ctx, params, optFns...)
|
||||
select {
|
||||
case <-errVal:
|
||||
return &secretsmanager.CreateSecretOutput{}, nil
|
||||
default:
|
||||
return &secretsmanager.CreateSecretOutput{}, getResourceExistsException()
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, smCache)
|
||||
_, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("GetCertificates errors", t, func() {
|
||||
smanager, err := imagetrust.GetSecretsManagerClient("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
|
||||
So(err, ShouldBeNil)
|
||||
name := "ca/test/digest"
|
||||
content := "invalid certificate content"
|
||||
|
||||
smCache := imagetrust.GetSecretsManagerRetrieval("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
|
||||
secretsManagerMock := mocks.SecretsManagerMock{
|
||||
DeleteSecretFn: func(ctx context.Context, params *secretsmanager.DeleteSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.DeleteSecretOutput, error) {
|
||||
return &secretsmanager.DeleteSecretOutput{}, nil
|
||||
},
|
||||
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.CreateSecretOutput, error) {
|
||||
if *params.Name == trustpolicyDoc {
|
||||
return &secretsmanager.CreateSecretOutput{}, nil
|
||||
}
|
||||
|
||||
notationStorage, err := imagetrust.NewCertificateAWSStorage(smanager, smCache)
|
||||
return &secretsmanager.CreateSecretOutput{}, errUnexpectedError
|
||||
},
|
||||
ListSecretsFn: func(ctx context.Context, params *secretsmanager.ListSecretsInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.ListSecretsOutput, error) {
|
||||
return &secretsmanager.ListSecretsOutput{
|
||||
SecretList: []types.SecretListEntry{{Name: &name}},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
secretsManagerCacheMock := mocks.SecretsManagerCacheMock{
|
||||
GetSecretStringFn: func(secretID string) (string, error) {
|
||||
return content, nil
|
||||
},
|
||||
}
|
||||
|
||||
notationStorage, err := imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = notationStorage.GetCertificates(context.Background(), "wrongType", "")
|
||||
@@ -766,36 +793,48 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
So(err, ShouldNotBeNil)
|
||||
So(err, ShouldEqual, zerr.ErrInvalidTruststoreName)
|
||||
|
||||
name := "ca/test/digest"
|
||||
description := "notation certificate"
|
||||
content := "invalid certificate content"
|
||||
|
||||
_, err = smanager.CreateSecret(context.Background(),
|
||||
&secretsmanager.CreateSecretInput{
|
||||
Name: &name,
|
||||
Description: &description,
|
||||
SecretString: &content,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = notationStorage.GetCertificates(context.Background(), "ca", "test")
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
newName := "ca/newtest/digest"
|
||||
newSecret := base64.StdEncoding.EncodeToString([]byte(content))
|
||||
|
||||
_, err = smanager.CreateSecret(context.Background(),
|
||||
&secretsmanager.CreateSecretInput{
|
||||
Name: &newName,
|
||||
Description: &description,
|
||||
SecretString: &newSecret,
|
||||
})
|
||||
secretsManagerMock = mocks.SecretsManagerMock{
|
||||
DeleteSecretFn: func(ctx context.Context, params *secretsmanager.DeleteSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.DeleteSecretOutput, error) {
|
||||
return &secretsmanager.DeleteSecretOutput{}, nil
|
||||
},
|
||||
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.CreateSecretOutput, error) {
|
||||
if *params.Name == trustpolicyDoc {
|
||||
return &secretsmanager.CreateSecretOutput{}, nil
|
||||
}
|
||||
|
||||
return &secretsmanager.CreateSecretOutput{}, errUnexpectedError
|
||||
},
|
||||
ListSecretsFn: func(ctx context.Context, params *secretsmanager.ListSecretsInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.ListSecretsOutput, error) {
|
||||
return &secretsmanager.ListSecretsOutput{
|
||||
SecretList: []types.SecretListEntry{{Name: &newName}},
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
|
||||
GetSecretStringFn: func(secretID string) (string, error) {
|
||||
return newSecret, nil
|
||||
},
|
||||
}
|
||||
|
||||
notationStorage, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = notationStorage.GetCertificates(context.Background(), "ca", "newtest")
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
secretsManagerMock := mocks.SecretsManagerMock{
|
||||
secretsManagerMock = mocks.SecretsManagerMock{
|
||||
ListSecretsFn: func(ctx context.Context, params *secretsmanager.ListSecretsInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.ListSecretsOutput, error) {
|
||||
@@ -803,7 +842,7 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
notationStorage, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, smCache)
|
||||
notationStorage, err = imagetrust.NewCertificateAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = notationStorage.GetCertificates(context.Background(), "ca", "newtest")
|
||||
@@ -817,7 +856,7 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
secretsManagerCacheMock := mocks.SecretsManagerCacheMock{
|
||||
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
|
||||
GetSecretStringFn: func(secretID string) (string, error) {
|
||||
return "", errUnexpectedError
|
||||
},
|
||||
@@ -831,42 +870,41 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("GetPublicKeyVerifier errors", t, func() {
|
||||
smanager, err := imagetrust.GetSecretsManagerClient("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
|
||||
So(err, ShouldBeNil)
|
||||
secretsManagerMock := mocks.SecretsManagerMock{}
|
||||
secretsManagerCacheMock := mocks.SecretsManagerCacheMock{
|
||||
GetSecretStringFn: func(secretID string) (string, error) {
|
||||
return "", errUnexpectedError
|
||||
},
|
||||
}
|
||||
|
||||
smCache := imagetrust.GetSecretsManagerRetrieval("us-east-2", os.Getenv("DYNAMODBMOCK_ENDPOINT"))
|
||||
cosignStorage := imagetrust.NewPublicKeyAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
|
||||
cosignStorage := imagetrust.NewPublicKeyAWSStorage(smanager, smCache)
|
||||
|
||||
_, _, err = cosignStorage.GetPublicKeyVerifier("badsecret")
|
||||
_, _, err := cosignStorage.GetPublicKeyVerifier("badsecret")
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
secretName := "digest"
|
||||
description := "cosign public key"
|
||||
secret := "invalid public key content"
|
||||
|
||||
_, err = smanager.CreateSecret(context.Background(),
|
||||
&secretsmanager.CreateSecretInput{
|
||||
Name: &secretName,
|
||||
Description: &description,
|
||||
SecretString: &secret,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
|
||||
GetSecretStringFn: func(secretID string) (string, error) {
|
||||
return secret, nil
|
||||
},
|
||||
}
|
||||
|
||||
cosignStorage = imagetrust.NewPublicKeyAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
|
||||
_, _, err = cosignStorage.GetPublicKeyVerifier(secretName)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
secretName = "newdigest"
|
||||
|
||||
newSecret := base64.StdEncoding.EncodeToString([]byte(secret))
|
||||
|
||||
_, err = smanager.CreateSecret(context.Background(),
|
||||
&secretsmanager.CreateSecretInput{
|
||||
Name: &secretName,
|
||||
Description: &description,
|
||||
SecretString: &newSecret,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
secretsManagerCacheMock = mocks.SecretsManagerCacheMock{
|
||||
GetSecretStringFn: func(secretID string) (string, error) {
|
||||
return newSecret, nil
|
||||
},
|
||||
}
|
||||
|
||||
cosignStorage = imagetrust.NewPublicKeyAWSStorage(secretsManagerMock, secretsManagerCacheMock)
|
||||
|
||||
_, _, err = cosignStorage.GetPublicKeyVerifier(secretName)
|
||||
So(err, ShouldNotBeNil)
|
||||
@@ -900,6 +938,39 @@ func TestAWSTrustStore(t *testing.T) {
|
||||
|
||||
err := cosignStorage.StorePublicKey(digest.FromString("dig"), []byte("content"))
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
secretsManagerMock = mocks.SecretsManagerMock{
|
||||
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.CreateSecretOutput, error) {
|
||||
return &secretsmanager.CreateSecretOutput{}, getResourceExistsException()
|
||||
},
|
||||
}
|
||||
|
||||
cosignStorage = imagetrust.NewPublicKeyAWSStorage(secretsManagerMock, nil)
|
||||
|
||||
err = cosignStorage.StorePublicKey(digest.FromString("dig"), []byte("content"))
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("StoreCertificate error", t, func() {
|
||||
secretsManagerMock := mocks.SecretsManagerMock{
|
||||
CreateSecretFn: func(ctx context.Context, params *secretsmanager.CreateSecretInput,
|
||||
optFns ...func(*secretsmanager.Options),
|
||||
) (*secretsmanager.CreateSecretOutput, error) {
|
||||
if *params.Name != trustpolicyDoc {
|
||||
return &secretsmanager.CreateSecretOutput{}, getResourceExistsException()
|
||||
}
|
||||
|
||||
return &secretsmanager.CreateSecretOutput{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
notationStorage, err := imagetrust.NewCertificateAWSStorage(secretsManagerMock, nil)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = notationStorage.StoreCertificate([]byte("content"), "ca")
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
|
||||
Convey("VerifySignature - trustpolicy.json does not exist", t, func() {
|
||||
@@ -1337,3 +1408,17 @@ func RunVerificationTests(t *testing.T, dbDriverParams map[string]interface{}) {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
func getResourceExistsException() error {
|
||||
errAlreadyExists := "the secret already exists"
|
||||
|
||||
return &smithy.OperationError{
|
||||
Err: &awshttp.ResponseError{
|
||||
ResponseError: &smithyhttp.ResponseError{
|
||||
Err: &types.ResourceExistsException{
|
||||
Message: &errAlreadyExists,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ func (cloud *CertificateAWSStorage) InitTrustpolicy(trustpolicy []byte) error {
|
||||
}
|
||||
|
||||
_, err := cloud.secretsManagerClient.CreateSecret(context.Background(), secretInputParam)
|
||||
if err != nil && strings.Contains(err.Error(), "the secret trustpolicy already exists.") {
|
||||
if err != nil && IsResourceExistsException(err) {
|
||||
trustpolicyContent, err := cloud.secretsManagerCache.GetSecretString(name)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -495,6 +495,10 @@ func (cloud *CertificateAWSStorage) StoreCertificate(
|
||||
|
||||
_, err := cloud.secretsManagerClient.CreateSecret(context.Background(), secretInputParam)
|
||||
|
||||
if err != nil && IsResourceExistsException(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user