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

chore: start using plugin-framework package #372

Merged
merged 14 commits into from
Feb 1, 2024
Merged
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.20
require (
github.com/go-ldap/ldap/v3 v3.4.6
github.com/notaryproject/notation-core-go v1.0.2
github.com/notaryproject/notation-plugin-framework-go v1.0.0
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0-rc5
github.com/veraison/go-cose v1.1.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/notaryproject/notation-core-go v1.0.2 h1:VEt+mbsgdANd9b4jqgmx2C7U0DmwynOuD2Nhxh3bANw=
github.com/notaryproject/notation-core-go v1.0.2/go.mod h1:2HkQzUwg08B3x9oVIztHsEh7Vil2Rj+tYgxH+JObLX4=
github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4=
github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
Expand Down
21 changes: 10 additions & 11 deletions internal/mock/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import (
_ "embed"

"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation-go/plugin"
"github.com/notaryproject/notation-go/plugin/proto"
"github.com/notaryproject/notation-plugin-framework-go/plugin"
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
Expand Down Expand Up @@ -168,36 +167,36 @@ func (t Repository) PushSignature(ctx context.Context, mediaType string, blob []
}

type PluginMock struct {
Metadata proto.GetMetadataResponse
Metadata plugin.GetMetadataResponse
ExecuteResponse interface{}
ExecuteError error
}

func (p *PluginMock) GetMetadata(ctx context.Context, req *proto.GetMetadataRequest) (*proto.GetMetadataResponse, error) {
func (p *PluginMock) GetMetadata(ctx context.Context, req *plugin.GetMetadataRequest) (*plugin.GetMetadataResponse, error) {
return &p.Metadata, nil
}

func (p *PluginMock) VerifySignature(ctx context.Context, req *proto.VerifySignatureRequest) (*proto.VerifySignatureResponse, error) {
if resp, ok := p.ExecuteResponse.(*proto.VerifySignatureResponse); ok {
func (p *PluginMock) VerifySignature(ctx context.Context, req *plugin.VerifySignatureRequest) (*plugin.VerifySignatureResponse, error) {
if resp, ok := p.ExecuteResponse.(*plugin.VerifySignatureResponse); ok {
return resp, nil
}
return nil, p.ExecuteError
}

func (p *PluginMock) DescribeKey(ctx context.Context, req *proto.DescribeKeyRequest) (*proto.DescribeKeyResponse, error) {
func (p *PluginMock) DescribeKey(ctx context.Context, req *plugin.DescribeKeyRequest) (*plugin.DescribeKeyResponse, error) {
panic("not implemented") // TODO: Implement
}

func (p *PluginMock) GenerateSignature(ctx context.Context, req *proto.GenerateSignatureRequest) (*proto.GenerateSignatureResponse, error) {
func (p *PluginMock) GenerateSignature(ctx context.Context, req *plugin.GenerateSignatureRequest) (*plugin.GenerateSignatureResponse, error) {
panic("not implemented") // TODO: Implement
}

func (p *PluginMock) GenerateEnvelope(ctx context.Context, req *proto.GenerateEnvelopeRequest) (*proto.GenerateEnvelopeResponse, error) {
func (p *PluginMock) GenerateEnvelope(ctx context.Context, req *plugin.GenerateEnvelopeRequest) (*plugin.GenerateEnvelopeResponse, error) {
panic("not implemented") // TODO: Implement
}

type PluginManager struct {
PluginCapabilities []proto.Capability
PluginCapabilities []plugin.Capability
GetPluginError error
PluginRunnerLoadError error
PluginRunnerExecuteResponse interface{}
Expand All @@ -206,7 +205,7 @@ type PluginManager struct {

func (pm PluginManager) Get(ctx context.Context, name string) (plugin.Plugin, error) {
return &PluginMock{
Metadata: proto.GetMetadataResponse{
Metadata: plugin.GetMetadataResponse{
Name: "plugin-name",
Description: "for mocking in unit tests",
Version: "1.0.0",
Expand Down
10 changes: 5 additions & 5 deletions plugin/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,16 @@ import (
"testing"

"github.com/notaryproject/notation-go/dir"
"github.com/notaryproject/notation-go/plugin/proto"
"github.com/notaryproject/notation-plugin-framework-go/plugin"
)

var exampleMetadata = proto.GetMetadataResponse{
var exampleMetadata = plugin.GetMetadataResponse{
Name: "foo",
Description: "friendly",
Version: "1",
URL: "example.com",
SupportedContractVersions: []string{"1.0"},
Capabilities: []proto.Capability{"cap"}}
Capabilities: []plugin.Capability{"cap"}}

func preparePlugin(t *testing.T) string {
root := t.TempDir()
Expand Down Expand Up @@ -87,11 +87,11 @@ func TestIntegration(t *testing.T) {
}

// validate and create
plugin, err := mgr.Get(context.Background(), "foo")
pl, err := mgr.Get(context.Background(), "foo")
if err != nil {
t.Fatal(err)
}
metadata, err := plugin.GetMetadata(context.Background(), &proto.GetMetadataRequest{})
metadata, err := pl.GetMetadata(context.Background(), &plugin.GetMetadataRequest{})
priteshbandi marked this conversation as resolved.
Show resolved Hide resolved
if err != nil {
t.Fatal(err)
}
Expand Down
14 changes: 7 additions & 7 deletions plugin/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ import (
"github.com/notaryproject/notation-go/internal/file"
"github.com/notaryproject/notation-go/internal/semver"
"github.com/notaryproject/notation-go/log"
"github.com/notaryproject/notation-go/plugin/proto"
"github.com/notaryproject/notation-plugin-framework-go/plugin"
)

// Manager manages plugins installed on the system.
type Manager interface {
Get(ctx context.Context, name string) (Plugin, error)
Get(ctx context.Context, name string) (plugin.Plugin, error)
List(ctx context.Context) ([]string, error)
}

Expand All @@ -48,7 +48,7 @@ func NewCLIManager(pluginFS dir.SysFS) *CLIManager {
// Get returns a plugin on the system by its name.
//
// If the plugin is not found, the error is of type os.ErrNotExist.
func (m *CLIManager) Get(ctx context.Context, name string) (Plugin, error) {
func (m *CLIManager) Get(ctx context.Context, name string) (plugin.Plugin, error) {
pluginPath := path.Join(name, binName(name))
path, err := m.pluginFS.SysPath(pluginPath)
if err != nil {
Expand Down Expand Up @@ -118,7 +118,7 @@ type CLIInstallOptions struct {
//
// If overwrite is set, version check is skipped. If existing
// plugin is malfunctioning, it will be overwritten.
func (m *CLIManager) Install(ctx context.Context, installOpts CLIInstallOptions) (*proto.GetMetadataResponse, *proto.GetMetadataResponse, error) {
func (m *CLIManager) Install(ctx context.Context, installOpts CLIInstallOptions) (*plugin.GetMetadataResponse, *plugin.GetMetadataResponse, error) {
// initialization
logger := log.GetLogger(ctx)
overwrite := installOpts.Overwrite
Expand Down Expand Up @@ -153,20 +153,20 @@ func (m *CLIManager) Install(ctx context.Context, installOpts CLIInstallOptions)
if err != nil {
return nil, nil, err
}
newPluginMetadata, err := newPlugin.GetMetadata(ctx, &proto.GetMetadataRequest{})
newPluginMetadata, err := newPlugin.GetMetadata(ctx, &plugin.GetMetadataRequest{})
if err != nil {
return nil, nil, fmt.Errorf("failed to get metadata of new plugin: %w", err)
}
// check plugin existence and get existing plugin metadata
var existingPluginMetadata *proto.GetMetadataResponse
var existingPluginMetadata *plugin.GetMetadataResponse
existingPlugin, err := m.Get(ctx, pluginName)
if err != nil {
// fail only if overwrite is not set
if !errors.Is(err, os.ErrNotExist) && !overwrite {
return nil, nil, fmt.Errorf("failed to check plugin existence: %w", err)
}
} else { // plugin already exists
existingPluginMetadata, err = existingPlugin.GetMetadata(ctx, &proto.GetMetadataRequest{})
existingPluginMetadata, err = existingPlugin.GetMetadata(ctx, &plugin.GetMetadataRequest{})
if err != nil && !overwrite { // fail only if overwrite is not set
return nil, nil, fmt.Errorf("failed to get metadata of existing plugin: %w", err)
}
Expand Down
77 changes: 31 additions & 46 deletions plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package plugin provides the toolings to use the notation plugin.
// Package plugin provides the tooling to use the notation plugin.
//
// includes a CLIManager and a CLIPlugin implementation.
package plugin
Expand All @@ -30,44 +30,30 @@ import (
"github.com/notaryproject/notation-go/internal/slices"
"github.com/notaryproject/notation-go/log"
"github.com/notaryproject/notation-go/plugin/proto"
"github.com/notaryproject/notation-plugin-framework-go/plugin"
)

var executor commander = &execCommander{} // for unit test

// GenericPlugin is the base requirement to be an plugin.
type GenericPlugin interface {
priteshbandi marked this conversation as resolved.
Show resolved Hide resolved
// GetMetadata returns the metadata information of the plugin.
GetMetadata(ctx context.Context, req *proto.GetMetadataRequest) (*proto.GetMetadataResponse, error)
}
// GenericPlugin is the base requirement to be a plugin.
// Deprecated: GenericPlugin exists for historical compatibility and should not be used.
// To access GenericPlugin, use the notation-plugin-framework-go's plugin.GenericPlugin type.
type GenericPlugin = plugin.GenericPlugin

// SignPlugin defines the required methods to be a SignPlugin.
type SignPlugin interface {
GenericPlugin

// DescribeKey returns the KeySpec of a key.
DescribeKey(ctx context.Context, req *proto.DescribeKeyRequest) (*proto.DescribeKeyResponse, error)

// GenerateSignature generates the raw signature based on the request.
GenerateSignature(ctx context.Context, req *proto.GenerateSignatureRequest) (*proto.GenerateSignatureResponse, error)

// GenerateEnvelope generates the Envelope with signature based on the
// request.
GenerateEnvelope(ctx context.Context, req *proto.GenerateEnvelopeRequest) (*proto.GenerateEnvelopeResponse, error)
}
// Deprecated: SignPlugin exists for historical compatibility and should not be used.
// To access SignPlugin, use the notation-plugin-framework-go's plugin.SignPlugin type.
type SignPlugin = plugin.SignPlugin

// VerifyPlugin defines the required method to be a VerifyPlugin.
type VerifyPlugin interface {
GenericPlugin
// Deprecated: VerifyPlugin exists for historical compatibility and should not be used.
// To access VerifyPlugin, use the notation-plugin-framework-go's plugin.VerifyPlugin type.
type VerifyPlugin = plugin.VerifyPlugin

// VerifySignature validates the signature based on the request.
VerifySignature(ctx context.Context, req *proto.VerifySignatureRequest) (*proto.VerifySignatureResponse, error)
}

// Plugin defines required methods to be an Plugin.
type Plugin interface {
SignPlugin
VerifyPlugin
}
// Plugin defines required methods to be a Plugin.
// Deprecated: Plugin exists for historical compatibility and should not be used.
// To access Plugin, use the notation-plugin-framework-go's plugin.Plugin type.
type Plugin = plugin.Plugin

// CLIPlugin implements Plugin interface to CLI plugins.
type CLIPlugin struct {
Expand All @@ -90,16 +76,15 @@ func NewCLIPlugin(ctx context.Context, name, path string) (*CLIPlugin, error) {
}

// generate plugin
plugin := CLIPlugin{
return &CLIPlugin{
name: name,
path: path,
}
return &plugin, nil
}, nil
}

// GetMetadata returns the metadata information of the plugin.
func (p *CLIPlugin) GetMetadata(ctx context.Context, req *proto.GetMetadataRequest) (*proto.GetMetadataResponse, error) {
var metadata proto.GetMetadataResponse
func (p *CLIPlugin) GetMetadata(ctx context.Context, req *plugin.GetMetadataRequest) (*plugin.GetMetadataResponse, error) {
var metadata plugin.GetMetadataResponse
err := run(ctx, p.name, p.path, req, &metadata)
if err != nil {
return nil, err
Expand All @@ -120,56 +105,56 @@ func (p *CLIPlugin) GetMetadata(ctx context.Context, req *proto.GetMetadataReque
// DescribeKey returns the KeySpec of a key.
//
// if ContractVersion is not set, it will be set by the function.
func (p *CLIPlugin) DescribeKey(ctx context.Context, req *proto.DescribeKeyRequest) (*proto.DescribeKeyResponse, error) {
func (p *CLIPlugin) DescribeKey(ctx context.Context, req *plugin.DescribeKeyRequest) (*plugin.DescribeKeyResponse, error) {
if req.ContractVersion == "" {
req.ContractVersion = proto.ContractVersion
priteshbandi marked this conversation as resolved.
Show resolved Hide resolved
}

var resp proto.DescribeKeyResponse
var resp plugin.DescribeKeyResponse
err := run(ctx, p.name, p.path, req, &resp)
return &resp, err
}

// GenerateSignature generates the raw signature based on the request.
//
// if ContractVersion is not set, it will be set by the function.
func (p *CLIPlugin) GenerateSignature(ctx context.Context, req *proto.GenerateSignatureRequest) (*proto.GenerateSignatureResponse, error) {
func (p *CLIPlugin) GenerateSignature(ctx context.Context, req *plugin.GenerateSignatureRequest) (*plugin.GenerateSignatureResponse, error) {
if req.ContractVersion == "" {
req.ContractVersion = proto.ContractVersion
}

var resp proto.GenerateSignatureResponse
var resp plugin.GenerateSignatureResponse
err := run(ctx, p.name, p.path, req, &resp)
return &resp, err
}

// GenerateEnvelope generates the Envelope with signature based on the request.
//
// if ContractVersion is not set, it will be set by the function.
func (p *CLIPlugin) GenerateEnvelope(ctx context.Context, req *proto.GenerateEnvelopeRequest) (*proto.GenerateEnvelopeResponse, error) {
func (p *CLIPlugin) GenerateEnvelope(ctx context.Context, req *plugin.GenerateEnvelopeRequest) (*plugin.GenerateEnvelopeResponse, error) {
if req.ContractVersion == "" {
req.ContractVersion = proto.ContractVersion
}

var resp proto.GenerateEnvelopeResponse
var resp plugin.GenerateEnvelopeResponse
err := run(ctx, p.name, p.path, req, &resp)
return &resp, err
}

// VerifySignature validates the signature based on the request.
//
// if ContractVersion is not set, it will be set by the function.
func (p *CLIPlugin) VerifySignature(ctx context.Context, req *proto.VerifySignatureRequest) (*proto.VerifySignatureResponse, error) {
func (p *CLIPlugin) VerifySignature(ctx context.Context, req *plugin.VerifySignatureRequest) (*plugin.VerifySignatureResponse, error) {
if req.ContractVersion == "" {
req.ContractVersion = proto.ContractVersion
}

var resp proto.VerifySignatureResponse
var resp plugin.VerifySignatureResponse
err := run(ctx, p.name, p.path, req, &resp)
return &resp, err
}

func run(ctx context.Context, pluginName string, pluginPath string, req proto.Request, resp interface{}) error {
func run(ctx context.Context, pluginName string, pluginPath string, req plugin.Request, resp interface{}) error {
logger := log.GetLogger(ctx)

// serialize request
Expand Down Expand Up @@ -219,7 +204,7 @@ func run(ctx context.Context, pluginName string, pluginPath string, req proto.Re

// commander is defined for mocking purposes.
type commander interface {
// Output runs the command, passing req to the its stdin.
// Output runs the command, passing req to the stdin.
// It only returns an error if the binary can't be executed.
// Returns stdout if err is nil, stderr if err is not nil.
Output(ctx context.Context, path string, command proto.Command, req []byte) (stdout []byte, stderr []byte, err error)
Expand All @@ -242,7 +227,7 @@ func (c execCommander) Output(ctx context.Context, name string, command proto.Co
}

// validate checks if the metadata is correctly populated.
func validate(metadata *proto.GetMetadataResponse) error {
func validate(metadata *plugin.GetMetadataResponse) error {
if metadata.Name == "" {
return errors.New("empty name")
}
Expand Down
Loading
Loading