mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 10:15:35 +01:00
Refactor and Add trace to http Transport
* Refactor common http GetTransport function signature * Remove redendent GetHTTPTransport and similar functions * Update Authorized function signature to meet new HTTPTransport * Add trace for default Transport Signed-off-by: Qian Deng <dengq@vmware.com>
This commit is contained in:
parent
a15983432c
commit
879eecc926
@ -10,8 +10,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
tracelib "github.com/goharbor/harbor/src/lib/trace"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -22,7 +25,7 @@ const (
|
||||
|
||||
var (
|
||||
once sync.Once
|
||||
chartTransport *http.Transport
|
||||
chartTransport http.RoundTripper
|
||||
)
|
||||
|
||||
// ChartClient is a http client to get the content from the external http server
|
||||
@ -38,9 +41,13 @@ type ChartClient struct {
|
||||
// credential can be nil
|
||||
func NewChartClient(credential *Credential) *ChartClient { // Create http client with customized timeouts
|
||||
once.Do(func() {
|
||||
chartTransport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport).Clone()
|
||||
chartTransport.MaxIdleConns = maxIdleConnections
|
||||
chartTransport.IdleConnTimeout = idleConnectionTimeout
|
||||
chartTransport = commonhttp.NewTransport(
|
||||
commonhttp.WithMaxIdleConns(maxIdleConnections),
|
||||
commonhttp.WithIdleconnectionTimeout(idleConnectionTimeout),
|
||||
)
|
||||
if tracelib.Enabled() {
|
||||
chartTransport = otelhttp.NewTransport(chartTransport)
|
||||
}
|
||||
})
|
||||
|
||||
client := &http.Client{
|
||||
|
@ -53,7 +53,7 @@ func NewProxyEngine(target *url.URL, cred *Credential, middlewares ...func(http.
|
||||
director(target, cred, req)
|
||||
},
|
||||
ModifyResponse: modifyResponse,
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport),
|
||||
Transport: commonhttp.GetHTTPTransport(),
|
||||
}
|
||||
|
||||
if len(middlewares) > 0 {
|
||||
|
@ -1,11 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/spf13/viper"
|
||||
@ -43,7 +44,7 @@ func main() {
|
||||
HarborHost: viper.GetString("service.host"),
|
||||
HarborPort: viper.GetInt("service.port"),
|
||||
Client: &http.Client{
|
||||
Transport: commonthttp.GetHTTPTransport(commonthttp.SecureTransport),
|
||||
Transport: commonthttp.GetHTTPTransport(),
|
||||
},
|
||||
})
|
||||
|
||||
|
@ -16,65 +16,18 @@ package http
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/http/modifier"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
)
|
||||
|
||||
const (
|
||||
// InsecureTransport used to get the insecure http Transport
|
||||
InsecureTransport = iota
|
||||
// SecureTransport used to get the external secure http Transport
|
||||
SecureTransport
|
||||
)
|
||||
|
||||
var (
|
||||
secureHTTPTransport *http.Transport
|
||||
insecureHTTPTransport *http.Transport
|
||||
)
|
||||
|
||||
func init() {
|
||||
secureHTTPTransport = newDefaultTransport()
|
||||
insecureHTTPTransport = newDefaultTransport()
|
||||
insecureHTTPTransport.TLSClientConfig.InsecureSkipVerify = true
|
||||
|
||||
if InternalTLSEnabled() {
|
||||
tlsConfig, err := GetInternalTLSConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
secureHTTPTransport.TLSClientConfig = tlsConfig
|
||||
}
|
||||
}
|
||||
|
||||
// Use this instead of Default Transport in library because it sets ForceAttemptHTTP2 to true
|
||||
// And that options introduced in go 1.13 will cause the https requests hang forever in replication environment
|
||||
func newDefaultTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
TLSClientConfig: &tls.Config{},
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
// Client is a util for common HTTP operations, such Get, Head, Post, Put and Delete.
|
||||
// Use Do instead if those methods can not meet your requirement
|
||||
type Client struct {
|
||||
@ -87,27 +40,6 @@ func (c *Client) GetClient() *http.Client {
|
||||
return c.client
|
||||
}
|
||||
|
||||
// GetHTTPTransport returns HttpTransport based on insecure configuration
|
||||
func GetHTTPTransport(clientType uint) *http.Transport {
|
||||
switch clientType {
|
||||
case SecureTransport:
|
||||
return secureHTTPTransport
|
||||
case InsecureTransport:
|
||||
return insecureHTTPTransport
|
||||
default:
|
||||
// default Transport is secure one
|
||||
return secureHTTPTransport
|
||||
}
|
||||
}
|
||||
|
||||
// GetHTTPTransportByInsecure returns a insecure HttpTransport if insecure is true or it returns secure one
|
||||
func GetHTTPTransportByInsecure(insecure bool) *http.Transport {
|
||||
if insecure {
|
||||
return insecureHTTPTransport
|
||||
}
|
||||
return secureHTTPTransport
|
||||
}
|
||||
|
||||
// NewClient creates an instance of Client.
|
||||
// Use net/http.Client as the default value if c is nil.
|
||||
// Modifiers modify the request before sending it.
|
||||
@ -117,7 +49,7 @@ func NewClient(c *http.Client, modifiers ...modifier.Modifier) *Client {
|
||||
}
|
||||
if client.client == nil {
|
||||
client.client = &http.Client{
|
||||
Transport: GetHTTPTransport(SecureTransport),
|
||||
Transport: GetHTTPTransport(),
|
||||
}
|
||||
}
|
||||
if len(modifiers) > 0 {
|
||||
|
@ -1,14 +0,0 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetHTTPTransport(t *testing.T) {
|
||||
transport := GetHTTPTransport(InsecureTransport)
|
||||
assert.True(t, transport.TLSClientConfig.InsecureSkipVerify)
|
||||
transport = GetHTTPTransport(SecureTransport)
|
||||
assert.False(t, transport.TLSClientConfig.InsecureSkipVerify)
|
||||
}
|
126
src/common/http/transport.go
Normal file
126
src/common/http/transport.go
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright Project Harbor Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package http
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
tracelib "github.com/goharbor/harbor/src/lib/trace"
|
||||
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
||||
)
|
||||
|
||||
const (
|
||||
// InsecureTransport used to get the insecure http Transport
|
||||
InsecureTransport = iota
|
||||
// SecureTransport used to get the external secure http Transport
|
||||
SecureTransport
|
||||
)
|
||||
|
||||
var (
|
||||
secureHTTPTransport http.RoundTripper
|
||||
insecureHTTPTransport http.RoundTripper
|
||||
)
|
||||
|
||||
func init() {
|
||||
insecureHTTPTransport = NewTransport(WithInsecureSkipVerify(true))
|
||||
if InternalTLSEnabled() {
|
||||
secureHTTPTransport = NewTransport(WithInternalTLSConfig())
|
||||
} else {
|
||||
secureHTTPTransport = NewTransport()
|
||||
}
|
||||
if tracelib.Enabled() {
|
||||
insecureHTTPTransport = otelhttp.NewTransport(insecureHTTPTransport)
|
||||
secureHTTPTransport = otelhttp.NewTransport(secureHTTPTransport)
|
||||
}
|
||||
}
|
||||
|
||||
// Use this instead of Default Transport in library because it sets ForceAttemptHTTP2 to true
|
||||
// And that options introduced in go 1.13 will cause the https requests hang forever in replication environment
|
||||
func newDefaultTransport() *http.Transport {
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
TLSClientConfig: &tls.Config{},
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
}
|
||||
|
||||
func WithInternalTLSConfig() func(*http.Transport) {
|
||||
return func(tr *http.Transport) {
|
||||
tlsConfig, err := GetInternalTLSConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
tr.TLSClientConfig = tlsConfig
|
||||
}
|
||||
}
|
||||
func WithInsecureSkipVerify(skipVerify bool) func(*http.Transport) {
|
||||
return func(tr *http.Transport) {
|
||||
tr.TLSClientConfig.InsecureSkipVerify = skipVerify
|
||||
}
|
||||
}
|
||||
|
||||
func WithMaxIdleConns(maxIdleConns int) func(*http.Transport) {
|
||||
return func(tr *http.Transport) {
|
||||
tr.MaxIdleConns = maxIdleConns
|
||||
}
|
||||
}
|
||||
|
||||
func WithIdleconnectionTimeout(idleConnectionTimeout time.Duration) func(*http.Transport) {
|
||||
return func(tr *http.Transport) {
|
||||
tr.IdleConnTimeout = idleConnectionTimeout
|
||||
}
|
||||
}
|
||||
|
||||
func NewTransport(opts ...func(*http.Transport)) http.RoundTripper {
|
||||
tr := newDefaultTransport()
|
||||
for _, opt := range opts {
|
||||
opt(tr)
|
||||
}
|
||||
return tr
|
||||
}
|
||||
|
||||
type TransportConfig struct {
|
||||
Insecure bool
|
||||
}
|
||||
type TransportOption func(*TransportConfig)
|
||||
|
||||
func WithInsecure(skipVerify bool) TransportOption {
|
||||
return func(cfg *TransportConfig) {
|
||||
cfg.Insecure = skipVerify
|
||||
}
|
||||
}
|
||||
|
||||
// GetHTTPTransport returns HttpTransport based on insecure configuration
|
||||
func GetHTTPTransport(opts ...TransportOption) http.RoundTripper {
|
||||
cfg := &TransportConfig{}
|
||||
for _, opt := range opts {
|
||||
opt(cfg)
|
||||
}
|
||||
if cfg.Insecure {
|
||||
return insecureHTTPTransport
|
||||
}
|
||||
return secureHTTPTransport
|
||||
}
|
14
src/common/http/transport_test.go
Normal file
14
src/common/http/transport_test.go
Normal file
@ -0,0 +1,14 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetHTTPTransport(t *testing.T) {
|
||||
transport := GetHTTPTransport()
|
||||
assert.Equal(t, secureHTTPTransport, transport, "Transport should be secure")
|
||||
transport = GetHTTPTransport(WithInsecure(true))
|
||||
assert.Equal(t, insecureHTTPTransport, transport, "Transport should be insecure")
|
||||
}
|
@ -5,12 +5,13 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/http/modifier/auth"
|
||||
"github.com/goharbor/harbor/src/common/job/models"
|
||||
@ -61,7 +62,7 @@ type DefaultClient struct {
|
||||
func NewDefaultClient(endpoint, secret string) *DefaultClient {
|
||||
var c *commonhttp.Client
|
||||
httpCli := &http.Client{
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport),
|
||||
Transport: commonhttp.GetHTTPTransport(),
|
||||
}
|
||||
if len(secret) > 0 {
|
||||
c = commonhttp.NewClient(httpCli, auth.NewSecretAuthorizer(secret))
|
||||
@ -81,12 +82,12 @@ func NewReplicationClient(endpoint, secret string) *DefaultClient {
|
||||
|
||||
if len(secret) > 0 {
|
||||
c = commonhttp.NewClient(&http.Client{
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport),
|
||||
Transport: commonhttp.GetHTTPTransport(),
|
||||
},
|
||||
auth.NewSecretAuthorizer(secret))
|
||||
} else {
|
||||
c = commonhttp.NewClient(&http.Client{
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport),
|
||||
Transport: commonhttp.GetHTTPTransport(),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ func HTTPStatusCodeHealthChecker(method string, url string, header http.Header,
|
||||
}
|
||||
|
||||
client := httputil.NewClient(&http.Client{
|
||||
Transport: httputil.GetHTTPTransport(httputil.SecureTransport),
|
||||
Transport: httputil.GetHTTPTransport(),
|
||||
Timeout: timeout,
|
||||
})
|
||||
resp, err := client.Do(req)
|
||||
|
@ -25,9 +25,9 @@ func init() {
|
||||
clients: map[string]*http.Client{},
|
||||
}
|
||||
httpHelper.clients[secure] = &http.Client{
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.SecureTransport),
|
||||
Transport: commonhttp.GetHTTPTransport(),
|
||||
}
|
||||
httpHelper.clients[insecure] = &http.Client{
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.InsecureTransport),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(true)),
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ package rest
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/http/modifier"
|
||||
@ -32,11 +31,6 @@ type Driver struct {
|
||||
|
||||
// NewRESTDriver - Create Driver
|
||||
func NewRESTDriver(configRESTURL string, modifiers ...modifier.Modifier) *Driver {
|
||||
if commonhttp.InternalTLSEnabled() {
|
||||
tr := commonhttp.GetHTTPTransport(commonhttp.SecureTransport)
|
||||
return &Driver{configRESTURL: configRESTURL, client: commonhttp.NewClient(&http.Client{Transport: tr}, modifiers...)}
|
||||
|
||||
}
|
||||
return &Driver{configRESTURL: configRESTURL, client: commonhttp.NewClient(nil, modifiers...)}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,9 @@ package policy
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
@ -10,8 +13,6 @@ import (
|
||||
"github.com/goharbor/harbor/src/pkg/notification/policy/dao"
|
||||
"github.com/goharbor/harbor/src/pkg/notification/policy/model"
|
||||
notifier_model "github.com/goharbor/harbor/src/pkg/notifier/model"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -159,7 +160,7 @@ func (m *manager) policyHTTPTest(address string, skipCertVerify bool) error {
|
||||
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
client := http.Client{
|
||||
Transport: commonhttp.GetHTTPTransportByInsecure(skipCertVerify),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(skipCertVerify)),
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
|
@ -61,7 +61,7 @@ func newAdapter(registry *model.Registry) (*adapter, error) {
|
||||
return nil, err
|
||||
}
|
||||
credential := NewAuth(region, registry.Credential.AccessKey, registry.Credential.AccessSecret)
|
||||
authorizer := bearer.NewAuthorizer(realm, service, credential, util.GetHTTPTransport(registry.Insecure))
|
||||
authorizer := bearer.NewAuthorizer(realm, service, credential, commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)))
|
||||
return &adapter{
|
||||
region: region,
|
||||
registry: registry,
|
||||
@ -71,11 +71,8 @@ func newAdapter(registry *model.Registry) (*adapter, error) {
|
||||
}
|
||||
|
||||
func ping(registry *model.Registry) (string, string, error) {
|
||||
client := &http.Client{}
|
||||
if registry.Insecure {
|
||||
client.Transport = commonhttp.GetHTTPTransport(commonhttp.InsecureTransport)
|
||||
} else {
|
||||
client.Transport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport)
|
||||
client := &http.Client{
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)),
|
||||
}
|
||||
|
||||
resp, err := client.Get(registry.URL + "/v2/")
|
||||
|
@ -3,11 +3,12 @@ package artifacthub
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
)
|
||||
|
||||
// Client is a client to interact with Artifact Hub
|
||||
@ -19,7 +20,7 @@ type Client struct {
|
||||
func newClient(registry *model.Registry) *Client {
|
||||
return &Client{
|
||||
httpClient: &http.Client{
|
||||
Transport: util.GetHTTPTransport(registry.Insecure),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -18,19 +18,21 @@ import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/http/modifier"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/aws/awserr"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials/ec2rolecreds"
|
||||
"github.com/aws/aws-sdk-go/aws/session"
|
||||
awsecrapi "github.com/aws/aws-sdk-go/service/ecr"
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/http/modifier"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Credential ...
|
||||
@ -103,17 +105,12 @@ func getAwsSvc(region, accessKey, accessSecret string, insecure bool, forceEndpo
|
||||
} else {
|
||||
cred = ec2rolecreds.NewCredentials(sess)
|
||||
}
|
||||
var tr *http.Transport
|
||||
if insecure {
|
||||
tr = commonhttp.GetHTTPTransport(commonhttp.InsecureTransport)
|
||||
} else {
|
||||
tr = commonhttp.GetHTTPTransport(commonhttp.SecureTransport)
|
||||
}
|
||||
|
||||
config := &aws.Config{
|
||||
Credentials: cred,
|
||||
Region: ®ion,
|
||||
HTTPClient: &http.Client{
|
||||
Transport: tr,
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(insecure)),
|
||||
},
|
||||
}
|
||||
if forceEndpoint != nil {
|
||||
|
@ -8,9 +8,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
)
|
||||
|
||||
// Client is a client to interact with DockerHub
|
||||
@ -26,7 +26,7 @@ func NewClient(registry *model.Registry) (*Client, error) {
|
||||
client := &Client{
|
||||
host: registry.URL,
|
||||
client: &http.Client{
|
||||
Transport: util.GetHTTPTransport(registry.Insecure),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,6 @@ import (
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
)
|
||||
|
||||
// Client is a client to interact with DTR
|
||||
@ -35,7 +34,7 @@ func NewClient(registry *model.Registry) *Client {
|
||||
password: registry.Credential.AccessSecret,
|
||||
client: common_http.NewClient(
|
||||
&http.Client{
|
||||
Transport: util.GetHTTPTransport(registry.Insecure),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)),
|
||||
}),
|
||||
}
|
||||
return client
|
||||
|
@ -6,7 +6,6 @@ import (
|
||||
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/utils/test"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@ -164,7 +163,7 @@ func TestProjects(t *testing.T) {
|
||||
username: "test",
|
||||
client: common_http.NewClient(
|
||||
&http.Client{
|
||||
Transport: util.GetHTTPTransport(true),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(true)),
|
||||
}),
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ func newAdapter(registry *model.Registry) *adapter {
|
||||
registry.Credential.AccessSecret)
|
||||
}
|
||||
|
||||
var transport = util.GetHTTPTransport(registry.Insecure)
|
||||
var transport = common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure))
|
||||
|
||||
return &adapter{
|
||||
Adapter: native.NewAdapter(registry),
|
||||
|
@ -4,17 +4,16 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/docker/distribution/registry/client/auth/challenge"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
"net/url"
|
||||
"reflect"
|
||||
|
||||
"github.com/docker/distribution/registry/client/auth/challenge"
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -33,7 +32,7 @@ type Client struct {
|
||||
func NewClient(registry *model.Registry) (*Client, error) {
|
||||
|
||||
realm, _, err := ping(&http.Client{
|
||||
Transport: util.GetHTTPTransport(registry.Insecure),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)),
|
||||
}, registry.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -51,7 +50,7 @@ func NewClient(registry *model.Registry) (*Client, error) {
|
||||
token: registry.Credential.AccessSecret,
|
||||
client: common_http.NewClient(
|
||||
&http.Client{
|
||||
Transport: util.GetHTTPTransport(registry.Insecure),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)),
|
||||
}),
|
||||
}
|
||||
return client, nil
|
||||
|
@ -1,13 +1,13 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/utils/test"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/utils/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestProjects(t *testing.T) {
|
||||
@ -76,7 +76,7 @@ func TestProjects(t *testing.T) {
|
||||
token: "test",
|
||||
client: common_http.NewClient(
|
||||
&http.Client{
|
||||
Transport: util.GetHTTPTransport(true),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(true)),
|
||||
}),
|
||||
}
|
||||
projects, e := client.getProjects()
|
||||
|
@ -40,7 +40,7 @@ func New(registry *model.Registry) (*Adapter, error) {
|
||||
// core, so insecure transport is ok
|
||||
// If using the secure one, as we'll replace the URL with 127.0.0.1 and this will
|
||||
// cause error "x509: cannot validate certificate for 127.0.0.1 because it doesn't contain any IP SANs"
|
||||
Transport: common_http.GetHTTPTransport(common_http.InsecureTransport),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(true)),
|
||||
}, authorizer)
|
||||
client, err := NewClient(registry.URL, httpClient)
|
||||
if err != nil {
|
||||
@ -62,7 +62,7 @@ func New(registry *model.Registry) (*Adapter, error) {
|
||||
registry.Credential.AccessSecret))
|
||||
}
|
||||
httpClient := common_http.NewClient(&http.Client{
|
||||
Transport: common_http.GetHTTPTransportByInsecure(registry.Insecure),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)),
|
||||
}, authorizers...)
|
||||
client, err := NewClient(registry.URL, httpClient)
|
||||
if err != nil {
|
||||
|
@ -3,11 +3,12 @@ package helmhub
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
)
|
||||
|
||||
// ErrHTTPNotFound defines the return error when receiving 404 response code
|
||||
@ -22,7 +23,7 @@ type Client struct {
|
||||
func NewClient(registry *model.Registry) *Client {
|
||||
return &Client{
|
||||
client: &http.Client{
|
||||
Transport: util.GetHTTPTransport(registry.Insecure),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import (
|
||||
adp "github.com/goharbor/harbor/src/pkg/reg/adapter"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/adapter/native"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@ -270,7 +269,7 @@ func newAdapter(registry *model.Registry) (adp.Adapter, error) {
|
||||
modifiers = append(modifiers, authorizer)
|
||||
}
|
||||
|
||||
transport := util.GetHTTPTransport(registry.Insecure)
|
||||
transport := common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure))
|
||||
return &adapter{
|
||||
Adapter: native.NewAdapter(registry),
|
||||
registry: registry,
|
||||
|
@ -23,7 +23,6 @@ import (
|
||||
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
"github.com/goharbor/harbor/src/pkg/registry/auth/basic"
|
||||
)
|
||||
|
||||
@ -48,7 +47,7 @@ func newClient(reg *model.Registry) *client {
|
||||
return &client{
|
||||
client: common_http.NewClient(
|
||||
&http.Client{
|
||||
Transport: util.GetHTTPTransport(reg.Insecure),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(reg.Insecure)),
|
||||
},
|
||||
basic.NewAuthorizer(username, password),
|
||||
),
|
||||
|
@ -31,7 +31,6 @@ import (
|
||||
"github.com/goharbor/harbor/src/pkg/reg/adapter/native"
|
||||
qauth "github.com/goharbor/harbor/src/pkg/reg/adapter/quay/auth"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -87,7 +86,7 @@ func newAdapter(registry *model.Registry) (*adapter, error) {
|
||||
registry: registry,
|
||||
client: common_http.NewClient(
|
||||
&http.Client{
|
||||
Transport: util.GetHTTPTransport(registry.Insecure),
|
||||
Transport: common_http.GetHTTPTransport(common_http.WithInsecure(registry.Insecure)),
|
||||
},
|
||||
modifiers...,
|
||||
),
|
||||
|
@ -16,7 +16,6 @@ import (
|
||||
adp "github.com/goharbor/harbor/src/pkg/reg/adapter"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/adapter/native"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util"
|
||||
"github.com/goharbor/harbor/src/pkg/registry/auth/bearer"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
|
||||
@ -147,7 +146,7 @@ func newAdapter(registry *model.Registry) (a *adapter, err error) {
|
||||
}
|
||||
|
||||
var credential = NewAuth(instanceInfo.RegistryId, client)
|
||||
var transport = util.GetHTTPTransport(registry.Insecure)
|
||||
var transport = commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure))
|
||||
var authorizer = bearer.NewAuthorizer(realm, service, credential, transport)
|
||||
|
||||
return &adapter{
|
||||
@ -168,7 +167,7 @@ func newAdapter(registry *model.Registry) (a *adapter, err error) {
|
||||
|
||||
func ping(registry *model.Registry) (string, string, error) {
|
||||
client := &http.Client{
|
||||
Transport: util.GetHTTPTransport(registry.Insecure),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)),
|
||||
}
|
||||
|
||||
resp, err := client.Get(registry.URL + "/v2/")
|
||||
|
@ -15,20 +15,9 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
)
|
||||
|
||||
// GetHTTPTransport can be used to share the common HTTP transport
|
||||
func GetHTTPTransport(insecure bool) *http.Transport {
|
||||
if insecure {
|
||||
return commonhttp.GetHTTPTransport(commonhttp.InsecureTransport)
|
||||
}
|
||||
return commonhttp.GetHTTPTransport(commonhttp.SecureTransport)
|
||||
}
|
||||
|
||||
// ParseRepository parses the "repository" provided into two parts: namespace and the rest
|
||||
// the string before the last "/" is the namespace part
|
||||
// c -> [,c]
|
||||
|
@ -20,13 +20,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetHTTPTransport(t *testing.T) {
|
||||
transport := GetHTTPTransport(true)
|
||||
assert.True(t, transport.TLSClientConfig.InsecureSkipVerify)
|
||||
transport = GetHTTPTransport(false)
|
||||
assert.False(t, transport.TLSClientConfig.InsecureSkipVerify)
|
||||
}
|
||||
|
||||
func TestParseRepository(t *testing.T) {
|
||||
// empty repository
|
||||
repository := ""
|
||||
|
@ -36,7 +36,7 @@ func NewAuthorizer(username, password string, insecure bool) lib.Authorizer {
|
||||
username: username,
|
||||
password: password,
|
||||
client: &http.Client{
|
||||
Transport: commonhttp.GetHTTPTransportByInsecure(insecure),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(insecure)),
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -101,7 +101,7 @@ func (a *authorizer) initialize(u *url.URL) error {
|
||||
if challenge, exist := cm["bearer"]; exist {
|
||||
a.authorizer = bearer.NewAuthorizer(challenge.Parameters["realm"],
|
||||
challenge.Parameters["service"], basic.NewAuthorizer(a.username, a.password),
|
||||
a.client.Transport.(*http.Transport))
|
||||
a.client.Transport)
|
||||
return nil
|
||||
}
|
||||
if _, exist := cm["basic"]; exist {
|
||||
|
@ -17,11 +17,12 @@ package bearer
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -30,18 +31,15 @@ const (
|
||||
|
||||
// NewAuthorizer return a bearer token authorizer
|
||||
// The parameter "a" is an authorizer used to fetch the token
|
||||
func NewAuthorizer(realm, service string, a lib.Authorizer, transport ...*http.Transport) lib.Authorizer {
|
||||
func NewAuthorizer(realm, service string, a lib.Authorizer, transport http.RoundTripper) lib.Authorizer {
|
||||
authorizer := &authorizer{
|
||||
realm: realm,
|
||||
service: service,
|
||||
authorizer: a,
|
||||
cache: newCache(cacheCapacity),
|
||||
}
|
||||
tp := http.DefaultTransport
|
||||
if len(transport) > 0 && transport[0] != nil {
|
||||
tp = transport[0]
|
||||
}
|
||||
authorizer.client = &http.Client{Transport: tp}
|
||||
|
||||
authorizer.client = &http.Client{Transport: transport}
|
||||
return authorizer
|
||||
}
|
||||
|
||||
|
@ -16,13 +16,16 @@ package bearer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/registry/auth/basic"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/registry/auth/basic"
|
||||
)
|
||||
|
||||
func TestModify(t *testing.T) {
|
||||
@ -39,7 +42,7 @@ func TestModify(t *testing.T) {
|
||||
|
||||
// invalid credential
|
||||
a := basic.NewAuthorizer("username", "invalid_password")
|
||||
authorizer := NewAuthorizer(server.URL, "service", a)
|
||||
authorizer := NewAuthorizer(server.URL, "service", a, commonhttp.NewTransport())
|
||||
req, _ := http.NewRequest(http.MethodGet, server.URL, nil)
|
||||
err := authorizer.Modify(req)
|
||||
require.NotNil(t, err)
|
||||
@ -47,7 +50,7 @@ func TestModify(t *testing.T) {
|
||||
|
||||
// valid credential
|
||||
a = basic.NewAuthorizer("username", "password")
|
||||
authorizer = NewAuthorizer(server.URL, "service", a)
|
||||
authorizer = NewAuthorizer(server.URL, "service", a, commonhttp.NewTransport())
|
||||
req, _ = http.NewRequest(http.MethodGet, server.URL, nil)
|
||||
err = authorizer.Modify(req)
|
||||
require.Nil(t, err)
|
||||
|
@ -18,7 +18,6 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@ -27,6 +26,8 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
_ "github.com/docker/distribution/manifest/ocischema" // register oci manifest unmarshal function
|
||||
@ -105,7 +106,7 @@ func NewClient(url, username, password string, insecure bool) Client {
|
||||
url: url,
|
||||
authorizer: auth.NewAuthorizer(username, password, insecure),
|
||||
client: &http.Client{
|
||||
Transport: commonhttp.GetHTTPTransportByInsecure(insecure),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(insecure)),
|
||||
Timeout: 30 * time.Minute,
|
||||
},
|
||||
}
|
||||
@ -113,18 +114,11 @@ func NewClient(url, username, password string, insecure bool) Client {
|
||||
|
||||
// NewClientWithAuthorizer creates a registry client with the provided authorizer
|
||||
func NewClientWithAuthorizer(url string, authorizer lib.Authorizer, insecure bool) Client {
|
||||
var transportType uint
|
||||
if insecure {
|
||||
transportType = commonhttp.InsecureTransport
|
||||
} else {
|
||||
transportType = commonhttp.SecureTransport
|
||||
}
|
||||
|
||||
return &client{
|
||||
url: url,
|
||||
authorizer: authorizer,
|
||||
client: &http.Client{
|
||||
Transport: commonhttp.GetHTTPTransport(transportType),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(insecure)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -536,7 +536,7 @@ func makeBearerAuthorization(robotAccount *model.Robot, tokenURL string, reposit
|
||||
req.Header.Set("Authorization", auth)
|
||||
|
||||
client := &http.Client{
|
||||
Transport: commonhttp.GetHTTPTransportByInsecure(true),
|
||||
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(true)),
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
|
@ -18,23 +18,23 @@ import (
|
||||
"context"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
tokenutil "github.com/goharbor/harbor/src/core/service/token"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
model2 "github.com/goharbor/harbor/src/pkg/signature/notary/model"
|
||||
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/theupdateframework/notary"
|
||||
"github.com/theupdateframework/notary/client"
|
||||
"github.com/theupdateframework/notary/trustpinning"
|
||||
"github.com/theupdateframework/notary/tuf/data"
|
||||
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -83,7 +83,7 @@ func GetTargets(ctx context.Context, notaryEndpoint string, username string, fqR
|
||||
authorizer := ¬aryAuthorizer{
|
||||
token: t.Token,
|
||||
}
|
||||
tr := NewTransport(commonhttp.GetHTTPTransport(commonhttp.SecureTransport), authorizer)
|
||||
tr := NewTransport(commonhttp.GetHTTPTransport(), authorizer)
|
||||
gun := data.GUN(fqRepo)
|
||||
notaryRepo, err := client.NewFileCachedRepository(notaryCachePath, gun, notaryEndpoint, tr, mockRetriever, trustPin)
|
||||
if err != nil {
|
||||
|
@ -16,7 +16,6 @@ package client
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
@ -62,9 +61,7 @@ func NewClient(baseURL string, cfg *Config) Client {
|
||||
}
|
||||
if cfg != nil {
|
||||
authorizer := auth.NewSecretAuthorizer(cfg.Secret)
|
||||
client.client = common_http.NewClient(&http.Client{
|
||||
Transport: common_http.GetHTTPTransport(common_http.SecureTransport),
|
||||
}, authorizer)
|
||||
client.client = common_http.NewClient(nil, authorizer)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
@ -16,11 +16,12 @@ package registry
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
)
|
||||
|
||||
@ -34,7 +35,7 @@ func newProxy() http.Handler {
|
||||
}
|
||||
proxy := httputil.NewSingleHostReverseProxy(url)
|
||||
if commonhttp.InternalTLSEnabled() {
|
||||
proxy.Transport = commonhttp.GetHTTPTransport(commonhttp.SecureTransport)
|
||||
proxy.Transport = commonhttp.GetHTTPTransport()
|
||||
}
|
||||
|
||||
proxy.Director = basicAuthDirector(proxy.Director)
|
||||
|
Loading…
Reference in New Issue
Block a user