mirror of
https://github.com/containrrr/watchtower.git
synced 2025-12-16 23:20:12 +01:00
fix linter issues
This commit is contained in:
parent
6b9fd8d7ef
commit
a32468d1fe
9 changed files with 64 additions and 61 deletions
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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,7 +140,7 @@ 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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"`
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue