feature (workers): add repository CreateWorker(...) (#2105)
This commit is contained in:
20 files changed
+343
-54
No files matched your search
@@ -0,0 +1,4 @@
|
||||
**
|
||||
!bin/**
|
||||
!dist/**
|
||||
!.release/docker/**
|
||||
@@ -60,10 +60,28 @@ jobs:
|
||||
project="$(go list -m)"
|
||||
sha="$(git rev-parse HEAD)"
|
||||
echo "::set-output name=ldflags::"-s -w -X \'$project/version.GitCommit=$sha\'""
|
||||
|
||||
get-product-edition:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
product-edition: ${{ steps.get-product-edition.outputs.product-edition}}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: "1.18.1"
|
||||
- name: Get product edition
|
||||
id: get-product-edition
|
||||
run: |
|
||||
make edition
|
||||
echo "::set-output name=product-edition::$(make edition)"
|
||||
|
||||
|
||||
build-other:
|
||||
needs:
|
||||
- get-product-version
|
||||
- get-product-edition
|
||||
- set-ld-flags
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
@@ -102,7 +120,7 @@ jobs:
|
||||
workflow: build-admin-ui.yaml
|
||||
commit: ${{ steps.set-sha.outputs.sha }}
|
||||
repo: "hashicorp/boundary-ui"
|
||||
name: admin-ui
|
||||
name: admin-ui-${{ needs.get-product-edition.outputs.product-edition }}
|
||||
path: internal/ui/.tmp/boundary-ui/ui/admin/dist
|
||||
- name: Go Build
|
||||
env:
|
||||
@@ -124,6 +142,7 @@ jobs:
|
||||
build-linux:
|
||||
needs:
|
||||
- get-product-version
|
||||
- get-product-edition
|
||||
- set-ld-flags
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
@@ -157,7 +176,7 @@ jobs:
|
||||
workflow: build-admin-ui.yaml
|
||||
commit: ${{ steps.set-sha.outputs.sha }}
|
||||
repo: "hashicorp/boundary-ui"
|
||||
name: admin-ui
|
||||
name: admin-ui-${{ needs.get-product-edition.outputs.product-edition }}
|
||||
path: internal/ui/.tmp/boundary-ui/ui/admin/dist
|
||||
- name: Go Build
|
||||
env:
|
||||
@@ -209,6 +228,7 @@ jobs:
|
||||
build-darwin:
|
||||
needs:
|
||||
- get-product-version
|
||||
- get-product-edition
|
||||
- set-ld-flags
|
||||
runs-on: macos-latest
|
||||
strategy:
|
||||
@@ -239,7 +259,7 @@ jobs:
|
||||
workflow: build-admin-ui.yaml
|
||||
commit: ${{ steps.set-sha.outputs.sha }}
|
||||
repo: "hashicorp/boundary-ui"
|
||||
name: admin-ui
|
||||
name: admin-ui-${{ needs.get-product-edition.outputs.product-edition }}
|
||||
path: internal/ui/.tmp/boundary-ui/ui/admin/dist
|
||||
- name: Go Build
|
||||
env:
|
||||
|
||||
@@ -6,6 +6,10 @@ Canonical reference for changes, improvements, and bugfixes for Boundary.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
## 0.8.1 (2022/05/13)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* controller: Do not shut down cluster listener when it receives an invalid
|
||||
packet ([Issue](https://github.com/hashicorp/boundary/issues/2072),
|
||||
[PR](https://github.com/hashicorp/boundary/pull/2073))
|
||||
|
||||
@@ -327,3 +327,13 @@ ci-verify:
|
||||
# This is used for release builds by .github/workflows/build.yml
|
||||
version:
|
||||
@go run ./cmd/boundary version | awk '/Version Number:/ { print $$3 }'
|
||||
|
||||
EDITION?=
|
||||
.PHONY: edition
|
||||
# This is used for release builds by .github/workflows/build.yml
|
||||
edition:
|
||||
@if [ -z "$(EDITION)" ]; then \
|
||||
go run ./cmd/boundary version -format=json | jq -r '.version_metadata // "oss"'; \
|
||||
else \
|
||||
echo $(EDITION); \
|
||||
fi; \
|
||||
@@ -90,7 +90,8 @@ require (
|
||||
require github.com/hashicorp/go-dbw v0.0.0-20220412153211-c470aec9369f // this is a branch and should be updated before merging
|
||||
|
||||
require (
|
||||
github.com/hashicorp/go-kms-wrapping/extras/kms/v2 v2.0.0-20220512190651-85bdcdd684e6
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0
|
||||
github.com/hashicorp/go-kms-wrapping/extras/kms/v2 v2.0.0-20220515130442-cac0b5ac133b
|
||||
github.com/hashicorp/nodeenrollment v0.0.0-20220520141833-ad7323153acc
|
||||
)
|
||||
|
||||
@@ -98,7 +99,6 @@ require (
|
||||
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
|
||||
github.com/AlecAivazis/survey/v2 v2.2.9 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver v1.5.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
@@ -172,7 +172,6 @@ require (
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.32.1 // indirect
|
||||
github.com/prometheus/procfs v0.7.3 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/rogpeppe/go-internal v1.8.1 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/sethvargo/go-diceware v0.3.0 // indirect
|
||||
@@ -195,14 +194,5 @@ require (
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
gorm.io/driver/sqlite v1.2.4 // indirect
|
||||
modernc.org/cc/v3 v3.32.4 // indirect
|
||||
modernc.org/ccgo/v3 v3.9.2 // indirect
|
||||
modernc.org/libc v1.9.5 // indirect
|
||||
modernc.org/mathutil v1.2.2 // indirect
|
||||
modernc.org/memory v1.0.4 // indirect
|
||||
modernc.org/opt v0.1.1 // indirect
|
||||
modernc.org/sqlite v1.10.6 // indirect
|
||||
modernc.org/strutil v1.1.0 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
@@ -377,7 +377,6 @@ github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNE
|
||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM=
|
||||
github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU=
|
||||
@@ -678,8 +677,8 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jUIEJnBlbgKS1N2Q61QkHiZyR1g=
|
||||
github.com/hashicorp/go-kms-wrapping/extras/kms/v2 v2.0.0-20220512190651-85bdcdd684e6 h1:3BknAN8P8326GPQac8e3iM132lwtwkO/3OilBU67S1I=
|
||||
github.com/hashicorp/go-kms-wrapping/extras/kms/v2 v2.0.0-20220512190651-85bdcdd684e6/go.mod h1:TzFKcCsMKyMwFiMfH2MfO8SXqsFQLxzR7Z8JZiGzpK4=
|
||||
github.com/hashicorp/go-kms-wrapping/extras/kms/v2 v2.0.0-20220515130442-cac0b5ac133b h1:NmqGrxmUGR1XRhmYA3wsD2BktB9PfbCDIhXd4FM0hbk=
|
||||
github.com/hashicorp/go-kms-wrapping/extras/kms/v2 v2.0.0-20220515130442-cac0b5ac133b/go.mod h1:puo5dXNWmXx4xoKCzbKSevcFQ4w+z72k3ZF3EVo6zI4=
|
||||
github.com/hashicorp/go-kms-wrapping/plugin/v2 v2.0.2 h1:it114Kjpk79JVh6AfxFMP5oi1gb+RPzcSLiG3zF/J0w=
|
||||
github.com/hashicorp/go-kms-wrapping/plugin/v2 v2.0.2/go.mod h1:b9mq0bG5xJ10ZcTEQJLZ22O9y71hIt2MGTLqROA/SAM=
|
||||
github.com/hashicorp/go-kms-wrapping/v2 v2.0.6-0.20220512190651-85bdcdd684e6 h1:isD0/0pGWppbxkakRvnX4M4k65+ZSRW0yELW+twLPDk=
|
||||
@@ -1159,7 +1158,6 @@ github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
|
||||
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
@@ -1967,41 +1965,29 @@ k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAG
|
||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
|
||||
modernc.org/cc/v3 v3.32.4 h1:1ScT6MCQRWwvwVdERhGPsPq0f55J1/pFEOCiqM7zc78=
|
||||
modernc.org/cc/v3 v3.32.4/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
|
||||
modernc.org/ccgo/v3 v3.9.2 h1:mOLFgduk60HFuPmxSix3AluTEh7zhozkby+e1VDo/ro=
|
||||
modernc.org/ccgo/v3 v3.9.2/go.mod h1:gnJpy6NIVqkETT+L5zPsQFj7L2kkhfPMzOghRNv/CFo=
|
||||
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
|
||||
modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw=
|
||||
modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8=
|
||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM=
|
||||
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.9.5 h1:zv111ldxmP7DJ5mOIqzRbza7ZDl3kh4ncKfASB2jIYY=
|
||||
modernc.org/libc v1.9.5/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2 h1:+yFk8hBprV+4c0U9GjFtL+dV3N8hOJ8JCituQcMShFY=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4 h1:utMBrFcpnQDdNsmM6asmyH/FM9TqLPS7XF7otpJmrwM=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
|
||||
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
|
||||
modernc.org/sqlite v1.10.6 h1:iNDTQbULcm0IJAqrzCm2JcCqxaKRS94rJ5/clBMRmc8=
|
||||
modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs=
|
||||
modernc.org/strutil v1.1.0 h1:+1/yCzZxY2pZwwrsbH+4T7BQMoLQ9QiBshRC9eicYsc=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/tcl v1.5.2 h1:sYNjGr4zK6cDH74USl8wVJRrvDX6UOLpG0j4lFvR0W0=
|
||||
modernc.org/tcl v1.5.2/go.mod h1:pmJYOLgpiys3oI4AeAafkcUfE+TKKilminxNyU/+Zlo=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/z v1.0.1 h1:WyIDpEpAIx4Hel6q/Pcgj/VhaQV5XPJ2I6ryIYbjnpc=
|
||||
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4=
|
||||
mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// We expect the database already to be initialized iff initialized is set to true.
|
||||
// Returns a cleanup function which must be called even if an error is returned and
|
||||
// an error code where a non-zero value indicates an error happened.
|
||||
func migrateDatabase(ctx context.Context, ui cli.Ui, dialect, u string, initialized bool) (func(), int) {
|
||||
func migrateDatabase(ctx context.Context, ui cli.Ui, dialect, u string, initialized bool, maxOpenConns int) (func(), int) {
|
||||
noop := func() {}
|
||||
// This database is used to keep an exclusive lock on the database for the
|
||||
// remainder of the command
|
||||
@@ -25,6 +25,7 @@ func migrateDatabase(ctx context.Context, ui cli.Ui, dialect, u string, initiali
|
||||
ui.Error(fmt.Errorf("Error establishing db connection: %w", err).Error())
|
||||
return noop, 2
|
||||
}
|
||||
dBase.SetMaxOpenConns(maxOpenConns)
|
||||
if err := dBase.PingContext(ctx); err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to connect to the database at %q", u))
|
||||
return noop, 2
|
||||
|
||||
@@ -193,7 +193,7 @@ func TestMigrateDatabase(t *testing.T) {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
u := tc.urlProvider()
|
||||
ui := cli.NewMockUi()
|
||||
clean, errCode := migrateDatabase(ctx, ui, dialect, u, tc.initialized)
|
||||
clean, errCode := migrateDatabase(ctx, ui, dialect, u, tc.initialized, 10)
|
||||
clean()
|
||||
assert.EqualValues(t, tc.expectedCode, errCode)
|
||||
assert.Equal(t, tc.expectedOutput, ui.OutputWriter.String())
|
||||
|
||||
@@ -239,6 +239,8 @@ func (c *InitCommand) Run(args []string) (retCode int) {
|
||||
return base.CommandUserError
|
||||
}
|
||||
|
||||
c.DatabaseMaxOpenConnections = c.Config.Controller.Database.MaxOpenConnections
|
||||
|
||||
var migrationUrlToParse string
|
||||
if c.Config.Controller.Database.MigrationUrl != "" {
|
||||
migrationUrlToParse = c.Config.Controller.Database.MigrationUrl
|
||||
@@ -262,7 +264,7 @@ func (c *InitCommand) Run(args []string) (retCode int) {
|
||||
return base.CommandUserError
|
||||
}
|
||||
|
||||
clean, errCode := migrateDatabase(c.Context, c.UI, dialect, migrationUrl, false)
|
||||
clean, errCode := migrateDatabase(c.Context, c.UI, dialect, migrationUrl, false, c.DatabaseMaxOpenConnections)
|
||||
defer clean()
|
||||
switch errCode {
|
||||
case 0:
|
||||
|
||||
@@ -259,7 +259,7 @@ plugins {
|
||||
return base.CommandUserError
|
||||
}
|
||||
|
||||
clean, errCode := migrateDatabase(c.Context, c.UI, dialect, migrationUrl, true)
|
||||
clean, errCode := migrateDatabase(c.Context, c.UI, dialect, migrationUrl, true, c.Config.Controller.Database.MaxOpenConnections)
|
||||
defer clean()
|
||||
if errCode != 0 {
|
||||
return errCode
|
||||
|
||||
@@ -75,7 +75,7 @@ func (c *ClientCertificate) SetTableName(n string) {
|
||||
func (c *ClientCertificate) encrypt(ctx context.Context, cipher wrapping.Wrapper) error {
|
||||
const op = "vault.(ClientCertificate).encrypt"
|
||||
if len(c.CertificateKey) == 0 {
|
||||
errors.New(ctx, errors.InvalidParameter, op, "no certificate key defined")
|
||||
return errors.New(ctx, errors.InvalidParameter, op, "no certificate key defined")
|
||||
}
|
||||
if err := structwrapping.WrapStruct(ctx, cipher, c.ClientCertificate, nil); err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt))
|
||||
@@ -86,7 +86,7 @@ func (c *ClientCertificate) encrypt(ctx context.Context, cipher wrapping.Wrapper
|
||||
}
|
||||
c.KeyId = keyId
|
||||
if err := c.hmacCertificateKey(ctx, cipher); err != nil {
|
||||
errors.Wrap(ctx, err, op)
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
|
||||
"github.com/hashicorp/boundary/internal/credential/vault/store"
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -49,11 +50,12 @@ func TestClientCertificate_New(t *testing.T) {
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want *ClientCertificate
|
||||
wantErr bool
|
||||
wantEncryptErr bool
|
||||
name string
|
||||
args args
|
||||
want *ClientCertificate
|
||||
wantErr bool
|
||||
wantEncryptErr bool
|
||||
wantEncryptErrCode errors.Code
|
||||
}{
|
||||
{
|
||||
name: "missing-certificate",
|
||||
@@ -64,7 +66,7 @@ func TestClientCertificate_New(t *testing.T) {
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "valid-missing-key",
|
||||
name: "missing-key",
|
||||
args: args{
|
||||
certificate: []byte(certPem),
|
||||
},
|
||||
@@ -73,7 +75,8 @@ func TestClientCertificate_New(t *testing.T) {
|
||||
Certificate: []byte(certPem),
|
||||
},
|
||||
},
|
||||
wantEncryptErr: true,
|
||||
wantEncryptErr: true,
|
||||
wantEncryptErrCode: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "valid",
|
||||
@@ -116,10 +119,12 @@ func TestClientCertificate_New(t *testing.T) {
|
||||
err = got.encrypt(ctx, databaseWrapper)
|
||||
if tt.wantEncryptErr {
|
||||
require.Error(err)
|
||||
} else {
|
||||
require.NoError(err)
|
||||
require.NoError(got.decrypt(ctx, databaseWrapper))
|
||||
assert.Truef(errors.Match(errors.T(tt.wantEncryptErrCode), err), "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(err)
|
||||
assert.NoError(got.decrypt(ctx, databaseWrapper))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func (t *Token) encrypt(ctx context.Context, cipher wrapping.Wrapper) error {
|
||||
}
|
||||
keyId, err := cipher.KeyId(ctx)
|
||||
if err != nil {
|
||||
errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("error fetching wrapper key id"))
|
||||
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Encrypt), errors.WithMsg("error fetching wrapper key id"))
|
||||
}
|
||||
t.KeyId = keyId
|
||||
return nil
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/DATA-DOG/go-sqlmock"
|
||||
_ "github.com/golang-migrate/migrate/v4/database/postgres"
|
||||
_ "github.com/golang-migrate/migrate/v4/source/file"
|
||||
"github.com/hashicorp/boundary/internal/db/schema"
|
||||
@@ -20,6 +21,7 @@ import (
|
||||
aead "github.com/hashicorp/go-kms-wrapping/v2/aead"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
pgDriver "gorm.io/driver/postgres"
|
||||
)
|
||||
|
||||
// setup the tests (initialize the database one-time and intialized
|
||||
@@ -73,6 +75,23 @@ func TestSetup(t testing.TB, dialect string, opt ...TestOption) (*DB, string) {
|
||||
return db, url
|
||||
}
|
||||
|
||||
// TestSetupWithMock will return a test DB and an associated Sqlmock which can
|
||||
// be used to mock out the db responses.
|
||||
func TestSetupWithMock(t *testing.T) (*DB, sqlmock.Sqlmock) {
|
||||
t.Helper()
|
||||
require := require.New(t)
|
||||
db, mock, err := sqlmock.New()
|
||||
require.NoError(err)
|
||||
require.NoError(err)
|
||||
dbw, err := dbw.OpenWith(pgDriver.New(pgDriver.Config{
|
||||
Conn: db,
|
||||
}))
|
||||
require.NoError(err)
|
||||
return &DB{
|
||||
wrapped: dbw,
|
||||
}, mock
|
||||
}
|
||||
|
||||
// TestWrapper initializes an AEAD wrapping.Wrapper for testing the oplog
|
||||
func TestWrapper(t testing.TB) wrapping.Wrapper {
|
||||
t.Helper()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -31,10 +32,13 @@ type options struct {
|
||||
withControllerEncryptionPrivateKey []byte
|
||||
withKeyId string
|
||||
withNonce []byte
|
||||
withNewIdFunc func(context.Context) (string, error)
|
||||
}
|
||||
|
||||
func getDefaultOptions() options {
|
||||
return options{}
|
||||
return options{
|
||||
withNewIdFunc: newWorkerId,
|
||||
}
|
||||
}
|
||||
|
||||
// WithDescription provides an optional description.
|
||||
@@ -128,3 +132,11 @@ func WithNonce(nonce []byte) Option {
|
||||
o.withNonce = nonce
|
||||
}
|
||||
}
|
||||
|
||||
// WithNewIdFunc allows an optional factory function for new worker IDs to be
|
||||
// specified (this option is likely only useful for tests).
|
||||
func WithNewIdFunc(fn func(context.Context) (string, error)) Option {
|
||||
return func(o *options) {
|
||||
o.withNewIdFunc = fn
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package servers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -10,49 +13,60 @@ import (
|
||||
// Test_GetOpts provides unit tests for GetOpts and all the options
|
||||
func Test_GetOpts(t *testing.T) {
|
||||
t.Parallel()
|
||||
opts := getOpts()
|
||||
assert.Equal(t, options{}, opts)
|
||||
|
||||
t.Run("WithName", func(t *testing.T) {
|
||||
opts := getOpts(WithName("test"))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withName = "test"
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithDescription", func(t *testing.T) {
|
||||
opts := getOpts(WithDescription("test desc"))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withDescription = "test desc"
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithLimit", func(t *testing.T) {
|
||||
opts := getOpts(WithLimit(5))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withLimit = 5
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithAddress", func(t *testing.T) {
|
||||
opts := getOpts(WithAddress("test"))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withAddress = "test"
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithPublicId", func(t *testing.T) {
|
||||
opts := getOpts(WithPublicId("test"))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withPublicId = "test"
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithLiveness", func(t *testing.T) {
|
||||
opts := getOpts(WithLiveness(time.Hour))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withLiveness = time.Hour
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithUpdateTags", func(t *testing.T) {
|
||||
opts := getOpts(WithUpdateTags(true))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withUpdateTags = true
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithWorkerTags", func(t *testing.T) {
|
||||
@@ -63,6 +77,8 @@ func Test_GetOpts(t *testing.T) {
|
||||
opts := getOpts(WithWorkerTags(tags...))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withWorkerTags = tags
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithWorkerKeys", func(t *testing.T) {
|
||||
@@ -77,6 +93,8 @@ func Test_GetOpts(t *testing.T) {
|
||||
opts := getOpts(WithWorkerKeys(keys))
|
||||
testOpts = getDefaultOptions()
|
||||
testOpts.withWorkerKeys = keys
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithControllerEncryptionPrivateKey", func(t *testing.T) {
|
||||
@@ -88,6 +106,8 @@ func Test_GetOpts(t *testing.T) {
|
||||
opts := getOpts(WithControllerEncryptionPrivateKey(key))
|
||||
testOpts = getDefaultOptions()
|
||||
testOpts.withControllerEncryptionPrivateKey = key
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithKeyId", func(t *testing.T) {
|
||||
@@ -97,6 +117,8 @@ func Test_GetOpts(t *testing.T) {
|
||||
opts := getOpts(WithKeyId("hi i'm another key id"))
|
||||
testOpts = getDefaultOptions()
|
||||
testOpts.withKeyId = "hi i'm another key id"
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithNonce", func(t *testing.T) {
|
||||
@@ -108,6 +130,19 @@ func Test_GetOpts(t *testing.T) {
|
||||
opts := getOpts(WithNonce(nonce))
|
||||
testOpts = getDefaultOptions()
|
||||
testOpts.withNonce = nonce
|
||||
opts.withNewIdFunc = nil
|
||||
testOpts.withNewIdFunc = nil
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithNewIdFunc", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
testFn := func(context.Context) (string, error) { return "", nil }
|
||||
opts := getOpts(WithNewIdFunc(testFn))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withNewIdFunc = testFn
|
||||
assert.Equal(
|
||||
runtime.FuncForPC(reflect.ValueOf(opts.withNewIdFunc).Pointer()).Name(),
|
||||
runtime.FuncForPC(reflect.ValueOf(testOpts.withNewIdFunc).Pointer()).Name(),
|
||||
)
|
||||
})
|
||||
}
|
||||
@@ -191,3 +191,51 @@ func setWorkerTags(ctx context.Context, w db.Writer, id string, ts TagSource, ta
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateWorker will create a worker in the repository and return the written
|
||||
// worker. Creating a worker is not intentionally oplogged. A worker's
|
||||
// ReportedStatus and Tags are intentionally ignored when creating a worker (not
|
||||
// included). Currently, a worker can only be created in the global scope
|
||||
//
|
||||
// Options supported: WithNewIdFunc (this option is likely only useful for tests)
|
||||
func (r *Repository) CreateWorker(ctx context.Context, worker *Worker, opt ...Option) (*Worker, error) {
|
||||
const op = "servers.CreateWorker"
|
||||
switch {
|
||||
case worker == nil:
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing worker")
|
||||
case worker.PublicId != "":
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "public id is not empty")
|
||||
case worker.ScopeId == "":
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, "missing scope id")
|
||||
case worker.ScopeId != scope.Global.String():
|
||||
return nil, errors.New(ctx, errors.InvalidParameter, op, fmt.Sprintf("scope id must be %q", scope.Global.String()))
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
var err error
|
||||
if worker.PublicId, err = opts.withNewIdFunc(ctx); err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to generate worker id"))
|
||||
}
|
||||
|
||||
var returnedWorker *Worker
|
||||
_, err = r.writer.DoTx(
|
||||
ctx,
|
||||
db.StdRetryCnt,
|
||||
db.ExpBackoff{},
|
||||
func(_ db.Reader, w db.Writer) error {
|
||||
returnedWorker = worker.clone()
|
||||
err := w.Create(
|
||||
ctx,
|
||||
returnedWorker,
|
||||
)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to create worker"))
|
||||
}
|
||||
return returnedWorker, nil
|
||||
}
|
||||
@@ -8,8 +8,11 @@ import (
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/iam"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
"github.com/hashicorp/boundary/internal/servers"
|
||||
"github.com/hashicorp/boundary/internal/servers/store"
|
||||
"github.com/hashicorp/boundary/internal/types/scope"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -315,3 +318,153 @@ func TestListWorkersWithLiveness(t *testing.T) {
|
||||
require.Len(result, 3)
|
||||
requireIds([]string{workConf1.WorkerId, workConf2.WorkerId, workConf3.WorkerId}, result)
|
||||
}
|
||||
|
||||
func TestRepository_CreateWorker(t *testing.T) {
|
||||
t.Parallel()
|
||||
testCtx := context.Background()
|
||||
conn, _ := db.TestSetup(t, "postgres")
|
||||
rw := db.New(conn)
|
||||
wrapper := db.TestWrapper(t)
|
||||
kms := kms.TestKms(t, conn, wrapper)
|
||||
testRepo, err := servers.NewRepository(rw, rw, kms)
|
||||
require.NoError(t, err)
|
||||
|
||||
iamRepo := iam.TestRepo(t, conn, wrapper)
|
||||
org, _ := iam.TestScopes(t, iamRepo)
|
||||
|
||||
testNewIdFn := func(context.Context) (string, error) {
|
||||
return "", errors.New(testCtx, errors.Internal, "test", "testNewIdFn-error")
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
setup func() *servers.Worker
|
||||
repo *servers.Repository
|
||||
opt []servers.Option
|
||||
wantErr bool
|
||||
wantErrIs errors.Code
|
||||
wantErrContains string
|
||||
}{
|
||||
{
|
||||
name: "missing-worker",
|
||||
setup: func() *servers.Worker {
|
||||
return nil
|
||||
},
|
||||
repo: testRepo,
|
||||
wantErr: true,
|
||||
wantErrIs: errors.InvalidParameter,
|
||||
wantErrContains: "missing worker",
|
||||
},
|
||||
{
|
||||
name: "public-id-not-empty",
|
||||
setup: func() *servers.Worker {
|
||||
w := servers.NewWorker(scope.Global.String())
|
||||
var err error
|
||||
w.PublicId, err = db.NewPublicId(servers.WorkerPrefix)
|
||||
require.NoError(t, err)
|
||||
return w
|
||||
},
|
||||
repo: testRepo,
|
||||
wantErr: true,
|
||||
wantErrIs: errors.InvalidParameter,
|
||||
wantErrContains: "public id is not empty",
|
||||
},
|
||||
{
|
||||
name: "empty-scope-id",
|
||||
setup: func() *servers.Worker {
|
||||
w := servers.NewWorker(scope.Global.String())
|
||||
w.ScopeId = ""
|
||||
return w
|
||||
},
|
||||
repo: testRepo,
|
||||
wantErr: true,
|
||||
wantErrIs: errors.InvalidParameter,
|
||||
wantErrContains: "missing scope id",
|
||||
},
|
||||
{
|
||||
name: "org-scope-id",
|
||||
setup: func() *servers.Worker {
|
||||
w := servers.NewWorker(org.PublicId)
|
||||
return w
|
||||
},
|
||||
repo: testRepo,
|
||||
wantErr: true,
|
||||
wantErrIs: errors.InvalidParameter,
|
||||
wantErrContains: "scope id must be \"global\"",
|
||||
},
|
||||
{
|
||||
name: "new-id-error",
|
||||
setup: func() *servers.Worker {
|
||||
w := servers.NewWorker(scope.Global.String())
|
||||
return w
|
||||
},
|
||||
repo: testRepo,
|
||||
opt: []servers.Option{servers.WithNewIdFunc(testNewIdFn)},
|
||||
wantErr: true,
|
||||
wantErrIs: errors.Internal,
|
||||
wantErrContains: "testNewIdFn-error",
|
||||
},
|
||||
{
|
||||
name: "create-error",
|
||||
setup: func() *servers.Worker {
|
||||
w := servers.NewWorker(scope.Global.String())
|
||||
return w
|
||||
},
|
||||
repo: func() *servers.Repository {
|
||||
conn, mock := db.TestSetupWithMock(t)
|
||||
writer := db.New(conn)
|
||||
mock.ExpectBegin()
|
||||
mock.ExpectQuery(`INSERT`).WillReturnError(errors.New(testCtx, errors.Internal, "test", "create-error"))
|
||||
mock.ExpectRollback()
|
||||
r, err := servers.NewRepository(rw, writer, kms)
|
||||
require.NoError(t, err)
|
||||
return r
|
||||
}(),
|
||||
wantErr: true,
|
||||
wantErrContains: "unable to create worker",
|
||||
},
|
||||
{
|
||||
name: "success",
|
||||
setup: func() *servers.Worker {
|
||||
w := servers.NewWorker(scope.Global.String())
|
||||
return w
|
||||
},
|
||||
repo: testRepo,
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
testWorker := tc.setup()
|
||||
got, err := tc.repo.CreateWorker(testCtx, testWorker, tc.opt...)
|
||||
if tc.wantErr {
|
||||
require.Error(err)
|
||||
assert.Nil(got)
|
||||
if tc.wantErrIs != errors.Unknown {
|
||||
assert.True(errors.Match(errors.T(tc.wantErrIs), err))
|
||||
}
|
||||
if tc.wantErrContains != "" {
|
||||
assert.Contains(err.Error(), tc.wantErrContains)
|
||||
}
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.NotNil(got)
|
||||
assert.NotEmpty(got.PublicId)
|
||||
assert.NotEmpty(got.UpdateTime)
|
||||
assert.NotEmpty(got.CreateTime)
|
||||
|
||||
found := &servers.Worker{
|
||||
Worker: &store.Worker{
|
||||
PublicId: got.PublicId,
|
||||
},
|
||||
}
|
||||
err = rw.LookupByPublicId(testCtx, found)
|
||||
require.NoError(err)
|
||||
if found.Tags == nil {
|
||||
found.Tags = []*servers.Tag{}
|
||||
}
|
||||
assert.Equal(got, found)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -179,11 +179,11 @@ func TestList(t *testing.T) {
|
||||
require.NoError(err)
|
||||
expected[i] = tcr.Item
|
||||
}
|
||||
filterItem := expected[3]
|
||||
ul, err = tarClient.List(tc.Context(), proj.GetPublicId())
|
||||
require.NoError(err)
|
||||
assert.ElementsMatch(comparableSlice(expected), comparableSlice(ul.Items))
|
||||
|
||||
filterItem := ul.Items[3]
|
||||
ul, err = tarClient.List(tc.Context(), proj.GetPublicId(),
|
||||
targets.WithFilter(fmt.Sprintf(`"/item/id"==%q`, filterItem.Id)))
|
||||
require.NoError(err)
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
8545697b430a432bd50c1bde6a080759f803f157 Add toolbar regions to align refresh button to the right (#1098)
|
||||
698160d423e8fee640d3286c3a3f17434f56a12b
|
||||
# This file determines the version of the UI to embed in the boundary binary.
|
||||
# Update this file by running 'make update-ui-version' from the root of this repo.
|
||||
# Set UI_COMMITISH when running the above target to update to a specific version.
|
||||
Reference in new issue
Block a user