diff --git a/.dive-ci b/.dive-ci
new file mode 100644
index 00000000..75f947d3
--- /dev/null
+++ b/.dive-ci
@@ -0,0 +1,13 @@
+rules:
+ # If the efficiency is measured below X%, mark as failed.
+ # Expressed as a ratio between 0-1.
+ lowestEfficiency: 0.90
+
+ # If the amount of wasted space is at least X or larger than X, mark as failed.
+ # Expressed in B, KB, MB, and GB.
+ highestWastedBytes: 20MB
+
+ # If the amount of wasted space makes up for X% or more of the image, mark as failed.
+ # Note: the base image layer is NOT included in the total image size.
+ # Expressed as a ratio between 0-1; fails if the threshold is met or crossed.
+ highestUserWastedPercent: 0.25
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..75bc82fd
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,15 @@
+---
+version: 2
+updates:
+ - package-ecosystem: 'docker'
+ directory: '/'
+ schedule:
+ interval: 'weekly'
+ - package-ecosystem: 'github-actions'
+ directory: '/'
+ schedule:
+ interval: 'weekly'
+ - package-ecosystem: 'gomod'
+ directory: '/'
+ schedule:
+ interval: 'weekly'
diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml
index b4f1d01a..db8e9111 100644
--- a/.github/workflows/trivy.yml
+++ b/.github/workflows/trivy.yml
@@ -12,7 +12,7 @@ jobs:
run: |
docker build -t utrecht/n3dr:${{ github.sha }} .
- name: Run Trivy vulnerability scanner
- uses: aquasecurity/trivy-action@master
+ uses: aquasecurity/trivy-action@0.14.0
with:
image-ref: 'utrecht/n3dr:${{ github.sha }}'
format: 'table'
@@ -20,3 +20,13 @@ jobs:
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH'
+ trivyignores: .trivyignore
+ - name: Run Trivy vulnerability scanner in fs mode
+ uses: aquasecurity/trivy-action@0.14.0
+ with:
+ scan-type: 'fs'
+ scan-ref: '.'
+ exit-code: '1'
+ ignore-unfixed: true
+ severity: 'CRITICAL,HIGH'
+ trivyignores: .trivyignore
diff --git a/.trivyignore b/.trivyignore
new file mode 100644
index 00000000..a1cc6963
--- /dev/null
+++ b/.trivyignore
@@ -0,0 +1 @@
+#CVE-2023-5363
diff --git a/Dockerfile b/Dockerfile
index 9872e566..9c948db3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,13 +5,16 @@ RUN adduser -D -g '' $USERNAME
COPY . /go/${USERNAME}/
WORKDIR /go/${USERNAME}/cmd/${USERNAME}
RUN apk add --no-cache \
- git=~2 && \
- CGO_ENABLED=0 go build -ldflags "-X main.Version=${VERSION}" -buildvcs=false && \
- cp n3dr /n3dr
+ git=~2 && \
+ CGO_ENABLED=0 go build -ldflags "-X main.Version=${VERSION}" -buildvcs=false && \
+ cp n3dr /n3dr
-FROM alpine:3.18.3
+FROM alpine:3.18.4
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /n3dr /usr/local/bin/n3dr
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
+RUN apk add --no-cache \
+ libcrypto3=3.1.4-r1 \
+ libssl3=3.1.4-r1
USER n3dr
-ENTRYPOINT ["/usr/local/bin/n3dr"]
+ENTRYPOINT ["n3dr"]
diff --git a/README.md b/README.md
index a6f52f8d..d16b4daf 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
[![DevOps SE Questions](https://img.shields.io/stackexchange/devops/t/n3dr.svg?logo=stackexchange)](https://devops.stackexchange.com/tags/n3dr)
[![ServerFault SE Questions](https://img.shields.io/stackexchange/serverfault/t/n3dr.svg?logo=serverfault)](https://serverfault.com/tags/n3dr)
[![Docker Pulls](https://img.shields.io/docker/pulls/utrecht/n3dr?logo=docker&logoColor=white)](https://hub.docker.com/r/utrecht/n3dr)
-![Docker Image Size (latest semver)](https://img.shields.io/docker/image-size/utrecht/n3dr?logo=docker&logoColor=white&sort=semver)
+[![Docker Image Size (latest semver)](https://img.shields.io/docker/image-size/utrecht/n3dr?logo=docker&logoColor=white&sort=semver)](https://hub.docker.com/r/utrecht/n3dr)
![Issues](https://img.shields.io/github/issues-raw/030/n3dr.svg)
![Pull requests](https://img.shields.io/github/issues-pr-raw/030/n3dr.svg)
![Total downloads](https://img.shields.io/github/downloads/030/n3dr/total.svg)
diff --git a/build/package/snap/snapcraft.yaml b/build/package/snap/snapcraft.yaml
index 5de84cd6..b526b3e2 100644
--- a/build/package/snap/snapcraft.yaml
+++ b/build/package/snap/snapcraft.yaml
@@ -1,7 +1,7 @@
---
name: n3dr
base: core20
-version: 7.3.1
+version: 7.3.2
summary: Nexus3 Disaster Recovery
description: |
Download all artifacts at once or migrate automatically from Nexus to Nexus.
diff --git a/cmd/n3dr/configRepository.go b/cmd/n3dr/configRepository.go
index d8e78d4e..7d8f9f44 100644
--- a/cmd/n3dr/configRepository.go
+++ b/cmd/n3dr/configRepository.go
@@ -1,6 +1,7 @@
package main
import (
+ "fmt"
"os"
"github.com/030/n3dr/internal/app/n3dr/config/repository"
@@ -13,8 +14,109 @@ var (
configRepoDockerPortSecure, configRepoDelete, snapshot, strictContentTypeValidation bool
configRepoDockerPort int32
configRepoName, configRepoRecipe, configRepoType, configRepoProxyURL string
+ configRepoGroupMemberNames []string
)
+type repo struct {
+ conn repository.Repository
+ kind, name, recipe string
+ snapshot bool
+}
+
+var repoRecipeAndKindNotSupported = "repoRecipe: '%s' not supported in conjunction with repoKind: '%s'"
+
+func (r *repo) createByType() error {
+ switch configRepoType {
+ case "apt":
+ return r.Apt()
+ case "docker":
+ return r.Docker()
+ case "gem":
+ return r.Gem()
+ case "maven2":
+ return r.Maven2()
+ case "npm":
+ return r.Npm()
+ case "raw":
+ return r.Raw()
+ case "yum":
+ return r.Yum()
+ default:
+ return fmt.Errorf("configRepoType should not be empty, but: 'apt', 'docker', 'gem', 'maven2', 'npm' 'raw' or 'yum' and not: '%s'. Did you populate the --configRepoType parameter?", configRepoType)
+ }
+}
+
+func (r *repo) Apt() error {
+ switch r.recipe {
+ case "proxy":
+ return r.conn.CreateAptProxied(r.name)
+ default:
+ return fmt.Errorf(repoRecipeAndKindNotSupported, r.recipe, r.kind)
+ }
+}
+
+func (r *repo) Docker() error {
+ switch r.recipe {
+ case "hosted":
+ return r.conn.CreateDockerHosted(configRepoDockerPortSecure, configRepoDockerPort, r.name)
+ default:
+ return fmt.Errorf(repoRecipeAndKindNotSupported, r.recipe, r.kind)
+ }
+}
+
+func (r *repo) Gem() error {
+ switch r.recipe {
+ case "hosted":
+ return r.conn.CreateGemHosted(r.name)
+ default:
+ return fmt.Errorf(repoRecipeAndKindNotSupported, r.recipe, r.kind)
+ }
+}
+
+func (r *repo) Maven2() error {
+ switch r.recipe {
+ case "group":
+ return r.conn.CreateMavenGroup(configRepoGroupMemberNames, r.name)
+ case "hosted":
+ return r.conn.CreateMavenHosted(r.name, snapshot)
+ case "proxy":
+ return r.conn.CreateMavenProxied(r.name)
+ default:
+ return fmt.Errorf(repoRecipeAndKindNotSupported, r.recipe, r.kind)
+ }
+}
+
+func (r *repo) Npm() error {
+ switch r.recipe {
+ case "hosted":
+ return r.conn.CreateNpmHosted(r.name, snapshot)
+ case "proxy":
+ return r.conn.CreateNpmProxied(r.name)
+ default:
+ return fmt.Errorf(repoRecipeAndKindNotSupported, r.recipe, r.kind)
+ }
+}
+
+func (r *repo) Raw() error {
+ switch r.recipe {
+ case "hosted":
+ return r.conn.CreateRawHosted(r.name)
+ default:
+ return fmt.Errorf(repoRecipeAndKindNotSupported, r.recipe, r.kind)
+ }
+}
+
+func (r *repo) Yum() error {
+ switch r.recipe {
+ case "hosted":
+ return r.conn.CreateYumHosted(r.name)
+ case "proxy":
+ return r.conn.CreateYumProxied(r.name)
+ default:
+ return fmt.Errorf(repoRecipeAndKindNotSupported, r.recipe, r.kind)
+ }
+}
+
// configRepositoryCmd represents the configRepository command.
var configRepositoryCmd = &cobra.Command{
Use: "configRepository",
@@ -26,6 +128,9 @@ Examples:
# Create a Docker repository:
n3dr configRepository -u some-user -p some-pass -n localhost:9000 --https=false --configRepoName some-name --configRepoType docker
+ # Create a Maven2 repository if credentials and FQDN have been set in a '~/.n3dr/config.yml' file:
+ n3dr configRepository --configRepoName some-name --configRepoType maven2
+
# Create a Maven2 repository:
n3dr configRepository -u some-user -p some-pass -n localhost:9000 --https=false --configRepoName some-name --configRepoType maven2
@@ -40,6 +145,16 @@ Examples:
# Create a Rubygems repository:
n3dr configRepository -u admin -p some-pass -n localhost:9000 --https=false --configRepoName 3rdparty-rubygems --configRepoType gem
+
+ # Create Maven2 proxies:
+ n3dr configRepository --configRepoType maven2 --configRepoName 3rdparty-maven --configRepoRecipe proxy --configRepoProxyURL https://repo.maven.apache.org/maven2/
+ n3dr configRepository --configRepoType maven2 --configRepoName 3rdparty-maven-gradle-plugins --configRepoRecipe proxy --configRepoProxyURL https://plugins.gradle.org/m2/
+
+ # Create a NPM proxy:
+ n3dr configRepository --configRepoType npm --configRepoName 3rdparty-npm --configRepoRecipe proxy --configRepoProxyURL https://registry.npmjs.org/
+
+ # Create a Maven2 group:
+ n3dr configRepository --configRepoType maven2 --configRepoRecipe group --configRepoName some-group --configRepoGroupMemberNames releases,snapshots
`,
Run: func(cmd *cobra.Command, args []string) {
n := connection.Nexus3{
@@ -49,10 +164,10 @@ Examples:
StrictContentTypeValidation: strictContentTypeValidation,
User: n3drUser,
}
- r := repository.Repository{Nexus3: n}
+ rr := repository.Repository{Nexus3: n}
if configRepoDelete {
- if err := r.Delete(configRepoName); err != nil {
+ if err := rr.Delete(configRepoName); err != nil {
log.Fatal(err)
}
os.Exit(0)
@@ -62,64 +177,17 @@ Examples:
log.Fatal("configRepoReceipe should not be empty")
}
- if configRepoRecipe == "proxy" {
- if configRepoProxyURL == "" {
- log.Fatal("configRepoProxyURL should not be empty")
- }
- r.ProxyRemoteURL = configRepoProxyURL
+ if configRepoRecipe == "proxy" && configRepoProxyURL == "" {
+ log.Fatal("configRepoProxyURL should not be empty")
+ } else {
+ rr.ProxyRemoteURL = configRepoProxyURL
+ log.Infof("configRepoProxyURL has been set to: '%s'", rr.ProxyRemoteURL)
}
- switch configRepoType {
- case "apt":
- if configRepoRecipe == "proxy" {
- if err := r.CreateAptProxied(configRepoName); err != nil {
- log.Fatal(err)
- }
- }
- case "docker":
- if configRepoRecipe == "hosted" {
- if err := r.CreateDockerHosted(configRepoDockerPortSecure, configRepoDockerPort, configRepoName); err != nil {
- log.Fatal(err)
- }
- }
- case "gem":
- if configRepoRecipe == "hosted" {
- if err := r.CreateGemHosted(configRepoName); err != nil {
- log.Fatal(err)
- }
- }
- case "maven2":
- if configRepoRecipe == "hosted" {
- if err := r.CreateMavenHosted(configRepoName, snapshot); err != nil {
- log.Fatal(err)
- }
- }
- case "npm":
- if configRepoRecipe == "hosted" {
- if err := r.CreateNpmHosted(configRepoName, snapshot); err != nil {
- log.Fatal(err)
- }
- }
- case "raw":
- if configRepoRecipe == "hosted" {
- if err := r.CreateRawHosted(configRepoName); err != nil {
- log.Fatal(err)
- }
- }
- case "yum":
- if configRepoRecipe == "hosted" {
- if err := r.CreateYumHosted(configRepoName); err != nil {
- log.Fatal(err)
- }
- } else if configRepoRecipe == "proxy" {
- if err := r.CreateYumProxied(configRepoName); err != nil {
- log.Fatal(err)
- }
- } else {
- log.Fatalf("configRepoRecipe: '%s' not supported in conjunction with configRepoType: '%s'", configRepoRecipe, configRepoType)
- }
- default:
- log.Fatalf("configRepoType should not be empty, but: 'apt', 'docker', 'maven2', 'raw' or 'yum' and not: '%s'. Did you populate the --configRepoType parameter?", configRepoType)
+ log.Infof("creating repo: '%s' of type: '%s'", configRepoName, configRepoType)
+ r := repo{conn: rr, kind: configRepoType, name: configRepoName, recipe: configRepoRecipe, snapshot: snapshot}
+ if err := r.createByType(); err != nil {
+ log.Fatalf("repo not created. Error: '%v'", err)
}
},
}
@@ -140,4 +208,5 @@ func init() {
configRepositoryCmd.Flags().Int32Var(&configRepoDockerPort, "configRepoDockerPort", 8082, "The docker connector port, e.g. 8082")
configRepositoryCmd.Flags().BoolVar(&configRepoDockerPortSecure, "configRepoDockerPortSecure", false, "Whether the docker connector port should be secure")
configRepositoryCmd.Flags().BoolVar(&strictContentTypeValidation, "strictContentTypeValidation", true, "whether strictContentTypeValidation should be enabled")
+ configRepositoryCmd.Flags().StringSliceVar(&configRepoGroupMemberNames, "configRepoGroupMemberNames", []string{}, "The repository type, e.g.: 'apt', 'raw'")
}
diff --git a/cmd/n3dr/root.go b/cmd/n3dr/root.go
index b7374e67..245f3425 100644
--- a/cmd/n3dr/root.go
+++ b/cmd/n3dr/root.go
@@ -219,7 +219,7 @@ func parseConfig(cfgFile string) error {
return err
}
} else {
- log.Warnf("Looked for config file: '%v', but found: '%v' including err: '%v'. Check whether it exists, the YAML is correct and the content is valid", cfgFile, viper.ConfigFileUsed(), err)
+ log.Debugf("Looked for config file: '%v', but found: '%v' including err: '%v'. Check whether it exists, the YAML is correct and the content is valid", cfgFile, viper.ConfigFileUsed(), err)
}
return nil
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 9dc51e5c..c2b5bd70 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -2,6 +2,18 @@
## [Unreleased]
+
+## [7.3.2] - 2023-12-02
+### Build
+- **deps:** bump golang.org/x/net from 0.15.0 to 0.17.0
+
+### Feat
+- Determine what images are running in a k8s cluster.
+
+### Fix
+- [[#384](https://github.com/030/n3dr/issues/384)] Create groups.
+
+
## [7.3.1] - 2023-10-14
### Fix
@@ -394,7 +406,8 @@ The `backup`, `upload` and `repositories` commands have been removed.
## 1.0.0 - 2019-05-12
-[Unreleased]: https://github.com/030/n3dr/compare/7.3.1...HEAD
+[Unreleased]: https://github.com/030/n3dr/compare/7.3.2...HEAD
+[7.3.2]: https://github.com/030/n3dr/compare/7.3.1...7.3.2
[7.3.1]: https://github.com/030/n3dr/compare/7.3.0...7.3.1
[7.3.0]: https://github.com/030/n3dr/compare/7.2.5...7.3.0
[7.2.5]: https://github.com/030/n3dr/compare/7.2.4...7.2.5
diff --git a/docs/README.md b/docs/README.md
index 931db96a..3049604e 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -238,7 +238,7 @@ n3dr config \
### Build
```bash
-docker build -t utrecht/n3dr:7.3.1 .
+docker build -t utrecht/n3dr:7.3.2 .
```
[![dockeri.co](https://dockeri.co/image/utrecht/n3dr)](https://hub.docker.com/r/utrecht/n3dr)
@@ -248,7 +248,7 @@ docker build -t utrecht/n3dr:7.3.1 .
```bash
docker run -it \
-v /home/${USER}/.n3dr:/root/.n3dr \
- -v /tmp/n3dr:/tmp/n3dr utrecht/n3dr:7.3.1
+ -v /tmp/n3dr:/tmp/n3dr utrecht/n3dr:7.3.2
```
### Upload
@@ -257,7 +257,7 @@ docker run -it \
docker run -it \
--entrypoint=/bin/ash \
-v /home/${USER}/.n3dr:/root/.n3dr \
- -v /tmp/n3dr:/tmp/n3dr utrecht/n3dr:7.3.1
+ -v /tmp/n3dr:/tmp/n3dr utrecht/n3dr:7.3.2
```
navigate to the repository folder, e.g. `/tmp/n3dr/download*/` and upload:
diff --git a/docs/quickstarts/snippets/n3dr/DOWNLOAD.md b/docs/quickstarts/snippets/n3dr/DOWNLOAD.md
index 8e8047aa..b9140867 100644
--- a/docs/quickstarts/snippets/n3dr/DOWNLOAD.md
+++ b/docs/quickstarts/snippets/n3dr/DOWNLOAD.md
@@ -1,12 +1,12 @@
# Download
-Download the [latest N3DR binary](https://github.com/030/n3dr/releases/tag/7.3.1):
+Download the [latest N3DR binary](https://github.com/030/n3dr/releases/tag/7.3.2):
```bash
cd /tmp && \
-curl -L https://github.com/030/n3dr/releases/download/7.3.1/n3dr-ubuntu-latest \
+curl -L https://github.com/030/n3dr/releases/download/7.3.2/n3dr-ubuntu-latest \
-o n3dr-ubuntu-latest && \
-curl -L https://github.com/030/n3dr/releases/download/7.3.1/\
+curl -L https://github.com/030/n3dr/releases/download/7.3.2/\
n3dr-ubuntu-latest.sha512.txt \
-o n3dr-ubuntu-latest.sha512.txt && \
sha512sum -c n3dr-ubuntu-latest.sha512.txt && \
diff --git a/go.mod b/go.mod
index 9848dd04..a995ae2a 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/030/n3dr
-go 1.19
+go 1.21
require (
github.com/030/logging v0.1.2
@@ -14,7 +14,7 @@ require (
github.com/go-openapi/validate v0.22.1
github.com/go-playground/validator/v10 v10.15.5
github.com/hashicorp/go-retryablehttp v0.7.4
- github.com/mholt/archiver v3.1.1+incompatible
+ github.com/mholt/archiver/v3 v3.5.1
github.com/mitchellh/go-homedir v1.1.0
github.com/samber/lo v1.38.1
github.com/sirupsen/logrus v1.9.3
@@ -25,7 +25,7 @@ require (
)
require (
- github.com/andybalholm/brotli v1.0.4 // indirect
+ github.com/andybalholm/brotli v1.0.6 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
@@ -46,20 +46,19 @@ require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
- github.com/klauspost/compress v1.17.0 // indirect
- github.com/klauspost/pgzip v1.2.5 // indirect
+ github.com/klauspost/compress v1.17.2 // indirect
+ github.com/klauspost/pgzip v1.2.6 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mholt/archiver/v4 v4.0.0-alpha.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
- github.com/nwaples/rardecode v1.1.3 // indirect
+ github.com/nwaples/rardecode v1.1.0 // indirect
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
- github.com/pierrec/lz4 v2.6.1+incompatible // indirect
- github.com/pierrec/lz4/v4 v4.1.17 // indirect
+ github.com/pierrec/lz4/v4 v4.1.18 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
@@ -83,7 +82,7 @@ require (
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
- golang.org/x/text v0.13.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/go.sum b/go.sum
index 04dcd21d..d721742e 100644
--- a/go.sum
+++ b/go.sum
@@ -46,8 +46,9 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
-github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
-github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
+github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
+github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
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=
@@ -77,7 +78,9 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
+github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
+github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
@@ -126,6 +129,7 @@ github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+
github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU=
github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
+github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
@@ -183,6 +187,7 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
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/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@@ -198,6 +203,7 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
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.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
+github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
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=
@@ -215,6 +221,7 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
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.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
@@ -222,6 +229,7 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c=
+github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA=
github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -246,18 +254,21 @@ github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaR
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
+github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
-github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
+github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
-github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
+github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
+github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
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=
@@ -274,9 +285,11 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
+github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
-github.com/mholt/archiver v3.1.1+incompatible h1:1dCVxuqs0dJseYEhi5pl7MYPH9zDa1wBi7mF09cbNkU=
-github.com/mholt/archiver v3.1.1+incompatible/go.mod h1:Dh2dOXnSdiLxRiPoVfIr/fI1TwETms9B8CTWfeh7ROU=
+github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
+github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo=
+github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
github.com/mholt/archiver/v4 v4.0.0-alpha.7 h1:xzByj8G8tj0Oq7ZYYU4+ixL/CVb5ruWCm0EZQ1PjOkE=
github.com/mholt/archiver/v4 v4.0.0-alpha.7/go.mod h1:Fs8qUkO74HHaidabihzYephJH8qmGD/nCP6tE5xC9BM=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
@@ -287,8 +300,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/nwaples/rardecode v1.1.3 h1:cWCaZwfM5H7nAD6PyEdcVnczzV8i/JtotnyW/dD9lEc=
-github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
+github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
+github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
github.com/nwaples/rardecode/v2 v2.0.0-beta.2 h1:e3mzJFJs4k83GXBEiTaQ5HgSc/kOK8q0rDaRO0MPaOk=
github.com/nwaples/rardecode/v2 v2.0.0-beta.2/go.mod h1:yntwv/HfMc/Hbvtq9I19D1n58te3h6KsqCf3GxyfBGY=
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
@@ -298,10 +311,9 @@ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYr
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
-github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9FV9ix19jjM=
-github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
-github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc=
-github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
+github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
+github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ=
+github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
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/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -314,6 +326,7 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
+github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sagikazarmark/locafero v0.3.0 h1:zT7VEGWC2DTflmccN/5T1etyKvxSxpHsjb9cJvm4SvQ=
github.com/sagikazarmark/locafero v0.3.0/go.mod h1:w+v7UsPNFwzF1cHuOajOOzoq4U7v/ig1mpRjqV+Bu1U=
@@ -371,6 +384,7 @@ github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhso
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
@@ -400,6 +414,7 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
+go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
@@ -576,8 +591,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+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=
@@ -729,6 +744,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
diff --git a/internal/app/n3dr/artifactsv2/download.go b/internal/app/n3dr/artifactsv2/download.go
index 73c9896e..863262ae 100644
--- a/internal/app/n3dr/artifactsv2/download.go
+++ b/internal/app/n3dr/artifactsv2/download.go
@@ -16,7 +16,7 @@ import (
"github.com/030/n3dr/internal/app/n3dr/s3"
"github.com/030/p2iwd/pkg/p2iwd"
"github.com/hashicorp/go-retryablehttp"
- "github.com/mholt/archiver"
+ "github.com/mholt/archiver/v3"
log "github.com/sirupsen/logrus"
)
diff --git a/internal/app/n3dr/artifactsv2/upload/maven2/snapshot/upload.go b/internal/app/n3dr/artifactsv2/upload/maven2/snapshot/upload.go
index 2c0075be..bf27b580 100644
--- a/internal/app/n3dr/artifactsv2/upload/maven2/snapshot/upload.go
+++ b/internal/app/n3dr/artifactsv2/upload/maven2/snapshot/upload.go
@@ -9,7 +9,6 @@ import (
"path/filepath"
"regexp"
- "github.com/030/n3dr/internal/app/n3dr/artifactsv2/artifacts"
"github.com/hashicorp/go-retryablehttp"
log "github.com/sirupsen/logrus"
)
@@ -22,8 +21,6 @@ type Nexus3 struct {
func (n *Nexus3) statusCode(resp *http.Response) error {
if resp.StatusCode == http.StatusCreated {
log.Trace("file has been uploaded")
- artifacts.PrintType(n.RepoFormat)
- return nil
} else {
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
@@ -65,7 +62,7 @@ func (n *Nexus3) readRetryAndUpload(path string) error {
log.Tracef("uri: '%s'", uri)
u := protocol + "://" + n.FQDN + "/repository/" + n.RepoName + "/" + uri
- log.Tracef("upload url: '%s'", u)
+ log.Tracef("snapshot upload url: '%s'", u)
req, err := http.NewRequest("PUT", u, f)
if err != nil {
return err
diff --git a/internal/app/n3dr/artifactsv2/upload/upload.go b/internal/app/n3dr/artifactsv2/upload/upload.go
index c47766e0..da4d8fff 100644
--- a/internal/app/n3dr/artifactsv2/upload/upload.go
+++ b/internal/app/n3dr/artifactsv2/upload/upload.go
@@ -40,6 +40,10 @@ type Nexus3 struct {
*connection.Nexus3
}
+type repoFormatAndType struct {
+ format, repoType string
+}
+
func uploadStatus(err error) (int, error) {
re := regexp.MustCompile(`status (\d{3})`)
match := re.FindStringSubmatch(err.Error())
@@ -70,10 +74,11 @@ func (n *Nexus3) reposOnDisk() (localDiskRepos []string, err error) {
return nil, err
}
log.Infof("found the following localDiskRepos: '%v'", localDiskRepos)
+
return localDiskRepos, nil
}
-func (n *Nexus3) repoFormatLocalDiskRepo(localDiskRepo string) (string, error) {
+func (n *Nexus3) repoFormatLocalDiskRepo(localDiskRepo string) (repoFormatAndType, error) {
cn := connection.Nexus3{
BasePathPrefix: n.BasePathPrefix,
FQDN: n.FQDN,
@@ -85,19 +90,21 @@ func (n *Nexus3) repoFormatLocalDiskRepo(localDiskRepo string) (string, error) {
a := artifacts.Nexus3{Nexus3: &cn}
repos, err := a.Repos()
if err != nil {
- return "", err
+ return repoFormatAndType{}, err
}
var repoFormat string
+ var repoType string
for _, repo := range repos {
repoName := repo.Name
if repoName == localDiskRepo {
repoFormat = repo.Format
+ repoType = repo.Type
}
}
- log.Infof("format of repo: '%s' is: '%s'", localDiskRepo, repoFormat)
+ log.Infof("format of repo: '%s' is: '%s' and repoType: '%s'", localDiskRepo, repoFormat, repoType)
- return repoFormat, nil
+ return repoFormatAndType{repoFormat, repoType}, nil
}
func maven(path string, skipErrors bool) (mp mavenParts, err error) {
@@ -298,7 +305,7 @@ func (n *Nexus3) checkLocalChecksumAndCompareWithOneInRemote(f, localDiskRepo, d
if err != nil {
return false, err
}
- log.Info(f, downloadedFileChecksum)
+ log.Debugf("checksum of file: '%s' is '%s'", f, downloadedFileChecksum)
retryClient := retryablehttp.NewClient()
retryClient.Logger = nil
@@ -311,7 +318,7 @@ func (n *Nexus3) checkLocalChecksumAndCompareWithOneInRemote(f, localDiskRepo, d
}
u := scheme + "://" + n.FQDN + "/repository/" + localDiskRepo + "/" + dir + "/" + filename + ".sha512"
- log.Info("URL: ", u)
+ log.Debugf("upload URL: '%s'", u)
req, err := http.NewRequest("GET", u, nil)
if err != nil {
@@ -335,10 +342,10 @@ func (n *Nexus3) checkLocalChecksumAndCompareWithOneInRemote(f, localDiskRepo, d
}()
bodyBytes, err := io.ReadAll(resp.Body)
if err != nil {
- return identical, err
+ return false, err
}
bodyString := string(bodyBytes)
- log.Info(bodyString)
+ log.Debugf("checksum of artifact in nexus3: '%s'", bodyString)
if bodyString == downloadedFileChecksum {
identical = true
@@ -347,7 +354,7 @@ func (n *Nexus3) checkLocalChecksumAndCompareWithOneInRemote(f, localDiskRepo, d
return identical, nil
}
-func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo, localDiskRepoHome, repoFormat string, skipErrors bool) error {
+func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo, localDiskRepoHome, repoFormat string, skipErrors bool) (bool, error) {
dir := strings.Replace(filepath.Dir(path), localDiskRepoHome+"/", "", -1)
filename := filepath.Base(path)
@@ -355,8 +362,8 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
af := artifactFiles{}
if identical, _ := n.checkLocalChecksumAndCompareWithOneInRemote(filepath.Clean(path), localDiskRepo, dir, filename); identical {
- log.Info("Already uploaded")
- return nil
+ log.Debugf("artifact: '%s' has already been uploaded", filename)
+ return true, nil
}
c := components.UploadComponentParams{}
@@ -365,7 +372,7 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
c.Repository = localDiskRepo
f, err := os.Open(filepath.Clean(path))
if err != nil {
- return err
+ return false, err
}
c.AptAsset = f
case "maven2":
@@ -375,7 +382,7 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
filePathPom := fileNameWithoutExtIncludingDir + ".pom"
if slices.Contains(checkedMavenFolders, dirPath) {
- return nil
+ return false, nil
}
if _, err := os.Stat(filePathPom); err == nil {
@@ -384,13 +391,13 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
c.Repository = localDiskRepo
if err := af.mavenJarAndOtherExtensions(&c, fileNameWithoutExtIncludingDir, skipErrors); err != nil {
- return err
+ return false, err
}
var err error
f, err = os.Open(filepath.Clean(filePathPom))
if err != nil {
- return err
+ return false, err
}
c.Maven2Asset1 = f
ext1 := "pom"
@@ -441,13 +448,13 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
c.Repository = localDiskRepo
if err := af.mavenJarAndOtherExtensions(&c, fileNameWithoutExtIncludingDir, skipErrors); err != nil {
- return err
+ return false, err
}
//
mp, err := maven(path, skipErrors)
if err != nil {
- return err
+ return false, err
}
c.Maven2ArtifactID = &mp.artifact
c.Maven2Version = &mp.version
@@ -463,7 +470,7 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
groupID = match[1]
groupID = strings.ReplaceAll(groupID, `/`, `.`)
} else {
- return fmt.Errorf("groupID should not be empty, path: '%s' and regex: '%s'", path, regex)
+ return false, fmt.Errorf("groupID should not be empty, path: '%s' and regex: '%s'", path, regex)
}
c.Maven2GroupID = &groupID
generatePOM := true
@@ -516,21 +523,21 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
c.Repository = localDiskRepo
f, err := os.Open(filepath.Clean(path))
if err != nil {
- return err
+ return false, err
}
c.NpmAsset = f
case "nuget":
c.Repository = localDiskRepo
f, err := os.Open(filepath.Clean(path))
if err != nil {
- return err
+ return false, err
}
c.NugetAsset = f
case "raw":
c.Repository = localDiskRepo
f, err := os.Open(filepath.Clean(path))
if err != nil {
- return err
+ return false, err
}
c.RawAsset1 = f
c.RawDirectory = &dir
@@ -541,7 +548,7 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
c.Repository = localDiskRepo
f, err := os.Open(filepath.Clean(path))
if err != nil {
- return err
+ return false, err
}
c.RubygemsAsset = f
}
@@ -549,20 +556,20 @@ func (n *Nexus3) UploadSingleArtifact(client *client.Nexus3, path, localDiskRepo
c.Repository = localDiskRepo
f, err := os.Open(filepath.Clean(path))
if err != nil {
- return err
+ return false, err
}
c.YumAsset = f
c.YumAssetFilename = &filename
default:
- return nil
+ return false, nil
}
files := []*os.File{f, af.f2, af.f3, af.f4, af.f5, af.f6, af.f2, af.f7}
if err := upload(c, client, path, files); err != nil {
- return err
+ return false, err
}
- return nil
+ return false, nil
}
func upload(c components.UploadComponentParams, client *client.Nexus3, path string, files []*os.File) error {
@@ -595,6 +602,35 @@ func upload(c components.UploadComponentParams, client *client.Nexus3, path stri
return nil
}
+func (n *Nexus3) uploadAndPrintRepoFormat(c *client.Nexus3, path, localDiskRepo, localDiskRepoHome, repoFormat string, skipErrors bool) error {
+ identical, err := n.UploadSingleArtifact(c, path, localDiskRepo, localDiskRepoHome, repoFormat, skipErrors)
+ if err != nil {
+ uploaded, errRegex := regexp.MatchString("status 400", err.Error())
+ if errRegex != nil {
+ return err
+ }
+ if uploaded {
+ log.Debugf("artifact: '%s' has already been uploaded", path)
+ return nil
+ }
+
+ errString := fmt.Errorf("could not upload artifact: '%s', err: '%w'", path, err)
+ if n.SkipErrors {
+ log.Error(errString)
+ } else {
+ return errString
+ }
+ } else {
+ artifacts.PrintType(repoFormat)
+ }
+ if identical {
+ log.Debugf("checksum file: '%s' locally is identical compared to one in nexus", path)
+ return nil
+ }
+
+ return nil
+}
+
func (n *Nexus3) ReadLocalDirAndUploadArtifacts(localDiskRepoHome, localDiskRepo, repoFormat string) error {
var wg sync.WaitGroup
@@ -617,24 +653,8 @@ func (n *Nexus3) ReadLocalDirAndUploadArtifacts(localDiskRepoHome, localDiskRepo
go func(path, localDiskRepo, localDiskRepoHome, repoFormat string, skipErrors bool) {
defer wg.Done()
- if err := n.UploadSingleArtifact(c, path, localDiskRepo, localDiskRepoHome, repoFormat, skipErrors); err != nil {
- uploaded, errRegex := regexp.MatchString("status 400", err.Error())
- if errRegex != nil {
- panic(err)
- }
- if uploaded {
- log.Debugf("artifact: '%s' has already been uploaded", path)
- return
- }
-
- errString := fmt.Errorf("could not upload artifact: '%s', err: '%w'", path, err)
- if n.SkipErrors {
- log.Error(errString)
- } else {
- panic(errString)
- }
- } else {
- artifacts.PrintType(repoFormat)
+ if err := n.uploadAndPrintRepoFormat(c, path, localDiskRepo, localDiskRepoHome, repoFormat, skipErrors); err != nil {
+ panic(err)
}
}(path, localDiskRepo, localDiskRepoHome, repoFormat, n.SkipErrors)
}
@@ -676,8 +696,17 @@ func (n *Nexus3) maven2SnapshotsUpload(localDiskRepo string) {
log.Tracef("VersionPolicy: '%s'", vp)
if strings.EqualFold(vp, "snapshot") {
- s := snapshot.Nexus3{DownloadDirName: n.DownloadDirName, FQDN: n.FQDN, Pass: n.Pass, RepoFormat: "maven2", RepoName: localDiskRepo, SkipErrors: n.SkipErrors, User: n.User}
+ s := snapshot.Nexus3{DownloadDirName: n.DownloadDirName, FQDN: n.FQDN, HTTPS: *n.HTTPS, Pass: n.Pass, RepoFormat: "maven2", RepoName: localDiskRepo, SkipErrors: n.SkipErrors, User: n.User}
+
if err := s.Upload(); err != nil {
+ uploaded, errRegex := regexp.MatchString("bad status: 400 Repository does not allow updating assets", err.Error())
+ if errRegex != nil {
+ panic(err)
+ }
+ if uploaded {
+ log.Debugf("artifact from localDiskRepo: '%s' has been uploaded already", localDiskRepo)
+ return
+ }
if !n.SkipErrors {
panic(err)
}
@@ -698,22 +727,26 @@ func (n *Nexus3) uploadArtifactsSingleDir(localDiskRepo string) {
return
}
- repoFormat, err := n.repoFormatLocalDiskRepo(localDiskRepo)
+ repoFormatAndType, err := n.repoFormatLocalDiskRepo(localDiskRepo)
if err != nil {
panic(err)
}
- if repoFormat == "" {
+ if repoFormatAndType.format == "" {
log.Errorf("repoFormat not detected. Verify whether repo: '%s' resides in Nexus", localDiskRepo)
return
}
- if repoFormat == "maven2" {
- n.maven2SnapshotsUpload(localDiskRepo)
- }
+ log.Warnf("only uploads to 'hosted' repositories are supported. Current: '%v'", repoFormatAndType)
+ if repoFormatAndType.repoType == "hosted" {
+ if repoFormatAndType.format == "maven2" {
+ log.Info("upload to snapshot repo")
+ n.maven2SnapshotsUpload(localDiskRepo)
+ }
- localDiskRepoHome := filepath.Join(n.DownloadDirName, localDiskRepo)
- if err := n.ReadLocalDirAndUploadArtifacts(localDiskRepoHome, localDiskRepo, repoFormat); err != nil {
- panic(err)
+ localDiskRepoHome := filepath.Join(n.DownloadDirName, localDiskRepo)
+ if err := n.ReadLocalDirAndUploadArtifacts(localDiskRepoHome, localDiskRepo, repoFormatAndType.format); err != nil {
+ panic(err)
+ }
}
}
diff --git a/internal/app/n3dr/config/repository/repository.go b/internal/app/n3dr/config/repository/repository.go
index f2867971..23cdd58b 100644
--- a/internal/app/n3dr/config/repository/repository.go
+++ b/internal/app/n3dr/config/repository/repository.go
@@ -31,6 +31,42 @@ func created(name string, err error) error {
return fmt.Errorf("could not create repository: '%v', err: '%w'", name, err)
}
+func (r *Repository) CreateMavenGroup(memberNames []string, name string) error {
+ log.Infof("creating maven group: '%s'...", name)
+ client, err := r.Nexus3.Client()
+ if err != nil {
+ return err
+ }
+ if name == "" {
+ return fmt.Errorf("repo name should not be empty")
+ }
+ if len(memberNames) == 0 {
+ return fmt.Errorf("memberNames should not be empty")
+ }
+
+ online := true
+ mhsa := models.StorageAttributes{BlobStoreName: "default", StrictContentTypeValidation: &r.StrictContentTypeValidation}
+ group := models.GroupAttributes{MemberNames: memberNames}
+ body := models.MavenGroupRepositoryAPIRequest{
+ Group: &group,
+ Name: &name,
+ Online: &online,
+ Storage: &mhsa,
+ }
+ createMavenGroup := repository_management.CreateRepositoryParams{Body: &body}
+ createMavenGroup.WithTimeout(time.Second * 30)
+ if createRepositoryCreated, err := client.RepositoryManagement.CreateRepository(&createMavenGroup); err != nil {
+ log.Debugf("createRepositoryCreated: '%v'", createRepositoryCreated)
+ log.Tracef("createRepositoryCreatedError '%v'", err)
+ if err := created(name, err); err != nil {
+ return err
+ }
+ }
+ log.Infof("created the following maven group: '%v'", name)
+
+ return nil
+}
+
func (r *Repository) CreateAptProxied(name string) error {
log.Infof("Creating proxied apt repository: '%s'...", name)
client, err := r.Nexus3.Client()
@@ -68,6 +104,42 @@ func (r *Repository) CreateAptProxied(name string) error {
return nil
}
+func (r *Repository) CreateNpmProxied(name string) error {
+ log.Infof("Creating npm proxy: '%s'...", name)
+ client, err := r.Nexus3.Client()
+ if err != nil {
+ return err
+ }
+ if name == "" {
+ return fmt.Errorf("repo name should not be empty")
+ }
+
+ httpClientBlocked := false
+ httpClientAutoBlocked := true
+ httpClient := models.HTTPClientAttributes{AutoBlock: &httpClientAutoBlocked, Blocked: &httpClientBlocked}
+ negativeCacheEnabled := true
+ var negativeCacheTimeToLive int32 = 1440
+ negativeCache := models.NegativeCacheAttributes{Enabled: &negativeCacheEnabled, TimeToLive: &negativeCacheTimeToLive}
+ var contentMaxAge int32 = 1440
+ var metadataMaxAge int32 = 1440
+ remoteURL := r.ProxyRemoteURL
+ proxy := models.ProxyAttributes{ContentMaxAge: &contentMaxAge, MetadataMaxAge: &metadataMaxAge, RemoteURL: remoteURL}
+ online := true
+ npm := models.NpmAttributes{}
+ mhsa := models.StorageAttributes{BlobStoreName: "default", StrictContentTypeValidation: &r.StrictContentTypeValidation}
+ ma := models.NpmProxyRepositoryAPIRequest{Npm: &npm, Name: &name, Online: &online, Storage: &mhsa, Proxy: &proxy, NegativeCache: &negativeCache, HTTPClient: &httpClient}
+ createNpmProxy := repository_management.CreateRepository10Params{Body: &ma}
+ createNpmProxy.WithTimeout(time.Second * 30)
+ if _, err := client.RepositoryManagement.CreateRepository10(&createNpmProxy); err != nil {
+ if err := created(name, err); err != nil {
+ return err
+ }
+ }
+ log.Infof("created the following repository: '%v'", name)
+
+ return nil
+}
+
func (r *Repository) CreateYumProxied(name string) error {
log.Infof("Creating proxied yum repository: '%s'...", name)
client, err := r.Nexus3.Client()
@@ -103,6 +175,43 @@ func (r *Repository) CreateYumProxied(name string) error {
return nil
}
+func (r *Repository) CreateMavenProxied(name string) error {
+ log.Infof("creating the following maven proxy: '%s'...", name)
+ client, err := r.Nexus3.Client()
+ if err != nil {
+ return err
+ }
+ remoteURL := r.ProxyRemoteURL
+ log.Infof("remoteURL: '%s'", remoteURL)
+ if name == "" || remoteURL == "" {
+ return fmt.Errorf("repo name of proxy url should not be empty")
+ }
+
+ httpClientBlocked := false
+ httpClientAutoBlocked := true
+ httpClient := models.HTTPClientAttributesWithPreemptiveAuth{AutoBlock: &httpClientAutoBlocked, Blocked: &httpClientBlocked}
+ negativeCacheEnabled := true
+ var negativeCacheTimeToLive int32 = 1440
+ negativeCache := models.NegativeCacheAttributes{Enabled: &negativeCacheEnabled, TimeToLive: &negativeCacheTimeToLive}
+ var contentMaxAge int32 = 1440
+ var metadataMaxAge int32 = 1440
+ proxy := models.ProxyAttributes{ContentMaxAge: &contentMaxAge, MetadataMaxAge: &metadataMaxAge, RemoteURL: remoteURL}
+ online := true
+ maven := models.MavenAttributes{LayoutPolicy: "STRICT", VersionPolicy: "MIXED"}
+ mhsa := models.StorageAttributes{BlobStoreName: "default", StrictContentTypeValidation: &r.StrictContentTypeValidation}
+ ma := models.MavenProxyRepositoryAPIRequest{Maven: &maven, Name: &name, Online: &online, Storage: &mhsa, Proxy: &proxy, NegativeCache: &negativeCache, HTTPClient: &httpClient}
+ createMavenProxy := repository_management.CreateRepository2Params{Body: &ma}
+ createMavenProxy.WithTimeout(time.Second * 30)
+ if _, err := client.RepositoryManagement.CreateRepository2(&createMavenProxy); err != nil {
+ if err := created(name, err); err != nil {
+ return err
+ }
+ }
+ log.Infof("created the following maven proxy: '%v'", name)
+
+ return nil
+}
+
func (r *Repository) CreateDockerHosted(secure bool, port int32, name string) error {
log.Infof("Creating docker hosted repository: '%s'...", name)
client, err := r.Nexus3.Client()
diff --git a/test/integration-tests.sh b/test/integration-tests.sh
index 16535d9a..534d82b6 100755
--- a/test/integration-tests.sh
+++ b/test/integration-tests.sh
@@ -409,7 +409,7 @@ repositories() {
--dockerHost ${DOCKER_URL}
count_downloads 354 ${testZipSizeDir}
- test_zip 1399 ${testZipSizeDir}
+ test_zip "1403[0-9]\{2\}" ${testZipSizeDir}
cleanup_downloads
}