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

Remove log from signer impl and add it to options #44

Merged
merged 1 commit into from
Feb 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 5 additions & 7 deletions sign/impl.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ import (
"sigs.k8s.io/release-utils/util"
)

type defaultImpl struct {
log *logrus.Logger
}
type defaultImpl struct{}

//go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 -generate
//counterfeiter:generate . impl
Expand All @@ -50,7 +48,7 @@ type impl interface {
recursive bool, attachment string) error
Setenv(string, string) error
EnvDefault(string, string) string
TokenFromProviders(context.Context) (string, error)
TokenFromProviders(context.Context, *logrus.Logger) (string, error)
FileExists(string) bool
}

Expand Down Expand Up @@ -112,9 +110,9 @@ func (*defaultImpl) IsImageSignedInternal(

// TokenFromProviders will try the cosign OIDC providers to get an
// oidc token from them.
func (di *defaultImpl) TokenFromProviders(ctx context.Context) (string, error) {
if !di.IdentityProvidersEnabled(ctx) {
di.log.Warn("No OIDC provider enabled. Token cannot be obtained autmatically.")
func (d *defaultImpl) TokenFromProviders(ctx context.Context, logger *logrus.Logger) (string, error) {
if !d.IdentityProvidersEnabled(ctx) {
logger.Warn("No OIDC provider enabled. Token cannot be obtained autmatically.")
return "", nil
}

Expand Down
3 changes: 1 addition & 2 deletions sign/impl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"os"
"testing"

"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -60,7 +59,7 @@ func TestFileExists(t *testing.T) {
require.NoError(t, err)
defer os.Remove(f.Name())
require.NoError(t, os.WriteFile(f.Name(), []byte("hey"), os.FileMode(0o644)))
sut := &defaultImpl{log: logrus.New()}
sut := &defaultImpl{}
require.True(t, sut.FileExists(f.Name()))
require.False(t, sut.FileExists(f.Name()+"a"))
}
14 changes: 11 additions & 3 deletions sign/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package sign

import (
"context"
"errors"
"time"

Expand All @@ -27,6 +28,9 @@ import (

// Options can be used to modify the behavior of the signer.
type Options struct {
// Logger is the custom logger to be used for message printing.
Logger *logrus.Logger

// Verbose can be used to enable a higher log verbosity
Verbose bool

Expand Down Expand Up @@ -58,6 +62,7 @@ type Options struct {
// Default returns a default Options instance.
func Default() *Options {
return &Options{
Logger: logrus.StandardLogger(),
Timeout: 3 * time.Minute,
PassFunc: generate.GetPass,
EnableTokenProviders: true,
Expand All @@ -75,11 +80,14 @@ func (o *Options) verifySignOptions() error {
}

// Ensure that the private key file exists
i := defaultImpl{
log: logrus.New(),
}
i := defaultImpl{}
if o.PrivateKeyPath != "" && !i.FileExists(o.PrivateKeyPath) {
return errors.New("specified private key file not found")
}
return nil
}

// context creates a new context with the timeout set within the options.
func (o *Options) context() (context.Context, context.CancelFunc) {
return context.WithTimeout(context.Background(), o.Timeout)
}
50 changes: 27 additions & 23 deletions sign/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,24 +31,22 @@ import (
type Signer struct {
impl impl
options *Options
log *logrus.Logger
}

// New returns a new Signer instance.
func New(options *Options) *Signer {
logger := logrus.New()
if options.Logger == nil {
options.Logger = logrus.New()
}

if options.Verbose {
logs.Debug.SetOutput(os.Stderr)
logger.SetLevel(logrus.DebugLevel)
options.Logger.SetLevel(logrus.DebugLevel)
}

return &Signer{
impl: &defaultImpl{
log: logger,
},
impl: &defaultImpl{},
options: options,
log: logger,
}
}

Expand All @@ -58,8 +56,13 @@ func (s *Signer) SetImpl(impl impl) {
s.impl = impl
}

// log returns the internally set logger.
func (s *Signer) log() *logrus.Logger {
return s.options.Logger
}

func (s *Signer) UploadBlob(path string) error {
s.log.Infof("Uploading blob: %s", path)
s.log().Infof("Uploading blob: %s", path)

// TODO: unimplemented

Expand All @@ -69,7 +72,7 @@ func (s *Signer) UploadBlob(path string) error {
// SignImage can be used to sign any provided container image reference by
// using keyless signing.
func (s *Signer) SignImage(reference string) (*SignedObject, error) {
s.log.Infof("Signing reference: %s", reference)
s.log().Infof("Signing reference: %s", reference)

// Ensure options to sign are correct
if err := s.options.verifySignOptions(); err != nil {
Expand All @@ -82,12 +85,15 @@ func (s *Signer) SignImage(reference string) (*SignedObject, error) {
}
defer resetFn()

ctx, cancel := s.options.context()
defer cancel()

// If we don't have a key path, we must ensure we can get an OIDC
// token or there is no way to sign. Depending on the options set,
// we may get the ID token from the cosign providers
identityToken := ""
if s.options.PrivateKeyPath == "" {
tok, err := s.identityToken()
tok, err := s.identityToken(ctx)
if err != nil {
return nil, errors.Wrap(err, "getting identity token for keyless signing")
}
Expand Down Expand Up @@ -126,9 +132,6 @@ func (s *Signer) SignImage(reference string) (*SignedObject, error) {
outputCertificate = s.options.OutputCertificatePath
}

ctx, cancel := context.WithTimeout(context.Background(), s.options.Timeout)
defer cancel()

if err := s.impl.SignImageInternal(ctx, ko, regOpts,
s.options.Annotations, images, "", true, outputSignature,
outputCertificate, "", true, false, "",
Expand All @@ -147,7 +150,7 @@ func (s *Signer) SignImage(reference string) (*SignedObject, error) {
// SignFile can be used to sign any provided file path by using keyless
// signing.
func (s *Signer) SignFile(path string) (*SignedObject, error) {
s.log.Infof("Signing file path: %s", path)
s.log().Infof("Signing file path: %s", path)

// TODO: unimplemented

Expand All @@ -161,16 +164,17 @@ func (s *Signer) SignFile(path string) (*SignedObject, error) {
// VerifyImage can be used to validate any provided container image reference by
// using keyless signing.
func (s *Signer) VerifyImage(reference string) (*SignedObject, error) {
s.log.Infof("Verifying reference: %s", reference)
s.log().Infof("Verifying reference: %s", reference)

resetFn, err := s.enableExperimental()
if err != nil {
return nil, err
}
defer resetFn()

ctx, cancel := context.WithTimeout(context.Background(), s.options.Timeout)
ctx, cancel := s.options.context()
defer cancel()

images := []string{reference}
object, err := s.impl.VerifyImageInternal(ctx, s.options.PublicKeyPath, images)
if err != nil {
Expand All @@ -181,7 +185,7 @@ func (s *Signer) VerifyImage(reference string) (*SignedObject, error) {

// VerifyFile can be used to validate any provided file path.
func (s *Signer) VerifyFile(path string) (*SignedObject, error) {
s.log.Infof("Verifying file path: %s", path)
s.log().Infof("Verifying file path: %s", path)

// TODO: unimplemented

Expand All @@ -198,7 +202,7 @@ func (s *Signer) enableExperimental() (resetFn func(), err error) {
}
return func() {
if err := s.impl.Setenv(key, previousValue); err != nil {
s.log.Errorf("Unable to reset cosign experimental mode: %v", err)
s.log().Errorf("Unable to reset cosign experimental mode: %v", err)
}
}, nil
}
Expand All @@ -207,7 +211,7 @@ func (s *Signer) enableExperimental() (resetFn func(), err error) {
// signatures available for it. It makes no signature verification, only
// checks to see if more than one signature is available.
func (s *Signer) IsImageSigned(imageRef string) (bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), s.options.Timeout)
ctx, cancel := s.options.context()
defer cancel()

return s.impl.IsImageSignedInternal(ctx, imageRef)
Expand All @@ -217,17 +221,17 @@ func (s *Signer) IsImageSigned(imageRef string) (bool, error) {
// If there is one set in the options we will use that one. If not,
// signer will try to get one from the cosign OIDC identity providers
// if options.EnableTokenProviders is set
func (s *Signer) identityToken() (string, error) {
func (s *Signer) identityToken(ctx context.Context) (string, error) {
tok := s.options.IdentityToken
if s.options.PrivateKeyPath == "" && s.options.IdentityToken == "" {
// We only attempt to pull from the providers if the option is set
if !s.options.EnableTokenProviders {
logrus.Warn("No token set in options and OIDC providers are disabled")
s.log().Warn("No token set in options and OIDC providers are disabled")
return "", nil
}

logrus.Info("No identity token was provided. Attempting to get one from supported providers.")
token, err := s.impl.TokenFromProviders(context.Background())
s.log().Info("No identity token was provided. Attempting to get one from supported providers.")
token, err := s.impl.TokenFromProviders(ctx, s.log())
if err != nil {
return "", errors.Wrap(err, "getting identity token from providers")
}
Expand Down
19 changes: 11 additions & 8 deletions sign/signfakes/fake_impl.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.