mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-16 15:25:18 +01:00
Fix replication failure in kubernetes with hairpin mode disabled
Fixes #11480 Fixes #11461 Fix replication failure in kubernetes with hairpin mode disabled Signed-off-by: Wenkai Yin <yinw@vmware.com>
This commit is contained in:
parent
bf6c4ff1f1
commit
8ee3421176
@ -17,6 +17,7 @@ package base
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -32,7 +33,7 @@ import (
|
|||||||
|
|
||||||
// New creates an instance of the base adapter
|
// New creates an instance of the base adapter
|
||||||
func New(registry *model.Registry) (*Adapter, error) {
|
func New(registry *model.Registry) (*Adapter, error) {
|
||||||
if isLocalHarbor(registry) {
|
if isLocalHarbor(registry.URL) {
|
||||||
authorizer := common_http_auth.NewSecretAuthorizer(registry.Credential.AccessSecret)
|
authorizer := common_http_auth.NewSecretAuthorizer(registry.Credential.AccessSecret)
|
||||||
httpClient := common_http.NewClient(&http.Client{
|
httpClient := common_http.NewClient(&http.Client{
|
||||||
Transport: common_http.GetHTTPTransport(common_http.SecureTransport),
|
Transport: common_http.GetHTTPTransport(common_http.SecureTransport),
|
||||||
@ -266,6 +267,11 @@ type Project struct {
|
|||||||
Metadata map[string]interface{} `json:"metadata"`
|
Metadata map[string]interface{} `json:"metadata"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func isLocalHarbor(registry *model.Registry) bool {
|
func isLocalHarbor(url string) bool {
|
||||||
return registry.Type == model.RegistryTypeHarbor && registry.Name == "Local"
|
return url == os.Getenv("CORE_URL")
|
||||||
|
}
|
||||||
|
|
||||||
|
// check whether the current process is running inside core
|
||||||
|
func isInCore() bool {
|
||||||
|
return len(os.Getenv("EXT_ENDPOINT")) > 0
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ func (a *Adapter) FetchCharts(filters []*model.Filter) ([]*model.Resource, error
|
|||||||
|
|
||||||
resources := []*model.Resource{}
|
resources := []*model.Resource{}
|
||||||
for _, project := range projects {
|
for _, project := range projects {
|
||||||
url := fmt.Sprintf("%s/api/chartrepo/%s/charts", a.url, project.Name)
|
url := fmt.Sprintf("%s/api/chartrepo/%s/charts", a.Client.GetURL(), project.Name)
|
||||||
repositories := []*model.Repository{}
|
repositories := []*model.Repository{}
|
||||||
if err := a.httpClient.Get(url, &repositories); err != nil {
|
if err := a.httpClient.Get(url, &repositories); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -72,7 +72,7 @@ func (a *Adapter) FetchCharts(filters []*model.Filter) ([]*model.Resource, error
|
|||||||
|
|
||||||
for _, repository := range repositories {
|
for _, repository := range repositories {
|
||||||
name := strings.SplitN(repository.Name, "/", 2)[1]
|
name := strings.SplitN(repository.Name, "/", 2)[1]
|
||||||
url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s", a.url, project.Name, name)
|
url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s", a.Client.GetURL(), project.Name, name)
|
||||||
versions := []*chartVersion{}
|
versions := []*chartVersion{}
|
||||||
if err := a.httpClient.Get(url, &versions); err != nil {
|
if err := a.httpClient.Get(url, &versions); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -134,7 +134,7 @@ func (a *Adapter) getChartInfo(name, version string) (*chartVersionDetail, error
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s/%s", a.url, project, name, version)
|
url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s/%s", a.Client.GetURL(), project, name, version)
|
||||||
info := &chartVersionDetail{}
|
info := &chartVersionDetail{}
|
||||||
if err = a.httpClient.Get(url, info); err != nil {
|
if err = a.httpClient.Get(url, info); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -158,7 +158,7 @@ func (a *Adapter) DownloadChart(name, version string) (io.ReadCloser, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
url = fmt.Sprintf("%s/chartrepo/%s/%s", a.url, project, url)
|
url = fmt.Sprintf("%s/chartrepo/%s/%s", a.Client.GetURL(), project, url)
|
||||||
}
|
}
|
||||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -196,7 +196,7 @@ func (a *Adapter) UploadChart(name, version string, chart io.Reader) error {
|
|||||||
}
|
}
|
||||||
w.Close()
|
w.Close()
|
||||||
|
|
||||||
url := fmt.Sprintf("%s/api/chartrepo/%s/charts", a.url, project)
|
url := fmt.Sprintf("%s/api/chartrepo/%s/charts", a.Client.GetURL(), project)
|
||||||
|
|
||||||
req, err := http.NewRequest(http.MethodPost, url, buf)
|
req, err := http.NewRequest(http.MethodPost, url, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -228,7 +228,7 @@ func (a *Adapter) DeleteChart(name, version string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s/%s", a.url, project, name, version)
|
url := fmt.Sprintf("%s/api/chartrepo/%s/charts/%s/%s", a.Client.GetURL(), project, name, version)
|
||||||
return a.httpClient.Delete(url)
|
return a.httpClient.Delete(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ func (c *Client) GetAPIVersion() (string, error) {
|
|||||||
version := &struct {
|
version := &struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
}{}
|
}{}
|
||||||
err := c.C.Get(c.URL+"/api/version", version)
|
err := c.C.Get(c.GetURL()+"/api/version", version)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return version.Version, nil
|
return version.Version, nil
|
||||||
}
|
}
|
||||||
@ -64,7 +64,7 @@ func (c *Client) ChartRegistryEnabled() (bool, error) {
|
|||||||
sys := &struct {
|
sys := &struct {
|
||||||
ChartRegistryEnabled bool `json:"with_chartmuseum"`
|
ChartRegistryEnabled bool `json:"with_chartmuseum"`
|
||||||
}{}
|
}{}
|
||||||
if err := c.C.Get(c.BaseURL()+"/systeminfo", sys); err != nil {
|
if err := c.C.Get(c.BasePath()+"/systeminfo", sys); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return sys.ChartRegistryEnabled, nil
|
return sys.ChartRegistryEnabled, nil
|
||||||
@ -75,7 +75,7 @@ func (c *Client) ListLabels() ([]string, error) {
|
|||||||
labels := []*struct {
|
labels := []*struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
}{}
|
}{}
|
||||||
err := c.C.Get(c.BaseURL()+"/labels?scope=g", &labels)
|
err := c.C.Get(c.BasePath()+"/labels?scope=g", &labels)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
var lbs []string
|
var lbs []string
|
||||||
for _, label := range labels {
|
for _, label := range labels {
|
||||||
@ -99,13 +99,13 @@ func (c *Client) CreateProject(name string, metadata map[string]interface{}) err
|
|||||||
Name: name,
|
Name: name,
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
}
|
}
|
||||||
return c.C.Post(c.BaseURL()+"/projects", project)
|
return c.C.Post(c.BasePath()+"/projects", project)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListProjects lists projects
|
// ListProjects lists projects
|
||||||
func (c *Client) ListProjects(name string) ([]*Project, error) {
|
func (c *Client) ListProjects(name string) ([]*Project, error) {
|
||||||
projects := []*Project{}
|
projects := []*Project{}
|
||||||
url := fmt.Sprintf("%s/projects?name=%s", c.BaseURL(), name)
|
url := fmt.Sprintf("%s/projects?name=%s", c.BasePath(), name)
|
||||||
if err := c.C.GetAndIteratePagination(url, &projects); err != nil {
|
if err := c.C.GetAndIteratePagination(url, &projects); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -126,10 +126,27 @@ func (c *Client) GetProject(name string) (*Project, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// BaseURL returns the base URL of APIs
|
// BasePath returns the API base path that contains version part
|
||||||
func (c *Client) BaseURL() string {
|
func (c *Client) BasePath() string {
|
||||||
if len(c.APIVersion) == 0 {
|
path := fmt.Sprintf("%s/api", c.GetURL())
|
||||||
return fmt.Sprintf("%s/api", c.URL)
|
if len(c.APIVersion) > 0 {
|
||||||
|
path = fmt.Sprintf("%s/%s", path, c.APIVersion)
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s/api/%s", c.URL, c.APIVersion)
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetURL returns the URL of the registry that the client is for
|
||||||
|
func (c *Client) GetURL() string {
|
||||||
|
if !isLocalHarbor(c.URL) || !isInCore() {
|
||||||
|
return c.URL
|
||||||
|
}
|
||||||
|
// if the adapter is created for local Harbor and the process is running
|
||||||
|
// inside core, returns the "127.0.0.1" as URL to avoid the issue:
|
||||||
|
// https://github.com/goharbor/harbor-helm/issues/222
|
||||||
|
// when harbor is deployed on Kubernetes with hairpin mode disabled
|
||||||
|
url := "http://127.0.0.1:8080"
|
||||||
|
if common_http.InternalTLSEnabled() {
|
||||||
|
url = "https://127.0.0.1:8443"
|
||||||
|
}
|
||||||
|
return url
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ type client struct {
|
|||||||
|
|
||||||
func (c *client) listRepositories(project *base.Project) ([]*model.Repository, error) {
|
func (c *client) listRepositories(project *base.Project) ([]*model.Repository, error) {
|
||||||
repositories := []*models.RepoRecord{}
|
repositories := []*models.RepoRecord{}
|
||||||
url := fmt.Sprintf("%s/repositories?project_id=%d", c.BaseURL(), project.ID)
|
url := fmt.Sprintf("%s/repositories?project_id=%d", c.BasePath(), project.ID)
|
||||||
if err := c.C.GetAndIteratePagination(url, &repositories); err != nil {
|
if err := c.C.GetAndIteratePagination(url, &repositories); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ func (c *client) listRepositories(project *base.Project) ([]*model.Repository, e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) listArtifacts(repository string) ([]*model.Artifact, error) {
|
func (c *client) listArtifacts(repository string) ([]*model.Artifact, error) {
|
||||||
url := fmt.Sprintf("%s/repositories/%s/tags", c.BaseURL(), repository)
|
url := fmt.Sprintf("%s/repositories/%s/tags", c.BasePath(), repository)
|
||||||
tags := []*struct {
|
tags := []*struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Labels []*struct {
|
Labels []*struct {
|
||||||
@ -68,6 +68,6 @@ func (c *client) listArtifacts(repository string) ([]*model.Artifact, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *client) deleteManifest(repository, reference string) error {
|
func (c *client) deleteManifest(repository, reference string) error {
|
||||||
url := fmt.Sprintf("%s/repositories/%s/tags/%s", c.BaseURL(), repository, reference)
|
url := fmt.Sprintf("%s/repositories/%s/tags/%s", c.BasePath(), repository, reference)
|
||||||
return c.C.Delete(url)
|
return c.C.Delete(url)
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ type client struct {
|
|||||||
|
|
||||||
func (c *client) listRepositories(project *base.Project) ([]*model.Repository, error) {
|
func (c *client) listRepositories(project *base.Project) ([]*model.Repository, error) {
|
||||||
repositories := []*models.RepoRecord{}
|
repositories := []*models.RepoRecord{}
|
||||||
url := fmt.Sprintf("%s/projects/%s/repositories", c.BaseURL(), project.Name)
|
url := fmt.Sprintf("%s/projects/%s/repositories", c.BasePath(), project.Name)
|
||||||
if err := c.C.GetAndIteratePagination(url, &repositories); err != nil {
|
if err := c.C.GetAndIteratePagination(url, &repositories); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -49,7 +49,7 @@ func (c *client) listArtifacts(repository string) ([]*model.Artifact, error) {
|
|||||||
project, repository := utils.ParseRepository(repository)
|
project, repository := utils.ParseRepository(repository)
|
||||||
repository = url.PathEscape(url.PathEscape(repository))
|
repository = url.PathEscape(url.PathEscape(repository))
|
||||||
url := fmt.Sprintf("%s/projects/%s/repositories/%s/artifacts?with_label=true",
|
url := fmt.Sprintf("%s/projects/%s/repositories/%s/artifacts?with_label=true",
|
||||||
c.BaseURL(), project, repository)
|
c.BasePath(), project, repository)
|
||||||
artifacts := []*artifact.Artifact{}
|
artifacts := []*artifact.Artifact{}
|
||||||
if err := c.C.GetAndIteratePagination(url, &artifacts); err != nil {
|
if err := c.C.GetAndIteratePagination(url, &artifacts); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -75,6 +75,6 @@ func (c *client) deleteTag(repository, tag string) error {
|
|||||||
project, repository := utils.ParseRepository(repository)
|
project, repository := utils.ParseRepository(repository)
|
||||||
repository = url.PathEscape(url.PathEscape(repository))
|
repository = url.PathEscape(url.PathEscape(repository))
|
||||||
url := fmt.Sprintf("%s/projects/%s/repositories/%s/artifacts/%s/tags/%s",
|
url := fmt.Sprintf("%s/projects/%s/repositories/%s/artifacts/%s/tags/%s",
|
||||||
c.BaseURL(), project, repository, tag, tag)
|
c.BasePath(), project, repository, tag, tag)
|
||||||
return c.C.Delete(url)
|
return c.C.Delete(url)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user