diff --git a/pkg/logger/logger.go b/pkg/logger/logger.go index 1ec3f4b..2efcab8 100644 --- a/pkg/logger/logger.go +++ b/pkg/logger/logger.go @@ -5,29 +5,32 @@ import ( "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 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 - } else { - return newLogger(&logrus.JSONFormatter{}, logrus.InfoLevel) } + return newLogger(&logrus.JSONFormatter{}, logrus.InfoLevel) } -func AddLogger(ctx context.Context) { - setLogger(ctx, &logrus.JSONFormatter{}, logrus.InfoLevel) +// AddLogger adds a logger to the passed context +func AddLogger(ctx context.Context) context.Context { + return setLogger(ctx, &logrus.JSONFormatter{}, logrus.InfoLevel) } -func AddDebugLogger(ctx context.Context) { - setLogger(ctx, &logrus.TextFormatter{}, logrus.DebugLevel) +// AddDebugLogger adds a text-formatted debug logger to the passed context +func AddDebugLogger(ctx context.Context) context.Context { + return setLogger(ctx, &logrus.TextFormatter{}, logrus.DebugLevel) } // 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) - context.WithValue(ctx, ContextKey, log) + return context.WithValue(ctx, contextKey, log) } 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.SetLevel(level) return log -} \ No newline at end of file +} diff --git a/pkg/registry/auth/auth.go b/pkg/registry/auth/auth.go index dac5f92..5d7f4e2 100644 --- a/pkg/registry/auth/auth.go +++ b/pkg/registry/auth/auth.go @@ -17,11 +17,10 @@ import ( "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) { var err error 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") } +// GetChallengeRequest creates a request for getting challenge instructions func GetChallengeRequest(url url2.URL) (*http.Request, error) { req, err := http.NewRequest("GET", url.String(), nil) @@ -72,6 +72,7 @@ func GetChallengeRequest(url url2.URL) (*http.Request, error) { 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) { log := logger.GetLogger(ctx) client := http.Client{} @@ -105,6 +106,7 @@ func GetBearerToken(ctx context.Context, challenge string, img string, err error return tokenResponse.Token, nil } +// GetAuthURL from the instructions in the challenge func GetAuthURL(challenge string, img string) *url2.URL { raw := strings.TrimPrefix(challenge, "bearer") pairs := strings.Split(raw, ",") @@ -128,6 +130,7 @@ func GetAuthURL(challenge string, img string) *url2.URL { return authURL } +// GetChallengeURL creates a URL object based on the image info func GetChallengeURL(img string) (url2.URL, error) { normalizedNamed, _ := ref.ParseNormalizedNamed(img) host, err := helpers.NormalizeRegistry(normalizedNamed.Name()) @@ -137,8 +140,8 @@ func GetChallengeURL(img string) (url2.URL, error) { url := url2.URL{ Scheme: "https", - Host: host , + Host: host, Path: "/v2/", } return url, nil -} \ No newline at end of file +} diff --git a/pkg/registry/digest/digest.go b/pkg/registry/digest/digest.go index 48fbcb1..c621ac1 100644 --- a/pkg/registry/digest/digest.go +++ b/pkg/registry/digest/digest.go @@ -14,8 +14,10 @@ import ( ) const ( + // ManifestListV2ContentType is the Content-Type used for fetching manifest lists 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 ... @@ -54,6 +56,7 @@ func CompareDigest(ctx context.Context, image apiTypes.ImageInspect, credentials 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) { client := &http.Client{} log := logger.GetLogger(ctx).WithField("fun", "GetDigest") @@ -73,10 +76,7 @@ func GetDigest(ctx context.Context, url string, token string) (string, error) { return "", err } if res.StatusCode != 200 { - return "", errors.New( - fmt.Sprintf("registry responded to head request with %d", res.StatusCode), - ) + return "", fmt.Errorf("registry responded to head request with %d", res.StatusCode) } return res.Header.Get(ContentDigestHeader), nil } - diff --git a/pkg/registry/digest/digest_test.go b/pkg/registry/digest/digest_test.go index 0946d82..e0078ec 100644 --- a/pkg/registry/digest/digest_test.go +++ b/pkg/registry/digest/digest_test.go @@ -52,44 +52,42 @@ func SkipIfCredentialsEmpty(credentials *wtTypes.RegistryCredentials, fn func()) } var _ = Describe("Digests", func() { - When("fetching a bearer token", func() { + var ctx = logger.AddDebugLogger(context.Background()) - 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 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)) - }), - ) + 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 return false if digests differ", func() { - }) - It("should return an error if the registry isn't available", 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 + }), + ) + }) }) diff --git a/pkg/registry/helpers/helpers.go b/pkg/registry/helpers/helpers.go index bf1591a..60182a7 100644 --- a/pkg/registry/helpers/helpers.go +++ b/pkg/registry/helpers/helpers.go @@ -16,7 +16,6 @@ func ConvertToHostname(url string) (string, string, error) { hostName := u.Hostname() port := u.Port() - return hostName, port, err } diff --git a/pkg/registry/helpers/helpers_test.go b/pkg/registry/helpers/helpers_test.go index 5267ea6..6dfe334 100644 --- a/pkg/registry/helpers/helpers_test.go +++ b/pkg/registry/helpers/helpers_test.go @@ -30,4 +30,4 @@ var _ = Describe("the helpers", func() { Expect(out).To(Equal("index.docker.io")) }) }) -}) \ No newline at end of file +}) diff --git a/pkg/registry/manifest/manifest.go b/pkg/registry/manifest/manifest.go index 0df0982..e75d02b 100644 --- a/pkg/registry/manifest/manifest.go +++ b/pkg/registry/manifest/manifest.go @@ -21,7 +21,6 @@ func BuildManifestURL(image apiTypes.ImageInspect) (string, error) { return "", err } - host, err := helpers.NormalizeRegistry(hostName.Name()) if err != nil { return "", err @@ -34,4 +33,3 @@ func BuildManifestURL(image apiTypes.ImageInspect) (string, error) { } return url.String(), nil } - diff --git a/pkg/types/registry_credentials.go b/pkg/types/registry_credentials.go index 443c835..607fa05 100644 --- a/pkg/types/registry_credentials.go +++ b/pkg/types/registry_credentials.go @@ -1,5 +1,6 @@ package types +// RegistryCredentials is a credential pair used for basic auth type RegistryCredentials struct { Username string Password string // usually a token rather than an actual password diff --git a/pkg/types/token_response.go b/pkg/types/token_response.go index 81bc436..722dde8 100644 --- a/pkg/types/token_response.go +++ b/pkg/types/token_response.go @@ -1,5 +1,6 @@ package types +// TokenResponse is returned by the registry on successful authentication type TokenResponse struct { Token string `json:"token"` -} \ No newline at end of file +}