mirror of
https://github.com/goharbor/harbor
synced 2024-09-20 08:45:31 +00:00
Upgrade to distribution (registry) v3 alpha (#19784)
* registryctl/api/registry/blob: fix dropped test error (#19721) Signed-off-by: Lars Lehtonen <lars.lehtonen@gmail.com> * Remove robot account update quota permission (#19819) Signed-off-by: Yang Jiao <yang.jiao@broadcom.com> Co-authored-by: Yang Jiao <yang.jiao@broadcom.com> * Cache image list with digest key (#19801) fixes #19429 Signed-off-by: stonezdj <daojunz@vmware.com> Co-authored-by: stonezdj <daojunz@vmware.com> * Add quota permissions testcase (#19822) Signed-off-by: Yang Jiao <yang.jiao@broadcom.com> Co-authored-by: Yang Jiao <yang.jiao@broadcom.com> * deprecate gosec in makefile (#19828) remove the unused the part from makefile Signed-off-by: wang yan <wangyan@vmware.com> * Add verification that robot account duration is not 0 (#19829) Signed-off-by: Yang Jiao <yang.jiao@broadcom.com> * fix artifact page bug (#19807) * fix artifact page bug * update testcase * Upgrade to distribution (registry) v3 alpha This includes all the benefits of the v3 distribution, but also all breaking changes. Most notably, Image Manifest v2 Schema v1 support has been dropped, as well as the `oss` and `swift` storage drivers. Currently, this still relies on v2's github.com/docker/distribution/registry/client/auth/challenge, because that code has been removed from the public API in v3. Signed-off-by: Aaron Dewes <aaron.dewes@protonmail.com> --------- Signed-off-by: Lars Lehtonen <lars.lehtonen@gmail.com> Signed-off-by: Yang Jiao <yang.jiao@broadcom.com> Signed-off-by: stonezdj <daojunz@vmware.com> Signed-off-by: wang yan <wangyan@vmware.com> Signed-off-by: Aaron Dewes <aaron.dewes@protonmail.com> Co-authored-by: Lars Lehtonen <lars.lehtonen@gmail.com> Co-authored-by: Yang Jiao <72076317+YangJiao0817@users.noreply.github.com> Co-authored-by: Yang Jiao <yang.jiao@broadcom.com> Co-authored-by: stonezdj(Daojun Zhang) <stonezdj@gmail.com> Co-authored-by: stonezdj <daojunz@vmware.com> Co-authored-by: Wang Yan <wangyan@vmware.com> Co-authored-by: ShengqiWang <124650040+ShengqiWang@users.noreply.github.com>
This commit is contained in:
parent
9e5efc99e8
commit
caee762b51
14
Makefile
14
Makefile
|
@ -103,12 +103,12 @@ PKGVERSIONTAG=dev
|
|||
PREPARE_VERSION_NAME=versions
|
||||
|
||||
#versions
|
||||
REGISTRYVERSION=v2.8.3-patch-redis
|
||||
REGISTRYVERSION=v3.0.0-alpha.1+redis-sentinel
|
||||
TRIVYVERSION=v0.47.0
|
||||
TRIVYADAPTERVERSION=v0.30.19
|
||||
|
||||
# version of registry for pulling the source code
|
||||
REGISTRY_SRC_TAG=v2.8.3
|
||||
REGISTRY_SRC_TAG=v3.0.0-alpha.1
|
||||
|
||||
# dependency binaries
|
||||
REGISTRYURL=https://storage.googleapis.com/harbor-builds/bin/registry/release-${REGISTRYVERSION}/registry
|
||||
|
@ -452,16 +452,6 @@ package_offline: update_prepare_version compile build
|
|||
@rm -rf $(HARBORPKG)
|
||||
@echo "Done."
|
||||
|
||||
gosec:
|
||||
#go get github.com/securego/gosec/cmd/gosec
|
||||
#go get github.com/dghubble/sling
|
||||
@echo "run secure go scan ..."
|
||||
@if [ "$(GOSECRESULTS)" != "" ] ; then \
|
||||
$(GOPATH)/bin/gosec -fmt=json -out=$(GOSECRESULTS) -quiet ./... | true ; \
|
||||
else \
|
||||
$(GOPATH)/bin/gosec -fmt=json -out=harbor_gas_output.json -quiet ./... | true ; \
|
||||
fi
|
||||
|
||||
go_check: gen_apis mocks_check misspell commentfmt lint
|
||||
|
||||
commentfmt:
|
||||
|
|
|
@ -4719,7 +4719,7 @@ paths:
|
|||
summary: Get job log by job id
|
||||
description: Get job log by job id, it is only used by administrator
|
||||
produces:
|
||||
- text/plain
|
||||
- text/plain
|
||||
tags:
|
||||
- jobservice
|
||||
parameters:
|
||||
|
@ -6071,7 +6071,7 @@ paths:
|
|||
description: Specify whether the dangerous Artifact are included inside summary information
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
default: false
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
|
@ -6090,15 +6090,15 @@ paths:
|
|||
get:
|
||||
summary: Get the vulnerability list.
|
||||
description: |
|
||||
Get the vulnerability list. use q to pass the query condition,
|
||||
Get the vulnerability list. use q to pass the query condition,
|
||||
supported conditions:
|
||||
cve_id(exact match)
|
||||
cvss_score_v3(range condition)
|
||||
severity(exact match)
|
||||
repository_name(exact match)
|
||||
project_id(exact match)
|
||||
repository_name(exact match)
|
||||
project_id(exact match)
|
||||
package(exact match)
|
||||
tag(exact match)
|
||||
tag(exact match)
|
||||
digest(exact match)
|
||||
tags:
|
||||
- securityhub
|
||||
|
@ -7656,8 +7656,9 @@ definitions:
|
|||
description: The level of the robot, project or system
|
||||
duration:
|
||||
type: integer
|
||||
x-nullable: true
|
||||
format: int64
|
||||
description: The duration of the robot in days
|
||||
description: The duration of the robot in days, duration must be either -1(Never) or a positive integer
|
||||
editable:
|
||||
type: boolean
|
||||
x-omitempty: false
|
||||
|
@ -7704,7 +7705,7 @@ definitions:
|
|||
duration:
|
||||
type: integer
|
||||
format: int64
|
||||
description: The duration of the robot in days
|
||||
description: The duration of the robot in days, duration must be either -1(Never) or a positive integer
|
||||
permissions:
|
||||
type: array
|
||||
items:
|
||||
|
@ -7994,7 +7995,7 @@ definitions:
|
|||
type: string
|
||||
description: |
|
||||
The schedule type. The valid values are 'Hourly', 'Daily', 'Weekly', 'Custom', 'Manual', 'None' and 'Schedule'.
|
||||
'Manual' means to trigger it right away, 'Schedule' means to trigger it by a specified cron schedule and
|
||||
'Manual' means to trigger it right away, 'Schedule' means to trigger it by a specified cron schedule and
|
||||
'None' means to cancel the schedule.
|
||||
enum:
|
||||
- Hourly
|
||||
|
@ -9813,12 +9814,12 @@ definitions:
|
|||
type: object
|
||||
description: the dangerous CVE information
|
||||
properties:
|
||||
cve_id:
|
||||
cve_id:
|
||||
type: string
|
||||
description: the cve id
|
||||
severity:
|
||||
type: string
|
||||
description: the severity of the CVE
|
||||
description: the severity of the CVE
|
||||
cvss_score_v3:
|
||||
type: number
|
||||
format: float64
|
||||
|
@ -9828,7 +9829,7 @@ definitions:
|
|||
description: the description of the CVE
|
||||
package:
|
||||
type: string
|
||||
description: the package of the CVE
|
||||
description: the package of the CVE
|
||||
version:
|
||||
type: string
|
||||
description: the version of the package
|
||||
|
@ -9836,14 +9837,14 @@ definitions:
|
|||
type: object
|
||||
description: the dangerous artifact information
|
||||
properties:
|
||||
project_id:
|
||||
project_id:
|
||||
type: integer
|
||||
format: int64
|
||||
description: the project id of the artifact
|
||||
repository_name:
|
||||
type: string
|
||||
description: the repository name of the artifact
|
||||
digest:
|
||||
digest:
|
||||
type: string
|
||||
description: the digest of the artifact
|
||||
critical_cnt:
|
||||
|
@ -9903,6 +9904,6 @@ definitions:
|
|||
description: The description of the vulnerability
|
||||
links:
|
||||
type: array
|
||||
items:
|
||||
items:
|
||||
type: string
|
||||
description: Links of the vulnerability
|
||||
|
|
|
@ -29,9 +29,14 @@ storage:
|
|||
{% endif %}
|
||||
redis:
|
||||
{% if sentinel_master_set %}
|
||||
# sentinel hosts with comma
|
||||
addr: {{redis_host}}
|
||||
sentinelMasterSet: {{sentinel_master_set}}
|
||||
sentinel:
|
||||
{# sentinel hosts are separated with comma #}
|
||||
{% set redis_hosts = redis_host.split(',') %}
|
||||
addresses:
|
||||
{% for local_redis_host in redis_hosts %}
|
||||
- {{local_redis_host}}
|
||||
{% endfor %}
|
||||
sentinelMasterSet: {{sentinel_master_set}}
|
||||
{% else %}
|
||||
addr: {{redis_host}}
|
||||
{% endif %}
|
||||
|
@ -70,6 +75,3 @@ auth:
|
|||
path: /etc/registry/passwd
|
||||
validation:
|
||||
disabled: true
|
||||
compatibility:
|
||||
schema1:
|
||||
enabled: true
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
FROM golang:1.21.5
|
||||
|
||||
ENV DISTRIBUTION_DIR /go/src/github.com/docker/distribution
|
||||
ENV DISTRIBUTION_DIR /go/src/github.com/distribution/distribution/v3
|
||||
ENV BUILDTAGS include_oss include_gcs
|
||||
ENV GO111MODULE auto
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ docker build -f $TEMP/Dockerfile.binary -t registry-golang $TEMP
|
|||
|
||||
echo 'copy the registry binary to local...'
|
||||
ID=$(docker create registry-golang)
|
||||
docker cp $ID:/go/src/github.com/docker/distribution/bin/registry binary/registry
|
||||
docker cp $ID:/go/src/github.com/distribution/distribution/v3/bin/registry binary/registry
|
||||
|
||||
docker rm -f $ID
|
||||
docker rmi -f registry-golang
|
||||
|
|
|
@ -1,883 +1,112 @@
|
|||
diff --git a/configuration/configuration.go b/configuration/configuration.go
|
||||
index 7076df85d4..3e74330321 100644
|
||||
index e4d4311d..f25aadf9 100644
|
||||
--- a/configuration/configuration.go
|
||||
+++ b/configuration/configuration.go
|
||||
@@ -168,6 +168,9 @@ type Configuration struct {
|
||||
// Addr specifies the the redis instance available to the application.
|
||||
Addr string `yaml:"addr,omitempty"`
|
||||
@@ -271,11 +271,23 @@ type FileChecker struct {
|
||||
Threshold int `yaml:"threshold,omitempty"`
|
||||
}
|
||||
|
||||
+ // SentinelMasterSet specifies the the redis sentinel master set name.
|
||||
+ SentinelMasterSet string `yaml:"sentinelMasterSet,omitempty"`
|
||||
+type RedisSentinel struct {
|
||||
+ // MasterName specifies the name of the master sentinel.
|
||||
+ MasterName string `yaml:"masterName,omitempty"`
|
||||
+
|
||||
// Password string to use when making a connection.
|
||||
Password string `yaml:"password,omitempty"`
|
||||
+ // Addresses specifies the addresses of the sentinels.
|
||||
+ Addresses []string `yaml:"addresses,omitempty"`
|
||||
+}
|
||||
+
|
||||
// Redis configures the redis pool available to the registry webapp.
|
||||
type Redis struct {
|
||||
// Addr specifies the the redis instance available to the application.
|
||||
Addr string `yaml:"addr,omitempty"`
|
||||
|
||||
+ // Sentinel specifies the sentinel instance available to the application.
|
||||
+ // If this is set, the Addr field is ignored.
|
||||
+ Sentinel RedisSentinel `yaml:"sentinel,omitempty"`
|
||||
+
|
||||
// Usernames can be used as a finer-grained permission control since the introduction of the redis 6.0.
|
||||
Username string `yaml:"username,omitempty"`
|
||||
|
||||
diff --git a/registry/handlers/app.go b/registry/handlers/app.go
|
||||
index bf56cea22a..4a7cee9a2e 100644
|
||||
index 2983176b..11716496 100644
|
||||
--- a/registry/handlers/app.go
|
||||
+++ b/registry/handlers/app.go
|
||||
@@ -3,6 +3,7 @@ package handlers
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
+ "errors"
|
||||
"expvar"
|
||||
"fmt"
|
||||
"math"
|
||||
@@ -16,6 +17,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
@@ -487,12 +487,12 @@ func (app *App) configureEvents(configuration *configuration.Configuration) {
|
||||
}
|
||||
|
||||
+ "github.com/FZambia/sentinel"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/configuration"
|
||||
@@ -499,6 +501,45 @@ func (app *App) configureRedis(configuration *configuration.Configuration) {
|
||||
func (app *App) configureRedis(cfg *configuration.Configuration) {
|
||||
- if cfg.Redis.Addr == "" {
|
||||
+ if cfg.Redis.Addr == "" && (len(cfg.Redis.Sentinel.Addresses) == 0 || cfg.Redis.Sentinel.MasterName == "") {
|
||||
dcontext.GetLogger(app).Infof("redis not configured")
|
||||
return
|
||||
}
|
||||
|
||||
+ var getRedisAddr func() (string, error)
|
||||
+ var testOnBorrow func(c redis.Conn, t time.Time) error
|
||||
+ if configuration.Redis.SentinelMasterSet != "" {
|
||||
+ sntnl := &sentinel.Sentinel{
|
||||
+ Addrs: strings.Split(configuration.Redis.Addr, ","),
|
||||
+ MasterName: configuration.Redis.SentinelMasterSet,
|
||||
+ Dial: func(addr string) (redis.Conn, error) {
|
||||
+ c, err := redis.DialTimeout("tcp", addr,
|
||||
+ configuration.Redis.DialTimeout,
|
||||
+ configuration.Redis.ReadTimeout,
|
||||
+ configuration.Redis.WriteTimeout)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ return c, nil
|
||||
+ },
|
||||
+ }
|
||||
+ getRedisAddr = func() (string, error) {
|
||||
+ return sntnl.MasterAddr()
|
||||
+ }
|
||||
+ testOnBorrow = func(c redis.Conn, t time.Time) error {
|
||||
+ if !sentinel.TestRole(c, "master") {
|
||||
+ return errors.New("role check failed")
|
||||
+ }
|
||||
+ return nil
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ getRedisAddr = func() (string, error) {
|
||||
+ return configuration.Redis.Addr, nil
|
||||
+ }
|
||||
+ testOnBorrow = func(c redis.Conn, t time.Time) error {
|
||||
+ // TODO(stevvooe): We can probably do something more interesting
|
||||
+ // here with the health package.
|
||||
+ _, err := c.Do("PING")
|
||||
+ return err
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
pool := &redis.Pool{
|
||||
Dial: func() (redis.Conn, error) {
|
||||
// TODO(stevvooe): Yet another use case for contextual timing.
|
||||
@@ -514,8 +555,11 @@ func (app *App) configureRedis(configuration *configuration.Configuration) {
|
||||
}
|
||||
}
|
||||
- app.redis = app.createPool(cfg.Redis)
|
||||
+ app.redis = app.createRedisClient(cfg.Redis)
|
||||
|
||||
- conn, err := redis.DialTimeout("tcp",
|
||||
- configuration.Redis.Addr,
|
||||
+ redisAddr, err := getRedisAddr()
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ conn, err := redis.DialTimeout("tcp", redisAddr,
|
||||
configuration.Redis.DialTimeout,
|
||||
configuration.Redis.ReadTimeout,
|
||||
configuration.Redis.WriteTimeout)
|
||||
@@ -547,16 +591,11 @@ func (app *App) configureRedis(configuration *configuration.Configuration) {
|
||||
done(nil)
|
||||
return conn, nil
|
||||
},
|
||||
- MaxIdle: configuration.Redis.Pool.MaxIdle,
|
||||
- MaxActive: configuration.Redis.Pool.MaxActive,
|
||||
- IdleTimeout: configuration.Redis.Pool.IdleTimeout,
|
||||
- TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
||||
- // TODO(stevvooe): We can probably do something more interesting
|
||||
- // here with the health package.
|
||||
- _, err := c.Do("PING")
|
||||
- return err
|
||||
// Enable metrics instrumentation.
|
||||
if err := redisotel.InstrumentMetrics(app.redis); err != nil {
|
||||
@@ -514,25 +514,45 @@ func (app *App) configureRedis(cfg *configuration.Configuration) {
|
||||
}))
|
||||
}
|
||||
|
||||
-func (app *App) createPool(cfg configuration.Redis) *redis.Client {
|
||||
- return redis.NewClient(&redis.Options{
|
||||
- Addr: cfg.Addr,
|
||||
- OnConnect: func(ctx context.Context, cn *redis.Conn) error {
|
||||
- res := cn.Ping(ctx)
|
||||
- return res.Err()
|
||||
- },
|
||||
- Wait: false, // if a connection is not available, proceed without cache.
|
||||
+ MaxIdle: configuration.Redis.Pool.MaxIdle,
|
||||
+ MaxActive: configuration.Redis.Pool.MaxActive,
|
||||
+ IdleTimeout: configuration.Redis.Pool.IdleTimeout,
|
||||
+ TestOnBorrow: testOnBorrow,
|
||||
+ Wait: false, // if a connection is not available, proceed without cache.
|
||||
}
|
||||
|
||||
app.redis = pool
|
||||
diff --git a/registry/handlers/app_test.go b/registry/handlers/app_test.go
|
||||
index 60a57e6c15..8a644d83d8 100644
|
||||
--- a/registry/handlers/app_test.go
|
||||
+++ b/registry/handlers/app_test.go
|
||||
@@ -140,7 +140,29 @@ func TestAppDispatcher(t *testing.T) {
|
||||
// TestNewApp covers the creation of an application via NewApp with a
|
||||
// configuration.
|
||||
func TestNewApp(t *testing.T) {
|
||||
- ctx := context.Background()
|
||||
+
|
||||
+ config := configuration.Configuration{
|
||||
+ Storage: configuration.Storage{
|
||||
+ "testdriver": nil,
|
||||
+ "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{
|
||||
+ "enabled": false,
|
||||
+ }},
|
||||
+ },
|
||||
+ Auth: configuration.Auth{
|
||||
+ // For now, we simply test that new auth results in a viable
|
||||
+ // application.
|
||||
+ "silly": {
|
||||
+ "realm": "realm-test",
|
||||
+ "service": "service-test",
|
||||
- Username: cfg.Username,
|
||||
- Password: cfg.Password,
|
||||
- DB: cfg.DB,
|
||||
- MaxRetries: 3,
|
||||
- DialTimeout: cfg.DialTimeout,
|
||||
- ReadTimeout: cfg.ReadTimeout,
|
||||
- WriteTimeout: cfg.WriteTimeout,
|
||||
- PoolFIFO: false,
|
||||
- MaxIdleConns: cfg.Pool.MaxIdle,
|
||||
- PoolSize: cfg.Pool.MaxActive,
|
||||
- ConnMaxIdleTime: cfg.Pool.IdleTimeout,
|
||||
- })
|
||||
+func (app *App) createRedisClient(cfg configuration.Redis) *redis.Client {
|
||||
+ // This function assumes that cfg.Addresses is not empty, which is checked by the caller.
|
||||
+ if len(cfg.Sentinel.Addresses) > 0 && cfg.Sentinel.MasterName != "" {
|
||||
+ return redis.NewFailoverClient(&redis.FailoverOptions{
|
||||
+ MasterName: cfg.Sentinel.MasterName,
|
||||
+ SentinelAddrs: cfg.Sentinel.Addresses,
|
||||
+ OnConnect: nil,
|
||||
+ Username: cfg.Username,
|
||||
+ Password: cfg.Password,
|
||||
+ DB: cfg.DB,
|
||||
+ MaxRetries: 3,
|
||||
+ DialTimeout: cfg.DialTimeout,
|
||||
+ ReadTimeout: cfg.ReadTimeout,
|
||||
+ WriteTimeout: cfg.WriteTimeout,
|
||||
+ PoolFIFO: false,
|
||||
+ MaxIdleConns: cfg.Pool.MaxIdle,
|
||||
+ PoolSize: cfg.Pool.MaxActive,
|
||||
+ ConnMaxIdleTime: cfg.Pool.IdleTimeout,
|
||||
+ })
|
||||
+ } else {
|
||||
+ return redis.NewClient(&redis.Options{
|
||||
+ Addr: cfg.Addr,
|
||||
+ OnConnect: func(ctx context.Context, cn *redis.Conn) error {
|
||||
+ res := cn.Ping(ctx)
|
||||
+ return res.Err()
|
||||
+ },
|
||||
+ },
|
||||
+ Username: cfg.Username,
|
||||
+ Password: cfg.Password,
|
||||
+ DB: cfg.DB,
|
||||
+ MaxRetries: 3,
|
||||
+ DialTimeout: cfg.DialTimeout,
|
||||
+ ReadTimeout: cfg.ReadTimeout,
|
||||
+ WriteTimeout: cfg.WriteTimeout,
|
||||
+ PoolFIFO: false,
|
||||
+ MaxIdleConns: cfg.Pool.MaxIdle,
|
||||
+ PoolSize: cfg.Pool.MaxActive,
|
||||
+ ConnMaxIdleTime: cfg.Pool.IdleTimeout,
|
||||
+ })
|
||||
+ }
|
||||
+ runAppWithConfig(t, config)
|
||||
+}
|
||||
+
|
||||
+// TestNewApp covers the creation of an application via NewApp with a
|
||||
+// configuration(with redis).
|
||||
+func TestNewAppWithRedis(t *testing.T) {
|
||||
config := configuration.Configuration{
|
||||
Storage: configuration.Storage{
|
||||
"testdriver": nil,
|
||||
@@ -157,7 +179,38 @@ func TestNewApp(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
+ config.Redis.Addr = "127.0.0.1:6379"
|
||||
+ config.Redis.DB = 0
|
||||
+ runAppWithConfig(t, config)
|
||||
+}
|
||||
}
|
||||
|
||||
+// TestNewApp covers the creation of an application via NewApp with a
|
||||
+// configuration(with redis sentinel cluster).
|
||||
+func TestNewAppWithRedisSentinelCluster(t *testing.T) {
|
||||
+ config := configuration.Configuration{
|
||||
+ Storage: configuration.Storage{
|
||||
+ "testdriver": nil,
|
||||
+ "maintenance": configuration.Parameters{"uploadpurging": map[interface{}]interface{}{
|
||||
+ "enabled": false,
|
||||
+ }},
|
||||
+ },
|
||||
+ Auth: configuration.Auth{
|
||||
+ // For now, we simply test that new auth results in a viable
|
||||
+ // application.
|
||||
+ "silly": {
|
||||
+ "realm": "realm-test",
|
||||
+ "service": "service-test",
|
||||
+ },
|
||||
+ },
|
||||
+ }
|
||||
+ config.Redis.Addr = "192.168.0.11:26379,192.168.0.12:26379"
|
||||
+ config.Redis.DB = 0
|
||||
+ config.Redis.SentinelMasterSet = "mymaster"
|
||||
+ runAppWithConfig(t, config)
|
||||
+}
|
||||
+
|
||||
+func runAppWithConfig(t *testing.T, config configuration.Configuration) {
|
||||
+ ctx := context.Background()
|
||||
// Mostly, with this test, given a sane configuration, we are simply
|
||||
// ensuring that NewApp doesn't panic. We might want to tweak this
|
||||
// behavior.
|
||||
diff --git a/vendor.conf b/vendor.conf
|
||||
index 33fe616b76..a8d8f58bc6 100644
|
||||
--- a/vendor.conf
|
||||
+++ b/vendor.conf
|
||||
@@ -51,3 +51,4 @@ gopkg.in/yaml.v2 v2.2.1
|
||||
rsc.io/letsencrypt e770c10b0f1a64775ae91d240407ce00d1a5bdeb https://github.com/dmcgowan/letsencrypt.git
|
||||
github.com/opencontainers/go-digest ea51bea511f75cfa3ef6098cc253c5c3609b037a # v1.0.0
|
||||
github.com/opencontainers/image-spec 67d2d5658fe0476ab9bf414cec164077ebff3920 # v1.0.2
|
||||
+github.com/FZambia/sentinel 5585739eb4b6478aa30161866ccf9ce0ef5847c7 https://github.com/jeremyxu2010/sentinel.git
|
||||
diff --git a/vendor/github.com/FZambia/sentinel/LICENSE b/vendor/github.com/FZambia/sentinel/LICENSE
|
||||
new file mode 100644
|
||||
index 0000000000..8dada3edaf
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/FZambia/sentinel/LICENSE
|
||||
@@ -0,0 +1,201 @@
|
||||
+ Apache License
|
||||
+ Version 2.0, January 2004
|
||||
+ http://www.apache.org/licenses/
|
||||
+
|
||||
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
+
|
||||
+ 1. Definitions.
|
||||
+
|
||||
+ "License" shall mean the terms and conditions for use, reproduction,
|
||||
+ and distribution as defined by Sections 1 through 9 of this document.
|
||||
+
|
||||
+ "Licensor" shall mean the copyright owner or entity authorized by
|
||||
+ the copyright owner that is granting the License.
|
||||
+
|
||||
+ "Legal Entity" shall mean the union of the acting entity and all
|
||||
+ other entities that control, are controlled by, or are under common
|
||||
+ control with that entity. For the purposes of this definition,
|
||||
+ "control" means (i) the power, direct or indirect, to cause the
|
||||
+ direction or management of such entity, whether by contract or
|
||||
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
+ outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
+
|
||||
+ "You" (or "Your") shall mean an individual or Legal Entity
|
||||
+ exercising permissions granted by this License.
|
||||
+
|
||||
+ "Source" form shall mean the preferred form for making modifications,
|
||||
+ including but not limited to software source code, documentation
|
||||
+ source, and configuration files.
|
||||
+
|
||||
+ "Object" form shall mean any form resulting from mechanical
|
||||
+ transformation or translation of a Source form, including but
|
||||
+ not limited to compiled object code, generated documentation,
|
||||
+ and conversions to other media types.
|
||||
+
|
||||
+ "Work" shall mean the work of authorship, whether in Source or
|
||||
+ Object form, made available under the License, as indicated by a
|
||||
+ copyright notice that is included in or attached to the work
|
||||
+ (an example is provided in the Appendix below).
|
||||
+
|
||||
+ "Derivative Works" shall mean any work, whether in Source or Object
|
||||
+ form, that is based on (or derived from) the Work and for which the
|
||||
+ editorial revisions, annotations, elaborations, or other modifications
|
||||
+ represent, as a whole, an original work of authorship. For the purposes
|
||||
+ of this License, Derivative Works shall not include works that remain
|
||||
+ separable from, or merely link (or bind by name) to the interfaces of,
|
||||
+ the Work and Derivative Works thereof.
|
||||
+
|
||||
+ "Contribution" shall mean any work of authorship, including
|
||||
+ the original version of the Work and any modifications or additions
|
||||
+ to that Work or Derivative Works thereof, that is intentionally
|
||||
+ submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
+ or by an individual or Legal Entity authorized to submit on behalf of
|
||||
+ the copyright owner. For the purposes of this definition, "submitted"
|
||||
+ means any form of electronic, verbal, or written communication sent
|
||||
+ to the Licensor or its representatives, including but not limited to
|
||||
+ communication on electronic mailing lists, source code control systems,
|
||||
+ and issue tracking systems that are managed by, or on behalf of, the
|
||||
+ Licensor for the purpose of discussing and improving the Work, but
|
||||
+ excluding communication that is conspicuously marked or otherwise
|
||||
+ designated in writing by the copyright owner as "Not a Contribution."
|
||||
+
|
||||
+ "Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
+ on behalf of whom a Contribution has been received by Licensor and
|
||||
+ subsequently incorporated within the Work.
|
||||
+
|
||||
+ 2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
+ this License, each Contributor hereby grants to You a perpetual,
|
||||
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
+ copyright license to reproduce, prepare Derivative Works of,
|
||||
+ publicly display, publicly perform, sublicense, and distribute the
|
||||
+ Work and such Derivative Works in Source or Object form.
|
||||
+
|
||||
+ 3. Grant of Patent License. Subject to the terms and conditions of
|
||||
+ this License, each Contributor hereby grants to You a perpetual,
|
||||
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
+ (except as stated in this section) patent license to make, have made,
|
||||
+ use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
+ where such license applies only to those patent claims licensable
|
||||
+ by such Contributor that are necessarily infringed by their
|
||||
+ Contribution(s) alone or by combination of their Contribution(s)
|
||||
+ with the Work to which such Contribution(s) was submitted. If You
|
||||
+ institute patent litigation against any entity (including a
|
||||
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
+ or a Contribution incorporated within the Work constitutes direct
|
||||
+ or contributory patent infringement, then any patent licenses
|
||||
+ granted to You under this License for that Work shall terminate
|
||||
+ as of the date such litigation is filed.
|
||||
+
|
||||
+ 4. Redistribution. You may reproduce and distribute copies of the
|
||||
+ Work or Derivative Works thereof in any medium, with or without
|
||||
+ modifications, and in Source or Object form, provided that You
|
||||
+ meet the following conditions:
|
||||
+
|
||||
+ (a) You must give any other recipients of the Work or
|
||||
+ Derivative Works a copy of this License; and
|
||||
+
|
||||
+ (b) You must cause any modified files to carry prominent notices
|
||||
+ stating that You changed the files; and
|
||||
+
|
||||
+ (c) You must retain, in the Source form of any Derivative Works
|
||||
+ that You distribute, all copyright, patent, trademark, and
|
||||
+ attribution notices from the Source form of the Work,
|
||||
+ excluding those notices that do not pertain to any part of
|
||||
+ the Derivative Works; and
|
||||
+
|
||||
+ (d) If the Work includes a "NOTICE" text file as part of its
|
||||
+ distribution, then any Derivative Works that You distribute must
|
||||
+ include a readable copy of the attribution notices contained
|
||||
+ within such NOTICE file, excluding those notices that do not
|
||||
+ pertain to any part of the Derivative Works, in at least one
|
||||
+ of the following places: within a NOTICE text file distributed
|
||||
+ as part of the Derivative Works; within the Source form or
|
||||
+ documentation, if provided along with the Derivative Works; or,
|
||||
+ within a display generated by the Derivative Works, if and
|
||||
+ wherever such third-party notices normally appear. The contents
|
||||
+ of the NOTICE file are for informational purposes only and
|
||||
+ do not modify the License. You may add Your own attribution
|
||||
+ notices within Derivative Works that You distribute, alongside
|
||||
+ or as an addendum to the NOTICE text from the Work, provided
|
||||
+ that such additional attribution notices cannot be construed
|
||||
+ as modifying the License.
|
||||
+
|
||||
+ You may add Your own copyright statement to Your modifications and
|
||||
+ may provide additional or different license terms and conditions
|
||||
+ for use, reproduction, or distribution of Your modifications, or
|
||||
+ for any such Derivative Works as a whole, provided Your use,
|
||||
+ reproduction, and distribution of the Work otherwise complies with
|
||||
+ the conditions stated in this License.
|
||||
+
|
||||
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
+ any Contribution intentionally submitted for inclusion in the Work
|
||||
+ by You to the Licensor shall be under the terms and conditions of
|
||||
+ this License, without any additional terms or conditions.
|
||||
+ Notwithstanding the above, nothing herein shall supersede or modify
|
||||
+ the terms of any separate license agreement you may have executed
|
||||
+ with Licensor regarding such Contributions.
|
||||
+
|
||||
+ 6. Trademarks. This License does not grant permission to use the trade
|
||||
+ names, trademarks, service marks, or product names of the Licensor,
|
||||
+ except as required for reasonable and customary use in describing the
|
||||
+ origin of the Work and reproducing the content of the NOTICE file.
|
||||
+
|
||||
+ 7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
+ agreed to in writing, Licensor provides the Work (and each
|
||||
+ Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
+ implied, including, without limitation, any warranties or conditions
|
||||
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
+ PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
+ appropriateness of using or redistributing the Work and assume any
|
||||
+ risks associated with Your exercise of permissions under this License.
|
||||
+
|
||||
+ 8. Limitation of Liability. In no event and under no legal theory,
|
||||
+ whether in tort (including negligence), contract, or otherwise,
|
||||
+ unless required by applicable law (such as deliberate and grossly
|
||||
+ negligent acts) or agreed to in writing, shall any Contributor be
|
||||
+ liable to You for damages, including any direct, indirect, special,
|
||||
+ incidental, or consequential damages of any character arising as a
|
||||
+ result of this License or out of the use or inability to use the
|
||||
+ Work (including but not limited to damages for loss of goodwill,
|
||||
+ work stoppage, computer failure or malfunction, or any and all
|
||||
+ other commercial damages or losses), even if such Contributor
|
||||
+ has been advised of the possibility of such damages.
|
||||
+
|
||||
+ 9. Accepting Warranty or Additional Liability. While redistributing
|
||||
+ the Work or Derivative Works thereof, You may choose to offer,
|
||||
+ and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
+ or other liability obligations and/or rights consistent with this
|
||||
+ License. However, in accepting such obligations, You may act only
|
||||
+ on Your own behalf and on Your sole responsibility, not on behalf
|
||||
+ of any other Contributor, and only if You agree to indemnify,
|
||||
+ defend, and hold each Contributor harmless for any liability
|
||||
+ incurred by, or claims asserted against, such Contributor by reason
|
||||
+ of your accepting any such warranty or additional liability.
|
||||
+
|
||||
+ END OF TERMS AND CONDITIONS
|
||||
+
|
||||
+ APPENDIX: How to apply the Apache License to your work.
|
||||
+
|
||||
+ To apply the Apache License to your work, attach the following
|
||||
+ boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
+ replaced with your own identifying information. (Don't include
|
||||
+ the brackets!) The text should be enclosed in the appropriate
|
||||
+ comment syntax for the file format. We also recommend that a
|
||||
+ file or class name and description of purpose be included on the
|
||||
+ same "printed page" as the copyright notice for easier
|
||||
+ identification within third-party archives.
|
||||
+
|
||||
+ Copyright {yyyy} {name of copyright owner}
|
||||
+
|
||||
+ 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.
|
||||
diff --git a/vendor/github.com/FZambia/sentinel/README.md b/vendor/github.com/FZambia/sentinel/README.md
|
||||
new file mode 100644
|
||||
index 0000000000..f544c54ef6
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/FZambia/sentinel/README.md
|
||||
@@ -0,0 +1,39 @@
|
||||
+go-sentinel
|
||||
+===========
|
||||
+
|
||||
+Redis Sentinel support for [redigo](https://github.com/gomodule/redigo) library.
|
||||
+
|
||||
+Documentation
|
||||
+-------------
|
||||
+
|
||||
+- [API Reference](http://godoc.org/github.com/FZambia/sentinel)
|
||||
+
|
||||
+Alternative solution
|
||||
+--------------------
|
||||
+
|
||||
+You can alternatively configure Haproxy between your application and Redis to proxy requests to Redis master instance if you only need HA:
|
||||
+
|
||||
+```
|
||||
+listen redis
|
||||
+ server redis-01 127.0.0.1:6380 check port 6380 check inter 2s weight 1 inter 2s downinter 5s rise 10 fall 2
|
||||
+ server redis-02 127.0.0.1:6381 check port 6381 check inter 2s weight 1 inter 2s downinter 5s rise 10 fall 2 backup
|
||||
+ bind *:6379
|
||||
+ mode tcp
|
||||
+ option tcpka
|
||||
+ option tcplog
|
||||
+ option tcp-check
|
||||
+ tcp-check send PING\r\n
|
||||
+ tcp-check expect string +PONG
|
||||
+ tcp-check send info\ replication\r\n
|
||||
+ tcp-check expect string role:master
|
||||
+ tcp-check send QUIT\r\n
|
||||
+ tcp-check expect string +OK
|
||||
+ balance roundrobin
|
||||
+```
|
||||
+
|
||||
+This way you don't need to use this library.
|
||||
+
|
||||
+License
|
||||
+-------
|
||||
+
|
||||
+Library is available under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).
|
||||
diff --git a/vendor/github.com/FZambia/sentinel/sentinel.go b/vendor/github.com/FZambia/sentinel/sentinel.go
|
||||
new file mode 100644
|
||||
index 0000000000..79209e9f0d
|
||||
--- /dev/null
|
||||
+++ b/vendor/github.com/FZambia/sentinel/sentinel.go
|
||||
@@ -0,0 +1,426 @@
|
||||
+package sentinel
|
||||
+
|
||||
+import (
|
||||
+ "errors"
|
||||
+ "fmt"
|
||||
+ "net"
|
||||
+ "strings"
|
||||
+ "sync"
|
||||
+ "time"
|
||||
+
|
||||
+ "github.com/garyburd/redigo/redis"
|
||||
+)
|
||||
+
|
||||
+// Sentinel provides a way to add high availability (HA) to Redis Pool using
|
||||
+// preconfigured addresses of Sentinel servers and name of master which Sentinels
|
||||
+// monitor. It works with Redis >= 2.8.12 (mostly because of ROLE command that
|
||||
+// was introduced in that version, it's possible though to support old versions
|
||||
+// using INFO command).
|
||||
+//
|
||||
+// Example of the simplest usage to contact master "mymaster":
|
||||
+//
|
||||
+// func newSentinelPool() *redis.Pool {
|
||||
+// sntnl := &sentinel.Sentinel{
|
||||
+// Addrs: []string{":26379", ":26380", ":26381"},
|
||||
+// MasterName: "mymaster",
|
||||
+// Dial: func(addr string) (redis.Conn, error) {
|
||||
+// timeout := 500 * time.Millisecond
|
||||
+// c, err := redis.DialTimeout("tcp", addr, timeout, timeout, timeout)
|
||||
+// if err != nil {
|
||||
+// return nil, err
|
||||
+// }
|
||||
+// return c, nil
|
||||
+// },
|
||||
+// }
|
||||
+// return &redis.Pool{
|
||||
+// MaxIdle: 3,
|
||||
+// MaxActive: 64,
|
||||
+// Wait: true,
|
||||
+// IdleTimeout: 240 * time.Second,
|
||||
+// Dial: func() (redis.Conn, error) {
|
||||
+// masterAddr, err := sntnl.MasterAddr()
|
||||
+// if err != nil {
|
||||
+// return nil, err
|
||||
+// }
|
||||
+// c, err := redis.Dial("tcp", masterAddr)
|
||||
+// if err != nil {
|
||||
+// return nil, err
|
||||
+// }
|
||||
+// return c, nil
|
||||
+// },
|
||||
+// TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
||||
+// if !sentinel.TestRole(c, "master") {
|
||||
+// return errors.New("Role check failed")
|
||||
+// } else {
|
||||
+// return nil
|
||||
+// }
|
||||
+// },
|
||||
+// }
|
||||
+// }
|
||||
+type Sentinel struct {
|
||||
+ // Addrs is a slice with known Sentinel addresses.
|
||||
+ Addrs []string
|
||||
+
|
||||
+ // MasterName is a name of Redis master Sentinel servers monitor.
|
||||
+ MasterName string
|
||||
+
|
||||
+ // Dial is a user supplied function to connect to Sentinel on given address. This
|
||||
+ // address will be chosen from Addrs slice.
|
||||
+ // Note that as per the redis-sentinel client guidelines, a timeout is mandatory
|
||||
+ // while connecting to Sentinels, and should not be set to 0.
|
||||
+ Dial func(addr string) (redis.Conn, error)
|
||||
+
|
||||
+ // Pool is a user supplied function returning custom connection pool to Sentinel.
|
||||
+ // This can be useful to tune options if you are not satisfied with what default
|
||||
+ // Sentinel pool offers. See defaultPool() method for default pool implementation.
|
||||
+ // In most cases you only need to provide Dial function and let this be nil.
|
||||
+ Pool func(addr string) *redis.Pool
|
||||
+
|
||||
+ mu sync.RWMutex
|
||||
+ pools map[string]*redis.Pool
|
||||
+ addr string
|
||||
+}
|
||||
+
|
||||
+// NoSentinelsAvailable is returned when all sentinels in the list are exhausted
|
||||
+// (or none configured), and contains the last error returned by Dial (which
|
||||
+// may be nil)
|
||||
+type NoSentinelsAvailable struct {
|
||||
+ lastError error
|
||||
+}
|
||||
+
|
||||
+func (ns NoSentinelsAvailable) Error() string {
|
||||
+ if ns.lastError != nil {
|
||||
+ return fmt.Sprintf("redigo: no sentinels available; last error: %s", ns.lastError.Error())
|
||||
+ }
|
||||
+ return fmt.Sprintf("redigo: no sentinels available")
|
||||
+}
|
||||
+
|
||||
+// putToTop puts Sentinel address to the top of address list - this means
|
||||
+// that all next requests will use Sentinel on this address first.
|
||||
+//
|
||||
+// From Sentinel guidelines:
|
||||
+//
|
||||
+// The first Sentinel replying to the client request should be put at the
|
||||
+// start of the list, so that at the next reconnection, we'll try first
|
||||
+// the Sentinel that was reachable in the previous connection attempt,
|
||||
+// minimizing latency.
|
||||
+//
|
||||
+// Lock must be held by caller.
|
||||
+func (s *Sentinel) putToTop(addr string) {
|
||||
+ addrs := s.Addrs
|
||||
+ if addrs[0] == addr {
|
||||
+ // Already on top.
|
||||
+ return
|
||||
+ }
|
||||
+ newAddrs := []string{addr}
|
||||
+ for _, a := range addrs {
|
||||
+ if a == addr {
|
||||
+ continue
|
||||
+ }
|
||||
+ newAddrs = append(newAddrs, a)
|
||||
+ }
|
||||
+ s.Addrs = newAddrs
|
||||
+}
|
||||
+
|
||||
+// putToBottom puts Sentinel address to the bottom of address list.
|
||||
+// We call this method internally when see that some Sentinel failed to answer
|
||||
+// on application request so next time we start with another one.
|
||||
+//
|
||||
+// Lock must be held by caller.
|
||||
+func (s *Sentinel) putToBottom(addr string) {
|
||||
+ addrs := s.Addrs
|
||||
+ if addrs[len(addrs)-1] == addr {
|
||||
+ // Already on bottom.
|
||||
+ return
|
||||
+ }
|
||||
+ newAddrs := []string{}
|
||||
+ for _, a := range addrs {
|
||||
+ if a == addr {
|
||||
+ continue
|
||||
+ }
|
||||
+ newAddrs = append(newAddrs, a)
|
||||
+ }
|
||||
+ newAddrs = append(newAddrs, addr)
|
||||
+ s.Addrs = newAddrs
|
||||
+}
|
||||
+
|
||||
+// defaultPool returns a connection pool to one Sentinel. This allows
|
||||
+// us to call concurrent requests to Sentinel using connection Do method.
|
||||
+func (s *Sentinel) defaultPool(addr string) *redis.Pool {
|
||||
+ return &redis.Pool{
|
||||
+ MaxIdle: 3,
|
||||
+ MaxActive: 10,
|
||||
+ Wait: true,
|
||||
+ IdleTimeout: 240 * time.Second,
|
||||
+ Dial: func() (redis.Conn, error) {
|
||||
+ return s.Dial(addr)
|
||||
+ },
|
||||
+ TestOnBorrow: func(c redis.Conn, t time.Time) error {
|
||||
+ _, err := c.Do("PING")
|
||||
+ return err
|
||||
+ },
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+func (s *Sentinel) get(addr string) redis.Conn {
|
||||
+ pool := s.poolForAddr(addr)
|
||||
+ return pool.Get()
|
||||
+}
|
||||
+
|
||||
+func (s *Sentinel) poolForAddr(addr string) *redis.Pool {
|
||||
+ s.mu.Lock()
|
||||
+ if s.pools == nil {
|
||||
+ s.pools = make(map[string]*redis.Pool)
|
||||
+ }
|
||||
+ pool, ok := s.pools[addr]
|
||||
+ if ok {
|
||||
+ s.mu.Unlock()
|
||||
+ return pool
|
||||
+ }
|
||||
+ s.mu.Unlock()
|
||||
+ newPool := s.newPool(addr)
|
||||
+ s.mu.Lock()
|
||||
+ p, ok := s.pools[addr]
|
||||
+ if ok {
|
||||
+ s.mu.Unlock()
|
||||
+ return p
|
||||
+ }
|
||||
+ s.pools[addr] = newPool
|
||||
+ s.mu.Unlock()
|
||||
+ return newPool
|
||||
+}
|
||||
+
|
||||
+func (s *Sentinel) newPool(addr string) *redis.Pool {
|
||||
+ if s.Pool != nil {
|
||||
+ return s.Pool(addr)
|
||||
+ }
|
||||
+ return s.defaultPool(addr)
|
||||
+}
|
||||
+
|
||||
+// close connection pool to Sentinel.
|
||||
+// Lock must be hold by caller.
|
||||
+func (s *Sentinel) close() {
|
||||
+ if s.pools != nil {
|
||||
+ for _, pool := range s.pools {
|
||||
+ pool.Close()
|
||||
+ }
|
||||
+ }
|
||||
+ s.pools = nil
|
||||
+}
|
||||
+
|
||||
+func (s *Sentinel) doUntilSuccess(f func(redis.Conn) (interface{}, error)) (interface{}, error) {
|
||||
+ s.mu.RLock()
|
||||
+ addrs := s.Addrs
|
||||
+ s.mu.RUnlock()
|
||||
+
|
||||
+ var lastErr error
|
||||
+
|
||||
+ for _, addr := range addrs {
|
||||
+ conn := s.get(addr)
|
||||
+ reply, err := f(conn)
|
||||
+ conn.Close()
|
||||
+ if err != nil {
|
||||
+ lastErr = err
|
||||
+ s.mu.Lock()
|
||||
+ pool, ok := s.pools[addr]
|
||||
+ if ok {
|
||||
+ pool.Close()
|
||||
+ delete(s.pools, addr)
|
||||
+ }
|
||||
+ s.putToBottom(addr)
|
||||
+ s.mu.Unlock()
|
||||
+ continue
|
||||
+ }
|
||||
+ s.putToTop(addr)
|
||||
+ return reply, nil
|
||||
+ }
|
||||
+
|
||||
+ return nil, NoSentinelsAvailable{lastError: lastErr}
|
||||
+}
|
||||
+
|
||||
+// MasterAddr returns an address of current Redis master instance.
|
||||
+func (s *Sentinel) MasterAddr() (string, error) {
|
||||
+ res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) {
|
||||
+ return queryForMaster(c, s.MasterName)
|
||||
+ })
|
||||
+ if err != nil {
|
||||
+ return "", err
|
||||
+ }
|
||||
+ return res.(string), nil
|
||||
+}
|
||||
+
|
||||
+// SlaveAddrs returns a slice with known slave addresses of current master instance.
|
||||
+func (s *Sentinel) SlaveAddrs() ([]string, error) {
|
||||
+ res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) {
|
||||
+ return queryForSlaveAddrs(c, s.MasterName)
|
||||
+ })
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ return res.([]string), nil
|
||||
+}
|
||||
+
|
||||
+// Slave represents a Redis slave instance which is known by Sentinel.
|
||||
+type Slave struct {
|
||||
+ ip string
|
||||
+ port string
|
||||
+ flags string
|
||||
+}
|
||||
+
|
||||
+// Addr returns an address of slave.
|
||||
+func (s *Slave) Addr() string {
|
||||
+ return net.JoinHostPort(s.ip, s.port)
|
||||
+}
|
||||
+
|
||||
+// Available returns if slave is in working state at moment based on information in slave flags.
|
||||
+func (s *Slave) Available() bool {
|
||||
+ return !strings.Contains(s.flags, "disconnected") && !strings.Contains(s.flags, "s_down")
|
||||
+}
|
||||
+
|
||||
+// Slaves returns a slice with known slaves of master instance.
|
||||
+func (s *Sentinel) Slaves() ([]*Slave, error) {
|
||||
+ res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) {
|
||||
+ return queryForSlaves(c, s.MasterName)
|
||||
+ })
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ return res.([]*Slave), nil
|
||||
+}
|
||||
+
|
||||
+// SentinelAddrs returns a slice of known Sentinel addresses Sentinel server aware of.
|
||||
+func (s *Sentinel) SentinelAddrs() ([]string, error) {
|
||||
+ res, err := s.doUntilSuccess(func(c redis.Conn) (interface{}, error) {
|
||||
+ return queryForSentinels(c, s.MasterName)
|
||||
+ })
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ return res.([]string), nil
|
||||
+}
|
||||
+
|
||||
+// Discover allows to update list of known Sentinel addresses. From docs:
|
||||
+//
|
||||
+// A client may update its internal list of Sentinel nodes following this procedure:
|
||||
+// 1) Obtain a list of other Sentinels for this master using the command SENTINEL sentinels <master-name>.
|
||||
+// 2) Add every ip:port pair not already existing in our list at the end of the list.
|
||||
+func (s *Sentinel) Discover() error {
|
||||
+ addrs, err := s.SentinelAddrs()
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ s.mu.Lock()
|
||||
+ for _, addr := range addrs {
|
||||
+ if !stringInSlice(addr, s.Addrs) {
|
||||
+ s.Addrs = append(s.Addrs, addr)
|
||||
+ }
|
||||
+ }
|
||||
+ s.mu.Unlock()
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+// Close closes current connection to Sentinel.
|
||||
+func (s *Sentinel) Close() error {
|
||||
+ s.mu.Lock()
|
||||
+ s.close()
|
||||
+ s.mu.Unlock()
|
||||
+ return nil
|
||||
+}
|
||||
+
|
||||
+// TestRole wraps GetRole in a test to verify if the role matches an expected
|
||||
+// role string. If there was any error in querying the supplied connection,
|
||||
+// the function returns false. Works with Redis >= 2.8.12.
|
||||
+// It's not goroutine safe, but if you call this method on pooled connections
|
||||
+// then you are OK.
|
||||
+func TestRole(c redis.Conn, expectedRole string) bool {
|
||||
+ role, err := getRole(c)
|
||||
+ if err != nil || role != expectedRole {
|
||||
+ return false
|
||||
+ }
|
||||
+ return true
|
||||
+}
|
||||
+
|
||||
+// getRole is a convenience function supplied to query an instance (master or
|
||||
+// slave) for its role. It attempts to use the ROLE command introduced in
|
||||
+// redis 2.8.12.
|
||||
+func getRole(c redis.Conn) (string, error) {
|
||||
+ res, err := c.Do("ROLE")
|
||||
+ if err != nil {
|
||||
+ return "", err
|
||||
+ }
|
||||
+ rres, ok := res.([]interface{})
|
||||
+ if ok {
|
||||
+ return redis.String(rres[0], nil)
|
||||
+ }
|
||||
+ return "", errors.New("redigo: can not transform ROLE reply to string")
|
||||
+}
|
||||
+
|
||||
+func queryForMaster(conn redis.Conn, masterName string) (string, error) {
|
||||
+ res, err := redis.Strings(conn.Do("SENTINEL", "get-master-addr-by-name", masterName))
|
||||
+ if err != nil {
|
||||
+ return "", err
|
||||
+ }
|
||||
+ if len(res) < 2 {
|
||||
+ return "", errors.New("redigo: malformed get-master-addr-by-name reply")
|
||||
+ }
|
||||
+ masterAddr := net.JoinHostPort(res[0], res[1])
|
||||
+ return masterAddr, nil
|
||||
+}
|
||||
+
|
||||
+func queryForSlaveAddrs(conn redis.Conn, masterName string) ([]string, error) {
|
||||
+ slaves, err := queryForSlaves(conn, masterName)
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ slaveAddrs := make([]string, 0)
|
||||
+ for _, slave := range slaves {
|
||||
+ slaveAddrs = append(slaveAddrs, slave.Addr())
|
||||
+ }
|
||||
+ return slaveAddrs, nil
|
||||
+}
|
||||
+
|
||||
+func queryForSlaves(conn redis.Conn, masterName string) ([]*Slave, error) {
|
||||
+ res, err := redis.Values(conn.Do("SENTINEL", "slaves", masterName))
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ slaves := make([]*Slave, 0)
|
||||
+ for _, a := range res {
|
||||
+ sm, err := redis.StringMap(a, err)
|
||||
+ if err != nil {
|
||||
+ return slaves, err
|
||||
+ }
|
||||
+ slave := &Slave{
|
||||
+ ip: sm["ip"],
|
||||
+ port: sm["port"],
|
||||
+ flags: sm["flags"],
|
||||
+ }
|
||||
+ slaves = append(slaves, slave)
|
||||
+ }
|
||||
+ return slaves, nil
|
||||
+}
|
||||
+
|
||||
+func queryForSentinels(conn redis.Conn, masterName string) ([]string, error) {
|
||||
+ res, err := redis.Values(conn.Do("SENTINEL", "sentinels", masterName))
|
||||
+ if err != nil {
|
||||
+ return nil, err
|
||||
+ }
|
||||
+ sentinels := make([]string, 0)
|
||||
+ for _, a := range res {
|
||||
+ sm, err := redis.StringMap(a, err)
|
||||
+ if err != nil {
|
||||
+ return sentinels, err
|
||||
+ }
|
||||
+ sentinels = append(sentinels, fmt.Sprintf("%s:%s", sm["ip"], sm["port"]))
|
||||
+ }
|
||||
+ return sentinels, nil
|
||||
+}
|
||||
+
|
||||
+func stringInSlice(str string, slice []string) bool {
|
||||
+ for _, s := range slice {
|
||||
+ if s == str {
|
||||
+ return true
|
||||
+ }
|
||||
+ }
|
||||
+ return false
|
||||
+}
|
||||
// configureLogHook prepares logging hook parameters.
|
||||
|
|
|
@ -152,7 +152,6 @@ var (
|
|||
|
||||
{Resource: ResourceQuota, Action: ActionRead},
|
||||
{Resource: ResourceQuota, Action: ActionList},
|
||||
{Resource: ResourceQuota, Action: ActionUpdate},
|
||||
},
|
||||
"Project": {
|
||||
{Resource: ResourceLog, Action: ActionList},
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"context"
|
||||
"strings"
|
||||
|
||||
registry_token "github.com/docker/distribution/registry/auth/token"
|
||||
registry_token "github.com/distribution/distribution/v3/registry/auth/token"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
rbac_project "github.com/goharbor/harbor/src/common/rbac/project"
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
"github.com/distribution/distribution/v3/registry/auth/token"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
|
|
|
@ -19,15 +19,12 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/docker/distribution/manifest/schema1"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact/processor"
|
||||
"github.com/goharbor/harbor/src/controller/artifact/processor/wasm"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
"github.com/goharbor/harbor/src/pkg"
|
||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||
"github.com/goharbor/harbor/src/pkg/blob"
|
||||
|
@ -68,10 +65,6 @@ func (a *abstractor) AbstractMetadata(ctx context.Context, artifact *artifact.Ar
|
|||
artifact.ManifestMediaType = manifestMediaType
|
||||
|
||||
switch artifact.ManifestMediaType {
|
||||
case "", "application/json", schema1.MediaTypeSignedManifest:
|
||||
if err := a.abstractManifestV1Metadata(ctx, artifact, content); err != nil {
|
||||
return err
|
||||
}
|
||||
case v1.MediaTypeImageManifest, schema2.MediaTypeManifest:
|
||||
if err = a.abstractManifestV2Metadata(artifact, content); err != nil {
|
||||
return err
|
||||
|
@ -86,39 +79,6 @@ func (a *abstractor) AbstractMetadata(ctx context.Context, artifact *artifact.Ar
|
|||
return processor.Get(artifact.MediaType).AbstractMetadata(ctx, artifact, content)
|
||||
}
|
||||
|
||||
// the artifact is enveloped by docker manifest v1
|
||||
func (a *abstractor) abstractManifestV1Metadata(ctx context.Context, artifact *artifact.Artifact, content []byte) error {
|
||||
// unify the media type of v1 manifest to "schema1.MediaTypeSignedManifest"
|
||||
artifact.ManifestMediaType = schema1.MediaTypeSignedManifest
|
||||
// as no config layer in the docker v1 manifest, use the "schema1.MediaTypeSignedManifest"
|
||||
// as the media type of artifact
|
||||
artifact.MediaType = schema1.MediaTypeSignedManifest
|
||||
|
||||
manifest := &schema1.Manifest{}
|
||||
if err := json.Unmarshal(content, manifest); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var ol q.OrList
|
||||
for _, fsLayer := range manifest.FSLayers {
|
||||
ol.Values = append(ol.Values, fsLayer.BlobSum.String())
|
||||
}
|
||||
|
||||
// there is no layer size in v1 manifest, compute the artifact size from the blobs
|
||||
blobs, err := a.blobMgr.List(ctx, q.New(q.KeyWords{"digest": &ol}))
|
||||
if err != nil {
|
||||
log.G(ctx).Errorf("failed to get blobs of the artifact %s, error %v", artifact.Digest, err)
|
||||
return err
|
||||
}
|
||||
|
||||
artifact.Size = int64(len(content))
|
||||
for _, blob := range blobs {
|
||||
artifact.Size += blob.Size
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// the artifact is enveloped by OCI manifest or docker manifest v2
|
||||
func (a *abstractor) abstractManifestV2Metadata(artifact *artifact.Artifact, content []byte) error {
|
||||
manifest := &v1.Manifest{}
|
||||
|
|
|
@ -17,15 +17,13 @@ package artifact
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/schema1"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact/processor"
|
||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||
"github.com/goharbor/harbor/src/pkg/blob"
|
||||
"github.com/goharbor/harbor/src/testing/mock"
|
||||
tart "github.com/goharbor/harbor/src/testing/pkg/artifact"
|
||||
tblob "github.com/goharbor/harbor/src/testing/pkg/blob"
|
||||
|
@ -228,25 +226,6 @@ func (a *abstractorTestSuite) SetupTest() {
|
|||
processor.Registry[schema2.MediaTypeImageConfig] = a.processor
|
||||
}
|
||||
|
||||
// docker manifest v1
|
||||
func (a *abstractorTestSuite) TestAbstractMetadataOfV1Manifest() {
|
||||
manifest, _, err := distribution.UnmarshalManifest(schema1.MediaTypeSignedManifest, []byte(v1Manifest))
|
||||
a.Require().Nil(err)
|
||||
mock.OnAnything(a.blobMgr, "List").Return([]*blob.Blob{
|
||||
{Size: 10},
|
||||
{Size: 20},
|
||||
}, nil)
|
||||
a.regCli.On("PullManifest", mock.Anything, mock.Anything).Return(manifest, "", nil)
|
||||
artifact := &artifact.Artifact{
|
||||
ID: 1,
|
||||
}
|
||||
err = a.abstractor.AbstractMetadata(nil, artifact)
|
||||
a.Require().Nil(err)
|
||||
a.Assert().Equal(int64(1), artifact.ID)
|
||||
a.Assert().Equal(schema1.MediaTypeSignedManifest, artifact.ManifestMediaType)
|
||||
a.Assert().Equal(schema1.MediaTypeSignedManifest, artifact.MediaType)
|
||||
a.Assert().Equal(int64(30+len([]byte(v1Manifest))), artifact.Size)
|
||||
}
|
||||
|
||||
// docker manifest v2
|
||||
func (a *abstractorTestSuite) TestAbstractMetadataOfV2Manifest() {
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/stretchr/testify/suite"
|
||||
helm_chart "helm.sh/helm/v3/pkg/chart"
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
// annotation parsers will be registered
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ package image
|
|||
import (
|
||||
"context"
|
||||
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact/processor"
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
// 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 image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema1"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact/processor"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||
)
|
||||
|
||||
func init() {
|
||||
pc := &manifestV1Processor{}
|
||||
if err := processor.Register(pc, schema1.MediaTypeSignedManifest); err != nil {
|
||||
log.Errorf("failed to register processor for media type %s: %v", schema1.MediaTypeSignedManifest, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// manifestV1Processor processes image with docker v1 manifest
|
||||
type manifestV1Processor struct {
|
||||
}
|
||||
|
||||
func (m *manifestV1Processor) AbstractMetadata(_ context.Context, artifact *artifact.Artifact, manifest []byte) error {
|
||||
mani := &schema1.Manifest{}
|
||||
if err := json.Unmarshal(manifest, mani); err != nil {
|
||||
return err
|
||||
}
|
||||
if artifact.ExtraAttrs == nil {
|
||||
artifact.ExtraAttrs = map[string]interface{}{}
|
||||
}
|
||||
artifact.ExtraAttrs["architecture"] = mani.Architecture
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *manifestV1Processor) AbstractAddition(_ context.Context, _ *artifact.Artifact, addition string) (*processor.Addition, error) {
|
||||
return nil, errors.New(nil).WithCode(errors.BadRequestCode).
|
||||
WithMessage("addition %s isn't supported for %s(manifest version 1)", addition, ArtifactTypeImage)
|
||||
}
|
||||
|
||||
func (m *manifestV1Processor) GetArtifactType(_ context.Context, _ *artifact.Artifact) string {
|
||||
return ArtifactTypeImage
|
||||
}
|
||||
|
||||
func (m *manifestV1Processor) ListAdditionTypes(_ context.Context, _ *artifact.Artifact) []string {
|
||||
return nil
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
// 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 image
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/artifact"
|
||||
)
|
||||
|
||||
type manifestV1ProcessorTestSuite struct {
|
||||
suite.Suite
|
||||
processor *manifestV1Processor
|
||||
}
|
||||
|
||||
func (m *manifestV1ProcessorTestSuite) SetupSuite() {
|
||||
m.processor = &manifestV1Processor{}
|
||||
|
||||
}
|
||||
|
||||
func (m *manifestV1ProcessorTestSuite) TestAbstractMetadata() {
|
||||
manifest := `{
|
||||
"name": "hello-world",
|
||||
"tag": "latest",
|
||||
"architecture": "amd64",
|
||||
"fsLayers": [
|
||||
{
|
||||
"blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
},
|
||||
{
|
||||
"blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
},
|
||||
{
|
||||
"blobSum": "sha256:cc8567d70002e957612902a8e985ea129d831ebe04057d88fb644857caa45d11"
|
||||
},
|
||||
{
|
||||
"blobSum": "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef"
|
||||
}
|
||||
],
|
||||
"history": [
|
||||
{
|
||||
"v1Compatibility": "{\"id\":\"e45a5af57b00862e5ef5782a9925979a02ba2b12dff832fd0991335f4a11e5c5\",\"parent\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"created\":\"2014-12-31T22:57:59.178729048Z\",\"container\":\"27b45f8fb11795b52e9605b686159729b0d9ca92f76d40fb4f05a62e19c46b4f\",\"container_config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [/hello]\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"docker_version\":\"1.4.1\",\"config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/hello\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"
|
||||
},
|
||||
{
|
||||
"v1Compatibility": "{\"id\":\"e45a5af57b00862e5ef5782a9925979a02ba2b12dff832fd0991335f4a11e5c5\",\"parent\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"created\":\"2014-12-31T22:57:59.178729048Z\",\"container\":\"27b45f8fb11795b52e9605b686159729b0d9ca92f76d40fb4f05a62e19c46b4f\",\"container_config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/bin/sh\",\"-c\",\"#(nop) CMD [/hello]\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"docker_version\":\"1.4.1\",\"config\":{\"Hostname\":\"8ce6509d66e2\",\"Domainname\":\"\",\"User\":\"\",\"Memory\":0,\"MemorySwap\":0,\"CpuShares\":0,\"Cpuset\":\"\",\"AttachStdin\":false,\"AttachStdout\":false,\"AttachStderr\":false,\"PortSpecs\":null,\"ExposedPorts\":null,\"Tty\":false,\"OpenStdin\":false,\"StdinOnce\":false,\"Env\":[\"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"],\"Cmd\":[\"/hello\"],\"Image\":\"31cbccb51277105ba3ae35ce33c22b69c9e3f1002e76e4c736a2e8ebff9d7b5d\",\"Volumes\":null,\"WorkingDir\":\"\",\"Entrypoint\":null,\"NetworkDisabled\":false,\"MacAddress\":\"\",\"OnBuild\":[],\"SecurityOpt\":null,\"Labels\":null},\"architecture\":\"amd64\",\"os\":\"linux\",\"Size\":0}\n"
|
||||
}
|
||||
],
|
||||
"schemaVersion": 1,
|
||||
"signatures": [
|
||||
{
|
||||
"header": {
|
||||
"jwk": {
|
||||
"crv": "P-256",
|
||||
"kid": "OD6I:6DRK:JXEJ:KBM4:255X:NSAA:MUSF:E4VM:ZI6W:CUN2:L4Z6:LSF4",
|
||||
"kty": "EC",
|
||||
"x": "3gAwX48IQ5oaYQAYSxor6rYYc_6yjuLCjtQ9LUakg4A",
|
||||
"y": "t72ge6kIA1XOjqjVoEOiPPAURltJFBMGDSQvEGVB010"
|
||||
},
|
||||
"alg": "ES256"
|
||||
},
|
||||
"signature": "XREm0L8WNn27Ga_iE_vRnTxVMhhYY0Zst_FfkKopg6gWSoTOZTuW4rK0fg_IqnKkEKlbD83tD46LKEGi5aIVFg",
|
||||
"protected": "eyJmb3JtYXRMZW5ndGgiOjY2MjgsImZvcm1hdFRhaWwiOiJDbjAiLCJ0aW1lIjoiMjAxNS0wNC0wOFQxODo1Mjo1OVoifQ"
|
||||
}
|
||||
]
|
||||
}
|
||||
`
|
||||
artifact := &artifact.Artifact{}
|
||||
err := m.processor.AbstractMetadata(nil, artifact, []byte(manifest))
|
||||
m.Require().Nil(err)
|
||||
m.Assert().Equal("amd64", artifact.ExtraAttrs["architecture"].(string))
|
||||
}
|
||||
|
||||
func (m *manifestV1ProcessorTestSuite) TestAbstractAddition() {
|
||||
_, err := m.processor.AbstractAddition(nil, nil, AdditionTypeBuildHistory)
|
||||
m.True(errors.IsErr(err, errors.BadRequestCode))
|
||||
}
|
||||
|
||||
func (m *manifestV1ProcessorTestSuite) TestGetArtifactType() {
|
||||
m.Assert().Equal(ArtifactTypeImage, m.processor.GetArtifactType(nil, nil))
|
||||
}
|
||||
|
||||
func (m *manifestV1ProcessorTestSuite) TestListAdditionTypes() {
|
||||
additions := m.processor.ListAdditionTypes(nil, nil)
|
||||
m.Len(additions, 0)
|
||||
}
|
||||
|
||||
func TestManifestV1ProcessorTestSuite(t *testing.T) {
|
||||
suite.Run(t, &manifestV1ProcessorTestSuite{})
|
||||
}
|
|
@ -18,7 +18,7 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact/processor"
|
||||
|
|
|
@ -20,8 +20,8 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact/processor/base"
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact/processor/base"
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/go-redis/redis/v8"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/docker/distribution/health"
|
||||
"github.com/distribution/distribution/v3/health"
|
||||
|
||||
httputil "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
|
@ -38,7 +38,7 @@ import (
|
|||
// returned matches the expected one
|
||||
func HTTPStatusCodeHealthChecker(method string, url string, header http.Header,
|
||||
timeout time.Duration, statusCode int) health.Checker {
|
||||
return health.CheckFunc(func() error {
|
||||
return health.CheckFunc(func(context.Context) error {
|
||||
req, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create request: %v", err)
|
||||
|
@ -75,7 +75,7 @@ type updater struct {
|
|||
status error
|
||||
}
|
||||
|
||||
func (u *updater) Check() error {
|
||||
func (u *updater) Check(context.Context) error {
|
||||
u.Lock()
|
||||
defer u.Unlock()
|
||||
|
||||
|
@ -100,7 +100,7 @@ func PeriodicHealthChecker(checker health.Checker, period time.Duration) health.
|
|||
go func() {
|
||||
ticker := time.NewTicker(period)
|
||||
for {
|
||||
u.update(checker.Check())
|
||||
u.update(checker.Check(context.TODO()))
|
||||
<-ticker.C
|
||||
}
|
||||
}()
|
||||
|
@ -109,7 +109,7 @@ func PeriodicHealthChecker(checker health.Checker, period time.Duration) health.
|
|||
}
|
||||
|
||||
func coreHealthChecker() health.Checker {
|
||||
return health.CheckFunc(func() error {
|
||||
return health.CheckFunc(func(context.Context) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
@ -148,7 +148,7 @@ func registryCtlHealthChecker() health.Checker {
|
|||
|
||||
func databaseHealthChecker() health.Checker {
|
||||
period := 10 * time.Second
|
||||
checker := health.CheckFunc(func() error {
|
||||
checker := health.CheckFunc(func(context.Context) error {
|
||||
_, err := orm.NewOrm().Raw("SELECT 1").Exec()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to run SQL \"SELECT 1\": %v", err)
|
||||
|
@ -160,7 +160,7 @@ func databaseHealthChecker() health.Checker {
|
|||
|
||||
func redisHealthChecker() health.Checker {
|
||||
period := 10 * time.Second
|
||||
checker := health.CheckFunc(func() error {
|
||||
checker := health.CheckFunc(func(context.Context) error {
|
||||
return cache.Default().Ping(context.TODO())
|
||||
})
|
||||
return PeriodicHealthChecker(checker, period)
|
||||
|
|
|
@ -15,12 +15,13 @@
|
|||
package health
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/health"
|
||||
"github.com/distribution/distribution/v3/health"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/utils/test"
|
||||
|
@ -35,16 +36,16 @@ func TestStringOfHealthy(t *testing.T) {
|
|||
|
||||
func TestUpdater(t *testing.T) {
|
||||
updater := &updater{}
|
||||
assert.Equal(t, nil, updater.Check())
|
||||
assert.Equal(t, nil, updater.Check(context.Background()))
|
||||
updater.status = errors.New("unhealthy")
|
||||
assert.Equal(t, "unhealthy", updater.Check().Error())
|
||||
assert.Equal(t, "unhealthy", updater.Check(context.Background()).Error())
|
||||
}
|
||||
|
||||
func TestHTTPStatusCodeHealthChecker(t *testing.T) {
|
||||
handler := &test.RequestHandlerMapping{
|
||||
Method: http.MethodGet,
|
||||
Pattern: "/health",
|
||||
Handler: func(w http.ResponseWriter, r *http.Request) {
|
||||
Handler: func(w http.ResponseWriter, _ *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
},
|
||||
}
|
||||
|
@ -56,16 +57,16 @@ func TestHTTPStatusCodeHealthChecker(t *testing.T) {
|
|||
http.MethodGet, url, map[string][]string{
|
||||
"key": {"value"},
|
||||
}, 5*time.Second, http.StatusOK)
|
||||
assert.Equal(t, nil, checker.Check())
|
||||
assert.Equal(t, nil, checker.Check(context.TODO()))
|
||||
|
||||
checker = HTTPStatusCodeHealthChecker(
|
||||
http.MethodGet, url, nil, 5*time.Second, http.StatusUnauthorized)
|
||||
assert.NotEqual(t, nil, checker.Check())
|
||||
assert.NotEqual(t, nil, checker.Check(context.TODO()))
|
||||
}
|
||||
|
||||
func TestPeriodicHealthChecker(t *testing.T) {
|
||||
firstCheck := true
|
||||
checkFunc := func() error {
|
||||
checkFunc := func(context.Context) error {
|
||||
time.Sleep(2 * time.Second)
|
||||
if firstCheck {
|
||||
firstCheck = false
|
||||
|
@ -75,14 +76,14 @@ func TestPeriodicHealthChecker(t *testing.T) {
|
|||
}
|
||||
|
||||
checker := PeriodicHealthChecker(health.CheckFunc(checkFunc), 1*time.Second)
|
||||
assert.Equal(t, "unknown status", checker.Check().Error())
|
||||
assert.Equal(t, "unknown status", checker.Check(context.TODO()).Error())
|
||||
time.Sleep(3 * time.Second)
|
||||
assert.Equal(t, nil, checker.Check())
|
||||
assert.Equal(t, nil, checker.Check(context.TODO()))
|
||||
time.Sleep(3 * time.Second)
|
||||
assert.Equal(t, "unhealthy", checker.Check().Error())
|
||||
assert.Equal(t, "unhealthy", checker.Check(context.TODO()).Error())
|
||||
}
|
||||
|
||||
func TestCoreHealthChecker(t *testing.T) {
|
||||
checker := coreHealthChecker()
|
||||
assert.Equal(t, nil, checker.Check())
|
||||
assert.Equal(t, nil, checker.Check(context.TODO()))
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/health"
|
||||
"github.com/distribution/distribution/v3/health"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -68,7 +68,7 @@ func check(name string, checker health.Checker,
|
|||
timeout time.Duration, c chan *ComponentHealthStatus) {
|
||||
statusChan := make(chan *ComponentHealthStatus)
|
||||
go func() {
|
||||
err := checker.Check()
|
||||
err := checker.Check(context.TODO())
|
||||
var healthy healthy = err == nil
|
||||
status := &ComponentHealthStatus{
|
||||
Name: name,
|
||||
|
|
|
@ -15,16 +15,17 @@
|
|||
package health
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/health"
|
||||
"github.com/distribution/distribution/v3/health"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
)
|
||||
|
||||
func fakeHealthChecker(healthy bool) health.Checker {
|
||||
return health.CheckFunc(func() error {
|
||||
return health.CheckFunc(func(context.Context) error {
|
||||
if healthy {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
tk "github.com/docker/distribution/registry/auth/token"
|
||||
tk "github.com/distribution/distribution/v3/registry/auth/token"
|
||||
"golang.org/x/text/cases"
|
||||
"golang.org/x/text/language"
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/opencontainers/go-digest"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact"
|
||||
|
@ -183,7 +183,10 @@ func (c *controller) UseLocalManifest(ctx context.Context, art lib.ArtifactInfo,
|
|||
if c.cache == nil {
|
||||
return a != nil && string(desc.Digest) == a.Digest, nil, nil // digest matches
|
||||
}
|
||||
|
||||
// Pass digest to the cache key, digest is more stable than tag, because tag could be updated
|
||||
if len(art.Digest) == 0 {
|
||||
art.Digest = string(desc.Digest)
|
||||
}
|
||||
err = c.cache.Fetch(ctx, manifestListKey(art.Repository, art), &content)
|
||||
if err != nil {
|
||||
if errors.Is(err, cache.ErrNotFound) {
|
||||
|
@ -318,8 +321,8 @@ func getRemoteRepo(art lib.ArtifactInfo) string {
|
|||
}
|
||||
|
||||
func getReference(art lib.ArtifactInfo) string {
|
||||
if len(art.Tag) > 0 {
|
||||
return art.Tag
|
||||
if len(art.Digest) > 0 {
|
||||
return art.Digest
|
||||
}
|
||||
return art.Digest
|
||||
return art.Tag
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
@ -209,7 +209,7 @@ func TestGetRef(t *testing.T) {
|
|||
{
|
||||
name: `normal`,
|
||||
in: lib.ArtifactInfo{Repository: "hello-world", Tag: "latest", Digest: "sha256:aabbcc"},
|
||||
want: "latest",
|
||||
want: "sha256:aabbcc",
|
||||
},
|
||||
{
|
||||
name: `digest_only`,
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"context"
|
||||
"io"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact"
|
||||
"github.com/goharbor/harbor/src/controller/event/metadata"
|
||||
|
|
|
@ -18,8 +18,8 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
distribution2 "github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
distribution2 "github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
|
|
|
@ -20,9 +20,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/opencontainers/go-digest"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
|
@ -73,7 +73,10 @@ func (m *ManifestListCache) CacheContent(ctx context.Context, _ string, man dist
|
|||
log.Errorf("failed to get reference, reference is empty, skip to cache manifest list")
|
||||
return
|
||||
}
|
||||
// some registry will not return the digest in the HEAD request, if no digest returned, cache manifest list content with tag
|
||||
// cache key should contain digest if digest exist
|
||||
if len(art.Digest) == 0 {
|
||||
art.Digest = string(digest.FromBytes(payload))
|
||||
}
|
||||
key := manifestListKey(art.Repository, art)
|
||||
log.Debugf("cache manifest list with key=cache:%v", key)
|
||||
if err := m.cache.Save(ctx, manifestListContentTypeKey(art.Repository, art), contentType, manifestListCacheInterval); err != nil {
|
||||
|
|
|
@ -19,10 +19,10 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/manifest"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/reg"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/adapter"
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
package flow
|
||||
|
||||
import (
|
||||
distribution "github.com/docker/distribution"
|
||||
distribution "github.com/distribution/distribution/v3"
|
||||
|
||||
io "io"
|
||||
|
||||
|
|
|
@ -22,10 +22,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/docker/distribution/manifest/schema1"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
distribution "github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
|
@ -262,8 +261,7 @@ func (t *transfer) copyContent(content distribution.Descriptor, srcRepo, dstRepo
|
|||
// when the media type of pulled manifest is index,
|
||||
// the contents it contains are a few manifests/indexes
|
||||
case v1.MediaTypeImageIndex, manifestlist.MediaTypeManifestList,
|
||||
v1.MediaTypeImageManifest, schema2.MediaTypeManifest,
|
||||
schema1.MediaTypeSignedManifest, schema1.MediaTypeManifest:
|
||||
v1.MediaTypeImageManifest, schema2.MediaTypeManifest:
|
||||
// as using digest as the reference, so set the override to true directly
|
||||
return t.copyArtifact(srcRepo, digest, dstRepo, digest, true, opts)
|
||||
// handle foreign layer
|
||||
|
@ -272,7 +270,7 @@ func (t *transfer) copyContent(content distribution.Descriptor, srcRepo, dstRepo
|
|||
return nil
|
||||
// copy layer or artifact config
|
||||
// the media type of the layer or config can be "application/octet-stream",
|
||||
// schema1.MediaTypeManifestLayer, schema2.MediaTypeLayer, schema2.MediaTypeImageConfig
|
||||
// schema2.MediaTypeLayer, schema2.MediaTypeImageConfig
|
||||
default:
|
||||
if opts.CopyByChunk {
|
||||
// copy by chunk
|
||||
|
|
|
@ -19,8 +19,8 @@ import (
|
|||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
|
|
@ -102,10 +102,6 @@ func (d *controller) Create(ctx context.Context, r *Robot) (int64, string, error
|
|||
var expiresAt int64
|
||||
if r.Duration == -1 {
|
||||
expiresAt = -1
|
||||
} else if r.Duration == 0 {
|
||||
// system default robot duration
|
||||
r.Duration = int64(config.RobotTokenDuration(ctx))
|
||||
expiresAt = time.Now().AddDate(0, 0, config.RobotTokenDuration(ctx)).Unix()
|
||||
} else {
|
||||
durationStr := strconv.FormatInt(r.Duration, 10)
|
||||
duration, err := strconv.Atoi(durationStr)
|
||||
|
|
|
@ -925,6 +925,7 @@ func (bc *basicController) makeRobotAccount(ctx context.Context, projectID int64
|
|||
Name: fmt.Sprintf("%s-%s-%s", scannerPrefix, registration.Name, UUID),
|
||||
Description: "for scan",
|
||||
ProjectID: projectID,
|
||||
Duration: -1,
|
||||
},
|
||||
Level: robot.LEVELPROJECT,
|
||||
Permissions: []*robot.Permission{
|
||||
|
|
|
@ -199,6 +199,7 @@ func (suite *ControllerTestSuite) SetupSuite() {
|
|||
Name: rname,
|
||||
Description: "for scan",
|
||||
ProjectID: suite.artifact.ProjectID,
|
||||
Duration: -1,
|
||||
},
|
||||
Level: robot.LEVELPROJECT,
|
||||
Permissions: []*robot.Permission{
|
||||
|
@ -229,6 +230,7 @@ func (suite *ControllerTestSuite) SetupSuite() {
|
|||
Secret: "robot-account",
|
||||
Description: "for scan",
|
||||
ProjectID: suite.artifact.ProjectID,
|
||||
Duration: -1,
|
||||
},
|
||||
Level: "project",
|
||||
}, nil)
|
||||
|
@ -336,7 +338,7 @@ func (suite *ControllerTestSuite) TestScanControllerScan() {
|
|||
mock.OnAnything(suite.execMgr, "Create").Return(int64(1), nil).Once()
|
||||
mock.OnAnything(suite.taskMgr, "Create").Return(int64(1), nil).Once()
|
||||
|
||||
ctx := orm.NewContext(nil, &ormtesting.FakeOrmer{})
|
||||
ctx := orm.NewContext(context.TODO(), &ormtesting.FakeOrmer{})
|
||||
|
||||
suite.Require().NoError(suite.c.Scan(ctx, suite.artifact))
|
||||
}
|
||||
|
|
|
@ -275,7 +275,7 @@ func main() {
|
|||
log.Debugf("failed to ping %s, retry after %s : %v", url, sleep, err)
|
||||
}),
|
||||
}
|
||||
if err := retry.Retry(checker.Check, options...); err != nil {
|
||||
if err := retry.Retry(func() error { return checker.Check(context.TODO()) }, options...); err != nil {
|
||||
log.Errorf("failed to check the jobservice health status: timeout, error: %v", err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
"github.com/distribution/distribution/v3/registry/auth/token"
|
||||
"github.com/docker/libtrust"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
|
||||
|
@ -138,7 +138,7 @@ func MakeToken(ctx context.Context, username, service string, access []*token.Re
|
|||
return nil, err
|
||||
}
|
||||
// Add kid to token header for compatibility with docker distribution's code
|
||||
// see https://github.com/docker/distribution/blob/release/2.7/registry/auth/token/token.go#L197
|
||||
// see https://github.com/distribution/distribution/v3/blob/release/2.7/registry/auth/token/token.go#L197
|
||||
k, err := libtrust.UnmarshalPrivateKeyPEM(options.PrivateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
"github.com/distribution/distribution/v3/registry/auth/token"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/models"
|
||||
"github.com/goharbor/harbor/src/common/rbac"
|
||||
|
@ -35,7 +35,7 @@ import (
|
|||
var creatorMap map[string]Creator
|
||||
var registryFilterMap map[string]accessFilter
|
||||
var actionScopeMap = map[rbac.Action]string{
|
||||
// Scopes checked by distribution, see: https://github.com/docker/distribution/blob/master/registry/handlers/app.go
|
||||
// Scopes checked by distribution, see: https://github.com/distribution/distribution/v3/blob/master/registry/handlers/app.go
|
||||
rbac.ActionPull: "pull",
|
||||
rbac.ActionPush: "push",
|
||||
rbac.ActionDelete: "delete",
|
||||
|
|
|
@ -26,7 +26,7 @@ import (
|
|||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
"github.com/distribution/distribution/v3/registry/auth/token"
|
||||
jwt "github.com/golang-jwt/jwt/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
|
54
src/go.mod
54
src/go.mod
|
@ -7,7 +7,7 @@ require (
|
|||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190726115642-cd293c93fd97
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2
|
||||
github.com/aws/aws-sdk-go v1.34.28
|
||||
github.com/aws/aws-sdk-go v1.48.10
|
||||
github.com/beego/beego/v2 v2.0.6
|
||||
github.com/beego/i18n v0.0.0-20140604031826-e87155e8f0c0
|
||||
github.com/bmatcuk/doublestar v1.3.4
|
||||
|
@ -16,17 +16,16 @@ require (
|
|||
github.com/cloudevents/sdk-go/v2 v2.14.0
|
||||
github.com/coreos/go-oidc/v3 v3.9.0
|
||||
github.com/dghubble/sling v1.1.0
|
||||
github.com/docker/distribution v2.8.2+incompatible
|
||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1
|
||||
github.com/go-ldap/ldap/v3 v3.2.4
|
||||
github.com/go-openapi/errors v0.20.4
|
||||
github.com/go-openapi/loads v0.21.2 // indirect
|
||||
github.com/go-openapi/loads v0.21.2
|
||||
github.com/go-openapi/runtime v0.26.2
|
||||
github.com/go-openapi/spec v0.20.11 // indirect
|
||||
github.com/go-openapi/spec v0.20.11
|
||||
github.com/go-openapi/strfmt v0.21.8
|
||||
github.com/go-openapi/swag v0.22.4
|
||||
github.com/go-openapi/validate v0.22.3 // indirect
|
||||
github.com/go-openapi/validate v0.22.3
|
||||
github.com/go-redis/redis/v8 v8.11.4
|
||||
github.com/gocarina/gocsv v0.0.0-20210516172204-ca9e8a8ddea8
|
||||
github.com/gocraft/work v0.5.1
|
||||
|
@ -41,7 +40,6 @@ require (
|
|||
github.com/jackc/pgconn v1.14.0
|
||||
github.com/jackc/pgx/v4 v4.18.1
|
||||
github.com/jpillora/backoff v1.0.0
|
||||
github.com/ncw/swift v1.0.49 // indirect
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/opencontainers/go-digest v1.0.0
|
||||
|
@ -54,7 +52,7 @@ require (
|
|||
github.com/tencentcloud/tencentcloud-sdk-go v1.0.62
|
||||
github.com/vmihailenco/msgpack/v5 v5.0.0-rc.2
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.46.1
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1
|
||||
go.opentelemetry.io/otel v1.21.0
|
||||
go.opentelemetry.io/otel/exporters/jaeger v1.0.0
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0
|
||||
|
@ -62,7 +60,7 @@ require (
|
|||
go.opentelemetry.io/otel/trace v1.21.0
|
||||
go.uber.org/ratelimit v0.2.0
|
||||
golang.org/x/crypto v0.17.0
|
||||
golang.org/x/net v0.17.0
|
||||
golang.org/x/net v0.18.0
|
||||
golang.org/x/oauth2 v0.13.0
|
||||
golang.org/x/sync v0.3.0
|
||||
golang.org/x/text v0.14.0
|
||||
|
@ -79,14 +77,6 @@ require (
|
|||
require (
|
||||
cloud.google.com/go/compute v1.23.0 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v37.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.27 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
|
||||
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.0 // indirect
|
||||
|
@ -95,9 +85,9 @@ require (
|
|||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/denverdino/aliyungo v0.0.0-20191227032621-df38c6fa730c // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dnaeon/go-vcr v1.2.0 // indirect
|
||||
github.com/distribution/distribution/v3 v3.0.0-alpha.1
|
||||
github.com/distribution/reference v0.5.0
|
||||
github.com/docker/go-metrics v0.0.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||
|
@ -139,13 +129,12 @@ require (
|
|||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.3 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 // indirect
|
||||
github.com/prometheus/client_model v0.5.0 // indirect
|
||||
github.com/prometheus/common v0.44.0 // indirect
|
||||
github.com/prometheus/procfs v0.11.1 // indirect
|
||||
github.com/robfig/cron v1.0.0 // indirect
|
||||
github.com/satori/go.uuid v1.2.0 // indirect
|
||||
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 // indirect
|
||||
github.com/sirupsen/logrus v1.9.2 // indirect
|
||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.5.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
|
@ -164,7 +153,6 @@ require (
|
|||
golang.org/x/term v0.15.0 // indirect
|
||||
google.golang.org/api v0.126.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||
google.golang.org/grpc v1.59.0 // indirect
|
||||
|
@ -178,10 +166,28 @@ require (
|
|||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.7 // indirect
|
||||
cloud.google.com/go/iam v1.1.1 // indirect
|
||||
cloud.google.com/go/storage v1.30.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/s2a-go v0.1.4 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.11.0 // indirect
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/Azure/go-autorest => github.com/Azure/go-autorest v14.2.0+incompatible
|
||||
github.com/docker/distribution => github.com/distribution/distribution v2.8.2+incompatible
|
||||
github.com/goharbor/harbor => ../
|
||||
github.com/gomodule/redigo => github.com/gomodule/redigo v1.8.8
|
||||
google.golang.org/api => google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff
|
||||
)
|
||||
|
|
381
src/go.sum
381
src/go.sum
|
@ -1,50 +1,68 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
|
||||
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
|
||||
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
|
||||
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
|
||||
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
|
||||
cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o=
|
||||
cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
|
||||
cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
|
||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
|
||||
cloud.google.com/go/iam v1.1.1 h1:lW7fzj15aVIXYHREOqjRBV9PsH0Z6u8Y46a1YGvQP4Y=
|
||||
cloud.google.com/go/iam v1.1.1/go.mod h1:A5avdyVL2tCppe4unb0951eI9jreack+RJ0/d+KUZOU=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.30.1 h1:uOdMxAs8HExqBlnLtnQyP0YkvbiDpdGShGKtx6U/oNM=
|
||||
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/Azure/azure-sdk-for-go v37.2.0+incompatible h1:LTdcd2GK+cv+e7yhWCN8S7yf3eblBypKFZsPfKjCQ7E=
|
||||
github.com/Azure/azure-sdk-for-go v37.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic=
|
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0 h1:8kDqDngH+DmVBiCtIjCFTGa7MBnsIOkF9IccInFEbjk=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0 h1:u/LLAOFgsMv7HmNL4Qufg58y+qElGOt5qv0z1mURkRY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.0.0/go.mod h1:2e8rMJtl2+2j+HXbTBwnyGpm5Nou7KhvSfxOq8JpTag=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||
github.com/Azure/go-autorest/autorest v0.11.27 h1:F3R3q42aWytozkV8ihzcgMO4OA4cuqr3bNlsEuF6//A=
|
||||
github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20 h1:gJ3E98kMpFB1MFqQCvA1yFab8vthOeD4VlFRQULxahg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ=
|
||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU=
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0 h1:zebkZaadz7+wIQYgC7GXaz3Wb28yKYfVkkBKwc38VF8=
|
||||
github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA=
|
||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/FZambia/sentinel v1.1.0 h1:qrCBfxc8SvJihYNjBWgwUI93ZCvFe/PJIPTHKmlp8a8=
|
||||
|
@ -74,8 +92,8 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj
|
|||
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/aws/aws-sdk-go v1.34.28 h1:sscPpn/Ns3i0F4HPEWAVcwdIRaZZCuL7llJ2/60yPIk=
|
||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/aws/aws-sdk-go v1.48.10 h1:0LIFG3wp2Dt6PsxKWCg1Y1xRrn2vZnW5/gWdgaBalKg=
|
||||
github.com/aws/aws-sdk-go v1.48.10/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
|
||||
github.com/beego/beego/v2 v2.0.6 h1:21Aqz3+RzUE1yP9a5xdU6LK54n9Z7NLEJtR4PE7NrPQ=
|
||||
github.com/beego/beego/v2 v2.0.6/go.mod h1:CH2/JIaB4ceGYVQlYqTAFft4pVk/ol1ZkakUrUvAyns=
|
||||
|
@ -96,14 +114,23 @@ github.com/casbin/casbin v1.9.1/go.mod h1:z8uPsfBJGUsnkagrt3G8QvjgTKFMBJ32UP8HpZ
|
|||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
|
||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudevents/sdk-go/v2 v2.14.0 h1:Nrob4FwVgi5L4tV9lhjzZcjYqFVyJzsA56CwPaPfv6s=
|
||||
github.com/cloudevents/sdk-go/v2 v2.14.0/go.mod h1:xDmKfzNjM8gBvjaF8ijFjM1VYOVUEeUfapHMUX1T5To=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
|
||||
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
|
||||
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
|
||||
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
|
||||
github.com/coreos/go-oidc/v3 v3.9.0 h1:0J/ogVOd4y8P0f0xUh8l9t07xRP/d8tccvjHl2dcsSo=
|
||||
|
@ -114,22 +141,25 @@ github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7
|
|||
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
|
||||
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denverdino/aliyungo v0.0.0-20191227032621-df38c6fa730c h1:ZjNKFQ2pBtbkmtporMvGVu2M7fs3Ip3sSy0Gyqsq8xc=
|
||||
github.com/denverdino/aliyungo v0.0.0-20191227032621-df38c6fa730c/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
|
||||
github.com/dghubble/sling v1.1.0 h1:DLu20Bq2qsB9cI5Hldaxj+TMPEaPpPE8IR2kvD22Atg=
|
||||
github.com/dghubble/sling v1.1.0/go.mod h1:ZcPRuLm0qrcULW2gOrjXrAWgf76sahqSyxXyVOvkunE=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/dhui/dktest v0.3.16 h1:i6gq2YQEtcrjKbeJpBkWjE8MmLZPYllcjOFbTZuPDnw=
|
||||
github.com/dhui/dktest v0.3.16/go.mod h1:gYaA3LRmM8Z4vJl2MA0THIigJoZrwOansEOsp+kqxp0=
|
||||
github.com/distribution/distribution v2.8.2+incompatible h1:k9+4DKdOG+quPFZXT/mUsiQrGu9vYCp+dXpuPkuqhk8=
|
||||
github.com/distribution/distribution v2.8.2+incompatible/go.mod h1:EgLm2NgWtdKgzF9NpMzUKgzmR7AMmb0VQi2B+ZzDRjc=
|
||||
github.com/distribution/distribution/v3 v3.0.0-alpha.1 h1:jn7I1gvjOvmLztH1+1cLiUFud7aeJCIQcgzugtwjyJo=
|
||||
github.com/distribution/distribution/v3 v3.0.0-alpha.1/go.mod h1:LCp4JZp1ZalYg0W/TN05jarCQu+h4w7xc7ZfQF4Y/cY=
|
||||
github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0=
|
||||
github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
|
||||
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE=
|
||||
github.com/docker/docker v20.10.24+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
|
@ -147,7 +177,10 @@ github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRr
|
|||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
|
@ -161,6 +194,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
|
|||
github.com/go-asn1-ber/asn1-ber v1.5.1 h1:pDbRAunXzIUXfx4CB2QJFv5IuPiuoW+sWvr/Us009o8=
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
|
||||
github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
|
@ -209,7 +244,6 @@ github.com/go-openapi/validate v0.22.3 h1:KxG9mu5HBRYbecRb37KRCihvGGtND2aXziBAv0
|
|||
github.com/go-openapi/validate v0.22.3/go.mod h1:kVxh31KbfsxU8ZyoHaDbLBWU5CnMdqBUEtadQ2G4d5M=
|
||||
github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg=
|
||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
|
@ -225,8 +259,6 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
|
|||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A=
|
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-migrate/migrate/v4 v4.16.2 h1:8coYbMKUyInrFk1lfGfRovTLAW7PhWp8qQDT2iKfuoA=
|
||||
|
@ -234,12 +266,25 @@ github.com/golang-migrate/migrate/v4 v4.16.2/go.mod h1:pfcJX4nPHaVdc5nmdCikFBWtm
|
|||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/glog v1.1.2 h1:DVjP2PbBOzHyzA+dn3WhHIq4NdVu3Q+pvivFICf/7fo=
|
||||
github.com/golang/glog v1.1.2/go.mod h1:zR+okUeTbrL6EL3xHUDxZuEtGv04p5shwip1+mL/rLQ=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
|
@ -247,7 +292,9 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
|
@ -262,8 +309,12 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
|
|||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
|
@ -274,14 +325,36 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
|
|||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw=
|
||||
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
|
||||
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.11.0 h1:9V9PWXEsWnPpQhu/PeQIkS4eGzMlTLGgt80cUUI8Ki4=
|
||||
github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/csrf v1.6.2 h1:QqQ/OWwuFp4jMKgBFAzJVW3FMULdyUW7JoM4pEWuqKg=
|
||||
|
@ -320,6 +393,10 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/arc/v2 v2.0.5 h1:l2zaLDubNhW4XO3LnliVj0GXO3+/CGNJAg1dcN2Fpfw=
|
||||
github.com/hashicorp/golang-lru/arc/v2 v2.0.5/go.mod h1:ny6zBSQZi2JxIeYcv7kt2sH2PXJtirBN7RDhRpxPkxU=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5 h1:wW7h1TG88eUIJ2i69gaE3uNVtEPIagzhGvHgwfx2Vm4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.5/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
|
@ -327,6 +404,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
|
|||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
|
||||
github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
|
||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||
|
@ -393,6 +472,7 @@ github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/
|
|||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
|
@ -412,6 +492,8 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
|||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
|
@ -460,7 +542,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
|||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||
|
@ -469,8 +550,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
|||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/ncw/swift v1.0.49 h1:eQaKIjSt/PXLKfYgzg01nevmO+CMXfXGRhB1gOhDs7E=
|
||||
github.com/ncw/swift v1.0.49/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
|
@ -499,6 +578,8 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr
|
|||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
|
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
|
@ -515,8 +596,8 @@ github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+L
|
|||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16 h1:v7DLqVdK4VrYkVD5diGdl4sxJurKJEMnODWRJlxV9oM=
|
||||
github.com/prometheus/client_model v0.4.1-0.20230718164431-9a2bf3000d16/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU=
|
||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
||||
github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
|
||||
|
@ -538,7 +619,6 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
|||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
|
||||
github.com/shiena/ansicolor v0.0.0-20200904210342-c7312218db18 h1:DAYUYH5869yV94zvCES9F51oYtN5oGlwjxJJz7ZCnik=
|
||||
|
@ -550,8 +630,8 @@ github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR
|
|||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y=
|
||||
github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
|
@ -602,7 +682,9 @@ github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3k
|
|||
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
|
@ -613,11 +695,19 @@ go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsX
|
|||
go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
|
||||
go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
|
||||
go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.46.1 h1:Ifzy1lucGMQJh6wPRxusde8bWaDhYjSNOqDyn6Hb4TM=
|
||||
go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.46.1/go.mod h1:YfFNem80G9UZ/mL5zd5GGXZSy95eXK+RhzIWBkLjLSc=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0 h1:x8Z78aZx8cOF0+Kkazoc7lwUNMGy0LrzEMxTm4BbTxg=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0/go.mod h1:62CPTSry9QZtOaSsE3tOzhx6LzDhHnXJ6xHeMNNiM6Q=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24=
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo=
|
||||
go.opentelemetry.io/otel v1.0.0/go.mod h1:AjRVh9A5/5DE7S+mZtTR6t8vpKKryam+0lREnfmS4cg=
|
||||
go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc=
|
||||
go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo=
|
||||
|
@ -635,6 +725,7 @@ go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6
|
|||
go.opentelemetry.io/otel/trace v1.0.0/go.mod h1:PXTWqayeFUlJV1YDNhsJYB184+IvAH814St6o6ajzIs=
|
||||
go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc=
|
||||
go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ=
|
||||
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
@ -674,7 +765,7 @@ golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWP
|
|||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
|
||||
|
@ -684,14 +775,24 @@ golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL
|
|||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
|
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
|
@ -699,8 +800,11 @@ golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCc
|
|||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
|
@ -716,27 +820,54 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
|
|||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
|
||||
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
|
||||
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.13.0 h1:jDDenyj+WgFtmV3zYVoi8aE2BwtXFLWOA67ZfNWftiY=
|
||||
golang.org/x/oauth2 v0.13.0/go.mod h1:/JMhi4ZRXAf4HG9LiNmxvk+45+96RUlVThiH8FzNBn0=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -745,7 +876,10 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ
|
|||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
|
||||
|
@ -763,26 +897,51 @@ golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
@ -795,7 +954,9 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX
|
|||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4=
|
||||
golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
|
@ -806,7 +967,9 @@ golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
|||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
|
@ -814,9 +977,11 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
|
|||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
|
@ -829,12 +994,41 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn
|
|||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
|
||||
|
@ -845,23 +1039,81 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
|||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff h1:mk5zS3XLqVUzdF/CQCZ5ERujSF/8JFo+Wpkp/5I93NA=
|
||||
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
|
||||
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
|
||||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
|
||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
|
||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
|
||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
|
||||
google.golang.org/api v0.126.0 h1:q4GJq+cAdMAC7XP7njvQ4tvohGLiSlytuL4BQxbIZ+o=
|
||||
google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA=
|
||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
|
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
|
||||
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d h1:VBu5YqKPv6XiJ199exd8Br+Aetz+o08F+PLMnwJQHAY=
|
||||
google.golang.org/genproto v0.0.0-20230822172742-b8732ec3820d/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
|
||||
|
@ -874,9 +1126,22 @@ google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiq
|
|||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
|
||||
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
|
||||
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
|
||||
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
|
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
|
@ -887,6 +1152,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
|
|||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
|
@ -927,9 +1193,12 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|||
helm.sh/helm/v3 v3.11.3 h1:n1X5yaQTP5DYywlBOZMl2gX398Gp6YwFp/IAVj6+5D4=
|
||||
helm.sh/helm/v3 v3.11.3/go.mod h1:S+sOdQc3BLvt09a9rSlKKVs9x0N/yx+No0y3qFw+FQ8=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
k8s.io/api v0.26.2 h1:dM3cinp3PGB6asOySalOZxEG4CZ0IAdJsrYZXE/ovGQ=
|
||||
k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU=
|
||||
k8s.io/apimachinery v0.26.2 h1:da1u3D5wfR5u2RpLhE/ZtZS2P7QvDgLZTi9wrNZl/tQ=
|
||||
|
@ -943,6 +1212,8 @@ k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhkl
|
|||
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5 h1:kmDqav+P+/5e1i9tFfHq1qcF3sOrDp+YEkVDAHu7Jwk=
|
||||
k8s.io/utils v0.0.0-20230220204549-a5ecb0141aa5/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
|
||||
|
|
|
@ -490,7 +490,7 @@ func (gc *GarbageCollector) sweep(ctx job.Context) error {
|
|||
}
|
||||
|
||||
// cleanCache is to clean the registry cache for GC.
|
||||
// To do this is because the issue https://github.com/docker/distribution/issues/2094
|
||||
// To do this is because the issue https://github.com/distribution/distribution/v3/issues/2094
|
||||
func (gc *GarbageCollector) cleanCache(ctx context.Context) error {
|
||||
u, err := url.Parse(gc.redisURL)
|
||||
if err != nil {
|
||||
|
|
|
@ -17,7 +17,7 @@ package gc
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
commom_regctl "github.com/goharbor/harbor/src/common/registryctl"
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/q"
|
||||
|
|
|
@ -21,9 +21,8 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/beego/beego/v2/client/orm"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/docker/distribution/manifest/schema1"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
)
|
||||
|
||||
|
@ -117,7 +116,6 @@ func (b *Blob) IsForeignLayer() bool {
|
|||
// IsManifest returns true if the blob is manifest layer
|
||||
func (b *Blob) IsManifest() bool {
|
||||
return b.ContentType == schema2.MediaTypeManifest ||
|
||||
b.ContentType == schema1.MediaTypeManifest || b.ContentType == schema1.MediaTypeSignedManifest ||
|
||||
b.ContentType == v1.MediaTypeImageManifest || b.ContentType == v1.MediaTypeImageIndex ||
|
||||
b.ContentType == manifestlist.MediaTypeManifestList
|
||||
}
|
||||
|
|
|
@ -18,29 +18,27 @@ import (
|
|||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
// manifestlist
|
||||
_ "github.com/docker/distribution/manifest/manifestlist"
|
||||
_ "github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
// oci schema
|
||||
_ "github.com/docker/distribution/manifest/ocischema"
|
||||
// docker schema1 manifest
|
||||
_ "github.com/docker/distribution/manifest/schema1"
|
||||
_ "github.com/distribution/distribution/v3/manifest/ocischema"
|
||||
// docker schema2 manifest
|
||||
_ "github.com/docker/distribution/manifest/schema2"
|
||||
ref "github.com/docker/distribution/reference"
|
||||
_ "github.com/distribution/distribution/v3/manifest/schema2"
|
||||
ref "github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
)
|
||||
|
||||
// Descriptor alias type of github.com/docker/distribution.Descriptor
|
||||
// Descriptor alias type of github.com/distribution/distribution/v3.Descriptor
|
||||
type Descriptor = distribution.Descriptor
|
||||
|
||||
// Manifest alias type of github.com/docker/distribution.Manifest
|
||||
// Manifest alias type of github.com/distribution/distribution/v3.Manifest
|
||||
type Manifest = distribution.Manifest
|
||||
|
||||
var (
|
||||
// UnmarshalManifest alias func from `github.com/docker/distribution`
|
||||
// UnmarshalManifest alias func from `github.com/distribution/distribution/v3`
|
||||
UnmarshalManifest = distribution.UnmarshalManifest
|
||||
)
|
||||
|
||||
|
|
|
@ -17,10 +17,9 @@ package distribution
|
|||
import (
|
||||
"testing"
|
||||
|
||||
_ "github.com/docker/distribution/manifest/manifestlist"
|
||||
_ "github.com/docker/distribution/manifest/ocischema"
|
||||
_ "github.com/docker/distribution/manifest/schema1"
|
||||
_ "github.com/docker/distribution/manifest/schema2"
|
||||
_ "github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
_ "github.com/distribution/distribution/v3/manifest/ocischema"
|
||||
_ "github.com/distribution/distribution/v3/manifest/schema2"
|
||||
)
|
||||
|
||||
func TestParseSessionID(t *testing.T) {
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/utils"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"io"
|
||||
"sort"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
)
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/docker/distribution/registry/client/auth/challenge"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util/challenge"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
)
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/distribution/distribution/v3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
gock "gopkg.in/h2non/gock.v1"
|
||||
|
||||
|
|
42
src/pkg/reg/util/challenge/addr.go
Normal file
42
src/pkg/reg/util/challenge/addr.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright Project Harbor Authors
|
||||
// Based on code from https://github.com/distribution/distribution.
|
||||
//
|
||||
// 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 challenge
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// FROM: https://golang.org/src/net/http/http.go
|
||||
// Given a string of the form "host", "host:port", or "[ipv6::address]:port",
|
||||
// return true if the string includes a port.
|
||||
func hasPort(s string) bool { return strings.LastIndex(s, ":") > strings.LastIndex(s, "]") }
|
||||
|
||||
// FROM: http://golang.org/src/net/http/transport.go
|
||||
var portMap = map[string]string{
|
||||
"http": "80",
|
||||
"https": "443",
|
||||
}
|
||||
|
||||
// canonicalAddr returns url.Host but always with a ":port" suffix
|
||||
// FROM: http://golang.org/src/net/http/transport.go
|
||||
func canonicalAddr(url *url.URL) string {
|
||||
addr := url.Host
|
||||
if !hasPort(addr) {
|
||||
return addr + ":" + portMap[url.Scheme]
|
||||
}
|
||||
return addr
|
||||
}
|
252
src/pkg/reg/util/challenge/authchallenge.go
Normal file
252
src/pkg/reg/util/challenge/authchallenge.go
Normal file
|
@ -0,0 +1,252 @@
|
|||
// Copyright Project Harbor Authors
|
||||
// Based on code from https://github.com/distribution/distribution.
|
||||
//
|
||||
// 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 challenge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Octet types from RFC 2616.
|
||||
type octetType byte
|
||||
|
||||
var octetTypes [256]octetType
|
||||
|
||||
const (
|
||||
isToken octetType = 1 << iota
|
||||
isSpace
|
||||
)
|
||||
|
||||
func init() {
|
||||
// OCTET = <any 8-bit sequence of data>
|
||||
// CHAR = <any US-ASCII character (octets 0 - 127)>
|
||||
// CTL = <any US-ASCII control character (octets 0 - 31) and DEL (127)>
|
||||
// CR = <US-ASCII CR, carriage return (13)>
|
||||
// LF = <US-ASCII LF, linefeed (10)>
|
||||
// SP = <US-ASCII SP, space (32)>
|
||||
// HT = <US-ASCII HT, horizontal-tab (9)>
|
||||
// <"> = <US-ASCII double-quote mark (34)>
|
||||
// CRLF = CR LF
|
||||
// LWS = [CRLF] 1*( SP | HT )
|
||||
// TEXT = <any OCTET except CTLs, but including LWS>
|
||||
// separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <">
|
||||
// | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
|
||||
// token = 1*<any CHAR except CTLs or separators>
|
||||
// qdtext = <any TEXT except <">>
|
||||
|
||||
for c := 0; c < 256; c++ {
|
||||
var t octetType
|
||||
isCtl := c <= 31 || c == 127
|
||||
isChar := 0 <= c && c <= 127
|
||||
isSeparator := strings.ContainsRune(" \t\"(),/:;<=>?@[]\\{}", rune(c))
|
||||
if strings.ContainsRune(" \t\r\n", rune(c)) {
|
||||
t |= isSpace
|
||||
}
|
||||
if isChar && !isCtl && !isSeparator {
|
||||
t |= isToken
|
||||
}
|
||||
octetTypes[c] = t
|
||||
}
|
||||
}
|
||||
|
||||
// Challenge carries information from a WWW-Authenticate response header.
|
||||
// See RFC 2617.
|
||||
type Challenge struct {
|
||||
// Scheme is the auth-scheme according to RFC 2617
|
||||
Scheme string
|
||||
|
||||
// Parameters are the auth-params according to RFC 2617
|
||||
Parameters map[string]string
|
||||
}
|
||||
|
||||
// Manager manages the challenges for endpoints.
|
||||
// The challenges are pulled out of HTTP responses. Only
|
||||
// responses which expect challenges should be added to
|
||||
// the manager, since a non-unauthorized request will be
|
||||
// viewed as not requiring challenges.
|
||||
type Manager interface {
|
||||
// GetChallenges returns the challenges for the given
|
||||
// endpoint URL.
|
||||
GetChallenges(endpoint url.URL) ([]Challenge, error)
|
||||
|
||||
// AddResponse adds the response to the challenge
|
||||
// manager. The challenges will be parsed out of
|
||||
// the WWW-Authenicate headers and added to the
|
||||
// URL which was produced the response. If the
|
||||
// response was authorized, any challenges for the
|
||||
// endpoint will be cleared.
|
||||
AddResponse(resp *http.Response) error
|
||||
}
|
||||
|
||||
// NewSimpleManager returns an instance of
|
||||
// Manager which only maps endpoints to challenges
|
||||
// based on the responses which have been added the
|
||||
// manager. The simple manager will make no attempt to
|
||||
// perform requests on the endpoints or cache the responses
|
||||
// to a backend.
|
||||
func NewSimpleManager() Manager {
|
||||
return &simpleManager{
|
||||
Challenges: make(map[string][]Challenge),
|
||||
}
|
||||
}
|
||||
|
||||
type simpleManager struct {
|
||||
sync.RWMutex
|
||||
Challenges map[string][]Challenge
|
||||
}
|
||||
|
||||
func normalizeURL(endpoint *url.URL) {
|
||||
endpoint.Host = strings.ToLower(endpoint.Host)
|
||||
endpoint.Host = canonicalAddr(endpoint)
|
||||
}
|
||||
|
||||
func (m *simpleManager) GetChallenges(endpoint url.URL) ([]Challenge, error) {
|
||||
normalizeURL(&endpoint)
|
||||
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
challenges := m.Challenges[endpoint.String()]
|
||||
return challenges, nil
|
||||
}
|
||||
|
||||
func (m *simpleManager) AddResponse(resp *http.Response) error {
|
||||
challenges := ResponseChallenges(resp)
|
||||
if resp.Request == nil {
|
||||
return fmt.Errorf("missing request reference")
|
||||
}
|
||||
urlCopy := url.URL{
|
||||
Path: resp.Request.URL.Path,
|
||||
Host: resp.Request.URL.Host,
|
||||
Scheme: resp.Request.URL.Scheme,
|
||||
}
|
||||
normalizeURL(&urlCopy)
|
||||
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
m.Challenges[urlCopy.String()] = challenges
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResponseChallenges returns a list of authorization challenges
|
||||
// for the given http Response. Challenges are only checked if
|
||||
// the response status code was a 401.
|
||||
func ResponseChallenges(resp *http.Response) []Challenge {
|
||||
if resp.StatusCode == http.StatusUnauthorized {
|
||||
// Parse the WWW-Authenticate Header and store the challenges
|
||||
// on this endpoint object.
|
||||
return parseAuthHeader(resp.Header)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseAuthHeader(header http.Header) []Challenge {
|
||||
challenges := []Challenge{}
|
||||
for _, h := range header[http.CanonicalHeaderKey("WWW-Authenticate")] {
|
||||
v, p := parseValueAndParams(h)
|
||||
if v != "" {
|
||||
challenges = append(challenges, Challenge{Scheme: v, Parameters: p})
|
||||
}
|
||||
}
|
||||
return challenges
|
||||
}
|
||||
|
||||
func parseValueAndParams(header string) (value string, params map[string]string) {
|
||||
params = make(map[string]string)
|
||||
value, s := expectToken(header)
|
||||
if value == "" {
|
||||
return
|
||||
}
|
||||
value = strings.ToLower(value)
|
||||
s = "," + skipSpace(s)
|
||||
for strings.HasPrefix(s, ",") {
|
||||
var pkey string
|
||||
pkey, s = expectToken(skipSpace(s[1:]))
|
||||
if pkey == "" {
|
||||
return
|
||||
}
|
||||
if !strings.HasPrefix(s, "=") {
|
||||
return
|
||||
}
|
||||
var pvalue string
|
||||
pvalue, s = expectTokenOrQuoted(s[1:])
|
||||
if pvalue == "" {
|
||||
return
|
||||
}
|
||||
pkey = strings.ToLower(pkey)
|
||||
params[pkey] = pvalue
|
||||
s = skipSpace(s)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func skipSpace(s string) (rest string) {
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
if octetTypes[s[i]]&isSpace == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return s[i:]
|
||||
}
|
||||
|
||||
func expectToken(s string) (token, rest string) {
|
||||
i := 0
|
||||
for ; i < len(s); i++ {
|
||||
if octetTypes[s[i]]&isToken == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
return s[:i], s[i:]
|
||||
}
|
||||
|
||||
func expectTokenOrQuoted(s string) (value string, rest string) {
|
||||
if !strings.HasPrefix(s, "\"") {
|
||||
return expectToken(s)
|
||||
}
|
||||
s = s[1:]
|
||||
for i := 0; i < len(s); i++ {
|
||||
switch s[i] {
|
||||
case '"':
|
||||
return s[:i], s[i+1:]
|
||||
case '\\':
|
||||
p := make([]byte, len(s)-1)
|
||||
j := copy(p, s[:i])
|
||||
escape := true
|
||||
for i = i + 1; i < len(s); i++ {
|
||||
b := s[i]
|
||||
switch {
|
||||
case escape:
|
||||
escape = false
|
||||
p[j] = b
|
||||
j++
|
||||
case b == '\\':
|
||||
escape = true
|
||||
case b == '"':
|
||||
return string(p[:j]), s[i+1:]
|
||||
default:
|
||||
p[j] = b
|
||||
j++
|
||||
}
|
||||
}
|
||||
return "", ""
|
||||
}
|
||||
}
|
||||
return "", ""
|
||||
}
|
139
src/pkg/reg/util/challenge/authchallenge_test.go
Normal file
139
src/pkg/reg/util/challenge/authchallenge_test.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
// Copyright Project Harbor Authors
|
||||
// Based on code from https://github.com/distribution/distribution.
|
||||
//
|
||||
// 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 challenge
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestAuthChallengeParse(t *testing.T) {
|
||||
header := http.Header{}
|
||||
header.Add("WWW-Authenticate", `Bearer realm="https://auth.example.com/token",service="registry.example.com",other=fun,slashed="he\"\l\lo"`)
|
||||
|
||||
challenges := parseAuthHeader(header)
|
||||
if len(challenges) != 1 {
|
||||
t.Fatalf("Unexpected number of auth challenges: %d, expected 1", len(challenges))
|
||||
}
|
||||
challenge := challenges[0]
|
||||
|
||||
if expected := "bearer"; challenge.Scheme != expected {
|
||||
t.Fatalf("Unexpected scheme: %s, expected: %s", challenge.Scheme, expected)
|
||||
}
|
||||
|
||||
if expected := "https://auth.example.com/token"; challenge.Parameters["realm"] != expected {
|
||||
t.Fatalf("Unexpected param: %s, expected: %s", challenge.Parameters["realm"], expected)
|
||||
}
|
||||
|
||||
if expected := "registry.example.com"; challenge.Parameters["service"] != expected {
|
||||
t.Fatalf("Unexpected param: %s, expected: %s", challenge.Parameters["service"], expected)
|
||||
}
|
||||
|
||||
if expected := "fun"; challenge.Parameters["other"] != expected {
|
||||
t.Fatalf("Unexpected param: %s, expected: %s", challenge.Parameters["other"], expected)
|
||||
}
|
||||
|
||||
if expected := "he\"llo"; challenge.Parameters["slashed"] != expected {
|
||||
t.Fatalf("Unexpected param: %s, expected: %s", challenge.Parameters["slashed"], expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthChallengeNormalization(t *testing.T) {
|
||||
testAuthChallengeNormalization(t, "reg.EXAMPLE.com")
|
||||
testAuthChallengeNormalization(t, "bɿɒʜɔiɿ-ɿɘƚƨim-ƚol-ɒ-ƨʞnɒʜƚ.com")
|
||||
testAuthChallengeNormalization(t, "reg.example.com:80")
|
||||
testAuthChallengeConcurrent(t, "reg.EXAMPLE.com")
|
||||
}
|
||||
|
||||
func testAuthChallengeNormalization(t *testing.T, host string) {
|
||||
scm := NewSimpleManager()
|
||||
|
||||
url, err := url.Parse(fmt.Sprintf("http://%s/v2/", host))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp := &http.Response{
|
||||
Request: &http.Request{
|
||||
URL: url,
|
||||
},
|
||||
Header: make(http.Header),
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
}
|
||||
resp.Header.Add("WWW-Authenticate", fmt.Sprintf("Bearer realm=\"https://%s/token\",service=\"registry.example.com\"", host))
|
||||
|
||||
err = scm.AddResponse(resp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
lowered := *url
|
||||
lowered.Host = strings.ToLower(lowered.Host)
|
||||
lowered.Host = canonicalAddr(&lowered)
|
||||
c, err := scm.GetChallenges(lowered)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(c) == 0 {
|
||||
t.Fatal("Expected challenge for lower-cased-host URL")
|
||||
}
|
||||
}
|
||||
|
||||
func testAuthChallengeConcurrent(t *testing.T, host string) {
|
||||
scm := NewSimpleManager()
|
||||
|
||||
url, err := url.Parse(fmt.Sprintf("http://%s/v2/", host))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
resp := &http.Response{
|
||||
Request: &http.Request{
|
||||
URL: url,
|
||||
},
|
||||
Header: make(http.Header),
|
||||
StatusCode: http.StatusUnauthorized,
|
||||
}
|
||||
resp.Header.Add("WWW-Authenticate", fmt.Sprintf("Bearer realm=\"https://%s/token\",service=\"registry.example.com\"", host))
|
||||
var s sync.WaitGroup
|
||||
s.Add(2)
|
||||
go func() {
|
||||
defer s.Done()
|
||||
for i := 0; i < 200; i++ {
|
||||
err = scm.AddResponse(resp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer s.Done()
|
||||
lowered := *url
|
||||
lowered.Host = strings.ToLower(lowered.Host)
|
||||
for k := 0; k < 200; k++ {
|
||||
_, err := scm.GetChallenges(lowered)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
s.Wait()
|
||||
}
|
|
@ -18,11 +18,10 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/registry/client/auth/challenge"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util/challenge"
|
||||
)
|
||||
|
||||
// GetHTTPTransport can be used to share the common HTTP transport
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/distribution/registry/client/auth/challenge"
|
||||
"github.com/goharbor/harbor/src/pkg/reg/util/challenge"
|
||||
|
||||
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||
"github.com/goharbor/harbor/src/common/http/modifier"
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/distribution/reference"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -26,11 +26,10 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
_ "github.com/docker/distribution/manifest/ocischema" // register oci manifest unmarshal function
|
||||
"github.com/docker/distribution/manifest/schema1"
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
distribution "github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
_ "github.com/distribution/distribution/v3/manifest/ocischema" // register oci manifest unmarshal function
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/opencontainers/go-digest"
|
||||
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
|
@ -57,8 +56,6 @@ var (
|
|||
manifestlist.MediaTypeManifestList,
|
||||
v1.MediaTypeImageManifest,
|
||||
schema2.MediaTypeManifest,
|
||||
schema1.MediaTypeSignedManifest,
|
||||
schema1.MediaTypeManifest,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -609,8 +606,7 @@ func (c *client) Copy(srcRepo, srcRef, dstRepo, dstRef string, override bool) er
|
|||
continue
|
||||
// manifest or index
|
||||
case v1.MediaTypeImageIndex, manifestlist.MediaTypeManifestList,
|
||||
v1.MediaTypeImageManifest, schema2.MediaTypeManifest,
|
||||
schema1.MediaTypeSignedManifest, schema1.MediaTypeManifest:
|
||||
v1.MediaTypeImageManifest, schema2.MediaTypeManifest:
|
||||
if err = c.Copy(srcRepo, digest, dstRepo, digest, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/utils/test"
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"crypto/subtle"
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
"github.com/distribution/distribution/v3/registry/auth/token"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package v2
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/registry/auth/token"
|
||||
"github.com/distribution/distribution/v3/registry/auth/token"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
|
|
@ -83,6 +83,7 @@
|
|||
(clickLabel)="selectValue($event)"
|
||||
[scope]="'p'"
|
||||
[projectId]="projectId"
|
||||
[dropdownOpened]="dropdownOpened"
|
||||
[width]="200"
|
||||
[ownedLabels]="getSelectLabel()">
|
||||
</app-label-selector>
|
||||
|
|
|
@ -59,6 +59,6 @@ describe('LabelSelectorComponent', () => {
|
|||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
const checkIcon = fixture.nativeElement.querySelector('.check-icon');
|
||||
expect(checkIcon.style.visibility).toEqual('visible');
|
||||
expect(checkIcon.style.visibility).toEqual('hidden');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -41,6 +41,8 @@ export class LabelSelectorComponent implements OnInit, OnChanges, OnDestroy {
|
|||
scope: string = GLOBAL; // 'g' for global and 'p' for project, default 'g'
|
||||
@Input()
|
||||
projectId: number; // if scope = 'p', projectId is required
|
||||
@Input()
|
||||
dropdownOpened: boolean; // parent component opened status
|
||||
candidateLabels: Label[] = [];
|
||||
searchValue: string;
|
||||
loading: boolean = false;
|
||||
|
@ -159,7 +161,7 @@ export class LabelSelectorComponent implements OnInit, OnChanges, OnDestroy {
|
|||
isSelect(label: Label): boolean {
|
||||
if (this.ownedLabels?.length) {
|
||||
return this.ownedLabels.some(item => {
|
||||
return item.id === label.id;
|
||||
return item.id === label.id && this.dropdownOpened;
|
||||
});
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/distribution/registry/storage/driver"
|
||||
"github.com/distribution/distribution/v3/registry/storage/driver"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
lib_http "github.com/goharbor/harbor/src/lib/http"
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/registry/storage/driver"
|
||||
"github.com/distribution/distribution/v3/registry/storage/driver"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
)
|
||||
|
|
|
@ -18,8 +18,8 @@ import (
|
|||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/distribution/registry/storage"
|
||||
storagedriver "github.com/docker/distribution/registry/storage/driver"
|
||||
"github.com/distribution/distribution/v3/registry/storage"
|
||||
storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
|
||||
"github.com/gorilla/mux"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
"go.opentelemetry.io/otel/trace"
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/registry/storage/driver/inmemory"
|
||||
"github.com/docker/distribution/testutil"
|
||||
"github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
|
||||
"github.com/distribution/distribution/v3/testutil"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
@ -42,6 +42,9 @@ func TestDeletionBlob(t *testing.T) {
|
|||
}
|
||||
|
||||
req, err := http.NewRequest(http.MethodDelete, "", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create new http request: %v", err)
|
||||
}
|
||||
varMap := make(map[string]string, 1)
|
||||
varMap["reference"] = test.GetKeys(randomLayers1)[0].String()
|
||||
req = mux.SetURLVars(req, varMap)
|
||||
|
|
|
@ -17,8 +17,8 @@ package manifest
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/distribution/registry/storage"
|
||||
storagedriver "github.com/docker/distribution/registry/storage/driver"
|
||||
"github.com/distribution/distribution/v3/registry/storage"
|
||||
storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/opencontainers/go-digest"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package manifest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/registry/storage/driver/inmemory"
|
||||
"github.com/docker/distribution/testutil"
|
||||
"github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
|
||||
"github.com/distribution/distribution/v3/testutil"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
|
|
|
@ -15,26 +15,21 @@
|
|||
package test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution"
|
||||
"github.com/docker/distribution/context"
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/distribution/registry/storage"
|
||||
"github.com/docker/distribution/registry/storage/driver"
|
||||
"github.com/docker/libtrust"
|
||||
distribution "github.com/distribution/distribution/v3"
|
||||
"github.com/distribution/distribution/v3/registry/storage"
|
||||
"github.com/distribution/distribution/v3/registry/storage/driver"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
// CreateRegistry ...
|
||||
func CreateRegistry(t *testing.T, driver driver.StorageDriver, options ...storage.RegistryOption) distribution.Namespace {
|
||||
ctx := context.Background()
|
||||
k, err := libtrust.GenerateECP256PrivateKey()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
options = append([]storage.RegistryOption{storage.EnableDelete, storage.Schema1SigningKey(k), storage.EnableSchema1}, options...)
|
||||
options = append([]storage.RegistryOption{storage.EnableDelete}, options...)
|
||||
registry, err := storage.NewRegistry(ctx, driver, options...)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to construct namespace")
|
||||
|
|
|
@ -15,12 +15,13 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/docker/distribution/configuration"
|
||||
storagedriver "github.com/docker/distribution/registry/storage/driver"
|
||||
"github.com/docker/distribution/registry/storage/driver/factory"
|
||||
"github.com/distribution/distribution/v3/configuration"
|
||||
storagedriver "github.com/distribution/distribution/v3/registry/storage/driver"
|
||||
"github.com/distribution/distribution/v3/registry/storage/driver/factory"
|
||||
yaml "gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
|
@ -78,7 +79,7 @@ func (c *Configuration) setStorageDriver() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("error parsing registry configuration %s: %v", c.RegistryConfig, err)
|
||||
}
|
||||
storageDriver, err := factory.Create(rConf.Storage.Type(), rConf.Storage.Parameters())
|
||||
storageDriver, err := factory.Create(context.TODO(), rConf.Storage.Type(), rConf.Storage.Parameters())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ package config
|
|||
import (
|
||||
"testing"
|
||||
|
||||
_ "github.com/docker/distribution/registry/storage/driver/filesystem"
|
||||
_ "github.com/distribution/distribution/v3/registry/storage/driver/filesystem"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -24,15 +24,13 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
_ "github.com/docker/distribution/registry/storage/driver/azure"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/filesystem"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/gcs"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/inmemory"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/middleware/cloudfront"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/middleware/redirect"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/oss"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/s3-aws"
|
||||
_ "github.com/docker/distribution/registry/storage/driver/swift"
|
||||
_ "github.com/distribution/distribution/v3/registry/storage/driver/azure"
|
||||
_ "github.com/distribution/distribution/v3/registry/storage/driver/filesystem"
|
||||
_ "github.com/distribution/distribution/v3/registry/storage/driver/gcs"
|
||||
_ "github.com/distribution/distribution/v3/registry/storage/driver/inmemory"
|
||||
_ "github.com/distribution/distribution/v3/registry/storage/driver/middleware/cloudfront"
|
||||
_ "github.com/distribution/distribution/v3/registry/storage/driver/middleware/redirect"
|
||||
_ "github.com/distribution/distribution/v3/registry/storage/driver/s3-aws"
|
||||
|
||||
common_http "github.com/goharbor/harbor/src/common/http"
|
||||
cfgLib "github.com/goharbor/harbor/src/lib/config"
|
||||
|
|
|
@ -48,6 +48,3 @@ notifications:
|
|||
- application/vnd.oci.image.layer.nondistributable.v1.tar+gzip
|
||||
- application/vnd.oci.image.layer.nondistributable.v1.tar+zstd
|
||||
- application/octet-stream
|
||||
compatibility:
|
||||
schema1:
|
||||
enabled: true
|
|
@ -21,7 +21,7 @@ import (
|
|||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/opencontainers/go-digest"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
"net/http"
|
||||
"regexp"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/distribution/reference"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
|
||||
"github.com/goharbor/harbor/src/controller/artifact"
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
registry_token "github.com/docker/distribution/registry/auth/token"
|
||||
registry_token "github.com/distribution/distribution/v3/registry/auth/token"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/security"
|
||||
"github.com/goharbor/harbor/src/common/security/v2token"
|
||||
|
|
|
@ -5,7 +5,7 @@ import (
|
|||
"net/http"
|
||||
"testing"
|
||||
|
||||
registry_token "github.com/docker/distribution/registry/auth/token"
|
||||
registry_token "github.com/distribution/distribution/v3/registry/auth/token"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
"github.com/opencontainers/go-digest"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
"github.com/distribution/distribution/v3/manifest/schema2"
|
||||
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/docker/distribution/manifest/manifestlist"
|
||||
"github.com/distribution/distribution/v3/manifest/manifestlist"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/security"
|
||||
|
|
|
@ -191,7 +191,7 @@ func putManifest(w http.ResponseWriter, req *http.Request) {
|
|||
|
||||
// When got the response from the backend docker registry, the manifest and
|
||||
// tag are both ready, so we don't need to handle the issue anymore:
|
||||
// https://github.com/docker/distribution/issues/2625
|
||||
// https://github.com/distribution/distribution/v3/issues/2625
|
||||
|
||||
var tags []string
|
||||
dgt := reference
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/distribution/reference"
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/opencontainers/go-digest"
|
||||
|
|
|
@ -44,7 +44,7 @@ func (r *Robot) ToSwagger() *models.Robot {
|
|||
Name: r.Name,
|
||||
Description: r.Description,
|
||||
ExpiresAt: r.ExpiresAt,
|
||||
Duration: r.Duration,
|
||||
Duration: &r.Duration,
|
||||
Level: r.Level,
|
||||
Disable: r.Disabled,
|
||||
Editable: r.Editable,
|
||||
|
|
|
@ -29,7 +29,6 @@ import (
|
|||
"github.com/goharbor/harbor/src/common/utils"
|
||||
"github.com/goharbor/harbor/src/controller/robot"
|
||||
"github.com/goharbor/harbor/src/lib"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/errors"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/pkg/permission/types"
|
||||
|
@ -276,7 +275,7 @@ func (rAPI *robotAPI) requireAccess(ctx context.Context, level string, projectID
|
|||
// more validation
|
||||
func (rAPI *robotAPI) validate(d int64, level string, permissions []*models.RobotPermission) error {
|
||||
if !isValidDuration(d) {
|
||||
return errors.New(nil).WithMessage("bad request error duration input: %d", d).WithCode(errors.BadRequestCode)
|
||||
return errors.New(nil).WithMessage("bad request error duration input: %d, duration must be either -1(Never) or a positive integer", d).WithCode(errors.BadRequestCode)
|
||||
}
|
||||
|
||||
if !isValidLevel(level) {
|
||||
|
@ -323,7 +322,10 @@ func (rAPI *robotAPI) validate(d int64, level string, permissions []*models.Robo
|
|||
}
|
||||
|
||||
func (rAPI *robotAPI) updateV2Robot(ctx context.Context, params operation.UpdateRobotParams, r *robot.Robot) error {
|
||||
if err := rAPI.validate(params.Robot.Duration, params.Robot.Level, params.Robot.Permissions); err != nil {
|
||||
if params.Robot.Duration == nil {
|
||||
params.Robot.Duration = &r.Duration
|
||||
}
|
||||
if err := rAPI.validate(*params.Robot.Duration, params.Robot.Level, params.Robot.Permissions); err != nil {
|
||||
return err
|
||||
}
|
||||
if r.Level != robot.LEVELSYSTEM {
|
||||
|
@ -342,15 +344,12 @@ func (rAPI *robotAPI) updateV2Robot(ctx context.Context, params operation.Update
|
|||
return errors.BadRequestError(nil).WithMessage("cannot update the level or name of robot")
|
||||
}
|
||||
|
||||
if r.Duration != params.Robot.Duration {
|
||||
r.Duration = params.Robot.Duration
|
||||
if params.Robot.Duration == -1 {
|
||||
if r.Duration != *params.Robot.Duration {
|
||||
r.Duration = *params.Robot.Duration
|
||||
if *params.Robot.Duration == -1 {
|
||||
r.ExpiresAt = -1
|
||||
} else if params.Robot.Duration == 0 {
|
||||
r.Duration = int64(config.RobotTokenDuration(ctx))
|
||||
r.ExpiresAt = r.CreationTime.AddDate(0, 0, config.RobotTokenDuration(ctx)).Unix()
|
||||
} else {
|
||||
r.ExpiresAt = r.CreationTime.AddDate(0, 0, int(params.Robot.Duration)).Unix()
|
||||
r.ExpiresAt = r.CreationTime.AddDate(0, 0, int(*params.Robot.Duration)).Unix()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,7 +374,7 @@ func isValidLevel(l string) bool {
|
|||
}
|
||||
|
||||
func isValidDuration(d int64) bool {
|
||||
return d >= int64(-1) && d < math.MaxInt32
|
||||
return d >= int64(-1) && d != 0 && d < math.MaxInt32
|
||||
}
|
||||
|
||||
// validateName validates the robot name, especially '+' cannot be a valid character
|
||||
|
|
|
@ -47,7 +47,7 @@ func TestValidDuration(t *testing.T) {
|
|||
}{
|
||||
{"duration 0",
|
||||
0,
|
||||
true,
|
||||
false,
|
||||
},
|
||||
{"duration 1",
|
||||
1,
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
|
||||
blob "github.com/goharbor/harbor/src/controller/blob"
|
||||
|
||||
distribution "github.com/docker/distribution"
|
||||
distribution "github.com/distribution/distribution/v3"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user