From ba08c24369e2c359b001e8ff466582c6afa45426 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Mon, 20 Jun 2016 22:55:36 +0800 Subject: [PATCH] bug fix: there's access log generated each time when view the manifest of a repository. --- api/repository.go | 4 +- service/cache/cache.go | 2 +- utils/registry/registry.go | 94 +++++++++++++++--------------------- utils/registry/repository.go | 52 ++++++++++---------- 4 files changed, 66 insertions(+), 86 deletions(-) diff --git a/api/repository.go b/api/repository.go index 1296a3e5b..b64cef579 100644 --- a/api/repository.go +++ b/api/repository.go @@ -259,7 +259,7 @@ func (ra *RepositoryAPI) initRepositoryClient(repoName string) (r *registry.Repo username, password, ok := ra.Ctx.Request.BasicAuth() if ok { credential := auth.NewBasicAuthCredential(username, password) - return registry.NewRepositoryWithCredential(repoName, endpoint, credential) + return registry.NewRepositoryWithCredentialForUI(repoName, endpoint, credential) } username, err = ra.getUsername() @@ -267,7 +267,7 @@ func (ra *RepositoryAPI) initRepositoryClient(repoName string) (r *registry.Repo return nil, err } - return registry.NewRepositoryWithUsername(repoName, endpoint, username) + return registry.NewRepositoryWithUsernameForUI(repoName, endpoint, username) } func (ra *RepositoryAPI) getUsername() (string, error) { diff --git a/service/cache/cache.go b/service/cache/cache.go index 869afc54a..1fda211e1 100644 --- a/service/cache/cache.go +++ b/service/cache/cache.go @@ -72,7 +72,7 @@ func RefreshCatalogCache() error { for _, repo := range rs { rc, ok := repositoryClients[repo] if !ok { - rc, err = registry.NewRepositoryWithUsername(repo, endpoint, username) + rc, err = registry.NewRepositoryWithUsernameForUI(repo, endpoint, username) if err != nil { log.Errorf("error occurred while initializing repository client used by cache: %s %v", repo, err) continue diff --git a/utils/registry/registry.go b/utils/registry/registry.go index feb6c5fca..837e156a8 100644 --- a/utils/registry/registry.go +++ b/utils/registry/registry.go @@ -23,7 +23,6 @@ import ( "net/url" "strings" - "github.com/vmware/harbor/utils/log" "github.com/vmware/harbor/utils/registry/auth" registry_error "github.com/vmware/harbor/utils/registry/error" ) @@ -41,51 +40,6 @@ type Registry struct { // NewRegistry returns an instance of registry func NewRegistry(endpoint string, client *http.Client) (*Registry, error) { - endpoint = strings.TrimRight(endpoint, "/") - - u, err := url.Parse(endpoint) - if err != nil { - return nil, err - } - - registry := &Registry{ - Endpoint: u, - client: client, - } - - log.Debugf("initialized a registry client: %s", endpoint) - - return registry, nil -} - -// NewRegistryWithUsername returns a Registry instance which will authorize the request -// according to the privileges of user -func NewRegistryWithUsername(endpoint, username string) (*Registry, error) { - endpoint = strings.TrimRight(endpoint, "/") - - u, err := url.Parse(endpoint) - if err != nil { - return nil, err - } - - client, err := newClient(endpoint, username, nil, "registry", "catalog", "*") - if err != nil { - return nil, err - } - - registry := &Registry{ - Endpoint: u, - client: client, - } - - log.Debugf("initialized a registry client with username: %s %s", endpoint, username) - - return registry, nil -} - -// NewRegistryWithCredential returns a Registry instance which associate to a crendential. -// And Credential is essentially a decorator for client to docorate the request before sending it to the registry. -func NewRegistryWithCredential(endpoint string, credential auth.Credential) (*Registry, error) { endpoint = strings.TrimSpace(endpoint) endpoint = strings.TrimRight(endpoint, "/") if !strings.HasPrefix(endpoint, "http://") && @@ -98,21 +52,37 @@ func NewRegistryWithCredential(endpoint string, credential auth.Credential) (*Re return nil, err } - client, err := newClient(endpoint, "", credential, "", "", "") - if err != nil { - return nil, err - } - registry := &Registry{ Endpoint: u, client: client, } - log.Debugf("initialized a registry client with credential: %s", endpoint) - return registry, nil } +// NewRegistryWithUsername returns a Registry instance which will authorize the request +// according to the privileges of user +func NewRegistryWithUsername(endpoint, username string) (*Registry, error) { + + client, err := newClient(endpoint, username, nil, true, "registry", "catalog", "*") + if err != nil { + return nil, err + } + + return NewRegistry(endpoint, client) +} + +// NewRegistryWithCredential returns a Registry instance which associate to a crendential. +// And Credential is essentially a decorator for client to docorate the request before sending it to the registry. +func NewRegistryWithCredential(endpoint string, credential auth.Credential) (*Registry, error) { + client, err := newClient(endpoint, "", credential, true, "", "", "") + if err != nil { + return nil, err + } + + return NewRegistry(endpoint, client) +} + // Catalog ... func (r *Registry) Catalog() ([]string, error) { repos := []string{} @@ -198,9 +168,15 @@ func buildCatalogURL(endpoint string) string { } func newClient(endpoint, username string, credential auth.Credential, - scopeType, scopeName string, scopeActions ...string) (*http.Client, error) { + addUserAgent bool, scopeType, scopeName string, scopeActions ...string) (*http.Client, error) { + endpoint = strings.TrimSpace(endpoint) endpoint = strings.TrimRight(endpoint, "/") + if !strings.HasPrefix(endpoint, "http://") && + !strings.HasPrefix(endpoint, "https://") { + endpoint = "http://" + endpoint + } + resp, err := http.Get(buildPingURL(endpoint)) if err != nil { return nil, err @@ -218,9 +194,15 @@ func newClient(endpoint, username string, credential auth.Credential, challenges := auth.ParseChallengeFromResponse(resp) authorizer := auth.NewRequestAuthorizer(handlers, challenges) - headerModifier := NewHeaderModifier(map[string]string{http.CanonicalHeaderKey("User-Agent"): UserAgent}) - transport := NewTransport(http.DefaultTransport, []RequestModifier{authorizer, headerModifier}) + rm := []RequestModifier{} + rm = append(rm, authorizer) + if addUserAgent { + headerModifier := NewHeaderModifier(map[string]string{http.CanonicalHeaderKey("User-Agent"): UserAgent}) + rm = append(rm, headerModifier) + } + + transport := NewTransport(http.DefaultTransport, rm) return &http.Client{ Transport: transport, }, nil diff --git a/utils/registry/repository.go b/utils/registry/repository.go index c514413d8..b3d039592 100644 --- a/utils/registry/repository.go +++ b/utils/registry/repository.go @@ -28,7 +28,6 @@ import ( "github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema2" - "github.com/vmware/harbor/utils/log" "github.com/vmware/harbor/utils/registry/auth" registry_error "github.com/vmware/harbor/utils/registry/error" ) @@ -45,7 +44,13 @@ type Repository struct { // NewRepository returns an instance of Repository func NewRepository(name, endpoint string, client *http.Client) (*Repository, error) { name = strings.TrimSpace(name) + + endpoint = strings.TrimSpace(endpoint) endpoint = strings.TrimRight(endpoint, "/") + if !strings.HasPrefix(endpoint, "http://") && + !strings.HasPrefix(endpoint, "https://") { + endpoint = "http://" + endpoint + } u, err := url.Parse(endpoint) if err != nil { @@ -64,52 +69,45 @@ func NewRepository(name, endpoint string, client *http.Client) (*Repository, err // NewRepositoryWithCredential returns a Repository instance which will authorize the request // according to the credenttial func NewRepositoryWithCredential(name, endpoint string, credential auth.Credential) (*Repository, error) { - name = strings.TrimSpace(name) - endpoint = strings.TrimRight(endpoint, "/") - - u, err := url.Parse(endpoint) + client, err := newClient(endpoint, "", credential, true, "repository", name, "pull", "push") if err != nil { return nil, err } - client, err := newClient(endpoint, "", credential, "repository", name, "pull", "push") + return NewRepository(name, endpoint, client) +} + +// NewRepositoryWithCredentialForUI returns a Repository instance for UI +// The "user-agent" header of this instance does not been set +func NewRepositoryWithCredentialForUI(name, endpoint string, credential auth.Credential) (*Repository, error) { + client, err := newClient(endpoint, "", credential, false, "repository", name, "pull", "push") if err != nil { return nil, err } - repository := &Repository{ - Name: name, - Endpoint: u, - client: client, - } - - log.Debugf("initialized a repository client with credential: %s %s", endpoint, name) - - return repository, nil + return NewRepository(name, endpoint, client) } // NewRepositoryWithUsername returns a Repository instance which will authorize the request // according to the privileges of user func NewRepositoryWithUsername(name, endpoint, username string) (*Repository, error) { - name = strings.TrimSpace(name) - endpoint = strings.TrimRight(endpoint, "/") - - u, err := url.Parse(endpoint) + client, err := newClient(endpoint, username, nil, true, "repository", name, "pull", "push") if err != nil { return nil, err } - client, err := newClient(endpoint, username, nil, "repository", name, "pull", "push") + return NewRepository(name, endpoint, client) +} - repository := &Repository{ - Name: name, - Endpoint: u, - client: client, +// NewRepositoryWithUsernameForUI returns a Repository instance for UI +// The "user-agent" header of this instance does not been set +func NewRepositoryWithUsernameForUI(name, endpoint, username string) (*Repository, error) { + client, err := newClient(endpoint, username, nil, false, "repository", name, "pull", "push") + if err != nil { + return nil, err } - log.Debugf("initialized a repository client with username: %s %s %s", endpoint, name, username) - - return repository, nil + return NewRepository(name, endpoint, client) } func parseError(err error) error {