Skip to content
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

feat: Enable multi verifier name #1187

Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
ae7da73
feat: enable showing verifier name
junczhu Nov 23, 2023
6e96827
feat: enable showing verifier name 2
junczhu Nov 23, 2023
2387b5b
feat: enable showing verifier name related ut
junczhu Nov 23, 2023
dcee0b2
feat: enable showing verifier name related ut2
junczhu Nov 23, 2023
e46748c
feat: enable showing verifier name related ut3
junczhu Nov 23, 2023
f7bc7ea
feat: enable showing verifier name related ut4
junczhu Nov 23, 2023
f52f0ab
feat: enable showing verifier name related ut5
junczhu Nov 23, 2023
8d81fae
feat: enable showing verifier name related ut6
junczhu Nov 23, 2023
fdbb175
feat: enable showing verifier name related ut7
junczhu Nov 23, 2023
a68ecbb
feat: enable showing verifier name related ut8
junczhu Nov 29, 2023
da1b552
feat:set verifier type as optional property, added to notation vResult
junczhu Nov 29, 2023
e8aea98
chore: create func verifierCreateConfig, added err catcher
junczhu Nov 29, 2023
004f8e4
fix: update verifier dynamic cli-test
junczhu Nov 29, 2023
9e15057
fix: update verifier creation llog
junczhu Nov 29, 2023
20a95c5
fix: update verifier creation log2
junczhu Nov 29, 2023
a549c06
fix: update verifier creation log3
junczhu Nov 29, 2023
218606f
Merge branch 'main' into enable-multi-verifier-name
junczhu Dec 1, 2023
6efa929
fix: update verifier plugin log for e2e test
junczhu Dec 1, 2023
78bfe26
fix: typo; CT for notation plugin
junczhu Dec 4, 2023
4a8e33c
test: e2e test for verifier with type and multi verifier
junczhu Dec 4, 2023
e2f5b41
feat: resolve comments; fix: e2e test
junczhu Dec 4, 2023
0dfeda7
fix: go-lint
junczhu Dec 4, 2023
62ae222
fix: golangci-lint
junczhu Dec 4, 2023
2e0bf7f
fix: rename variable
junczhu Dec 6, 2023
54304e4
Merge branch 'main' into enable-multi-verifier-name
junczhu Dec 6, 2023
67d93c9
test: update e2e test cases
junczhu Dec 6, 2023
8609a62
Merge branch 'enable-multi-verifier-name' of https://github.com/ZAFT-…
junczhu Dec 6, 2023
b12019d
test: update e2e test cases and reports
junczhu Dec 6, 2023
bdb93e2
test: update e2e test cases and reports2
junczhu Dec 6, 2023
053802c
test: update e2e test cases and reports3
junczhu Dec 6, 2023
41a1e92
test: update e2e test cases and reports4
junczhu Dec 6, 2023
8b138d0
test: update e2e test cases and reports5
junczhu Dec 6, 2023
46b460f
test: update e2e test cases and reports6
junczhu Dec 6, 2023
f34519c
test: update e2e test cases and reports7
junczhu Dec 6, 2023
9042ff8
test: update e2e test cases and reports8
junczhu Dec 6, 2023
516730d
test: update e2e test cases and reports9
junczhu Dec 6, 2023
869b45d
test: update e2e test cases and reports0
junczhu Dec 6, 2023
46a35c5
test: update e2e test cases and reports10
junczhu Dec 6, 2023
b06bd62
test: update e2e test cases and reports11
junczhu Dec 6, 2023
92a63a0
test: update e2e test cases and reports12
junczhu Dec 6, 2023
c8fa6bf
test: update e2e test cases and reports13
junczhu Dec 6, 2023
2ff1060
chore: merge conflict
junczhu Dec 7, 2023
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
5 changes: 3 additions & 2 deletions pkg/controllers/verifier_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ func (r *VerifierReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
// creates a verifier reference from CRD spec and add store to map
func verifierAddOrReplace(spec configv1beta1.VerifierSpec, objectName string, namespace string) error {
verifierConfig, err := specToVerifierConfig(spec)

// add verifier name to verifier config
verifierConfig[types.Name] = objectName
junczhu marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
logrus.Error(err, "unable to convert crd specification to verifier config")
return fmt.Errorf("unable to convert crd specification to verifier config, err: %w", err)
Expand Down Expand Up @@ -139,7 +140,7 @@ func specToVerifierConfig(verifierSpec configv1beta1.VerifierSpec) (vc.VerifierC
}
}

verifierConfig[types.Name] = verifierSpec.Name
verifierConfig[types.SpecName] = verifierSpec.Name
verifierConfig[types.ArtifactTypes] = verifierSpec.ArtifactTypes
if verifierSpec.Source != nil {
verifierConfig[types.Source] = verifierSpec.Source
Expand Down
16 changes: 8 additions & 8 deletions pkg/verifier/factory/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@
// returns a single verifier from a verifierConfig
// namespace is only applicable in K8s environment, namespace is appended to the certstore of the truststore so it is uniquely identifiable in a cluster env
func CreateVerifierFromConfig(verifierConfig config.VerifierConfig, configVersion string, pluginBinDir []string, namespace string) (verifier.ReferenceVerifier, error) {
verifierName, ok := verifierConfig[types.Name]
verifierSpecName, ok := verifierConfig[types.SpecName]
junczhu marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithDetail(fmt.Sprintf("failed to find verifier name in the verifier config with key %s", "name"))
junczhu marked this conversation as resolved.
Show resolved Hide resolved
}

verifierNameStr := fmt.Sprintf("%s", verifierName)
if strings.ContainsRune(verifierNameStr, os.PathSeparator) {
return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithDetail(fmt.Sprintf("invalid plugin name for a verifier: %s", verifierNameStr))
verifierTypeStr := fmt.Sprintf("%s", verifierSpecName)
if strings.ContainsRune(verifierTypeStr, os.PathSeparator) {
return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithDetail(fmt.Sprintf("invalid plugin name for a verifier: %s", verifierTypeStr))

Check warning on line 62 in pkg/verifier/factory/factory.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/factory/factory.go#L62

Added line #L62 was not covered by tests
}

// if source is specified, download the plugin
Expand All @@ -70,18 +70,18 @@
return nil, re.ErrorCodeConfigInvalid.NewError(re.Verifier, "", re.EmptyLink, err, "failed to parse plugin source", re.HideStackTrace)
}

targetPath := path.Join(pluginBinDir[0], verifierNameStr)
targetPath := path.Join(pluginBinDir[0], verifierTypeStr)

Check warning on line 73 in pkg/verifier/factory/factory.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/factory/factory.go#L73

Added line #L73 was not covered by tests
junczhu marked this conversation as resolved.
Show resolved Hide resolved
err = pluginCommon.DownloadPlugin(source, targetPath)
if err != nil {
return nil, re.ErrorCodeDownloadPluginFailure.NewError(re.Verifier, "", re.EmptyLink, err, "failed to download plugin", re.HideStackTrace)
}
logrus.Infof("downloaded verifier plugin %s from %s to %s", verifierNameStr, source.Artifact, targetPath)
logrus.Infof("downloaded verifier plugin type %s from %s to %s", verifierTypeStr, source.Artifact, targetPath)

Check warning on line 78 in pkg/verifier/factory/factory.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/factory/factory.go#L78

Added line #L78 was not covered by tests
} else {
logrus.Warnf("%s was specified for verifier plugin %s, but dynamic plugins are currently disabled", types.Source, verifierNameStr)
logrus.Warnf("%s was specified for verifier plugin type %s, but dynamic plugins are currently disabled", types.Source, verifierTypeStr)

Check warning on line 80 in pkg/verifier/factory/factory.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/factory/factory.go#L80

Added line #L80 was not covered by tests
}
}

