From d37fdc59385ccc69b91296a24f57c9e95f1a0e87 Mon Sep 17 00:00:00 2001
From: Ben van B <030@users.noreply.github.com>
Date: Sun, 4 Feb 2024 09:14:55 +0100
Subject: [PATCH] feat: [#440] Create user and assign roles. (#447)
---
.github/dependabot.yml | 6 +-
.github/workflows/dip.yml | 3 +-
.github/workflows/go.yml | 3 +-
.github/workflows/integration.yml | 6 +-
.github/workflows/release.yml | 3 +-
.gitignore | 4 +-
.golangci.yml | 4 +
Taskfile.yml | 50 +++
build/package/snap/snapcraft.yaml | 2 +-
cmd/n3dr/configRole.go | 85 +++++
cmd/n3dr/configUser.go | 34 +-
docs/CHANGELOG.md | 46 ++-
docs/instructions/task.md | 6 +
docs/quickstarts/snippets/n3dr/DOWNLOAD.md | 6 +-
go.mod | 25 +-
go.sum | 82 ++++
.../n3dr/artifactsv2/count/artifacts_test.go | 2 +
.../n3dr/artifactsv2/upload/upload_test.go | 2 +
.../n3dr/config/repository/repository_test.go | 2 +
.../n3dr/config/security/anonymous_test.go | 2 +
internal/app/n3dr/config/user/user.go | 128 +++++--
internal/app/n3dr/config/user/user_test.go | 352 ++++++++++++++++++
internal/app/n3dr/connection/connection.go | 2 +-
23 files changed, 801 insertions(+), 54 deletions(-)
create mode 100644 Taskfile.yml
create mode 100644 cmd/n3dr/configRole.go
create mode 100644 docs/instructions/task.md
create mode 100644 internal/app/n3dr/config/user/user_test.go
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 75bc82fd..5d1d7103 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -4,12 +4,12 @@ updates:
- package-ecosystem: 'docker'
directory: '/'
schedule:
- interval: 'weekly'
+ interval: 'daily'
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
- interval: 'weekly'
+ interval: 'daily'
- package-ecosystem: 'gomod'
directory: '/'
schedule:
- interval: 'weekly'
+ interval: 'daily'
diff --git a/.github/workflows/dip.yml b/.github/workflows/dip.yml
index 2dced91a..5603e31e 100644
--- a/.github/workflows/dip.yml
+++ b/.github/workflows/dip.yml
@@ -23,7 +23,8 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5.0.0
with:
- go-version: 1.19.0
+ go-version-file: 'go.mod'
+ cache: false
- name: Check Golang
run: |
./dip image --name=golang --regex=^1\.[0-9]+\.[0-9]+-alpine3\.[0-9]+$ --updateDockerfile
diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml
index bac0b0b3..70459ff6 100644
--- a/.github/workflows/go.yml
+++ b/.github/workflows/go.yml
@@ -21,7 +21,8 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5.0.0
with:
- go-version: 1.19.0
+ go-version-file: 'go.mod'
+ cache: false
- name: Unit tests
run: |
go test -short -cover -v -coverprofile=coverage.txt \
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index cf1d80f0..71303ba2 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -9,10 +9,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4.1.1
- - name: Set up Go
- uses: actions/setup-go@v5.0.0
+ - uses: actions/setup-go@v5.0.0
with:
- go-version: 1.19.0
+ go-version-file: 'go.mod'
+ cache: false
- name: Install bats
run: |
set -x
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 7eee6d9b..ec9ec49b 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -21,7 +21,8 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v5.0.0
with:
- go-version: 1.19.0
+ go-version-file: 'go.mod'
+ cache: false
- name: Set N3DR deliverable environment variable
run: echo "n3dr-deliverable=n3dr-${{ matrix.os }}" >> $GITHUB_ENV
if: |
diff --git a/.gitignore b/.gitignore
index cccfe766..70cbc0f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,4 +10,6 @@ dip
test/gpg/my_rsa_key
test/rproxy-nginx-nexus3.conf.tmp
-.vagrant
\ No newline at end of file
+.vagrant
+
+coverage*
diff --git a/.golangci.yml b/.golangci.yml
index 43f8cd12..edff67d2 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -17,6 +17,10 @@ issues:
- gochecknoinits
path: cmd/n3dr/configUser.go
text: "don't use `init` function"
+ - linters:
+ - gochecknoinits
+ path: cmd/n3dr/configRole.go
+ text: "don't use `init` function"
- linters:
- gochecknoinits
path: cmd/n3dr/count.go
diff --git a/Taskfile.yml b/Taskfile.yml
new file mode 100644
index 00000000..9e117a3c
--- /dev/null
+++ b/Taskfile.yml
@@ -0,0 +1,50 @@
+---
+version: '3'
+
+env:
+ GIT_CHGLOG_URL: https://github.com/git-chglog/git-chglog/releases/download
+ GIT_CHGLOG_VERSION: v0.15.1/git-chglog_0.15.1_linux_amd64.tar.gz
+ CHANGELOG_NEXT_TAG: 7.4.0
+
+tasks:
+ changelog:
+ cmds:
+ - |
+ git fetch -p -P
+ curl \
+ -L ${GIT_CHGLOG_URL}/${GIT_CHGLOG_VERSION} \
+ -o /tmp/git-chglog.tar.gz
+ tar -xvf /tmp/git-chglog.tar.gz -C /tmp
+ chmod +x /tmp/git-chglog
+ /tmp/git-chglog \
+ -o docs/CHANGELOG.md \
+ --config configs/chglog/config.yml \
+ --next-tag ${CHANGELOG_NEXT_TAG}
+ sed -i "s|\/\([0-9]\+\.\)\{2\}[0-9]\+|/${CHANGELOG_NEXT_TAG}|g" \
+ ./docs/quickstarts/snippets/n3dr/DOWNLOAD.md
+ sed -i "s|version:.*|version: ${CHANGELOG_NEXT_TAG}|" \
+ ./build/package/snap/snapcraft.yaml
+ integration-tests:
+ cmds:
+ - |
+ go test \
+ -coverprofile=coverage.cov \
+ --tags=integration \
+ -v \
+ -count=1 \
+ --cover \
+ -race \
+ -p=4 \
+ ./...
+ go tool cover -func=coverage.cov > coverage-functions.out
+ go tool cover -html=coverage.cov -o coverage.html
+ open ./coverage.html
+ lint:
+ cmds:
+ - |
+ go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.2
+ ~/go/bin/golangci-lint --version
+ ~/go/bin/golangci-lint run \
+ -v \
+ --timeout 2m30s \
+ --config .golangci.yml
diff --git a/build/package/snap/snapcraft.yaml b/build/package/snap/snapcraft.yaml
index fdcec6e9..79790c06 100644
--- a/build/package/snap/snapcraft.yaml
+++ b/build/package/snap/snapcraft.yaml
@@ -1,7 +1,7 @@
---
name: n3dr
base: core20
-version: 7.3.3
+version: 7.4.0
summary: Nexus3 Disaster Recovery
description: |
Download all artifacts at once or migrate automatically from Nexus to Nexus.
diff --git a/cmd/n3dr/configRole.go b/cmd/n3dr/configRole.go
new file mode 100644
index 00000000..a4155019
--- /dev/null
+++ b/cmd/n3dr/configRole.go
@@ -0,0 +1,85 @@
+package main
+
+import (
+ "github.com/030/n3dr/internal/app/n3dr/config/user"
+ "github.com/030/n3dr/internal/app/n3dr/connection"
+ "github.com/030/n3dr/internal/app/n3dr/goswagger/models"
+ log "github.com/sirupsen/logrus"
+ "github.com/spf13/cobra"
+)
+
+var downloadRole, uploadRole bool
+
+// configUserCmd represents the configUser command.
+var configRoleCmd = &cobra.Command{
+ Use: "configRole",
+ Short: "Configure roles.",
+ Long: `Create roles.
+
+Examples:
+ # Create a download role:
+ n3dr configRole --downloadRole
+
+ # Create an upload role:
+ n3dr configRole --uploadRole --https=false --n3drPass X --n3drUser admin --n3drURL localhost:9999
+`,
+ Run: func(cmd *cobra.Command, args []string) {
+ if !downloadRole && !uploadRole {
+ log.Fatal("either the downloadRole or uploadRole is required")
+ }
+
+ acu := models.APICreateUser{
+ EmailAddress: email,
+ FirstName: firstName,
+ LastName: lastName,
+ Password: pass,
+ UserID: id,
+ }
+ n := connection.Nexus3{
+ FQDN: n3drURL,
+ HTTPS: &https,
+ Pass: n3drPass,
+ User: n3drUser,
+ }
+ u := user.User{APICreateUser: acu, Nexus3: n}
+
+ if downloadRole {
+ u.Roles = []string{"nx-download"}
+ rr := models.RoleXORequest{
+ ID: "nx-download",
+ Name: "nx-download",
+ Privileges: []string{
+ "nx-repository-view-*-*-browse",
+ "nx-repository-view-*-*-read",
+ },
+ }
+ r := user.Role{RoleXORequest: rr, Nexus3: n}
+ if err := r.CreateRole(); err != nil {
+ log.Fatal(err)
+ }
+ }
+
+ if uploadRole {
+ u.Roles = []string{"nx-upload"}
+ rr := models.RoleXORequest{
+ ID: "nx-upload",
+ Name: "nx-upload",
+ Privileges: []string{
+ "nx-repository-view-*-*-add",
+ "nx-repository-view-*-*-edit",
+ },
+ }
+ r := user.Role{RoleXORequest: rr, Nexus3: n}
+ if err := r.CreateRole(); err != nil {
+ log.Fatal(err)
+ }
+ }
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(configRoleCmd)
+
+ configRoleCmd.Flags().BoolVar(&downloadRole, "downloadRole", false, "Whether a download role should be created")
+ configRoleCmd.Flags().BoolVar(&uploadRole, "uploadRole", false, "Whether an upload role should be created")
+}
diff --git a/cmd/n3dr/configUser.go b/cmd/n3dr/configUser.go
index 76b0b42f..f15459a5 100644
--- a/cmd/n3dr/configUser.go
+++ b/cmd/n3dr/configUser.go
@@ -9,8 +9,9 @@ import (
)
var (
- admin, changePass, downloadUser, uploadUser bool
- email, firstName, id, lastName, pass string
+ admin, changePass, custom, downloadUser, uploadUser bool
+ email, firstName, id, lastName, pass string
+ roles []string
)
// configUserCmd represents the configUser command.
@@ -20,12 +21,24 @@ var configUserCmd = &cobra.Command{
Long: `Create users or change their passwords.
Examples:
+ # Create an admin user:
+ n3dr configUser --pass some-pass --email build@example.org --firstName build --id build --lastName build --admin
+
+ # Create a download user:
+ n3dr configUser --pass some-pass --email build@example.org --firstName build --id build --lastName build --downloadUser
+
+ # Create an upload user:
+ n3dr configUser --pass some-pass --email build@example.org --firstName build --id build --lastName build --uploadUser
+
+ # Create a custom user and assign certain roles:
+ n3dr configUser --pass some-pass --email build@example.org --firstName build --id build --lastName build --roles nx-download,nx-upload --custom
+
# Change the admin password:
n3dr configUser --changePass --https=false --n3drUser admin --n3drURL nexus3:8081 --n3drPass initial-pass --pass some-pass --email admin@example.org --firstName admin --id admin --lastName admin
`,
Run: func(cmd *cobra.Command, args []string) {
- if !admin && !downloadUser && !uploadUser && !changePass {
- log.Fatal("either the admin, changePass, downloadUser or uploadUser is required")
+ if !admin && !custom && !downloadUser && !uploadUser && !changePass {
+ log.Fatal("either the admin, custom, changePass, create, downloadUser or uploadUser is required")
}
acu := models.APICreateUser{
@@ -33,6 +46,7 @@ Examples:
FirstName: firstName,
LastName: lastName,
Password: pass,
+ Roles: roles,
UserID: id,
}
n := connection.Nexus3{
@@ -50,6 +64,15 @@ Examples:
}
}
+ if custom {
+ u.Roles = roles
+ log.Info("roles:", u)
+
+ if err := u.Create(); err != nil {
+ log.Fatal(err)
+ }
+ }
+
if downloadUser {
u.Roles = []string{"nx-download"}
rr := models.RoleXORequest{
@@ -125,7 +148,10 @@ func init() {
}
configUserCmd.Flags().BoolVar(&admin, "admin", false, "Whether a user should be admin")
+ configUserCmd.Flags().BoolVar(&custom, "custom", false, "Create a user and assign certain roles")
configUserCmd.Flags().BoolVar(&downloadUser, "downloadUser", false, "Whether a user should be able to download")
configUserCmd.Flags().BoolVar(&uploadUser, "uploadUser", false, "Whether a user should be able to upload")
configUserCmd.Flags().BoolVar(&changePass, "changePass", false, "Whether a pass should be changed")
+
+ configUserCmd.Flags().StringSliceVar(&roles, "roles", nil, "Which roles have to be assigned to the custom user")
}
diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 6db2a651..657fb184 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -2,10 +2,51 @@
## [Unreleased]
+
+## [7.4.0] - 2024-02-03
+### Build
+- [[#423](https://github.com/030/n3dr/issues/423)] Add golang action. ([#424](https://github.com/030/n3dr/issues/424))
+- Replace separate hadolint, dockle and trivy by one workflow. ([#417](https://github.com/030/n3dr/issues/417))
+- **deps:** bump github.com/spf13/viper from 1.17.0 to 1.18.2 ([#426](https://github.com/030/n3dr/issues/426))
+- **deps:** bump github.com/go-openapi/swag from 0.22.4 to 0.22.9 ([#454](https://github.com/030/n3dr/issues/454))
+- **deps:** bump github.com/aws/aws-sdk-go from 1.48.16 to 1.50.5 ([#453](https://github.com/030/n3dr/issues/453))
+- **deps:** bump golang.org/x/crypto from 0.14.0 to 0.17.0 ([#416](https://github.com/030/n3dr/issues/416))
+- **deps:** bump alpine from 3.19.0 to 3.19.1 ([#455](https://github.com/030/n3dr/issues/455))
+- **deps:** bump schubergphilis/mcvs-golang-action from 0.2.2 to 0.2.3 ([#457](https://github.com/030/n3dr/issues/457))
+- **deps:** bump EndBug/add-and-commit from 9.1.3 to 9.1.4 ([#458](https://github.com/030/n3dr/issues/458))
+- **deps:** bump schubergphilis/mcvs-golang-action from 0.1.1 to 0.2.2 ([#448](https://github.com/030/n3dr/issues/448))
+- **deps:** bump schubergphilis/mcvs-docker-action from 0.2.1 to 0.3.2 ([#449](https://github.com/030/n3dr/issues/449))
+- **deps:** bump github.com/go-playground/validator/v10 ([#444](https://github.com/030/n3dr/issues/444))
+- **deps:** bump golang from 1.21.5-alpine3.18 to 1.21.6-alpine3.18 ([#445](https://github.com/030/n3dr/issues/445))
+- **deps:** bump alpine from 3.18.5 to 3.19.0 ([#413](https://github.com/030/n3dr/issues/413))
+- **deps:** bump github.com/go-openapi/strfmt from 0.21.7 to 0.22.0 ([#434](https://github.com/030/n3dr/issues/434))
+- **deps:** bump schubergphilis/mcvs-docker-action from 0.2.0 to 0.2.1 ([#427](https://github.com/030/n3dr/issues/427))
+- **deps:** bump codecov/codecov-action from 3.1.4 to 4.0.1 ([#463](https://github.com/030/n3dr/issues/463))
+- **deps:** bump github.com/go-openapi/runtime from 0.26.0 to 0.27.1 ([#452](https://github.com/030/n3dr/issues/452))
+- **deps:** bump github.com/samber/lo from 1.38.1 to 1.39.0 ([#389](https://github.com/030/n3dr/issues/389))
+- **deps:** bump github.com/hashicorp/go-retryablehttp ([#392](https://github.com/030/n3dr/issues/392))
+- **deps:** bump github.com/spf13/cobra from 1.7.0 to 1.8.0 ([#393](https://github.com/030/n3dr/issues/393))
+- **deps:** bump github.com/aws/aws-sdk-go from 1.45.25 to 1.48.16 ([#406](https://github.com/030/n3dr/issues/406))
+- **deps:** bump golang from 1.21.0-alpine3.18 to 1.21.5-alpine3.18 ([#405](https://github.com/030/n3dr/issues/405))
+- **deps:** bump github.com/go-openapi/validate from 0.22.1 to 0.22.3 ([#388](https://github.com/030/n3dr/issues/388))
+- **deps:** bump alpine from 3.18.4 to 3.18.5 ([#387](https://github.com/030/n3dr/issues/387))
+
+### Feat
+- [[#440](https://github.com/030/n3dr/issues/440)] Create user and assign roles.
+
+### Fix
+- [[#428](https://github.com/030/n3dr/issues/428)] Resolve race condition. ([#435](https://github.com/030/n3dr/issues/435))
+- [[#430](https://github.com/030/n3dr/issues/430)] Use semantic version. ([#432](https://github.com/030/n3dr/issues/432))
+- [[#430](https://github.com/030/n3dr/issues/430)] Do not run Sonar if dependabot branch. ([#431](https://github.com/030/n3dr/issues/431))
+- [[#428](https://github.com/030/n3dr/issues/428)] Resolve data race condition in upload. ([#429](https://github.com/030/n3dr/issues/429))
+- Ensure that integration tests are skipped on dep updates. ([#420](https://github.com/030/n3dr/issues/420))
+
+
## [7.3.3] - 2023-12-09
### Build
-- **deps:** [[#399](https://github.com/030/n3dr/issues/399)] Use semantic versioning for plugins in github actions.
+- **deps:** [[#399](https://github.com/030/n3dr/issues/399)] V is omitted in upload-release-action. ([#404](https://github.com/030/n3dr/issues/404))
+- **deps:** [[#399](https://github.com/030/n3dr/issues/399)] Use semantic versioning for plugins in github actions. ([#403](https://github.com/030/n3dr/issues/403))
- **deps:** bump actions/checkout from 3 to 4 ([#394](https://github.com/030/n3dr/issues/394))
### Fix
@@ -413,7 +454,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.3...HEAD
+[Unreleased]: https://github.com/030/n3dr/compare/7.4.0...HEAD
+[7.4.0]: https://github.com/030/n3dr/compare/7.3.3...7.4.0
[7.3.3]: https://github.com/030/n3dr/compare/7.3.2...7.3.3
[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
diff --git a/docs/instructions/task.md b/docs/instructions/task.md
new file mode 100644
index 00000000..2ee0bb4e
--- /dev/null
+++ b/docs/instructions/task.md
@@ -0,0 +1,6 @@
+# task
+
+```bash
+go install github.com/go-task/task/v3/cmd/task@v3.33.1
+~/go/bin/task integration-tests
+```
diff --git a/docs/quickstarts/snippets/n3dr/DOWNLOAD.md b/docs/quickstarts/snippets/n3dr/DOWNLOAD.md
index 867d1b66..3d69548b 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.3):
+Download the [latest N3DR binary](https://github.com/030/n3dr/releases/tag/7.4.0):
```bash
cd /tmp && \
-curl -L https://github.com/030/n3dr/releases/download/7.3.3/n3dr-ubuntu-latest \
+curl -L https://github.com/030/n3dr/releases/download/7.4.0/n3dr-ubuntu-latest \
-o n3dr-ubuntu-latest && \
-curl -L https://github.com/030/n3dr/releases/download/7.3.3/\
+curl -L https://github.com/030/n3dr/releases/download/7.4.0/\
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 b87b218e..e5e0475d 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/030/n3dr
-go 1.21
+go 1.21.5
require (
github.com/030/logging v0.1.2
@@ -16,6 +16,7 @@ require (
github.com/hashicorp/go-retryablehttp v0.7.5
github.com/mholt/archiver/v3 v3.5.1
github.com/mitchellh/go-homedir v1.1.0
+ github.com/ory/dockertest/v3 v3.10.0
github.com/samber/lo v1.39.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.0
@@ -25,9 +26,18 @@ require (
)
require (
+ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
+ github.com/Microsoft/go-winio v0.6.0 // indirect
+ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/andybalholm/brotli v1.0.6 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
+ github.com/cenkalti/backoff/v4 v4.1.3 // indirect
+ github.com/containerd/continuity v0.3.0 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
+ github.com/docker/cli v20.10.24+incompatible // indirect
+ github.com/docker/docker v20.10.24+incompatible // indirect
+ github.com/docker/go-connections v0.4.0 // indirect
+ github.com/docker/go-units v0.5.0 // indirect
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
@@ -40,10 +50,13 @@ require (
github.com/go-openapi/spec v0.20.12 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
+ github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
+ github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.5.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
+ github.com/imdario/mergo v0.3.12 // indirect
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
@@ -54,12 +67,17 @@ require (
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/moby/term v0.0.0-20201216013528-df9cb8a40635 // 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/opencontainers/go-digest v1.0.0 // indirect
+ github.com/opencontainers/image-spec v1.0.2 // indirect
+ github.com/opencontainers/runc v1.1.12 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pierrec/lz4/v4 v4.1.18 // indirect
+ github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
@@ -74,6 +92,9 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/ulikunitz/xz v0.5.11 // indirect
+ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
+ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
+ github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
go.opentelemetry.io/otel v1.17.0 // indirect
@@ -82,10 +103,12 @@ require (
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
+ golang.org/x/mod v0.13.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
+ golang.org/x/tools 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 fbdfc126..43e96439 100644
--- a/go.sum
+++ b/go.sum
@@ -4,6 +4,12 @@ github.com/030/mij v1.0.2 h1:fJ6URW86neK1J0XXZ6VPdrN1ulv37hLgadIj7k3CuYg=
github.com/030/mij v1.0.2/go.mod h1:UZDCXdouLCtNrTS/UPUXzHkL09iNS6BFK6rVatYpSSo=
github.com/030/p2iwd v1.0.3 h1:Uk6lulNGQfMnQNBt2PoNv63ofsoYN4UN3yKYe2jsQNg=
github.com/030/p2iwd v1.0.3/go.mod h1:Vc2w6AckFhvyqPNFYnePs+F1fciCkmmct9yrdRKjlyo=
+github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
+github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
+github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg=
+github.com/Microsoft/go-winio v0.6.0/go.mod h1:cTAf44im0RAYeL23bpB+fzCyDH2MJiz2BO69KH/soAE=
+github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 h1:TngWCqHvy9oXAN6lEVMRuU21PR1EtLVZJmdB18Gu3Rw=
+github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8D7ML55dXQrVaamCz2vxCfdQBasLZfHKk=
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=
@@ -11,11 +17,25 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aws/aws-sdk-go v1.50.5 h1:H2Aadcgwr7a2aqS6ZwcE+l1mA6ZrTseYCvjw2QLmxIA=
github.com/aws/aws-sdk-go v1.50.5/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk=
+github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
+github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
+github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
+github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
+github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/docker/cli v20.10.24+incompatible h1:vfV+1kv9yD0/cpL6wWY9cE+Y9J8hL/NqJDGob0B3RVw=
+github.com/docker/cli v20.10.24+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+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=
+github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
+github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
@@ -60,14 +80,22 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.17.0 h1:SmVVlfAOtlZncTxRuinDPomC2DkXJ4E5T9gDA0AIH74=
github.com/go-playground/validator/v10 v10.17.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
+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/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
+github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
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/go-cmp v0.3.0/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.5.2/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/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
+github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
@@ -79,6 +107,8 @@ github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
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/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
+github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
@@ -87,6 +117,8 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGw
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
+github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
+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=
@@ -103,6 +135,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
+github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2 h1:hRGSmZu7j271trc9sneMrpOW7GN5ngLm8YUZIPzf394=
+github.com/lib/pq v0.0.0-20180327071824-d34b9ff171c2/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
@@ -119,6 +153,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
+github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/nwaples/rardecode v1.1.0 h1:vSxaY8vQhOcVr4mm5e8XllHWTiM4JF507A0Katqw7MQ=
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
@@ -126,13 +162,24 @@ github.com/nwaples/rardecode/v2 v2.0.0-beta.2 h1:e3mzJFJs4k83GXBEiTaQ5HgSc/kOK8q
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=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
+github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
+github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
+github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss=
+github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
+github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
+github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
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/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.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -158,6 +205,7 @@ github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
+github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
@@ -191,9 +239,17 @@ github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
+github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
+github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
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=
@@ -210,25 +266,40 @@ go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
+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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
+golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
+golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+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-20190620200207-3b0461eec859/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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
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.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
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-20201020160332-67f06af15bc9/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.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+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-20200831180312-196b9ba8737a/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-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -248,18 +319,29 @@ 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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
+golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
+golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+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=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/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/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
+gotest.tools/v3 v3.3.0 h1:MfDY1b1/0xN1CyMlQDac0ziEy9zJQd9CXBRRDHw2jJo=
+gotest.tools/v3 v3.3.0/go.mod h1:Mcr9QNxkg0uMvy/YElmo4SpXgJKWgQvYrT7Kw5RzJ1A=
diff --git a/internal/app/n3dr/artifactsv2/count/artifacts_test.go b/internal/app/n3dr/artifactsv2/count/artifacts_test.go
index 0c3086f6..5af6cb5a 100644
--- a/internal/app/n3dr/artifactsv2/count/artifacts_test.go
+++ b/internal/app/n3dr/artifactsv2/count/artifacts_test.go
@@ -1,3 +1,5 @@
+//go:build !integration
+
package count
import (
diff --git a/internal/app/n3dr/artifactsv2/upload/upload_test.go b/internal/app/n3dr/artifactsv2/upload/upload_test.go
index a5a3311f..4861eccf 100644
--- a/internal/app/n3dr/artifactsv2/upload/upload_test.go
+++ b/internal/app/n3dr/artifactsv2/upload/upload_test.go
@@ -1,3 +1,5 @@
+//go:build !integration
+
package upload
import (
diff --git a/internal/app/n3dr/config/repository/repository_test.go b/internal/app/n3dr/config/repository/repository_test.go
index 37e02c23..754f46cf 100644
--- a/internal/app/n3dr/config/repository/repository_test.go
+++ b/internal/app/n3dr/config/repository/repository_test.go
@@ -1,3 +1,5 @@
+//go:build !integration
+
package repository
import (
diff --git a/internal/app/n3dr/config/security/anonymous_test.go b/internal/app/n3dr/config/security/anonymous_test.go
index 07fe7392..a735374f 100644
--- a/internal/app/n3dr/config/security/anonymous_test.go
+++ b/internal/app/n3dr/config/security/anonymous_test.go
@@ -1,3 +1,5 @@
+//go:build !integration
+
package security
import (
diff --git a/internal/app/n3dr/config/user/user.go b/internal/app/n3dr/config/user/user.go
index b22e4c93..e808d907 100644
--- a/internal/app/n3dr/config/user/user.go
+++ b/internal/app/n3dr/config/user/user.go
@@ -23,63 +23,126 @@ type User struct {
}
func (u *User) Create() error {
- log.Infof("creating user: '%s'...", u.UserID)
- status := "active"
- u.Status = &status
+ exists, err := u.exists()
+ if err != nil {
+ return err
+ }
+ if !exists {
+ status := "active"
+ u.Status = &status
+
+ client, err := u.Nexus3.Client()
+ if err != nil {
+ return err
+ }
+
+ createUser := security_management_users.CreateUserParams{Body: &u.APICreateUser}
+ createUser.WithTimeout(time.Second * 30)
+ resp, err := client.SecurityManagementUsers.CreateUser(&createUser)
+ if err != nil {
+ return fmt.Errorf("could not create user: '%w'", err)
+ }
+ log.Infof("created the following user: '%v'", resp.Payload)
+ return nil
+ }
+ log.Infof("user: '%s' exists already", u.APICreateUser.UserID)
+
+ return nil
+}
+
+func (u *User) exists() (bool, error) {
+ exists := false
+
+ log.Info("checking whether user exists...")
client, err := u.Nexus3.Client()
if err != nil {
- return err
+ return exists, err
}
- createUser := security_management_users.CreateUserParams{Body: &u.APICreateUser}
- createUser.WithTimeout(time.Second * 30)
- resp, err := client.SecurityManagementUsers.CreateUser(&createUser)
+ getUsersParams := security_management_users.GetUsersParams{}
+ getUsersParams.WithTimeout(time.Second * 30)
+ resp, err := client.SecurityManagementUsers.GetUsers(&getUsersParams)
if err != nil {
- userCreated, errRegex := regexp.MatchString("status 500", err.Error())
- if errRegex != nil {
+ return exists, fmt.Errorf("could not check whether user: '%s' exists. Error: '%w'", u.APICreateUser.UserID, err)
+ }
+
+ users := resp.GetPayload()
+ for _, user := range users {
+ log.Infof("found user: '%+v'", user)
+ log.Infof("looking for user: '%+v'", u.APICreateUser)
+
+ if user.UserID == u.APICreateUser.UserID {
+ log.Infof("user: '%s' exists", u.APICreateUser.UserID)
+ exists = true
+ }
+ }
+
+ return exists, nil
+}
+
+func (r *Role) CreateRole() error {
+ log.Infof("creating role: '%s' if it does not exist...", r.ID)
+
+ exists, err := r.checkWhetherRoleExists()
+ if err != nil {
+ return err
+ }
+ if !exists {
+ client, err := r.Nexus3.Client()
+ if err != nil {
return err
}
- if userCreated {
- log.Infof("user: '%s' has already been created", u.UserID)
- return nil
+
+ createRole := security_management_roles.CreateParams{Body: &r.RoleXORequest}
+ createRole.WithTimeout(time.Second * 30)
+ resp, err := client.SecurityManagementRoles.Create(&createRole)
+ if err != nil {
+ return fmt.Errorf("could not create role. Error: '%w'", err)
}
- return fmt.Errorf("could not create user: '%w'", err)
+
+ log.Infof("created the following role: '%+v'", resp.Payload)
+ return nil
}
- log.Infof("created the following user: '%v'", resp.Payload)
+ log.Infof("role: '%s' exists already", r.RoleXORequest.ID)
return nil
}
-func (r *Role) CreateRole() error {
- log.Infof("creating role: '%s'...", r.ID)
+func (r *Role) checkWhetherRoleExists() (bool, error) {
+ exists := false
+
+ log.Infof("checking whether role id: '%s' exists...", r.ID)
client, err := r.Nexus3.Client()
if err != nil {
- return err
+ return exists, err
}
- createRole := security_management_roles.CreateParams{Body: &r.RoleXORequest}
- createRole.WithTimeout(time.Second * 30)
- resp, err := client.SecurityManagementRoles.Create(&createRole)
+ getRoleParams := security_management_roles.GetRoleParams{ID: r.RoleXORequest.ID}
+ getRoleParams.WithTimeout(time.Second * 30)
+ resp, err := client.SecurityManagementRoles.GetRole(&getRoleParams)
if err != nil {
- roleCreated, errRegex := regexp.MatchString("status 400", err.Error())
+ roleDoesNotExist, errRegex := regexp.MatchString(`\]\[404\] getRoleNotFound`, err.Error())
if errRegex != nil {
- return err
+ return exists, err
}
- if roleCreated {
- log.Infof("role: '%s' has already been created", r.Name)
- return nil
+ if roleDoesNotExist {
+ log.Infof("role id: '%s' does not exist...", r.ID)
+ return exists, nil
}
- return fmt.Errorf("could not create role: '%w', perhaps the role already exists?", err)
+ return exists, fmt.Errorf("could not get role: '%s'. Error: '%w'", getRoleParams.ID, err)
}
- log.Infof("created the following role: '%v'", resp.Payload)
- return nil
+ log.Infof("role: '%s' exists", resp.GetPayload().ID)
+ exists = true
+
+ return exists, nil
}
func (u *User) ChangePass() error {
log.Infof("changing pass user: '%s'...", u.UserID)
+
client, err := u.Nexus3.Client()
if err != nil {
return err
@@ -87,18 +150,19 @@ func (u *User) ChangePass() error {
changePass := security_management_users.ChangePasswordParams{Body: u.Password, UserID: u.UserID}
changePass.WithTimeout(time.Second * 30)
+
if err := client.SecurityManagementUsers.ChangePassword(&changePass); err != nil {
passwordChanged, errRegex := regexp.MatchString("status 204", err.Error())
if errRegex != nil {
return err
}
- if passwordChanged {
- log.Infof("user: '%s' pass has been changed", u.UserID)
- return nil
+ if !passwordChanged {
+ return fmt.Errorf("password of userID: '%s' did not change. Error: '%w'", u.UserID, err)
}
- return err
}
+ log.Infof("user: '%s' pass has been changed", u.UserID)
+
return nil
}
diff --git a/internal/app/n3dr/config/user/user_test.go b/internal/app/n3dr/config/user/user_test.go
new file mode 100644
index 00000000..394f7fb1
--- /dev/null
+++ b/internal/app/n3dr/config/user/user_test.go
@@ -0,0 +1,352 @@
+//go:build integration
+
+package user
+
+import (
+ "bytes"
+ "fmt"
+ "net/http"
+ "os"
+ "testing"
+ "time"
+
+ "github.com/030/n3dr/internal/app/n3dr/connection"
+ "github.com/030/n3dr/internal/app/n3dr/goswagger/models"
+ "github.com/ory/dockertest/v3"
+ "github.com/ory/dockertest/v3/docker"
+ log "github.com/sirupsen/logrus"
+ "github.com/stretchr/testify/assert"
+)
+
+const integrationTestAdminPassword = "someIntegrationTestPassword123!"
+
+var hostAndPort, initialAdminPassword string
+
+func TestMain(m *testing.M) {
+ // uses a sensible default on windows (tcp/http) and linux/osx (socket)
+ pool, err := dockertest.NewPool("")
+ if err != nil {
+ log.Fatalf("Could not construct pool: %s", err)
+ }
+
+ err = pool.Client.Ping()
+ if err != nil {
+ log.Fatalf("Could not connect to Docker: %s", err)
+ }
+
+ // pulls an image, creates a container based on it and runs it
+ resource, err := pool.RunWithOptions(&dockertest.RunOptions{
+ Repository: "sonatype/nexus3",
+ Tag: "3.64.0",
+ }, func(config *docker.HostConfig) {
+ // set AutoRemove to true so that stopped container goes away by itself
+ config.AutoRemove = true
+ config.RestartPolicy = docker.RestartPolicy{Name: "no"}
+ })
+ if err != nil {
+ log.Fatalf("Could not start resource: %s", err)
+ }
+
+ hostAndPort = resource.GetHostPort("8081/tcp")
+ log.Info("hostAndPort", hostAndPort)
+
+ client := http.Client{}
+
+ pool.MaxWait = time.Minute * 3
+ // exponential backoff-retry, because the application in the container might not be ready to accept connections yet.
+ if err = pool.Retry(func() error {
+ // Check whether Nexus3 is ready and writable
+ req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("http://localhost:%s/service/rest/v1/status/writable", resource.GetPort("8081/tcp")), nil)
+ if err != nil {
+ return err
+ }
+
+ _, err = client.Do(req)
+
+ return err
+ }); err != nil {
+ log.Fatalf("Could not connect to docker: %s", err)
+ }
+
+ var out bytes.Buffer
+ resource.Exec([]string{"cat", "/nexus-data/admin.password"}, dockertest.ExecOptions{
+ StdOut: &out,
+ StdErr: &out,
+ })
+ initialAdminPassword = out.String()
+
+ code := m.Run()
+
+ // You can't defer this because os.Exit doesn't care for defer
+ if err := pool.Purge(resource); err != nil {
+ log.Fatalf("Could not purge resource: %s", err)
+ }
+
+ os.Exit(code)
+}
+
+func TestChangePass(t *testing.T) {
+ https := false
+ c := connection.Nexus3{
+ HTTPS: &https,
+ User: "admin",
+ }
+ macu := models.APICreateUser{
+ EmailAddress: "admin@example.org",
+ FirstName: "admin",
+ UserID: "admin",
+ LastName: "admin",
+ Password: initialAdminPassword,
+ }
+
+ tests := []struct {
+ adminPassword, expectedErrorString, name, passwordOfUserIdThatHasToBeChanged string
+ unsetHostAndPort bool
+ }{
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "",
+ name: "If admin password is valid then it should be possible to change it with the same password that is valid.",
+ passwordOfUserIdThatHasToBeChanged: "admin",
+ unsetHostAndPort: false,
+ },
+ {
+ adminPassword: "incorrectPassword",
+ expectedErrorString: "password of userID: 'admin' did not change. Error: 'response status code does not match any response statuses defined for this endpoint in the swagger spec (status 401): {}'",
+ name: "Test that change of password will fail if it is not possible to login to Nexus3 due to an incorrect password.",
+ passwordOfUserIdThatHasToBeChanged: "admin",
+ unsetHostAndPort: false,
+ },
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "password of userID: 'someUserIDThatDoesNotExist' did not change. Error: '[PUT /v1/security/users/{userId}/change-password][404] changePasswordNotFound '",
+ name: "Test that password change will fail if userID does not exist.",
+ passwordOfUserIdThatHasToBeChanged: "someUserIDThatDoesNotExist",
+ unsetHostAndPort: false,
+ },
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "Key: 'Nexus3.FQDN' Error:Field validation for 'FQDN' failed on the 'required' tag",
+ name: "Test that password change will fail if host and port have not been set.",
+ passwordOfUserIdThatHasToBeChanged: "someUserIDThatDoesNotExist",
+ unsetHostAndPort: true,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ c.Pass = test.adminPassword
+ c.FQDN = hostAndPort
+ if test.unsetHostAndPort {
+ c.FQDN = ""
+ }
+
+ macu.UserID = test.passwordOfUserIdThatHasToBeChanged
+ u := User{c, macu}
+ err := u.ChangePass()
+
+ if test.expectedErrorString == "" {
+ assert.NoError(t, err)
+ } else {
+ assert.EqualError(t, err, test.expectedErrorString)
+ }
+ })
+ }
+}
+
+func TestCreateRole(t *testing.T) {
+ https := false
+ c := connection.Nexus3{
+ HTTPS: &https,
+ User: "admin",
+ }
+ mrxr := models.RoleXORequest{
+ Name: "nx-upload",
+ }
+
+ tests := []struct {
+ adminPassword, expectedErrorString, name, passwordOfUserIdThatHasToBeChanged, roleID string
+ rolePrivileges []string
+ unsetHostAndPort bool
+ }{
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "",
+ name: "Create a role.",
+ passwordOfUserIdThatHasToBeChanged: "admin",
+ unsetHostAndPort: false,
+ roleID: "nx-upload",
+ rolePrivileges: []string{
+ "nx-repository-view-*-*-add",
+ },
+ },
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "",
+ name: "Trying to create a role that exists should be handled by the code and return without any error.",
+ passwordOfUserIdThatHasToBeChanged: "admin",
+ unsetHostAndPort: false,
+ roleID: "nx-upload",
+ rolePrivileges: []string{
+ "nx-repository-view-*-*-edit",
+ },
+ },
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "could not create role. Response: ''. Error: 'response status code does not match any response statuses defined for this endpoint in the swagger spec (status 400): {}'",
+ name: "Trying to create a role with a privilege that does not exist.",
+ passwordOfUserIdThatHasToBeChanged: "admin",
+ unsetHostAndPort: false,
+ roleID: "role-that-does-not-exist",
+ rolePrivileges: []string{
+ "a-privilege-that-does-not-exist",
+ },
+ },
+ {
+ adminPassword: "incorrectPassword",
+ expectedErrorString: "could not get role: 'role-that-does-not-exist'. Error: 'response status code does not match any response statuses defined for this endpoint in the swagger spec (status 401): {}'",
+ name: "Test that role creatiom will fail if it is not possible to login to Nexus3 due to an incorrect password.",
+ passwordOfUserIdThatHasToBeChanged: "admin",
+ unsetHostAndPort: false,
+ roleID: "role-that-does-not-exist",
+ rolePrivileges: []string{
+ "a-privilege-that-does-not-exist",
+ },
+ },
+ {
+ adminPassword: "incorrectPassword",
+ expectedErrorString: "Key: 'Nexus3.FQDN' Error:Field validation for 'FQDN' failed on the 'required' tag",
+ name: "Test that role creatiom will fail if it is not possible to login to Nexus3 due to an incorrect password.",
+ passwordOfUserIdThatHasToBeChanged: "admin",
+ unsetHostAndPort: true,
+ roleID: "role-that-does-not-exist",
+ rolePrivileges: []string{
+ "a-privilege-that-does-not-exist",
+ },
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ c.Pass = test.adminPassword
+ c.FQDN = hostAndPort
+ if test.unsetHostAndPort {
+ c.FQDN = ""
+ }
+
+ r := Role{c, mrxr}
+ r.RoleXORequest.ID = test.roleID
+ r.RoleXORequest.Privileges = test.rolePrivileges
+ err := r.CreateRole()
+
+ if test.expectedErrorString == "" {
+ assert.NoError(t, err)
+ } else {
+ assert.EqualError(t, err, test.expectedErrorString)
+ }
+ })
+ }
+}
+
+func TestCreateUser(t *testing.T) {
+ https := false
+ c := connection.Nexus3{
+ HTTPS: &https,
+ User: "admin",
+ }
+
+ tests := []struct {
+ adminPassword, expectedErrorString, name, passwordOfUserIdThatHasToBeChanged, roleID string
+ rolePrivileges []string
+ unsetHostAndPort bool
+ macu models.APICreateUser
+ }{
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "",
+ name: "Create a user that exists.",
+ unsetHostAndPort: false,
+ macu: models.APICreateUser{
+ EmailAddress: "admin@example.org",
+ FirstName: "admin",
+ LastName: "admin",
+ Password: "some-password1234!",
+ UserID: "admin",
+ Roles: []string{"nx-anonymous"},
+ },
+ },
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "",
+ name: "Create a user that does not exist.",
+ unsetHostAndPort: false,
+ macu: models.APICreateUser{
+ EmailAddress: "admin42@example.org",
+ FirstName: "admin42",
+ LastName: "admin42",
+ Password: "some-password1234!",
+ UserID: "admin42",
+ Roles: []string{"nx-anonymous"},
+ },
+ },
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "",
+ name: "Create a user that has just been created for the second time.",
+ unsetHostAndPort: false,
+ macu: models.APICreateUser{
+ EmailAddress: "admin42@example.org",
+ FirstName: "admin42",
+ LastName: "admin42",
+ Password: "some-password1234!",
+ UserID: "admin42",
+ Roles: []string{"nx-anonymous"},
+ },
+ },
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "could not create user: '[POST /v1/security/users][400] createUserBadRequest '",
+ name: "Create a new user without specifying a role should return a 400 bad request as roles are required.",
+ unsetHostAndPort: false,
+ macu: models.APICreateUser{
+ EmailAddress: "admin43@example.org",
+ FirstName: "admin43",
+ LastName: "admin43",
+ Password: "some-password1234!",
+ UserID: "admin43",
+ },
+ },
+ {
+ adminPassword: initialAdminPassword,
+ expectedErrorString: "Key: 'Nexus3.FQDN' Error:Field validation for 'FQDN' failed on the 'required' tag",
+ name: "Create a new user, but this should fail as the Nexus3 URL is invalid.",
+ unsetHostAndPort: true,
+ macu: models.APICreateUser{
+ EmailAddress: "admin43@example.org",
+ FirstName: "admin43",
+ LastName: "admin43",
+ Password: "some-password1234!",
+ UserID: "admin43",
+ },
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ c.Pass = test.adminPassword
+ c.FQDN = hostAndPort
+ if test.unsetHostAndPort {
+ c.FQDN = ""
+ }
+
+ u := User{c, test.macu}
+ err := u.Create()
+
+ if test.expectedErrorString == "" {
+ assert.NoError(t, err)
+ } else {
+ assert.EqualError(t, err, test.expectedErrorString)
+ }
+ })
+ }
+}
diff --git a/internal/app/n3dr/connection/connection.go b/internal/app/n3dr/connection/connection.go
index b70d96ca..4473f223 100644
--- a/internal/app/n3dr/connection/connection.go
+++ b/internal/app/n3dr/connection/connection.go
@@ -13,7 +13,7 @@ type Nexus3 struct {
DockerPort int32
DockerPortSecure, SkipErrors, StrictContentTypeValidation, WithoutWaitGroups, WithoutWaitGroupArtifacts, WithoutWaitGroupRepositories, ZIP bool
HTTPS *bool `validate:"required"`
- FQDN string `validate:"required"`
+ FQDN string `validate:"required,min=3"`
}
func (n *Nexus3) Client() (*apiclient.Nexus3, error) {