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: blob inspect command #1133

Merged
merged 16 commits into from
Feb 16, 2025
1 change: 1 addition & 0 deletions cmd/notation/blob/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func Cmd() *cobra.Command {
signCommand(nil),
verifyCommand(nil),
policy.Cmd(),
inspectCommand(),
)
return command
}
90 changes: 90 additions & 0 deletions cmd/notation/blob/inspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright The Notary Project Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package blob

import (
"errors"
"fmt"
"os"

"github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation/cmd/notation/internal/display"
"github.com/notaryproject/notation/cmd/notation/internal/option"
"github.com/spf13/cobra"
)

type inspectOpts struct {
option.Common
option.Format
sigPath string
}

func inspectCommand() *cobra.Command {
opts := &inspectOpts{}
command := &cobra.Command{
Use: "inspect [flags] <signature_path>",
Short: "Inspect a signature associated with a blob",
Long: `Inspect a signature associated with a blob.

Example - Inspect a signature:
notation blob inspect blob.cose.sig

Example - Inspect a signature and output as JSON:
notation blob inspect -o json blob.cose.sig
`,
Args: func(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("missing signature path: use `notation blob inspect --help` to see what parameters are required")
}
opts.sigPath = args[0]
return nil
},
PreRun: func(cmd *cobra.Command, args []string) {
opts.Common.Parse(cmd)
},
RunE: func(cmd *cobra.Command, args []string) error {
return runInspect(opts)
},
}

opts.Format.ApplyFlags(command.Flags(), option.FormatTypeText, option.FormatTypeJSON)
return command
}