verifierFactory, ok := builtInVerifiers[verifierNameStr]
verifierFactory, ok := builtInVerifiers[verifierTypeStr]
if ok {
return verifierFactory.Create(configVersion, verifierConfig, pluginBinDir[0], namespace)
}
Expand Down
16 changes: 9 additions & 7 deletions pkg/verifier/factory/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type TestVerifier struct {
type TestVerifierFactory struct{}

func (s *TestVerifier) Name() string {
return "test-verifier"
return "test-verifier-0"
}

func (s *TestVerifier) CanVerify(_ context.Context, _ ocispecs.ReferenceDescriptor) bool {
Expand Down Expand Up @@ -63,7 +63,8 @@ func TestCreateVerifiersFromConfig_BuiltInVerifiers_ReturnsExpected(t *testing.T
}

verifierConfig := map[string]interface{}{
"name": "test-verifier",
"name": "test-verifier-0",
"specName": "test-verifier",
}
verifiersConfig := config.VerifiersConfig{
Verifiers: []config.VerifierConfig{verifierConfig},
Expand All @@ -79,8 +80,8 @@ func TestCreateVerifiersFromConfig_BuiltInVerifiers_ReturnsExpected(t *testing.T
t.Fatalf("expected to have %d verifiers, actual count %d", 1, len(verifiers))
}

if verifiers[0].Name() != "test-verifier" {
t.Fatalf("expected to create test verifier")
if nameResult := verifiers[0].Name(); nameResult != "test-verifier-0" {
t.Fatalf("expected to create test-verifier-0 for test case but got %v", nameResult)
}

if _, ok := verifiers[0].(*plugin.VerifierPlugin); ok {
Expand All @@ -98,7 +99,8 @@ func TestCreateVerifiersFromConfig_BuiltInVerifiers_ReturnsExpected(t *testing.T

func TestCreateVerifiersFromConfig_PluginVerifiers_ReturnsExpected(t *testing.T) {
verifierConfig := map[string]interface{}{
"name": "plugin-verifier",
"name": "plugin-verifier-0",
"specName": "plugin-verifier",
}
verifiersConfig := config.VerifiersConfig{
Verifiers: []config.VerifierConfig{verifierConfig},
Expand All @@ -114,8 +116,8 @@ func TestCreateVerifiersFromConfig_PluginVerifiers_ReturnsExpected(t *testing.T)
t.Fatalf("expected to have %d verifiers, actual count %d", 1, len(verifiers))
}

if verifiers[0].Name() != "plugin-verifier" {
t.Fatalf("expected to create plugin verifier")
if verifiers[0].Name() != "plugin-verifier-0" {
t.Fatalf("expected to create plugin-verifier-0")
}

if _, ok := verifiers[0].(*plugin.VerifierPlugin); !ok {
Expand Down
21 changes: 14 additions & 7 deletions pkg/verifier/notation/notation.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"github.com/deislabs/ratify/pkg/verifier"
"github.com/deislabs/ratify/pkg/verifier/config"
"github.com/deislabs/ratify/pkg/verifier/factory"
"github.com/deislabs/ratify/pkg/verifier/types"
"github.com/notaryproject/notation-go/log"

_ "github.com/notaryproject/notation-core-go/signature/cose" // register COSE signature
Expand All @@ -45,8 +46,8 @@
)

const (
verifierName = "notation"
defaultCertPath = "ratify-certs/notation/truststore"
verifierSpecName = "notation"
junczhu marked this conversation as resolved.
Show resolved Hide resolved
defaultCertPath = "ratify-certs/notation/truststore"
)

// NotationPluginVerifierConfig describes the configuration of notation verifier
Expand All @@ -63,18 +64,21 @@
}

type notationPluginVerifier struct {
name string
specName string
artifactTypes []string
notationVerifier *notation.Verifier
}

type notationPluginVerifierFactory struct{}

func init() {
factory.Register(verifierName, &notationPluginVerifierFactory{})
factory.Register(verifierSpecName, &notationPluginVerifierFactory{})
}

func (f *notationPluginVerifierFactory) Create(_ string, verifierConfig config.VerifierConfig, pluginDirectory string, namespace string) (verifier.ReferenceVerifier, error) {
logger.GetLogger(context.Background(), logOpt).Debugf("creating notation with config %v, namespace '%v'", verifierConfig, namespace)
verifierName := verifierConfig[types.Name].(string)
conf, err := parseVerifierConfig(verifierConfig, namespace)
if err != nil {
return nil, re.ErrorCodeConfigInvalid.WithComponentType(re.Verifier).WithPluginName(verifierName)
Expand All @@ -87,13 +91,15 @@

artifactTypes := strings.Split(conf.ArtifactTypes, ",")
return &notationPluginVerifier{
name: verifierName,
specName: verifierSpecName,
artifactTypes: artifactTypes,
notationVerifier: &verfiyService,
}, nil
}

func (v *notationPluginVerifier) Name() string {
return verifierName
return v.name
}

func (v *notationPluginVerifier) CanVerify(_ context.Context, referenceDescriptor ocispecs.ReferenceDescriptor) bool {
Expand Down Expand Up @@ -122,7 +128,7 @@
}

if len(referenceManifest.Blobs) == 0 {
return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeSignatureNotFound.NewError(re.Verifier, verifierName, re.EmptyLink, nil, fmt.Sprintf("no signature content found for referrer: %s@%s", subjectReference.Path, referenceDescriptor.Digest.String()), re.HideStackTrace)
return verifier.VerifierResult{IsSuccess: false}, re.ErrorCodeSignatureNotFound.NewError(re.Verifier, v.name, re.EmptyLink, nil, fmt.Sprintf("no signature content found for referrer: %s@%s", subjectReference.Path, referenceDescriptor.Digest.String()), re.HideStackTrace)

Check warning on line 131 in pkg/verifier/notation/notation.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/notation/notation.go#L131

Added line #L131 was not covered by tests
}

for _, blobDesc := range referenceManifest.Blobs {
Expand All @@ -136,7 +142,7 @@
subjectRef := fmt.Sprintf("%s@%s", subjectReference.Path, subjectReference.Digest.String())
outcome, err := v.verifySignature(ctx, subjectRef, blobDesc.MediaType, subjectDesc.Descriptor, refBlob)
if err != nil {
return verifier.VerifierResult{IsSuccess: false, Extensions: extensions}, re.ErrorCodeVerifyPluginFailure.NewError(re.Verifier, verifierName, re.NotationTsgLink, err, "failed to verify signature of digest", re.HideStackTrace)
return verifier.VerifierResult{IsSuccess: false, Extensions: extensions}, re.ErrorCodeVerifyPluginFailure.NewError(re.Verifier, v.name, re.NotationTsgLink, err, "failed to verify signature of digest", re.HideStackTrace)
}

// Note: notation verifier already validates certificate chain is not empty.
Expand All @@ -146,7 +152,7 @@
}

return verifier.VerifierResult{
Name: verifierName,
Name: v.name,
junczhu marked this conversation as resolved.
Show resolved Hide resolved
IsSuccess: true,
Message: "signature verification success",
Extensions: extensions,
Expand All @@ -173,6 +179,7 @@
}

func parseVerifierConfig(verifierConfig config.VerifierConfig, namespace string) (*NotationPluginVerifierConfig, error) {
verifierName := verifierConfig[types.Name].(string)
conf := &NotationPluginVerifierConfig{}

verifierConfigBytes, err := json.Marshal(verifierConfig)
Expand Down
22 changes: 16 additions & 6 deletions pkg/verifier/notation/notation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,19 @@ func (s mockStore) GetSubjectDescriptor(_ context.Context, _ common.Reference) (
}

func TestName(t *testing.T) {
v := &notationPluginVerifier{}
name := v.Name()
verifierConfig := map[string]interface{}{
"name": "notation-verifier-0",
"specName": "notation",
"trustPolicyDoc": testTrustPolicy,
}

if name != "notation" {
t.Fatalf("expect name: notation, got: %s", name)
f := &notationPluginVerifierFactory{}
verifier, err := f.Create(testVersion, verifierConfig, "", "")
if err != nil {
t.Fatalf("failed create notation verifier got error = %v", err)
}
if name := verifier.Name(); name != "notation-verifier-0" {
t.Fatalf("expect name: notation-verifier-0, got: %s", name)
}
}

Expand Down Expand Up @@ -192,7 +200,8 @@ func TestParseVerifierConfig(t *testing.T) {
{
name: "failed unmarshalling to notation config",
configMap: map[string]interface{}{
"name": []string{test},
"name": test,
"verificationCerts": test,
},
expectErr: true,
expect: nil,
Expand Down Expand Up @@ -281,7 +290,8 @@ func TestCreate(t *testing.T) {
{
name: "failed parsing verifier config",
configMap: map[string]interface{}{
"name": []string{test},
"name": test,
"trustPolicyDoc": 1,
},
expectErr: true,
},
Expand Down
9 changes: 8 additions & 1 deletion pkg/verifier/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
// VerifierPlugin describes a verifier that is implemented by invoking the plugins
type VerifierPlugin struct {
name string
specName string
artifactTypes []string
nestedReferences []string
version string
Expand All @@ -51,6 +52,11 @@
return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("failed to find verifier name in the verifier config with key: %s", types.Name))
}

verifierSpecName, ok := verifierConfig[types.SpecName]
if !ok {
return nil, re.ErrorCodeConfigInvalid.WithDetail(fmt.Sprintf("failed to find verifier spec name in the verifier config with key: %s", types.SpecName))
}

Check warning on line 58 in pkg/verifier/plugin/plugin.go

View check run for this annotation

Codecov / codecov/patch

pkg/verifier/plugin/plugin.go#L57-L58

Added lines #L57 - L58 were not covered by tests

var nestedReferences []string
if vs, ok := verifierConfig[types.NestedReferences]; ok {
nestedReferences = strings.Split(fmt.Sprintf("%s", vs), ",")
Expand All @@ -67,6 +73,7 @@

return &VerifierPlugin{
name: fmt.Sprintf("%s", verifierName),
specName: fmt.Sprintf("%s", verifierSpecName),
version: version,
path: pluginPaths,
rawConfig: verifierConfig,
Expand Down Expand Up @@ -107,7 +114,7 @@
subjectReference common.Reference,
referenceDescriptor ocispecs.ReferenceDescriptor,
referrerStoreConfig *rc.StoreConfig) (*verifier.VerifierResult, error) {
pluginPath, err := vp.executor.FindInPaths(vp.name, vp.path)
pluginPath, err := vp.executor.FindInPaths(vp.specName, vp.path)
if err != nil {
return nil, re.ErrorCodePluginNotFound.NewError(re.Verifier, vp.name, re.EmptyLink, err, nil, re.HideStackTrace)
}
Expand Down
1 change: 1 addition & 0 deletions pkg/verifier/plugin/plugin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func (e *TestExecutor) FindInPaths(plugin string, paths []string) (string, error
func TestNewVerifier_Expected(t *testing.T) {
verifierConfig := map[string]interface{}{
"name": "test-verifier",
"specName": "test-verifier",
"artifactTypes": "test1,test2",
"nestedReferences": "ref1,ref2",
}
Expand Down
1 change: 1 addition & 0 deletions pkg/verifier/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
SpecVersion string = "0.1.0"
Version string = "version"
Name string = "name"
SpecName string = "specName"
junczhu marked this conversation as resolved.
Show resolved Hide resolved
ArtifactTypes string = "artifactTypes"
NestedReferences string = "nestedReferences"
Source string = "source"
Expand Down
Loading