fix linter issues

This commit is contained in:
Simon Aronsson 2020-11-15 23:48:43 +01:00
parent 6b9fd8d7ef
commit a32468d1fe
No known key found for this signature in database
GPG key ID: 8DA57A5FD341605B
9 changed files with 64 additions and 61 deletions

View file

@ -5,29 +5,32 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
const ContextKey = "LogrusLoggerContext" type contextKeyType string
const contextKey = contextKeyType("LogrusLoggerContext")
// GetLogger returns a logger from the context if one is available, otherwise a default logger // GetLogger returns a logger from the context if one is available, otherwise a default logger
func GetLogger(ctx context.Context) *logrus.Logger { func GetLogger(ctx context.Context) *logrus.Logger {
if logger, ok := ctx.Value(ContextKey).(logrus.Logger); ok { if logger, ok := ctx.Value(contextKey).(logrus.Logger); ok {
return &logger return &logger
} else {
return newLogger(&logrus.JSONFormatter{}, logrus.InfoLevel)
} }
return newLogger(&logrus.JSONFormatter{}, logrus.InfoLevel)
} }
func AddLogger(ctx context.Context) { // AddLogger adds a logger to the passed context
setLogger(ctx, &logrus.JSONFormatter{}, logrus.InfoLevel) func AddLogger(ctx context.Context) context.Context {
return setLogger(ctx, &logrus.JSONFormatter{}, logrus.InfoLevel)
} }
func AddDebugLogger(ctx context.Context) { // AddDebugLogger adds a text-formatted debug logger to the passed context
setLogger(ctx, &logrus.TextFormatter{}, logrus.DebugLevel) func AddDebugLogger(ctx context.Context) context.Context {
return setLogger(ctx, &logrus.TextFormatter{}, logrus.DebugLevel)
} }
// SetLogger adds a logger to the supplied context // SetLogger adds a logger to the supplied context
func setLogger(ctx context.Context, fmt logrus.Formatter, level logrus.Level) { func setLogger(ctx context.Context, fmt logrus.Formatter, level logrus.Level) context.Context {
log := newLogger(fmt, level) log := newLogger(fmt, level)
context.WithValue(ctx, ContextKey, log) return context.WithValue(ctx, contextKey, log)
} }
func newLogger(fmt logrus.Formatter, level logrus.Level) *logrus.Logger { func newLogger(fmt logrus.Formatter, level logrus.Level) *logrus.Logger {
@ -36,4 +39,4 @@ func newLogger(fmt logrus.Formatter, level logrus.Level) *logrus.Logger {
log.SetFormatter(fmt) log.SetFormatter(fmt)
log.SetLevel(level) log.SetLevel(level)
return log return log
} }

View file

@ -17,11 +17,10 @@ import (
"strings" "strings"
) )
const ChallengeHeader = "WWW-Authenticate" // ChallengeHeader is the HTTP Header containing challenge instructions
const ChallengeHeader = "WWW-Authenticate"
// GetToken fetches a token for the registry hosting the provided image
func GetToken(ctx context.Context, image apiTypes.ImageInspect, credentials *types.RegistryCredentials) (string, error) { func GetToken(ctx context.Context, image apiTypes.ImageInspect, credentials *types.RegistryCredentials) (string, error) {
var err error var err error
log := logger.GetLogger(ctx) log := logger.GetLogger(ctx)
@ -61,6 +60,7 @@ func GetToken(ctx context.Context, image apiTypes.ImageInspect, credentials *typ
return "", errors.New("unsupported challenge type from registry") return "", errors.New("unsupported challenge type from registry")
} }
// GetChallengeRequest creates a request for getting challenge instructions
func GetChallengeRequest(url url2.URL) (*http.Request, error) { func GetChallengeRequest(url url2.URL) (*http.Request, error) {
req, err := http.NewRequest("GET", url.String(), nil) req, err := http.NewRequest("GET", url.String(), nil)
@ -72,6 +72,7 @@ func GetChallengeRequest(url url2.URL) (*http.Request, error) {
return req, nil return req, nil
} }
// GetBearerToken tries to fetch a bearer token from the registry based on the challenge instructions
func GetBearerToken(ctx context.Context, challenge string, img string, err error, credentials *types.RegistryCredentials) (string, error) { func GetBearerToken(ctx context.Context, challenge string, img string, err error, credentials *types.RegistryCredentials) (string, error) {
log := logger.GetLogger(ctx) log := logger.GetLogger(ctx)
client := http.Client{} client := http.Client{}
@ -105,6 +106,7 @@ func GetBearerToken(ctx context.Context, challenge string, img string, err error
return tokenResponse.Token, nil return tokenResponse.Token, nil
} }
// GetAuthURL from the instructions in the challenge
func GetAuthURL(challenge string, img string) *url2.URL { func GetAuthURL(challenge string, img string) *url2.URL {
raw := strings.TrimPrefix(challenge, "bearer") raw := strings.TrimPrefix(challenge, "bearer")
pairs := strings.Split(raw, ",") pairs := strings.Split(raw, ",")
@ -128,6 +130,7 @@ func GetAuthURL(challenge string, img string) *url2.URL {
return authURL return authURL
} }
// GetChallengeURL creates a URL object based on the image info
func GetChallengeURL(img string) (url2.URL, error) { func GetChallengeURL(img string) (url2.URL, error) {
normalizedNamed, _ := ref.ParseNormalizedNamed(img) normalizedNamed, _ := ref.ParseNormalizedNamed(img)
host, err := helpers.NormalizeRegistry(normalizedNamed.Name()) host, err := helpers.NormalizeRegistry(normalizedNamed.Name())
@ -137,8 +140,8 @@ func GetChallengeURL(img string) (url2.URL, error) {
url := url2.URL{ url := url2.URL{
Scheme: "https", Scheme: "https",
Host: host , Host: host,
Path: "/v2/", Path: "/v2/",
} }
return url, nil return url, nil
} }

View file

@ -14,8 +14,10 @@ import (
) )
const ( const (
// ManifestListV2ContentType is the Content-Type used for fetching manifest lists
ManifestListV2ContentType = "application/vnd.docker.distribution.manifest.list.v2+json" ManifestListV2ContentType = "application/vnd.docker.distribution.manifest.list.v2+json"
ContentDigestHeader = "Docker-Content-Digest" // ContentDigestHeader is the key for the key-value pair containing the digest header
ContentDigestHeader = "Docker-Content-Digest"
) )
// CompareDigest ... // CompareDigest ...
@ -54,6 +56,7 @@ func CompareDigest(ctx context.Context, image apiTypes.ImageInspect, credentials
return false, nil return false, nil
} }
// GetDigest from registry using a HEAD request to prevent rate limiting
func GetDigest(ctx context.Context, url string, token string) (string, error) { func GetDigest(ctx context.Context, url string, token string) (string, error) {
client := &http.Client{} client := &http.Client{}
log := logger.GetLogger(ctx).WithField("fun", "GetDigest") log := logger.GetLogger(ctx).WithField("fun", "GetDigest")
@ -73,10 +76,7 @@ func GetDigest(ctx context.Context, url string, token string) (string, error) {
return "", err return "", err
} }
if res.StatusCode != 200 { if res.StatusCode != 200 {
return "", errors.New( return "", fmt.Errorf("registry responded to head request with %d", res.StatusCode)
fmt.Sprintf("registry responded to head request with %d", res.StatusCode),
)
} }
return res.Header.Get(ContentDigestHeader), nil return res.Header.Get(ContentDigestHeader), nil
} }

View file

@ -52,44 +52,42 @@ func SkipIfCredentialsEmpty(credentials *wtTypes.RegistryCredentials, fn func())
} }
var _ = Describe("Digests", func() { var _ = Describe("Digests", func() {
When("fetching a bearer token", func() { var ctx = logger.AddDebugLogger(context.Background())
When("fetching a bearer token", func() {
It("should parse the token from the response",
SkipIfCredentialsEmpty(GHCRCredentials, func() {
token, err := auth.GetToken(ctx, ghImage, GHCRCredentials)
Expect(err).NotTo(HaveOccurred())
Expect(token).NotTo(Equal(""))
}),
)
})
When("a digest comparison is done", func() {
It("should return true if digests match",
SkipIfCredentialsEmpty(GHCRCredentials, func() {
matches, err := CompareDigest(ctx, ghImage, GHCRCredentials)
Expect(err).NotTo(HaveOccurred())
Expect(matches).To(Equal(true))
}),
)
It("should return false if digests differ", func() {
It("should parse the token from the response",
SkipIfCredentialsEmpty(GHCRCredentials, func() {
ctx := context.Background()
logger.AddDebugLogger(ctx)
token, err := auth.GetToken(ctx, ghImage, GHCRCredentials)
Expect(err).NotTo(HaveOccurred())
Expect(token).NotTo(Equal(""))
}),
)
}) })
When("a digest comparison is done", func() { It("should return an error if the registry isn't available", func() {
It("should return true if digests match",
SkipIfCredentialsEmpty(GHCRCredentials, func() {
ctx := context.Background()
logger.AddDebugLogger(ctx)
matches, err := CompareDigest(ctx, ghImage, GHCRCredentials)
Expect(err).NotTo(HaveOccurred())
Expect(matches).To(Equal(true))
}),
)
It("should return false if digests differ", func() {
})
It("should return an error if the registry isn't available", func() {
})
}) })
When("using different registries", func() { })
It("should work with DockerHub", func() { When("using different registries", func() {
It("should work with DockerHub", func() {
})
It("should work with GitHub Container Registry",
SkipIfCredentialsEmpty(GHCRCredentials, func() {
fmt.Println(GHCRCredentials != nil) // to avoid crying linters
}),
)
}) })
It("should work with GitHub Container Registry",
SkipIfCredentialsEmpty(GHCRCredentials, func() {
fmt.Println(GHCRCredentials != nil) // to avoid crying linters
}),
)
})
}) })