func runInspect(opts *inspectOpts) error {
// initialize display handler
displayHandler, err := display.NewBlobInspectHandler(opts.Printer, opts.Format)
if err != nil {
return err
}

// parse signature file
signatureMediaType, err := parseSignatureMediaType(opts.sigPath)
if err != nil {
return err
}
envelopeBytes, err := os.ReadFile(opts.sigPath)
if err != nil {
return fmt.Errorf("failed to read signature file: %w", err)
}
envelope, err := signature.ParseEnvelope(signatureMediaType, envelopeBytes)
if err != nil {
return fmt.Errorf("failed to parse signature: %w", err)
}
if err := displayHandler.OnEnvelopeParsed(opts.sigPath, signatureMediaType, envelope); err != nil {
return err
}

Check warning on line 87 in cmd/notation/blob/inspect.go

View check run for this annotation

Codecov / codecov/patch

cmd/notation/blob/inspect.go#L86-L87

Added lines #L86 - L87 were not covered by tests

return displayHandler.Render()
}
6 changes: 3 additions & 3 deletions cmd/notation/inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func runInspect(command *cobra.Command, opts *inspectOpts) error {
// set log level
ctx := opts.LoggingFlagOpts.InitializeLogger(command.Context())

displayHandler, err := display.NewInpsectHandler(opts.Printer, opts.Format)
displayHandler, err := display.NewInspectHandler(opts.Printer, opts.Format)
if err != nil {
return err
}
Expand Down Expand Up @@ -124,14 +124,14 @@ func runInspect(command *cobra.Command, opts *inspectOpts) error {
return nil
}

sigEnvelope, err := signature.ParseEnvelope(sigDesc.MediaType, sigBlob)
envelope, err := signature.ParseEnvelope(sigDesc.MediaType, sigBlob)
if err != nil {
logSkippedSignature(sigManifestDesc, err)
skippedSignatures = true
return nil
}

if err := displayHandler.InspectSignature(sigManifestDesc, sigEnvelope); err != nil {
if err := displayHandler.InspectSignature(sigManifestDesc, sigDesc, envelope); err != nil {
logSkippedSignature(sigManifestDesc, err)
skippedSignatures = true
return nil
Expand Down
16 changes: 14 additions & 2 deletions cmd/notation/internal/display/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ import (
"github.com/notaryproject/notation/cmd/notation/internal/option"
)

// NewInpsectHandler creates a new metadata InspectHandler based on the output
// NewInspectHandler creates a new metadata InspectHandler based on the output
// format.
func NewInpsectHandler(printer *output.Printer, format option.Format) (metadata.InspectHandler, error) {
func NewInspectHandler(printer *output.Printer, format option.Format) (metadata.InspectHandler, error) {
switch option.FormatType(format.CurrentType) {
case option.FormatTypeJSON:
return json.NewInspectHandler(printer), nil
Expand All @@ -42,6 +42,18 @@ func NewInpsectHandler(printer *output.Printer, format option.Format) (metadata.
return nil, fmt.Errorf("unrecognized output format %s", format.CurrentType)
}

// NewBlobInspectHandler creates a new metadata BlobInspectHandler based on the
// output format.
func NewBlobInspectHandler(printer *output.Printer, format option.Format) (metadata.BlobInspectHandler, error) {
switch option.FormatType(format.CurrentType) {
case option.FormatTypeJSON:
return json.NewBlobInspectHandler(printer), nil
case option.FormatTypeText:
return tree.NewBlobInspectHandler(printer), nil
}
return nil, fmt.Errorf("unrecognized output format %s", format.CurrentType)
}

// NewVerifyHandler creates a new metadata VerifyHandler for printing
// verification result and warnings.
func NewVerifyHandler(printer *output.Printer) metadata.VerifyHandler {
Expand Down
11 changes: 10 additions & 1 deletion cmd/notation/internal/display/metadata/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,16 @@ type InspectHandler interface {
OnReferenceResolved(reference, mediaType string)

// InspectSignature inspects a signature to get it ready to be rendered.
InspectSignature(manifestDesc ocispec.Descriptor, envelope signature.Envelope) error
InspectSignature(manifestDesc, signatureDesc ocispec.Descriptor, envelope signature.Envelope) error
}

// BlobInspectHandler is a handler for rendering metadata information of a blob
// signature.
type BlobInspectHandler interface {
Renderer

// OnEnvelopeParsed sets the parsed envelope for the handler.
OnEnvelopeParsed(signaturePath, signatureMediaType string, envelope signature.Envelope) error
}

// VerifyHandler is a handler for rendering metadata information of
Expand Down
51 changes: 51 additions & 0 deletions cmd/notation/internal/display/metadata/json/blob_inspect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright The Notary Project Authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package json

import (
coresignature "github.com/notaryproject/notation-core-go/signature"
"github.com/notaryproject/notation/cmd/notation/internal/display/output"
)

// BlobInspectHandler is a handler for inspecting metadata information and
// rendering it in JSON format. It implements the metadata.BlobInspectHandler
// interface.
type BlobInspectHandler struct {
printer *output.Printer
signature *signature
}

// NewBlobInspectHandler creates a BlobInspectHandler to inspect signature and
// print in JSON format.
func NewBlobInspectHandler(printer *output.Printer) *BlobInspectHandler {
return &BlobInspectHandler{
printer: printer,
}
}

// OnEnvelopeParsed sets the parsed envelope for the handler.
func (h *BlobInspectHandler) OnEnvelopeParsed(nodeName, signatureMediaType string, envelope coresignature.Envelope) error {
// blob signature does not have a digest
sig, err := newSignature("", signatureMediaType, envelope)
if err != nil {
return err
}

Check warning on line 43 in cmd/notation/internal/display/metadata/json/blob_inspect.go

View check run for this annotation

Codecov / codecov/patch

cmd/notation/internal/display/metadata/json/blob_inspect.go#L42-L43

Added lines #L42 - L43 were not covered by tests
h.signature = sig
return nil
}

// Render prints out the metadata information in JSON format.
func (h *BlobInspectHandler) Render() error {
return output.PrintPrettyJSON(h.printer, h.signature)
}
Loading
Loading