View file

@ -16,7 +16,6 @@ func ConvertToHostname(url string) (string, string, error) {
hostName := u.Hostname() hostName := u.Hostname()
port := u.Port() port := u.Port()
return hostName, port, err return hostName, port, err
} }

View file

@ -30,4 +30,4 @@ var _ = Describe("the helpers", func() {
Expect(out).To(Equal("index.docker.io")) Expect(out).To(Equal("index.docker.io"))
}) })
}) })
}) })

View file

@ -21,7 +21,6 @@ func BuildManifestURL(image apiTypes.ImageInspect) (string, error) {
return "", err return "", err
} }
host, err := helpers.NormalizeRegistry(hostName.Name()) host, err := helpers.NormalizeRegistry(hostName.Name())
if err != nil { if err != nil {
return "", err return "", err
@ -34,4 +33,3 @@ func BuildManifestURL(image apiTypes.ImageInspect) (string, error) {
} }
return url.String(), nil return url.String(), nil
} }

View file

@ -1,5 +1,6 @@
package types package types
// RegistryCredentials is a credential pair used for basic auth
type RegistryCredentials struct { type RegistryCredentials struct {
Username string Username string
Password string // usually a token rather than an actual password Password string // usually a token rather than an actual password

View file

@ -1,5 +1,6 @@
package types package types
// TokenResponse is returned by the registry on successful authentication
type TokenResponse struct { type TokenResponse struct {
Token string `json:"token"` Token string `json:"token"`
} }