Refactor host_repo -> domain errors (#786)
* Refactor domain errors: New -> E, create helper New and Wrap * Update host repo to use domain errors
This commit is contained in:
1 parent
aa4157639c
commit
ec0020de90
33 files changed
+996
-374
No files matched your search
+3
-2
@@ -17,12 +17,13 @@ func NewPublicId(prefix string) (string, error) {
|
||||
}
|
||||
|
||||
func newId(prefix string) (string, error) {
|
||||
const op = "db.newId"
|
||||
if prefix == "" {
|
||||
return "", fmt.Errorf("missing prefix %w", errors.ErrInvalidParameter)
|
||||
return "", errors.New(errors.InvalidParameter, op, "missing prefix")
|
||||
}
|
||||
publicId, err := base62.Random(10)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("unable to generate id: %w", err)
|
||||
return "", errors.Wrap(err, op, errors.WithMsg("unable to generate id"))
|
||||
}
|
||||
return fmt.Sprintf("%s_%s", prefix, publicId), nil
|
||||
}
|
||||
@@ -21,13 +21,17 @@ const (
|
||||
Unknown Code = 0 // Unknown will be equal to a zero value for Codes
|
||||
|
||||
// General function errors are reserved Codes 100-999
|
||||
InvalidParameter Code = 100 // InvalidParameter represents and invalid parameter for an operation.
|
||||
InvalidParameter Code = 100 // InvalidParameter represents an invalid parameter for an operation.
|
||||
InvalidAddress Code = 101 // InvalidAddress represents an invalid host address for an operation
|
||||
InvalidPublicId Code = 102 // InvalidPublicId represents an invalid public Id for an operation
|
||||
InvalidFieldMask Code = 103 // InvalidFieldMask represents an invalid field mast for an operation
|
||||
EmptyFieldMask Code = 104 // EmptyFieldMask represents an empty field mask for an operation
|
||||
|
||||
// DB errors are resevered Codes from 1000-1999
|
||||
// DB errors are reserved Codes from 1000-1999
|
||||
CheckConstraint Code = 1000 // CheckConstraint represents a check constraint error
|
||||
NotNull Code = 1001 // NotNull represents a value must not be null error
|
||||
NotUnique Code = 1002 // NotUnique represents a value must be unique error
|
||||
NotSpecificIntegrity Code = 1003 // NotSpecificIntegrity represents an integrity error that has no specificy domain error code
|
||||
NotSpecificIntegrity Code = 1003 // NotSpecificIntegrity represents an integrity error that has no specific domain error code
|
||||
MissingTable Code = 1004 // Missing table represents an undefined table error
|
||||
RecordNotFound Code = 1100 // RecordNotFound represents that a record/row was not found matching the criteria
|
||||
MultipleRecords Code = 1101 // MultipleRecords represents that multiple records/rows were found matching the criteria
|
||||
|
||||
@@ -32,6 +32,26 @@ func TestCode_Both_String_Info(t *testing.T) {
|
||||
c: InvalidParameter,
|
||||
want: InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "InvalidAddress",
|
||||
c: InvalidAddress,
|
||||
want: InvalidAddress,
|
||||
},
|
||||
{
|
||||
name: "InvalidPublicId",
|
||||
c: InvalidPublicId,
|
||||
want: InvalidPublicId,
|
||||
},
|
||||
{
|
||||
name: "InvalidFieldMask",
|
||||
c: InvalidFieldMask,
|
||||
want: InvalidFieldMask,
|
||||
},
|
||||
{
|
||||
name: "EmptyFieldMask",
|
||||
c: EmptyFieldMask,
|
||||
want: EmptyFieldMask,
|
||||
},
|
||||
{
|
||||
name: "CheckConstraint",
|
||||
c: CheckConstraint,
|
||||
|
||||
+89
-19
@@ -13,9 +13,8 @@ import (
|
||||
type Op string
|
||||
|
||||
// Err provides the ability to specify a Msg, Op, Code and Wrapped error.
|
||||
// Errs must have a Code and all other fields are optional. We've chosen Err
|
||||
// over Error for the identifier to support the easy embedding of Errs. Errs
|
||||
// can be embedded without a conflict between the embedded Err and Err.Error().
|
||||
// We've chosen Err over Error for the identifier to support the easy embedding of Errs.
|
||||
// Errs can be embedded without a conflict between the embedded Err and Err.Error().
|
||||
type Err struct {
|
||||
// Code is the error's code, which can be used to get the error's
|
||||
// errorCodeInfo, which contains the error's Kind and Message
|
||||
@@ -32,22 +31,85 @@ type Err struct {
|
||||
Wrapped error
|
||||
}
|
||||
|
||||
// New creates a new Err and supports the options of:
|
||||
// WithOp - allows you to specify an optional Op (operation)
|
||||
// WithMsg() - allows you to specify an optional error msg, if the default
|
||||
// E creates a new Err with provided code and supports the options of:
|
||||
//
|
||||
// * WithOp() - allows you to specify an optional Op (operation).
|
||||
//
|
||||
// * WithMsg() - allows you to specify an optional error msg, if the default
|
||||
// msg for the error Code is not sufficient.
|
||||
// WithWrap() - allows you to specify
|
||||
// an error to wrap
|
||||
func New(c Code, opt ...Option) error {
|
||||
//
|
||||
// * WithWrap() - allows you to specify an error to wrap.
|
||||
// If the wrapped error is a boundary domain error, the wrapped error code
|
||||
// will be used as the returned error's code.
|
||||
//
|
||||
// * WithCode() - allows you to specify an optional Code, this code will be prioritized
|
||||
// over a code used from WithWrap().
|
||||
func E(opt ...Option) error {
|
||||
opts := GetOpts(opt...)
|
||||
var code Code
|
||||
|
||||
// check if options includes a wrapped error to take code from
|
||||
var err *Err
|
||||
if As(opts.withErrWrapped, &err) {
|
||||
code = err.Code
|
||||
}
|
||||
|
||||
// if options include withCode prioritize using that code
|
||||
// even if one was set via wrapped error above
|
||||
if opts.withCode != Unknown {
|
||||
code = opts.withCode
|
||||
}
|
||||
|
||||
return &Err{
|
||||
Code: c,
|
||||
Code: code,
|
||||
Op: opts.withOp,
|
||||
Wrapped: opts.withErrWrapped,
|
||||
Msg: opts.withErrMsg,
|
||||
}
|
||||
}
|
||||
|
||||
// New creates a new Err with provided code, op and msg
|
||||
// It supports the options of:
|
||||
//
|
||||
// * WithWrap() - allows you to specify an error to wrap
|
||||
func New(c Code, op Op, msg string, opt ...Option) error {
|
||||
if c != Unknown {
|
||||
opt = append(opt, WithCode(c))
|
||||
}
|
||||
if op != "" {
|
||||
opt = append(opt, WithOp(op))
|
||||
}
|
||||
if msg != "" {
|
||||
opt = append(opt, WithMsg(msg))
|
||||
}
|
||||
|
||||
return E(opt...)
|
||||
}
|
||||
|
||||
// Wrap creates a new Err from the provided err and op,
|
||||
// preserving the code from the originating error.
|
||||
// It supports the options of:
|
||||
//
|
||||
// * WithMsg() - allows you to specify an optional error msg, if the default
|
||||
// msg for the error Code is not sufficient.
|
||||
func Wrap(e error, op Op, opt ...Option) error {
|
||||
if op != "" {
|
||||
opt = append(opt, WithOp(op))
|
||||
}
|
||||
if e != nil {
|
||||
// TODO: once db package has been refactored to only return domain errors,
|
||||
// this convert can be removed
|
||||
err := Convert(e)
|
||||
if err != nil {
|
||||
// wrapped converted error
|
||||
e = err
|
||||
}
|
||||
opt = append(opt, WithWrap(e))
|
||||
}
|
||||
|
||||
return E(opt...)
|
||||
}
|
||||
|
||||
// Convert will convert the error to a Boundary *Err (returning it as an error)
|
||||
// and attempt to add a helpful error msg as well. If that's not possible, it
|
||||
// will return nil
|
||||
@@ -55,7 +117,8 @@ func Convert(e error) *Err {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
if err, ok := e.(*Err); ok {
|
||||
var err *Err
|
||||
if As(e, &err) {
|
||||
return err
|
||||
}
|
||||
var pqError *pq.Error
|
||||
@@ -63,19 +126,19 @@ func Convert(e error) *Err {
|
||||
if pqError.Code.Class() == "23" { // class of integrity constraint violations
|
||||
switch pqError.Code {
|
||||
case "23505": // unique_violation
|
||||
return New(NotUnique, WithMsg(pqError.Detail), WithWrap(ErrNotUnique)).(*Err)
|
||||
return E(WithMsg(pqError.Detail), WithWrap(ErrNotUnique)).(*Err)
|
||||
case "23502": // not_null_violation
|
||||
msg := fmt.Sprintf("%s must not be empty", pqError.Column)
|
||||
return New(NotNull, WithMsg(msg), WithWrap(ErrNotNull)).(*Err)
|
||||
return E(WithMsg(msg), WithWrap(ErrNotNull)).(*Err)
|
||||
case "23514": // check_violation
|
||||
msg := fmt.Sprintf("%s constraint failed", pqError.Constraint)
|
||||
return New(CheckConstraint, WithMsg(msg), WithWrap(ErrCheckConstraint)).(*Err)
|
||||
return E(WithMsg(msg), WithWrap(ErrCheckConstraint)).(*Err)
|
||||
default:
|
||||
return New(NotSpecificIntegrity, WithMsg(pqError.Message)).(*Err)
|
||||
return E(WithCode(NotSpecificIntegrity), WithMsg(pqError.Message)).(*Err)
|
||||
}
|
||||
}
|
||||
if pqError.Code == "42P01" {
|
||||
return New(MissingTable, WithMsg(pqError.Message)).(*Err)
|
||||
return E(WithCode(MissingTable), WithMsg(pqError.Message)).(*Err)
|
||||
}
|
||||
}
|
||||
// unfortunately, we can't help.
|
||||
@@ -104,18 +167,25 @@ func (e *Err) Error() string {
|
||||
join(&s, ": ", e.Msg)
|
||||
}
|
||||
|
||||
if info, ok := errorCodeInfo[e.Code]; ok {
|
||||
var skipInfo bool
|
||||
var wrapped *Err
|
||||
if As(e.Wrapped, &wrapped) {
|
||||
// if wrapped error code is the same as this error, don't print redundant info
|
||||
skipInfo = wrapped.Code == e.Code
|
||||
}
|
||||
|
||||
if info, ok := errorCodeInfo[e.Code]; ok && !skipInfo {
|
||||
if e.Msg == "" {
|
||||
join(&s, ": ", info.Message) // provide a default.
|
||||
join(&s, ", ", info.Kind.String())
|
||||
} else {
|
||||
join(&s, ": ", info.Kind.String())
|
||||
}
|
||||
join(&s, ": ", fmt.Sprintf("error #%d", e.Code))
|
||||
}
|
||||
join(&s, ": ", fmt.Sprintf("error #%d", e.Code))
|
||||
|
||||
if e.Wrapped != nil {
|
||||
join(&s, ": \n", e.Wrapped.Error())
|
||||
join(&s, ": ", e.Wrapped.Error())
|
||||
}
|
||||
return s.String()
|
||||
}
|
||||
|
||||
+231
-16
@@ -3,6 +3,7 @@ package errors_test
|
||||
import (
|
||||
"context"
|
||||
stderrors "errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
@@ -12,18 +13,17 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func Test_NewError(t *testing.T) {
|
||||
func Test_ErrorE(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
code errors.Code
|
||||
opt []errors.Option
|
||||
want error
|
||||
}{
|
||||
{
|
||||
name: "all-options",
|
||||
code: errors.InvalidParameter,
|
||||
opt: []errors.Option{
|
||||
errors.WithCode(errors.InvalidParameter),
|
||||
errors.WithOp("alice.Bob"),
|
||||
errors.WithWrap(errors.ErrRecordNotFound),
|
||||
errors.WithMsg("test msg"),
|
||||
@@ -42,11 +42,204 @@ func Test_NewError(t *testing.T) {
|
||||
Code: errors.Unknown,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "withCode",
|
||||
opt: []errors.Option{
|
||||
errors.WithCode(errors.RecordNotFound),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Code: errors.RecordNotFound,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "uses-wrapped-code",
|
||||
opt: []errors.Option{
|
||||
errors.WithWrap(errors.ErrRecordNotFound),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Code: errors.RecordNotFound,
|
||||
Wrapped: errors.ErrRecordNotFound,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "conflicting-withCode-withWrap",
|
||||
opt: []errors.Option{
|
||||
errors.WithCode(errors.InvalidFieldMask),
|
||||
errors.WithWrap(errors.ErrRecordNotFound),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Code: errors.InvalidFieldMask,
|
||||
Wrapped: errors.ErrRecordNotFound,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
err := errors.New(tt.code, tt.opt...)
|
||||
err := errors.E(tt.opt...)
|
||||
require.Error(err)
|
||||
assert.Equal(tt.want, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_NewError(t *testing.T) {
|
||||
t.Parallel()
|
||||
tests := []struct {
|
||||
name string
|
||||
code errors.Code
|
||||
op errors.Op
|
||||
msg string
|
||||
opt []errors.Option
|
||||
want error
|
||||
}{
|
||||
{
|
||||
name: "all-options",
|
||||
code: errors.InvalidParameter,
|
||||
op: "alice.Bob",
|
||||
msg: "test msg",
|
||||
opt: []errors.Option{
|
||||
errors.WithWrap(errors.ErrRecordNotFound),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Op: "alice.Bob",
|
||||
Wrapped: errors.ErrRecordNotFound,
|
||||
Msg: "test msg",
|
||||
Code: errors.InvalidParameter,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "no-options",
|
||||
opt: nil,
|
||||
want: &errors.Err{
|
||||
Code: errors.Unknown,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "conflicting-op",
|
||||
op: "alice.Bob",
|
||||
opt: []errors.Option{
|
||||
errors.WithOp("bab.Op"),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Op: "alice.Bob",
|
||||
Code: errors.Unknown,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "conflicting-msg",
|
||||
msg: "test msg",
|
||||
opt: []errors.Option{
|
||||
errors.WithMsg("dont use this message"),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Msg: "test msg",
|
||||
Code: errors.Unknown,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
err := errors.New(tt.code, tt.op, tt.msg, tt.opt...)
|
||||
require.Error(err)
|
||||
assert.Equal(tt.want, err)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_WrapError(t *testing.T) {
|
||||
t.Parallel()
|
||||
testErr := errors.E(errors.WithCode(errors.InvalidParameter), errors.WithOp("alice.Bob"), errors.WithMsg("test msg"))
|
||||
tests := []struct {
|
||||
name string
|
||||
opt []errors.Option
|
||||
err error
|
||||
op errors.Op
|
||||
want error
|
||||
}{
|
||||
{
|
||||
name: "boundary-error",
|
||||
err: testErr,
|
||||
op: "alice.Bob",
|
||||
opt: []errors.Option{
|
||||
errors.WithMsg("test msg"),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Wrapped: testErr,
|
||||
Op: "alice.Bob",
|
||||
Msg: "test msg",
|
||||
Code: errors.InvalidParameter,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "boundary-error-no-op",
|
||||
err: testErr,
|
||||
opt: []errors.Option{
|
||||
errors.WithMsg("test msg"),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Wrapped: testErr,
|
||||
Msg: "test msg",
|
||||
Code: errors.InvalidParameter,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "boundary-error-no-options",
|
||||
err: testErr,
|
||||
want: &errors.Err{
|
||||
Wrapped: testErr,
|
||||
Code: errors.InvalidParameter,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "std-error",
|
||||
err: fmt.Errorf("std error"),
|
||||
want: &errors.Err{
|
||||
Wrapped: fmt.Errorf("std error"),
|
||||
Code: errors.Unknown,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "conflicting-with-wrap",
|
||||
err: testErr,
|
||||
opt: []errors.Option{
|
||||
errors.WithWrap(fmt.Errorf("dont wrap this error")),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Wrapped: testErr,
|
||||
Code: errors.InvalidParameter,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "conflicting-with-op",
|
||||
err: testErr,
|
||||
op: "alice.Bob",
|
||||
opt: []errors.Option{
|
||||
errors.WithOp("bad.Op"),
|
||||
},
|
||||
want: &errors.Err{
|
||||
Wrapped: testErr,
|
||||
Op: "alice.Bob",
|
||||
Code: errors.InvalidParameter,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NotSpecificIntegrity",
|
||||
err: &pq.Error{
|
||||
Code: pq.ErrorCode("23001"),
|
||||
Message: "test msg",
|
||||
},
|
||||
want: &errors.Err{
|
||||
Wrapped: errors.E(errors.WithCode(errors.NotSpecificIntegrity), errors.WithMsg("test msg")),
|
||||
Code: errors.NotSpecificIntegrity,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
err := errors.Wrap(tt.err, tt.op, tt.opt...)
|
||||
require.Error(err)
|
||||
assert.Equal(tt.want, err)
|
||||
})
|
||||
@@ -67,12 +260,12 @@ func TestError_Info(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "Unknown",
|
||||
err: errors.New(errors.Unknown).(*errors.Err),
|
||||
err: errors.E().(*errors.Err),
|
||||
want: errors.Unknown,
|
||||
},
|
||||
{
|
||||
name: "InvalidParameter",
|
||||
err: errors.New(errors.InvalidParameter).(*errors.Err),
|
||||
err: errors.E(errors.WithCode(errors.InvalidParameter)).(*errors.Err),
|
||||
want: errors.InvalidParameter,
|
||||
},
|
||||
}
|
||||
@@ -93,24 +286,39 @@ func TestError_Error(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "msg",
|
||||
err: errors.New(errors.Unknown, errors.WithMsg("test msg")),
|
||||
err: errors.E(errors.WithMsg("test msg")),
|
||||
want: "test msg: unknown: error #0",
|
||||
},
|
||||
{
|
||||
name: "code",
|
||||
err: errors.New(errors.CheckConstraint),
|
||||
err: errors.E(errors.WithCode(errors.CheckConstraint)),
|
||||
want: "constraint check failed, integrity violation: error #1000",
|
||||
},
|
||||
{
|
||||
name: "op-msg-and-code",
|
||||
err: errors.New(errors.CheckConstraint, errors.WithOp("alice.bob"), errors.WithMsg("test msg")),
|
||||
err: errors.E(errors.WithCode(errors.CheckConstraint), errors.WithOp("alice.bob"), errors.WithMsg("test msg")),
|
||||
want: "alice.bob: test msg: integrity violation: error #1000",
|
||||
},
|
||||
{
|
||||
name: "unknown",
|
||||
err: errors.New(errors.Unknown),
|
||||
err: errors.E(),
|
||||
want: "unknown, unknown: error #0",
|
||||
},
|
||||
{
|
||||
name: "wrapped-no-code",
|
||||
err: errors.E(errors.WithWrap(errors.E(errors.WithCode(errors.InvalidParameter), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
|
||||
want: "test msg: wrapped msg: parameter violation: error #100",
|
||||
},
|
||||
{
|
||||
name: "wrapped-different-error-codes",
|
||||
err: errors.E(errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.E(errors.WithCode(errors.InvalidParameter), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
|
||||
want: "test msg: integrity violation: error #1000: wrapped msg: parameter violation: error #100",
|
||||
},
|
||||
{
|
||||
name: "wrapped-same-error-codes",
|
||||
err: errors.E(errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.E(errors.WithCode(errors.CheckConstraint), errors.WithMsg("wrapped msg"))), errors.WithMsg("test msg")),
|
||||
want: "test msg: wrapped msg: integrity violation: error #1000",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -129,7 +337,7 @@ func TestError_Error(t *testing.T) {
|
||||
|
||||
func TestError_Unwrap(t *testing.T) {
|
||||
t.Parallel()
|
||||
testErr := errors.New(errors.Unknown, errors.WithMsg("test error"))
|
||||
testErr := errors.E(errors.WithMsg("test error"))
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -139,7 +347,7 @@ func TestError_Unwrap(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "ErrInvalidParameter",
|
||||
err: errors.New(errors.InvalidParameter, errors.WithWrap(errors.ErrInvalidParameter)),
|
||||
err: errors.E(errors.WithWrap(errors.ErrInvalidParameter)),
|
||||
want: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
},
|
||||
@@ -170,6 +378,7 @@ func TestError_Unwrap(t *testing.T) {
|
||||
|
||||
func TestConvertError(t *testing.T) {
|
||||
t.Parallel()
|
||||
testErr := errors.E(errors.WithCode(errors.InvalidParameter), errors.WithOp("alice.Bob"), errors.WithMsg("test msg"))
|
||||
const (
|
||||
createTable = `
|
||||
create table if not exists test_table (
|
||||
@@ -210,7 +419,12 @@ func TestConvertError(t *testing.T) {
|
||||
e: &pq.Error{
|
||||
Code: pq.ErrorCode("23001"),
|
||||
},
|
||||
wantErr: errors.New(errors.NotSpecificIntegrity),
|
||||
wantErr: errors.E(errors.WithCode(errors.NotSpecificIntegrity)),
|
||||
},
|
||||
{
|
||||
name: "convert-domain-error",
|
||||
e: testErr,
|
||||
wantErr: testErr,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -237,7 +451,7 @@ func TestConvertError(t *testing.T) {
|
||||
e := errors.Convert(err)
|
||||
require.NotNil(e)
|
||||
assert.True(errors.Is(e, errors.ErrNotUnique))
|
||||
assert.Equal("Key (name)=(alice) already exists.: integrity violation: error #1002: \nunique constraint violation: integrity violation: error #1002", e.Error())
|
||||
assert.Equal("Key (name)=(alice) already exists.: unique constraint violation: integrity violation: error #1002", e.Error())
|
||||
})
|
||||
t.Run("ErrCodeNotNull", func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
@@ -249,7 +463,7 @@ func TestConvertError(t *testing.T) {
|
||||
e := errors.Convert(err)
|
||||
require.NotNil(e)
|
||||
assert.True(errors.Is(e, errors.ErrNotNull))
|
||||
assert.Equal("description must not be empty: integrity violation: error #1001: \nnot null constraint violated: integrity violation: error #1001", e.Error())
|
||||
assert.Equal("description must not be empty: not null constraint violated: integrity violation: error #1001", e.Error())
|
||||
})
|
||||
t.Run("ErrCodeCheckConstraint", func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
@@ -261,12 +475,13 @@ func TestConvertError(t *testing.T) {
|
||||
e := errors.Convert(err)
|
||||
require.NotNil(e)
|
||||
assert.True(errors.Is(e, errors.ErrCheckConstraint))
|
||||
assert.Equal("test_table_five_check constraint failed: integrity violation: error #1000: \ncheck constraint violated: integrity violation: error #1000", e.Error())
|
||||
assert.Equal("test_table_five_check constraint failed: check constraint violated: integrity violation: error #1000", e.Error())
|
||||
})
|
||||
t.Run("MissingTable", func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
_, err := rw.Exec(ctx, missingTable, nil)
|
||||
require.Error(err)
|
||||
|
||||
e := errors.Convert(err)
|
||||
require.NotNil(e)
|
||||
assert.True(errors.Match(errors.T(errors.MissingTable), e))
|
||||
|
||||
+21
-1
@@ -1,7 +1,11 @@
|
||||
package errors
|
||||
|
||||
// Info contains details of the specific error code
|
||||
type Info struct {
|
||||
Kind Kind
|
||||
// Kind specifies the kind of error (unknown, parameter, integrity, etc).
|
||||
Kind Kind
|
||||
|
||||
// Message provides a default message for the error code
|
||||
Message string
|
||||
}
|
||||
|
||||
@@ -16,6 +20,22 @@ var errorCodeInfo = map[Code]Info{
|
||||
Message: "invalid parameter",
|
||||
Kind: Parameter,
|
||||
},
|
||||
InvalidAddress: {
|
||||
Message: "invalid address",
|
||||
Kind: Parameter,
|
||||
},
|
||||
InvalidPublicId: {
|
||||
Message: "invalid public id",
|
||||
Kind: Parameter,
|
||||
},
|
||||
InvalidFieldMask: {
|
||||
Message: "invalid field mask",
|
||||
Kind: Parameter,
|
||||
},
|
||||
EmptyFieldMask: {
|
||||
Message: "empty field mask",
|
||||
Kind: Parameter,
|
||||
},
|
||||
CheckConstraint: {
|
||||
Message: "constraint check failed",
|
||||
Kind: Integrity,
|
||||
|
||||
@@ -89,3 +89,20 @@ func IsMissingTableError(err error) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsNotFoundError returns a boolean indicating whether the error is known to
|
||||
// report a not found violation.
|
||||
func IsNotFoundError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
var domainErr *Err
|
||||
if errors.As(err, &domainErr) {
|
||||
if domainErr.Code == RecordNotFound {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package errors_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
@@ -44,7 +45,7 @@ func TestError_IsUnique(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "wrapped-pq-is-unique",
|
||||
in: errors.New(errors.NotUnique,
|
||||
in: errors.E(errors.WithCode(errors.NotUnique),
|
||||
errors.WithWrap(&pq.Error{
|
||||
Code: pq.ErrorCode("23505"),
|
||||
}),
|
||||
@@ -56,6 +57,11 @@ func TestError_IsUnique(t *testing.T) {
|
||||
in: errors.ErrRecordNotFound,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "conflicting-wrapped-code",
|
||||
in: errors.E(errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(errors.WithCode(errors.NotUnique)))),
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
@@ -96,12 +102,12 @@ func TestError_IsCheckConstraint(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "ErrCodeCheckConstraint",
|
||||
in: errors.New(errors.CheckConstraint),
|
||||
in: errors.E(errors.WithCode(errors.CheckConstraint)),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "wrapped-pq-is-check-constraint",
|
||||
in: errors.New(errors.CheckConstraint,
|
||||
in: errors.E(errors.WithCode(errors.CheckConstraint),
|
||||
errors.WithWrap(&pq.Error{
|
||||
Code: pq.ErrorCode("23514"),
|
||||
}),
|
||||
@@ -113,6 +119,11 @@ func TestError_IsCheckConstraint(t *testing.T) {
|
||||
in: errors.ErrRecordNotFound,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "conflicting-wrapped-code",
|
||||
in: errors.E(errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(errors.WithCode(errors.CheckConstraint)))),
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
@@ -160,12 +171,12 @@ func TestError_IsNotNullError(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "ErrCodeNotNull",
|
||||
in: errors.New(errors.NotNull),
|
||||
in: errors.E(errors.WithCode(errors.NotNull)),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "wrapped-pq-is-not-null",
|
||||
in: errors.New(errors.NotNull,
|
||||
in: errors.E(errors.WithCode(errors.NotNull),
|
||||
errors.WithWrap(&pq.Error{
|
||||
Code: pq.ErrorCode("23502"),
|
||||
}),
|
||||
@@ -177,6 +188,11 @@ func TestError_IsNotNullError(t *testing.T) {
|
||||
in: errors.ErrRecordNotFound,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "conflicting-wrapped-code",
|
||||
in: errors.E(errors.WithCode(errors.CheckConstraint), errors.WithWrap(errors.E(errors.WithCode(errors.NotNull)))),
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
@@ -240,3 +256,46 @@ func TestError_IsMissingTableError(t *testing.T) {
|
||||
assert.True(errors.IsMissingTableError(err))
|
||||
})
|
||||
}
|
||||
|
||||
func TestError_IsNotFoundError(t *testing.T) {
|
||||
var tests = []struct {
|
||||
name string
|
||||
in error
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
name: "nil-error",
|
||||
in: nil,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "not-found-error",
|
||||
in: errors.E(errors.WithCode(errors.RecordNotFound)),
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "sentinel-not-found",
|
||||
in: errors.ErrRecordNotFound,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
name: "std-err",
|
||||
in: fmt.Errorf("std error"),
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
name: "conflicting-wrapped-code",
|
||||
in: errors.E(errors.WithCode(errors.NotNull), errors.WithWrap(errors.E(errors.WithCode(errors.RecordNotFound)))),
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
tt := tt
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
err := tt.in
|
||||
got := errors.IsNotFoundError(err)
|
||||
assert.Equal(tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -149,7 +149,7 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "nil template",
|
||||
template: nil,
|
||||
err: New(NotUnique, WithMsg("this thing was must be unique")),
|
||||
err: E(WithCode(NotUnique), WithMsg("this thing was must be unique")),
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
@@ -161,8 +161,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "match on Kind only",
|
||||
template: T(Integrity),
|
||||
err: New(
|
||||
NotUnique,
|
||||
err: E(
|
||||
WithCode(NotUnique),
|
||||
WithMsg("this thing must be unique"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -172,8 +172,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "no match on Kind only",
|
||||
template: T(Integrity),
|
||||
err: New(
|
||||
RecordNotFound,
|
||||
err: E(
|
||||
WithCode(RecordNotFound),
|
||||
WithMsg("this thing is missing"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -183,8 +183,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "match on Code only",
|
||||
template: T(NotUnique),
|
||||
err: New(
|
||||
NotUnique,
|
||||
err: E(
|
||||
WithCode(NotUnique),
|
||||
WithMsg("this thing must be unique"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -194,8 +194,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "no match on Code only",
|
||||
template: T(NotUnique),
|
||||
err: New(
|
||||
RecordNotFound,
|
||||
err: E(
|
||||
WithCode(RecordNotFound),
|
||||
WithMsg("this thing is missing"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -205,8 +205,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "match on Op only",
|
||||
template: T(Op("alice.Bob")),
|
||||
err: New(
|
||||
NotUnique,
|
||||
err: E(
|
||||
WithCode(NotUnique),
|
||||
WithMsg("this thing must be unique"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -216,8 +216,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "no match on Op only",
|
||||
template: T(Op("alice.Alice")),
|
||||
err: New(
|
||||
RecordNotFound,
|
||||
err: E(
|
||||
WithCode(RecordNotFound),
|
||||
WithMsg("this thing is missing"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -233,8 +233,8 @@ func TestMatch(t *testing.T) {
|
||||
ErrInvalidFieldMask,
|
||||
Op("alice.Bob"),
|
||||
),
|
||||
err: New(
|
||||
InvalidParameter,
|
||||
err: E(
|
||||
WithCode(InvalidParameter),
|
||||
WithMsg("this thing must be unique"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -244,8 +244,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "match on Wrapped only",
|
||||
template: T(ErrInvalidFieldMask),
|
||||
err: New(
|
||||
NotUnique,
|
||||
err: E(
|
||||
WithCode(NotUnique),
|
||||
WithMsg("this thing must be unique"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -255,8 +255,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "no match on Wrapped only",
|
||||
template: T(ErrNotUnique),
|
||||
err: New(
|
||||
RecordNotFound,
|
||||
err: E(
|
||||
WithCode(RecordNotFound),
|
||||
WithMsg("this thing is missing"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(ErrInvalidFieldMask),
|
||||
@@ -266,8 +266,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "match on Wrapped only stderror",
|
||||
template: T(stdErr),
|
||||
err: New(
|
||||
NotUnique,
|
||||
err: E(
|
||||
WithCode(NotUnique),
|
||||
WithMsg("this thing must be unique"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(stdErr),
|
||||
@@ -277,8 +277,8 @@ func TestMatch(t *testing.T) {
|
||||
{
|
||||
name: "no match on Wrapped only stderror",
|
||||
template: T(stderrors.New("no match")),
|
||||
err: New(
|
||||
RecordNotFound,
|
||||
err: E(
|
||||
WithCode(RecordNotFound),
|
||||
WithMsg("this thing is missing"),
|
||||
WithOp("alice.Bob"),
|
||||
WithWrap(stdErr),
|
||||
|
||||
@@ -14,6 +14,7 @@ type Option func(*Options)
|
||||
|
||||
// Options - how Options are represented.
|
||||
type Options struct {
|
||||
withCode Code
|
||||
withErrWrapped error
|
||||
withErrMsg string
|
||||
withOp Op
|
||||
@@ -46,3 +47,11 @@ func WithOp(op Op) Option {
|
||||
o.withOp = op
|
||||
}
|
||||
}
|
||||
|
||||
// WithCode provides an option to provide a code when creating a new
|
||||
// error.
|
||||
func WithCode(code Code) Option {
|
||||
return func(o *Options) {
|
||||
o.withCode = code
|
||||
}
|
||||
}
|
||||
@@ -48,4 +48,17 @@ func Test_getOpts(t *testing.T) {
|
||||
testOpts.withOp = "alice.bob"
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
t.Run("WithCode", func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
// test default
|
||||
opts := GetOpts()
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withOp = ""
|
||||
assert.Equal(opts, testOpts)
|
||||
|
||||
// try setting it
|
||||
opts = GetOpts(WithCode(NotUnique))
|
||||
testOpts.withCode = NotUnique
|
||||
assert.Equal(opts, testOpts)
|
||||
})
|
||||
}
|
||||
@@ -6,39 +6,39 @@ package errors
|
||||
// Matching function.
|
||||
var (
|
||||
// ErrInvalidPublicId indicates an invalid PublicId.
|
||||
ErrInvalidPublicId = New(InvalidParameter, WithMsg("invalid publicId"))
|
||||
ErrInvalidPublicId = E(WithCode(InvalidParameter), WithMsg("invalid publicId"))
|
||||
|
||||
// ErrInvalidParameter is returned by create and update methods if
|
||||
// an attribute on a struct contains illegal or invalid values.
|
||||
ErrInvalidParameter = New(InvalidParameter, WithMsg("invalid parameter"))
|
||||
ErrInvalidParameter = E(WithCode(InvalidParameter), WithMsg("invalid parameter"))
|
||||
|
||||
// ErrInvalidFieldMask is returned by update methods if the field mask
|
||||
// contains unknown fields or fields that cannot be updated.
|
||||
ErrInvalidFieldMask = New(InvalidParameter, WithMsg("invalid field mask"))
|
||||
ErrInvalidFieldMask = E(WithCode(InvalidParameter), WithMsg("invalid field mask"))
|
||||
|
||||
// ErrEmptyFieldMask is returned by update methods if the field mask is
|
||||
// empty.
|
||||
ErrEmptyFieldMask = New(InvalidParameter, WithMsg("empty field mask"))
|
||||
ErrEmptyFieldMask = E(WithCode(InvalidParameter), WithMsg("empty field mask"))
|
||||
|
||||
// ErrNotUnique is returned by create and update methods when a write
|
||||
// to the repository resulted in a unique constraint violation.
|
||||
ErrNotUnique = New(NotUnique, WithMsg("unique constraint violation"))
|
||||
ErrNotUnique = E(WithCode(NotUnique), WithMsg("unique constraint violation"))
|
||||
|
||||
// ErrNotNull is returned by methods when a write to the repository resulted
|
||||
// in a check constraint violation
|
||||
ErrCheckConstraint = New(CheckConstraint, WithMsg("check constraint violated"))
|
||||
ErrCheckConstraint = E(WithCode(CheckConstraint), WithMsg("check constraint violated"))
|
||||
|
||||
// ErrNotNull is returned by methods when a write to the repository resulted
|
||||
// in a not null constraint violation
|
||||
ErrNotNull = New(NotNull, WithMsg("not null constraint violated"))
|
||||
ErrNotNull = E(WithCode(NotNull), WithMsg("not null constraint violated"))
|
||||
|
||||
// ErrRecordNotFound returns a "record not found" error and it only occurs
|
||||
// when attempting to read from the database into struct.
|
||||
// When reading into a slice it won't return this error.
|
||||
ErrRecordNotFound = New(RecordNotFound, WithMsg("record not found"))
|
||||
ErrRecordNotFound = E(WithCode(RecordNotFound), WithMsg("record not found"))
|
||||
|
||||
// ErrMultipleRecords is returned by update and delete methods when a
|
||||
// write to the repository would result in more than one record being
|
||||
// changed resulting in the transaction being rolled back.
|
||||
ErrMultipleRecords = New(MultipleRecords, WithMsg("multiple records"))
|
||||
ErrMultipleRecords = E(WithCode(MultipleRecords), WithMsg("multiple records"))
|
||||
)
|
||||
@@ -1,9 +0,0 @@
|
||||
package static
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
// ErrInvalidAddress results from attempting to perform an operation
|
||||
// that sets an address on a host to an invalid value.
|
||||
ErrInvalidAddress = errors.New("invalid address")
|
||||
)
|
||||
@@ -1,8 +1,6 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/host/static/store"
|
||||
"github.com/hashicorp/boundary/internal/oplog"
|
||||
@@ -25,7 +23,7 @@ type Host struct {
|
||||
// ignored.
|
||||
func NewHost(catalogId string, opt ...Option) (*Host, error) {
|
||||
if catalogId == "" {
|
||||
return nil, fmt.Errorf("new: static host: no catalog id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, "static.NewHost", "no catalog id")
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/host/static/store"
|
||||
"github.com/hashicorp/boundary/internal/oplog"
|
||||
@@ -21,7 +19,7 @@ type HostCatalog struct {
|
||||
// ignored.
|
||||
func NewHostCatalog(scopeId string, opt ...Option) (*HostCatalog, error) {
|
||||
if scopeId == "" {
|
||||
return nil, fmt.Errorf("new: static host catalog: no scope id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, "static.NewHostCatalog", "no scope id")
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/host/static/store"
|
||||
"github.com/hashicorp/boundary/internal/oplog"
|
||||
@@ -20,7 +18,7 @@ type HostSet struct {
|
||||
// ignored.
|
||||
func NewHostSet(catalogId string, opt ...Option) (*HostSet, error) {
|
||||
if catalogId == "" {
|
||||
return nil, fmt.Errorf("new: static host set: no catalog id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, "static.NewHostSet", "no catalog id")
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/host/static/store"
|
||||
)
|
||||
@@ -16,11 +14,12 @@ type HostSetMember struct {
|
||||
// NewHostSetMember creates a new in memory HostSetMember representing the
|
||||
// membership of hostId in hostSetId.
|
||||
func NewHostSetMember(hostSetId, hostId string, opt ...Option) (*HostSetMember, error) {
|
||||
const op = "static.NewHostSetMember"
|
||||
if hostSetId == "" {
|
||||
return nil, fmt.Errorf("new: static host set member: no host set id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no host set id")
|
||||
}
|
||||
if hostId == "" {
|
||||
return nil, fmt.Errorf("new: static host set member: no host id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no host id")
|
||||
}
|
||||
member := &HostSetMember{
|
||||
HostSetMember: &store.HostSetMember{
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
)
|
||||
|
||||
// PublicId prefixes for the resources in the static package.
|
||||
@@ -16,7 +15,7 @@ const (
|
||||
func newHostCatalogId() (string, error) {
|
||||
id, err := db.NewPublicId(HostCatalogPrefix)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("new host catalog id: %w", err)
|
||||
return "", errors.Wrap(err, "static.newHostCatalogId")
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
@@ -24,7 +23,7 @@ func newHostCatalogId() (string, error) {
|
||||
func newHostId() (string, error) {
|
||||
id, err := db.NewPublicId(HostPrefix)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("new host id: %w", err)
|
||||
return "", errors.Wrap(err, "static.newHostId")
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
@@ -32,7 +31,7 @@ func newHostId() (string, error) {
|
||||
func newHostSetId() (string, error) {
|
||||
id, err := db.NewPublicId(HostSetPrefix)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("new host set id: %w", err)
|
||||
return "", errors.Wrap(err, "static.newHostSetId")
|
||||
}
|
||||
return id, err
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/db"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
"github.com/hashicorp/boundary/internal/kms"
|
||||
@@ -25,13 +23,14 @@ type Repository struct {
|
||||
// limit applied to all ListX methods.
|
||||
// routines to access it.
|
||||
func NewRepository(r db.Reader, w db.Writer, kms *kms.Kms, opt ...Option) (*Repository, error) {
|
||||
const op = "static.NewRepository"
|
||||
switch {
|
||||
case r == nil:
|
||||
return nil, fmt.Errorf("db.Reader: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "db.Reader")
|
||||
case w == nil:
|
||||
return nil, fmt.Errorf("db.Writer: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "db.Writer")
|
||||
case kms == nil:
|
||||
return nil, fmt.Errorf("kms: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "kms")
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
|
||||
@@ -22,24 +22,25 @@ import (
|
||||
// Both h.Name and h.Description are optional. If h.Name is set, it must be
|
||||
// unique within h.CatalogId.
|
||||
func (r *Repository) CreateHost(ctx context.Context, scopeId string, h *Host, opt ...Option) (*Host, error) {
|
||||
const op = "static.CreateHost"
|
||||
if h == nil {
|
||||
return nil, fmt.Errorf("create: static host: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "nil Host")
|
||||
}
|
||||
if h.Host == nil {
|
||||
return nil, fmt.Errorf("create: static host: embedded Host: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "nil embedded Host")
|
||||
}
|
||||
if h.CatalogId == "" {
|
||||
return nil, fmt.Errorf("create: static host: no catalog id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no catalog id")
|
||||
}
|
||||
if h.PublicId != "" {
|
||||
return nil, fmt.Errorf("create: static host: public id not empty: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "public id not empty")
|
||||
}
|
||||
if scopeId == "" {
|
||||
return nil, fmt.Errorf("create: static host: no scopeId: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
h.Address = strings.TrimSpace(h.Address)
|
||||
if len(h.Address) < MinHostAddressLength || len(h.Address) > MaxHostAddressLength {
|
||||
return nil, fmt.Errorf("create: static host: bad address: %w", ErrInvalidAddress)
|
||||
return nil, errors.New(errors.InvalidAddress, op, "invalid address")
|
||||
}
|
||||
h = h.clone()
|
||||
|
||||
@@ -47,20 +48,24 @@ func (r *Repository) CreateHost(ctx context.Context, scopeId string, h *Host, op
|
||||
|
||||
if opts.withPublicId != "" {
|
||||
if !strings.HasPrefix(opts.withPublicId, HostPrefix+"_") {
|
||||
return nil, fmt.Errorf("create: static host: passed-in public ID %q has wrong prefix, should be %q: %w", opts.withPublicId, HostPrefix, errors.ErrInvalidPublicId)
|
||||
return nil, errors.New(
|
||||
errors.InvalidPublicId,
|
||||
op,
|
||||
fmt.Sprintf("passed-in public ID %q has wrong prefix, should be %q", opts.withPublicId, HostPrefix),
|
||||
)
|
||||
}
|
||||
h.PublicId = opts.withPublicId
|
||||
} else {
|
||||
id, err := newHostId()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create: static host: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
h.PublicId = id
|
||||
}
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create: static host: unable to get oplog wrapper: %w", err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var newHost *Host
|
||||
@@ -73,14 +78,17 @@ func (r *Repository) CreateHost(ctx context.Context, scopeId string, h *Host, op
|
||||
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) {
|
||||
return nil, fmt.Errorf("create: static host: in catalog: %s: name %s already exists: %w",
|
||||
h.CatalogId, h.Name, errors.ErrNotUnique)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in catalog: %s: name %s already exists", h.CatalogId, h.Name)))
|
||||
}
|
||||
if errors.IsCheckConstraintError(err) || errors.IsNotNullError(err) {
|
||||
return nil, fmt.Errorf("create: static host: in catalog: %s: %q: %w",
|
||||
h.CatalogId, h.Address, ErrInvalidAddress)
|
||||
return nil, errors.New(
|
||||
errors.InvalidAddress,
|
||||
op,
|
||||
fmt.Sprintf("in catalog: %s: %q", h.CatalogId, h.Address),
|
||||
errors.WithWrap(err),
|
||||
)
|
||||
}
|
||||
return nil, fmt.Errorf("create: static host: in catalog: %s: %w", h.CatalogId, err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in catalog: %s", h.CatalogId)))
|
||||
}
|
||||
return newHost, nil
|
||||
}
|
||||
@@ -98,20 +106,21 @@ func (r *Repository) CreateHost(ctx context.Context, scopeId string, h *Host, op
|
||||
// An attribute of h will be set to NULL in the database if the attribute
|
||||
// in h is the zero value and it is included in fieldMaskPaths.
|
||||
func (r *Repository) UpdateHost(ctx context.Context, scopeId string, h *Host, version uint32, fieldMaskPaths []string, opt ...Option) (*Host, int, error) {
|
||||
const op = "static.UpdateHost"
|
||||
if h == nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "nil Host")
|
||||
}
|
||||
if h.Host == nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: embedded Host: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "nil embedded Host")
|
||||
}
|
||||
if h.PublicId == "" {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: missing public id: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
if version == 0 {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: no version supplied: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no version")
|
||||
}
|
||||
if scopeId == "" {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: no scopeId: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
|
||||
for _, f := range fieldMaskPaths {
|
||||
@@ -121,10 +130,10 @@ func (r *Repository) UpdateHost(ctx context.Context, scopeId string, h *Host, ve
|
||||
case strings.EqualFold("Address", f):
|
||||
h.Address = strings.TrimSpace(h.Address)
|
||||
if len(h.Address) < MinHostAddressLength || len(h.Address) > MaxHostAddressLength {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: bad address: %w", ErrInvalidAddress)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidAddress, op, "invalid address")
|
||||
}
|
||||
default:
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: field: %s: %w", f, errors.ErrInvalidFieldMask)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, fmt.Sprintf("field: %s", f))
|
||||
}
|
||||
}
|
||||
var dbMask, nullFields []string
|
||||
@@ -138,12 +147,12 @@ func (r *Repository) UpdateHost(ctx context.Context, scopeId string, h *Host, ve
|
||||
nil,
|
||||
)
|
||||
if len(dbMask) == 0 && len(nullFields) == 0 {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: %w", errors.ErrEmptyFieldMask)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "empty field mask")
|
||||
}
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: unable to get oplog wrapper: %w", err)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var rowsUpdated int
|
||||
@@ -156,7 +165,7 @@ func (r *Repository) UpdateHost(ctx context.Context, scopeId string, h *Host, ve
|
||||
db.WithOplog(oplogWrapper, h.oplog(oplog.OpType_OP_TYPE_UPDATE)),
|
||||
db.WithVersion(&version))
|
||||
if err == nil && rowsUpdated > 1 {
|
||||
return errors.ErrMultipleRecords
|
||||
return errors.E(errors.WithCode(errors.MultipleRecords))
|
||||
}
|
||||
return err
|
||||
},
|
||||
@@ -164,13 +173,17 @@ func (r *Repository) UpdateHost(ctx context.Context, scopeId string, h *Host, ve
|
||||
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: %s: name %s already exists: %w",
|
||||
h.PublicId, h.Name, errors.ErrNotUnique)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in %s: name %s already exists", h.PublicId, h.Name)))
|
||||
}
|
||||
if errors.IsCheckConstraintError(err) || errors.IsNotNullError(err) {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: %s: %q: %w", h.PublicId, h.Address, ErrInvalidAddress)
|
||||
return nil, db.NoRowsAffected, errors.New(
|
||||
errors.InvalidAddress,
|
||||
op,
|
||||
fmt.Sprintf("in %s: %q", h.PublicId, h.Address),
|
||||
errors.WithWrap(err),
|
||||
)
|
||||
}
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host: %s: %w", h.PublicId, err)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in %s", h.PublicId)))
|
||||
}
|
||||
|
||||
return returnedHost, rowsUpdated, nil
|
||||
@@ -179,16 +192,17 @@ func (r *Repository) UpdateHost(ctx context.Context, scopeId string, h *Host, ve
|
||||
// LookupHost will look up a host in the repository. If the host is not
|
||||
// found, it will return nil, nil. All options are ignored.
|
||||
func (r *Repository) LookupHost(ctx context.Context, publicId string, opt ...Option) (*Host, error) {
|
||||
const op = "static.LookupHost"
|
||||
if publicId == "" {
|
||||
return nil, fmt.Errorf("lookup: static host: missing public id %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
h := allocHost()
|
||||
h.PublicId = publicId
|
||||
if err := r.reader.LookupByPublicId(ctx, h); err != nil {
|
||||
if errors.Is(err, errors.ErrRecordNotFound) {
|
||||
if errors.IsNotFoundError(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("lookup: static host: failed %w for %s", err, publicId)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for %s", publicId)))
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
@@ -196,8 +210,9 @@ func (r *Repository) LookupHost(ctx context.Context, publicId string, opt ...Opt
|
||||
// ListHosts returns a slice of Hosts for the catalogId.
|
||||
// WithLimit is the only option supported.
|
||||
func (r *Repository) ListHosts(ctx context.Context, catalogId string, opt ...Option) ([]*Host, error) {
|
||||
const op = "static.ListHosts"
|
||||
if catalogId == "" {
|
||||
return nil, fmt.Errorf("list: static host: missing catalog id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no catalog id")
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
limit := r.defaultLimit
|
||||
@@ -208,7 +223,7 @@ func (r *Repository) ListHosts(ctx context.Context, catalogId string, opt ...Opt
|
||||
var hosts []*Host
|
||||
err := r.reader.SearchWhere(ctx, &hosts, "catalog_id = ?", []interface{}{catalogId}, db.WithLimit(limit))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list: static host: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
return hosts, nil
|
||||
}
|
||||
@@ -217,15 +232,16 @@ func (r *Repository) ListHosts(ctx context.Context, catalogId string, opt ...Opt
|
||||
// returning a count of the number of records deleted. All options are
|
||||
// ignored.
|
||||
func (r *Repository) DeleteHost(ctx context.Context, scopeId string, publicId string, opt ...Option) (int, error) {
|
||||
const op = "static.DeleteHost"
|
||||
if publicId == "" {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host: missing public id: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
h := allocHost()
|
||||
h.PublicId = publicId
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host catalog: unable to get oplog wrapper: %w", err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var rowsDeleted int
|
||||
@@ -235,14 +251,14 @@ func (r *Repository) DeleteHost(ctx context.Context, scopeId string, publicId st
|
||||
dh := h.clone()
|
||||
rowsDeleted, err = w.Delete(ctx, dh, db.WithOplog(oplogWrapper, h.oplog(oplog.OpType_OP_TYPE_DELETE)))
|
||||
if err == nil && rowsDeleted > 1 {
|
||||
return errors.ErrMultipleRecords
|
||||
return errors.E(errors.WithCode(errors.MultipleRecords))
|
||||
}
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host: %s: %w", publicId, err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("delete failed for %s", publicId)))
|
||||
}
|
||||
|
||||
return rowsDeleted, nil
|
||||
|
||||
@@ -21,17 +21,18 @@ import (
|
||||
//
|
||||
// Both c.CreateTime and c.UpdateTime are ignored.
|
||||
func (r *Repository) CreateCatalog(ctx context.Context, c *HostCatalog, opt ...Option) (*HostCatalog, error) {
|
||||
const op = "static.CreateCatalog"
|
||||
if c == nil {
|
||||
return nil, fmt.Errorf("create: static host catalog: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "nil HostCatalog")
|
||||
}
|
||||
if c.HostCatalog == nil {
|
||||
return nil, fmt.Errorf("create: static host catalog: embedded HostCatalog: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "nil embedded HostCatalog")
|
||||
}
|
||||
if c.ScopeId == "" {
|
||||
return nil, fmt.Errorf("create: static host catalog: no scope id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
if c.PublicId != "" {
|
||||
return nil, fmt.Errorf("create: static host catalog: public id not empty: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "public id not empty")
|
||||
}
|
||||
c = c.clone()
|
||||
|
||||
@@ -39,20 +40,24 @@ func (r *Repository) CreateCatalog(ctx context.Context, c *HostCatalog, opt ...O
|
||||
|
||||
if opts.withPublicId != "" {
|
||||
if !strings.HasPrefix(opts.withPublicId, HostCatalogPrefix+"_") {
|
||||
return nil, fmt.Errorf("create: static host catalog: passed-in public ID %q has wrong prefix, should be %q: %w", opts.withPublicId, HostCatalogPrefix, errors.ErrInvalidPublicId)
|
||||
return nil, errors.New(
|
||||
errors.InvalidPublicId,
|
||||
op,
|
||||
fmt.Sprintf("passed-in public ID %q has wrong prefix, should be %q", opts.withPublicId, HostCatalogPrefix),
|
||||
)
|
||||
}
|
||||
c.PublicId = opts.withPublicId
|
||||
} else {
|
||||
id, err := newHostCatalogId()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create: static host catalog: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
c.PublicId = id
|
||||
}
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, c.ScopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create: static host catalog: unable to get oplog wrapper: %w", err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
metadata := newCatalogMetadata(c, oplog.OpType_OP_TYPE_CREATE)
|
||||
@@ -74,10 +79,9 @@ func (r *Repository) CreateCatalog(ctx context.Context, c *HostCatalog, opt ...O
|
||||
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) {
|
||||
return nil, fmt.Errorf("create: static host catalog: in scope: %s: name %s already exists: %w",
|
||||
c.ScopeId, c.Name, errors.ErrNotUnique)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in scope: %s: name %s already exists", c.ScopeId, c.Name)))
|
||||
}
|
||||
return nil, fmt.Errorf("create: static host catalog: in scope: %s: %w", c.ScopeId, err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in scope: %s", c.ScopeId)))
|
||||
}
|
||||
return newHostCatalog, nil
|
||||
}
|
||||
@@ -94,20 +98,21 @@ func (r *Repository) CreateCatalog(ctx context.Context, c *HostCatalog, opt ...O
|
||||
// An attribute of c will be set to NULL in the database if the attribute
|
||||
// in c is the zero value and it is included in fieldMask.
|
||||
func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version uint32, fieldMask []string, opt ...Option) (*HostCatalog, int, error) {
|
||||
const op = "static.UpdateCatalog"
|
||||
if c == nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "nil HostCatalog")
|
||||
}
|
||||
if c.HostCatalog == nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: embedded HostCatalog: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "nil embedded HostCatalog")
|
||||
}
|
||||
if c.PublicId == "" {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: missing public id: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
if c.ScopeId == "" {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: missing scope id: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
if len(fieldMask) == 0 {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: %w", errors.ErrEmptyFieldMask)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "empty field mask")
|
||||
}
|
||||
|
||||
var dbMask, nullFields []string
|
||||
@@ -123,13 +128,13 @@ func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version
|
||||
dbMask = append(dbMask, "description")
|
||||
|
||||
default:
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: field: %s: %w", f, errors.ErrInvalidFieldMask)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, fmt.Sprintf("field: %s", f))
|
||||
}
|
||||
}
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, c.ScopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: unable to get oplog wrapper: %w", err)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
c = c.clone()
|
||||
@@ -154,7 +159,7 @@ func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version
|
||||
db.WithVersion(&version),
|
||||
)
|
||||
if err == nil && rowsUpdated > 1 {
|
||||
return errors.ErrMultipleRecords
|
||||
return errors.E(errors.WithCode(errors.MultipleRecords))
|
||||
}
|
||||
return err
|
||||
},
|
||||
@@ -162,10 +167,9 @@ func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version
|
||||
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: %s: name %s already exists: %w",
|
||||
c.PublicId, c.Name, errors.ErrNotUnique)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in %s: name %s already exists", c.PublicId, c.Name)))
|
||||
}
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("update: static host catalog: %s: %w", c.PublicId, err)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in %s", c.PublicId)))
|
||||
}
|
||||
|
||||
return returnedCatalog, rowsUpdated, nil
|
||||
@@ -174,24 +178,26 @@ func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version
|
||||
// LookupCatalog returns the HostCatalog for id. Returns nil, nil if no
|
||||
// HostCatalog is found for id.
|
||||
func (r *Repository) LookupCatalog(ctx context.Context, id string, opt ...Option) (*HostCatalog, error) {
|
||||
const op = "static.LookupCatalog"
|
||||
if id == "" {
|
||||
return nil, fmt.Errorf("lookup: static host catalog: missing public id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
c := allocCatalog()
|
||||
c.PublicId = id
|
||||
if err := r.reader.LookupByPublicId(ctx, c); err != nil {
|
||||
if err == errors.ErrRecordNotFound {
|
||||
if errors.IsNotFoundError(err) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("lookup: static host catalog: %s: %w", id, err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for: %s", id)))
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// ListCatalogs returns a slice of HostCatalogs for the scopeId. WithLimit is the only option supported.
|
||||
func (r *Repository) ListCatalogs(ctx context.Context, scopeId string, opt ...Option) ([]*HostCatalog, error) {
|
||||
const op = "static.ListCatalogs"
|
||||
if scopeId == "" {
|
||||
return nil, fmt.Errorf("list: static host catalog: missing scope id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
limit := r.defaultLimit
|
||||
@@ -202,7 +208,7 @@ func (r *Repository) ListCatalogs(ctx context.Context, scopeId string, opt ...Op
|
||||
var hostCatalogs []*HostCatalog
|
||||
err := r.reader.SearchWhere(ctx, &hostCatalogs, "scope_id = ?", []interface{}{scopeId}, db.WithLimit(limit))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list: static host catalog: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
return hostCatalogs, nil
|
||||
}
|
||||
@@ -210,24 +216,25 @@ func (r *Repository) ListCatalogs(ctx context.Context, scopeId string, opt ...Op
|
||||
// DeleteCatalog deletes id from the repository returning a count of the
|
||||
// number of records deleted.
|
||||
func (r *Repository) DeleteCatalog(ctx context.Context, id string, opt ...Option) (int, error) {
|
||||
const op = "static.DeleteCatalog"
|
||||
if id == "" {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host catalog: missing public id: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
|
||||
c := allocCatalog()
|
||||
c.PublicId = id
|
||||
if err := r.reader.LookupByPublicId(ctx, c); err != nil {
|
||||
if errors.Is(err, errors.ErrRecordNotFound) {
|
||||
if errors.IsNotFoundError(err) {
|
||||
return db.NoRowsAffected, nil
|
||||
}
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host catalog: failed %w for %s", err, id)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("failed for %s", id)))
|
||||
}
|
||||
if c.ScopeId == "" {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host catalog: missing scope id: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, c.ScopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host catalog: unable to get oplog wrapper: %w", err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
metadata := newCatalogMetadata(c, oplog.OpType_OP_TYPE_DELETE)
|
||||
@@ -247,14 +254,14 @@ func (r *Repository) DeleteCatalog(ctx context.Context, id string, opt ...Option
|
||||
db.WithOplog(oplogWrapper, metadata),
|
||||
)
|
||||
if err == nil && rowsDeleted > 1 {
|
||||
return errors.ErrMultipleRecords
|
||||
return errors.E(errors.WithCode(errors.MultipleRecords))
|
||||
}
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host catalog: %s: %w", c.PublicId, err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("delete failed for %s", c.PublicId)))
|
||||
}
|
||||
|
||||
return rowsDeleted, nil
|
||||
|
||||
@@ -25,16 +25,16 @@ func TestRepository_CreateCatalog(t *testing.T) {
|
||||
in *HostCatalog
|
||||
opts []Option
|
||||
want *HostCatalog
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "nil-catalog",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "nil-embedded-catalog",
|
||||
in: &HostCatalog{},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "valid-no-options",
|
||||
@@ -87,8 +87,8 @@ func TestRepository_CreateCatalog(t *testing.T) {
|
||||
assert.Empty(tt.in.PublicId)
|
||||
}
|
||||
got, err := repo.CreateCatalog(context.Background(), tt.in, tt.opts...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
return
|
||||
}
|
||||
@@ -236,7 +236,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
masks []string
|
||||
want *HostCatalog
|
||||
wantCount int
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "nil-catalog",
|
||||
@@ -245,7 +245,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
},
|
||||
chgFn: makeNil(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "nil-embedded-catalog",
|
||||
@@ -254,7 +254,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
},
|
||||
chgFn: makeEmbeddedNil(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "no-public-id",
|
||||
@@ -263,7 +263,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
},
|
||||
chgFn: deletePublicId(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "updating-non-existent-catalog",
|
||||
@@ -274,7 +274,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
},
|
||||
chgFn: combine(nonExistentPublicId(), changeName("test-update-name-repo")),
|
||||
masks: []string{"Name"},
|
||||
wantIsErr: errors.ErrRecordNotFound,
|
||||
wantIsErr: errors.RecordNotFound,
|
||||
},
|
||||
{
|
||||
name: "empty-field-mask",
|
||||
@@ -284,7 +284,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
},
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
wantIsErr: errors.ErrEmptyFieldMask,
|
||||
wantIsErr: errors.EmptyFieldMask,
|
||||
},
|
||||
{
|
||||
name: "read-only-fields-in-field-mask",
|
||||
@@ -295,7 +295,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
masks: []string{"PublicId", "CreateTime", "UpdateTime", "ScopeId"},
|
||||
wantIsErr: errors.ErrInvalidFieldMask,
|
||||
wantIsErr: errors.InvalidFieldMask,
|
||||
},
|
||||
{
|
||||
name: "unknown-field-in-field-mask",
|
||||
@@ -306,7 +306,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
masks: []string{"Bilbo"},
|
||||
wantIsErr: errors.ErrInvalidFieldMask,
|
||||
wantIsErr: errors.InvalidFieldMask,
|
||||
},
|
||||
{
|
||||
name: "change-name",
|
||||
@@ -448,8 +448,8 @@ func TestRepository_UpdateCatalog(t *testing.T) {
|
||||
orig = tt.chgFn(orig)
|
||||
}
|
||||
got, gotCount, err := repo.UpdateCatalog(context.Background(), orig, 1, tt.masks)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Equal(tt.wantCount, gotCount, "row count")
|
||||
assert.Nil(got)
|
||||
return
|
||||
@@ -579,7 +579,7 @@ func TestRepository_LookupCatalog(t *testing.T) {
|
||||
name string
|
||||
id string
|
||||
want *HostCatalog
|
||||
wantErr error
|
||||
wantErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "found",
|
||||
@@ -595,7 +595,7 @@ func TestRepository_LookupCatalog(t *testing.T) {
|
||||
name: "bad-public-id",
|
||||
id: "",
|
||||
want: nil,
|
||||
wantErr: errors.ErrInvalidParameter,
|
||||
wantErr: errors.InvalidParameter,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -609,8 +609,8 @@ func TestRepository_LookupCatalog(t *testing.T) {
|
||||
assert.NotNil(repo)
|
||||
|
||||
got, err := repo.LookupCatalog(context.Background(), tt.id)
|
||||
if tt.wantErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantErr), "want err: %q got: %q", tt.wantErr, err)
|
||||
if tt.wantErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantErr), err), "want err: %q got: %q", tt.wantErr, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(err)
|
||||
@@ -641,7 +641,7 @@ func TestRepository_DeleteCatalog(t *testing.T) {
|
||||
name string
|
||||
id string
|
||||
want int
|
||||
wantErr error
|
||||
wantErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "found",
|
||||
@@ -657,7 +657,7 @@ func TestRepository_DeleteCatalog(t *testing.T) {
|
||||
name: "bad-public-id",
|
||||
id: "",
|
||||
want: 0,
|
||||
wantErr: errors.ErrInvalidParameter,
|
||||
wantErr: errors.InvalidParameter,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -671,8 +671,8 @@ func TestRepository_DeleteCatalog(t *testing.T) {
|
||||
assert.NotNil(repo)
|
||||
|
||||
got, err := repo.DeleteCatalog(context.Background(), tt.id)
|
||||
if tt.wantErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantErr), "want err: %q got: %q", tt.wantErr, err)
|
||||
if tt.wantErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantErr), err), "want err: %q got: %q", tt.wantErr, err)
|
||||
return
|
||||
}
|
||||
assert.NoError(err)
|
||||
|
||||
@@ -20,20 +20,21 @@ import (
|
||||
// Both s.Name and s.Description are optional. If s.Name is set, it must be
|
||||
// unique within s.CatalogId.
|
||||
func (r *Repository) CreateSet(ctx context.Context, scopeId string, s *HostSet, opt ...Option) (*HostSet, error) {
|
||||
const op = "static.CreateSet"
|
||||
if s == nil {
|
||||
return nil, fmt.Errorf("create: static host set: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "nil HostSet")
|
||||
}
|
||||
if s.HostSet == nil {
|
||||
return nil, fmt.Errorf("create: static host set: embedded HostSet: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "nil embedded HostSet")
|
||||
}
|
||||
if s.CatalogId == "" {
|
||||
return nil, fmt.Errorf("create: static host set: no catalog id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no catalog id")
|
||||
}
|
||||
if s.PublicId != "" {
|
||||
return nil, fmt.Errorf("create: static host set: public id not empty: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "public id not empty")
|
||||
}
|
||||
if scopeId == "" {
|
||||
return nil, fmt.Errorf("create: static host set: no scopeId: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
s = s.clone()
|
||||
|
||||
@@ -41,20 +42,24 @@ func (r *Repository) CreateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
|
||||
if opts.withPublicId != "" {
|
||||
if !strings.HasPrefix(opts.withPublicId, HostSetPrefix+"_") {
|
||||
return nil, fmt.Errorf("create: static host set: passed-in public ID %q has wrong prefix, should be %q: %w", opts.withPublicId, HostSetPrefix, errors.ErrInvalidPublicId)
|
||||
return nil, errors.New(
|
||||
errors.InvalidPublicId,
|
||||
op,
|
||||
fmt.Sprintf("passed-in public ID %q has wrong prefix, should be %q", opts.withPublicId, HostSetPrefix),
|
||||
)
|
||||
}
|
||||
s.PublicId = opts.withPublicId
|
||||
} else {
|
||||
id, err := newHostSetId()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create: static host set: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
s.PublicId = id
|
||||
}
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create: static host set: unable to get oplog wrapper: %w", err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var newHostSet *HostSet
|
||||
@@ -67,10 +72,9 @@ func (r *Repository) CreateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) {
|
||||
return nil, fmt.Errorf("create: static host set: in catalog: %s: name %s already exists: %w",
|
||||
s.CatalogId, s.Name, errors.ErrNotUnique)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in catalog: %s: name %s already exists", s.CatalogId, s.Name)))
|
||||
}
|
||||
return nil, fmt.Errorf("create: static host set: in catalog: %s: %w", s.CatalogId, err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in catalog: %s", s.CatalogId)))
|
||||
}
|
||||
return newHostSet, nil
|
||||
}
|
||||
@@ -90,20 +94,21 @@ func (r *Repository) CreateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
// The WithLimit option can be used to limit the number of hosts returned.
|
||||
// All other options are ignored.
|
||||
func (r *Repository) UpdateSet(ctx context.Context, scopeId string, s *HostSet, version uint32, fieldMaskPaths []string, opt ...Option) (*HostSet, []*Host, int, error) {
|
||||
const op = "static.UpdateSet"
|
||||
if s == nil {
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: %w", errors.ErrInvalidParameter)
|
||||
return nil, nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "nil HostSet")
|
||||
}
|
||||
if s.HostSet == nil {
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: embedded HostSet: %w", errors.ErrInvalidParameter)
|
||||
return nil, nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "nil embedded HostSet")
|
||||
}
|
||||
if s.PublicId == "" {
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: missing public id: %w", errors.ErrInvalidParameter)
|
||||
return nil, nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
if version == 0 {
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: no version supplied: %w", errors.ErrInvalidParameter)
|
||||
return nil, nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no version")
|
||||
}
|
||||
if scopeId == "" {
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: no scopeId: %w", errors.ErrInvalidParameter)
|
||||
return nil, nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
|
||||
for _, f := range fieldMaskPaths {
|
||||
@@ -111,7 +116,7 @@ func (r *Repository) UpdateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
case strings.EqualFold("Name", f):
|
||||
case strings.EqualFold("Description", f):
|
||||
default:
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: field: %s: %w", f, errors.ErrInvalidFieldMask)
|
||||
return nil, nil, db.NoRowsAffected, errors.New(errors.InvalidFieldMask, op, fmt.Sprintf("field: %s", f))
|
||||
}
|
||||
}
|
||||
var dbMask, nullFields []string
|
||||
@@ -124,7 +129,7 @@ func (r *Repository) UpdateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
nil,
|
||||
)
|
||||
if len(dbMask) == 0 && len(nullFields) == 0 {
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: %w", errors.ErrEmptyFieldMask)
|
||||
return nil, nil, db.NoRowsAffected, errors.New(errors.EmptyFieldMask, op, "empty field mask")
|
||||
}
|
||||
|
||||
opts := getOpts(opt...)
|
||||
@@ -136,7 +141,7 @@ func (r *Repository) UpdateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: unable to get oplog wrapper: %w", err)
|
||||
return nil, nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var rowsUpdated int
|
||||
@@ -150,7 +155,7 @@ func (r *Repository) UpdateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
db.WithOplog(oplogWrapper, s.oplog(oplog.OpType_OP_TYPE_UPDATE)),
|
||||
db.WithVersion(&version))
|
||||
if err == nil && rowsUpdated > 1 {
|
||||
return errors.ErrMultipleRecords
|
||||
return errors.E(errors.WithCode(errors.MultipleRecords))
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -162,10 +167,9 @@ func (r *Repository) UpdateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) {
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: %s: name %s already exists: %w",
|
||||
s.PublicId, s.Name, errors.ErrNotUnique)
|
||||
return nil, nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in %s: name %s already exists", s.PublicId, s.Name)))
|
||||
}
|
||||
return nil, nil, db.NoRowsAffected, fmt.Errorf("update: static host set: %s: %w", s.PublicId, err)
|
||||
return nil, nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in %s", s.PublicId)))
|
||||
}
|
||||
|
||||
return returnedHostSet, hosts, rowsUpdated, nil
|
||||
@@ -176,8 +180,9 @@ func (r *Repository) UpdateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
// found, it will return nil, nil, nil. The WithLimit option can be used to
|
||||
// limit the number of hosts returned. All other options are ignored.
|
||||
func (r *Repository) LookupSet(ctx context.Context, publicId string, opt ...Option) (*HostSet, []*Host, error) {
|
||||
const op = "static.LookupSet"
|
||||
if publicId == "" {
|
||||
return nil, nil, fmt.Errorf("lookup: static host set: missing public id %w", errors.ErrInvalidParameter)
|
||||
return nil, nil, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
limit := r.defaultLimit
|
||||
@@ -192,7 +197,7 @@ func (r *Repository) LookupSet(ctx context.Context, publicId string, opt ...Opti
|
||||
var hosts []*Host
|
||||
_, err := r.writer.DoTx(ctx, db.StdRetryCnt, db.ExpBackoff{}, func(reader db.Reader, _ db.Writer) error {
|
||||
if err := reader.LookupByPublicId(ctx, s); err != nil {
|
||||
if errors.Is(err, errors.ErrRecordNotFound) {
|
||||
if errors.IsNotFoundError(err) {
|
||||
s = nil
|
||||
return nil
|
||||
}
|
||||
@@ -204,7 +209,7 @@ func (r *Repository) LookupSet(ctx context.Context, publicId string, opt ...Opti
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("lookup: static host set: failed %w for %s", err, publicId)
|
||||
return nil, nil, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("in %s", s.PublicId)))
|
||||
}
|
||||
|
||||
return s, hosts, nil
|
||||
@@ -213,8 +218,9 @@ func (r *Repository) LookupSet(ctx context.Context, publicId string, opt ...Opti
|
||||
// ListSets returns a slice of HostSets for the catalogId. WithLimit is the
|
||||
// only option supported.
|
||||
func (r *Repository) ListSets(ctx context.Context, catalogId string, opt ...Option) ([]*HostSet, error) {
|
||||
const op = "static.ListSets"
|
||||
if catalogId == "" {
|
||||
return nil, fmt.Errorf("list: static host set: missing catalog id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no catalog id")
|
||||
}
|
||||
opts := getOpts(opt...)
|
||||
limit := r.defaultLimit
|
||||
@@ -225,7 +231,7 @@ func (r *Repository) ListSets(ctx context.Context, catalogId string, opt ...Opti
|
||||
var sets []*HostSet
|
||||
err := r.reader.SearchWhere(ctx, &sets, "catalog_id = ?", []interface{}{catalogId}, db.WithLimit(limit))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("list: static host set: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
return sets, nil
|
||||
}
|
||||
@@ -234,18 +240,19 @@ func (r *Repository) ListSets(ctx context.Context, catalogId string, opt ...Opti
|
||||
// returning a count of the number of records deleted. All options are
|
||||
// ignored.
|
||||
func (r *Repository) DeleteSet(ctx context.Context, scopeId string, publicId string, opt ...Option) (int, error) {
|
||||
const op = "static.DeleteSet"
|
||||
if publicId == "" {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set: missing public id: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no public id")
|
||||
}
|
||||
if scopeId == "" {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set: no scopeId: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
s := allocHostSet()
|
||||
s.PublicId = publicId
|
||||
|
||||
oplogWrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set: unable to get oplog wrapper: %w", err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var rowsDeleted int
|
||||
@@ -255,14 +262,14 @@ func (r *Repository) DeleteSet(ctx context.Context, scopeId string, publicId str
|
||||
ds := s.clone()
|
||||
rowsDeleted, err = w.Delete(ctx, ds, db.WithOplog(oplogWrapper, s.oplog(oplog.OpType_OP_TYPE_DELETE)))
|
||||
if err == nil && rowsDeleted > 1 {
|
||||
return errors.ErrMultipleRecords
|
||||
return errors.E(errors.WithCode(errors.MultipleRecords))
|
||||
}
|
||||
return err
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set: %s: %w", publicId, err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg(fmt.Sprintf("delete failed for %s", s.PublicId)))
|
||||
}
|
||||
|
||||
return rowsDeleted, nil
|
||||
|
||||
@@ -18,28 +18,29 @@ import (
|
||||
// the set to be added. The version must match the current version of the
|
||||
// setId in the repository.
|
||||
func (r *Repository) AddSetMembers(ctx context.Context, scopeId string, setId string, version uint32, hostIds []string, opt ...Option) ([]*Host, error) {
|
||||
const op = "static.AddSetMembers"
|
||||
if scopeId == "" {
|
||||
return nil, fmt.Errorf("add: static host set members: missing scope id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
if setId == "" {
|
||||
return nil, fmt.Errorf("add: static host set members: missing set id: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no set id")
|
||||
}
|
||||
if version == 0 {
|
||||
return nil, fmt.Errorf("add: static host set members: version is zero: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no version")
|
||||
}
|
||||
if len(hostIds) == 0 {
|
||||
return nil, fmt.Errorf("add: static host set members: empty hostIds: %w", errors.ErrInvalidParameter)
|
||||
return nil, errors.New(errors.InvalidParameter, op, "no host ids")
|
||||
}
|
||||
|
||||
// Create in-memory host set members
|
||||
members, err := r.newMembers(setId, hostIds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add: static host set members: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
|
||||
wrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add: static host set members: unable to get oplog wrapper: %w", err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
var hosts []*Host
|
||||
@@ -61,7 +62,7 @@ func (r *Repository) AddSetMembers(ctx context.Context, scopeId string, setId st
|
||||
return err
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("add: static host set members: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
|
||||
return hosts, nil
|
||||
@@ -73,7 +74,7 @@ func (r *Repository) newMembers(setId string, hostIds []string) ([]interface{},
|
||||
var m *HostSetMember
|
||||
m, err := NewHostSetMember(setId, id)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new members: %w", err)
|
||||
return nil, errors.Wrap(err, "static.newMembers")
|
||||
}
|
||||
members = append(members, m)
|
||||
}
|
||||
@@ -83,29 +84,30 @@ func (r *Repository) newMembers(setId string, hostIds []string) ([]interface{},
|
||||
func createMembers(ctx context.Context, w db.Writer, members []interface{}) ([]*oplog.Message, error) {
|
||||
var msgs []*oplog.Message
|
||||
if err := w.CreateItems(ctx, members, db.NewOplogMsgs(&msgs)); err != nil {
|
||||
return nil, fmt.Errorf("unable to create host set members: %w", err)
|
||||
return nil, errors.Wrap(err, "static.createMembers")
|
||||
}
|
||||
return msgs, nil
|
||||
}
|
||||
|
||||
func updateVersion(ctx context.Context, w db.Writer, wrapper wrapping.Wrapper, metadata oplog.Metadata, msgs []*oplog.Message, set *HostSet, version uint32) error {
|
||||
const op = "static.updateVersion"
|
||||
setMsg := new(oplog.Message)
|
||||
rowsUpdated, err := w.Update(ctx, set, []string{"Version"}, nil, db.NewOplogMsg(setMsg), db.WithVersion(&version))
|
||||
switch {
|
||||
case err != nil:
|
||||
return fmt.Errorf("unable to update host set version: %w", err)
|
||||
return errors.Wrap(err, op)
|
||||
case rowsUpdated > 1:
|
||||
return fmt.Errorf("unable to update host set version: %w", errors.ErrMultipleRecords)
|
||||
return errors.E(errors.WithCode(errors.MultipleRecords))
|
||||
}
|
||||
msgs = append(msgs, setMsg)
|
||||
|
||||
// Write oplog
|
||||
ticket, err := w.GetTicket(set)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to get ticket: %w", err)
|
||||
return errors.Wrap(err, op, errors.WithMsg("unable to get ticket"))
|
||||
}
|
||||
if err := w.WriteOplogEntryWith(ctx, wrapper, ticket, metadata, msgs); err != nil {
|
||||
return fmt.Errorf("unable to write oplog: %w", err)
|
||||
return errors.Wrap(err, op, errors.WithMsg("unable to write oplog"))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -142,7 +144,7 @@ func getHosts(ctx context.Context, reader db.Reader, setId string, limit int) ([
|
||||
params,
|
||||
db.WithLimit(limit),
|
||||
); err != nil {
|
||||
return nil, fmt.Errorf("get hosts: %w", err)
|
||||
return nil, errors.Wrap(err, "static.getHosts")
|
||||
}
|
||||
if len(hosts) == 0 {
|
||||
return nil, nil
|
||||
@@ -154,28 +156,29 @@ func getHosts(ctx context.Context, reader db.Reader, setId string, limit int) ([
|
||||
// returns the number of hosts deleted from the set. The version must match
|
||||
// the current version of the setId in the repository.
|
||||
func (r *Repository) DeleteSetMembers(ctx context.Context, scopeId string, setId string, version uint32, hostIds []string, opt ...Option) (int, error) {
|
||||
const op = "static.DeleteSetMembers"
|
||||
if scopeId == "" {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set members: missing scope id: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
if setId == "" {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set members: missing set id: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no set id")
|
||||
}
|
||||
if version == 0 {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set members: version is zero: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no version")
|
||||
}
|
||||
if len(hostIds) == 0 {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set members: empty hostIds: %w", errors.ErrInvalidParameter)
|
||||
return db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no host ids")
|
||||
}
|
||||
|
||||
// Create in-memory host set members
|
||||
members, err := r.newMembers(setId, hostIds)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set members: %w", err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op)
|
||||
}
|
||||
|
||||
wrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set members: unable to get oplog wrapper: %w", err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
_, err = r.writer.DoTx(ctx, db.StdRetryCnt, db.ExpBackoff{}, func(_ db.Reader, w db.Writer) error {
|
||||
@@ -193,19 +196,20 @@ func (r *Repository) DeleteSetMembers(ctx context.Context, scopeId string, setId
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return db.NoRowsAffected, fmt.Errorf("delete: static host set members: %w", err)
|
||||
return db.NoRowsAffected, errors.Wrap(err, op)
|
||||
}
|
||||
return len(hostIds), nil
|
||||
}
|
||||
|
||||
func deleteMembers(ctx context.Context, w db.Writer, members []interface{}) ([]*oplog.Message, error) {
|
||||
const op = "static.deleteMembers"
|
||||
var msgs []*oplog.Message
|
||||
rowsDeleted, err := w.DeleteItems(ctx, members, db.NewOplogMsgs(&msgs))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to delete host set members: %w", err)
|
||||
return nil, errors.Wrap(err, op)
|
||||
}
|
||||
if rowsDeleted != len(members) {
|
||||
return nil, fmt.Errorf("set members deleted %d did not match request for %d", rowsDeleted, len(members))
|
||||
return nil, errors.E(errors.WithMsg(fmt.Sprintf("set members deleted %d did not match request for %d", rowsDeleted, len(members))))
|
||||
}
|
||||
return msgs, nil
|
||||
}
|
||||
@@ -216,14 +220,15 @@ func deleteMembers(ctx context.Context, w db.Writer, members []interface{}) ([]*
|
||||
// set to be added. The version must match the current version of the setId
|
||||
// in the repository. If hostIds is empty, all hosts will be removed setId.
|
||||
func (r *Repository) SetSetMembers(ctx context.Context, scopeId string, setId string, version uint32, hostIds []string, opt ...Option) ([]*Host, int, error) {
|
||||
const op = "static.SetSetMembers"
|
||||
if scopeId == "" {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set: static host set members: missing scope id: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
if setId == "" {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set: static host set members: missing set id: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no set id")
|
||||
}
|
||||
if version == 0 {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set: static host set members: version is zero: %w", errors.ErrInvalidParameter)
|
||||
return nil, db.NoRowsAffected, errors.New(errors.InvalidParameter, op, "no version")
|
||||
}
|
||||
|
||||
// TODO(mgaffney) 08/2020: Oplog does not currently support bulk
|
||||
@@ -241,13 +246,13 @@ func (r *Repository) SetSetMembers(ctx context.Context, scopeId string, setId st
|
||||
// this pattern.
|
||||
changes, err := r.changes(ctx, setId, hostIds)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set: static host set members: %w", err)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op)
|
||||
}
|
||||
var deletions, additions []interface{}
|
||||
for _, c := range changes {
|
||||
m, err := NewHostSetMember(setId, c.HostId)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set: static host set members: %w", err)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op)
|
||||
}
|
||||
switch c.Action {
|
||||
case "delete":
|
||||
@@ -261,7 +266,7 @@ func (r *Repository) SetSetMembers(ctx context.Context, scopeId string, setId st
|
||||
if len(changes) > 0 {
|
||||
wrapper, err := r.kms.GetWrapper(ctx, scopeId, kms.KeyPurposeOplog)
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set: static host set members: unable to get oplog wrapper: %w", err)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op, errors.WithMsg("unable to get oplog wrapper"))
|
||||
}
|
||||
|
||||
_, err = r.writer.DoTx(ctx, db.StdRetryCnt, db.ExpBackoff{}, func(reader db.Reader, w db.Writer) error {
|
||||
@@ -299,7 +304,7 @@ func (r *Repository) SetSetMembers(ctx context.Context, scopeId string, setId st
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, db.NoRowsAffected, fmt.Errorf("set: static host set members: %w", err)
|
||||
return nil, db.NoRowsAffected, errors.Wrap(err, op)
|
||||
}
|
||||
}
|
||||
return hosts, len(changes), nil
|
||||
@@ -311,6 +316,7 @@ type change struct {
|
||||
}
|
||||
|
||||
func (r *Repository) changes(ctx context.Context, setId string, hostIds []string) ([]*change, error) {
|
||||
const op = "static.changes"
|
||||
var inClauseSpots []string
|
||||
// starts at 2 because there is already a $1 in the query
|
||||
for i := 2; i < len(hostIds)+2; i++ {
|
||||
@@ -329,7 +335,7 @@ func (r *Repository) changes(ctx context.Context, setId string, hostIds []string
|
||||
}
|
||||
rows, err := r.reader.Query(ctx, query, params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("changes: query failed: %w", err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg("query failed"))
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
@@ -337,7 +343,7 @@ func (r *Repository) changes(ctx context.Context, setId string, hostIds []string
|
||||
for rows.Next() {
|
||||
var chg change
|
||||
if err := r.reader.ScanRows(rows, &chg); err != nil {
|
||||
return nil, fmt.Errorf("changes: scan row failed: %w", err)
|
||||
return nil, errors.Wrap(err, op, errors.WithMsg("scan row failed"))
|
||||
}
|
||||
changes = append(changes, &chg)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ func TestRepository_AddSetMembers_Parameters(t *testing.T) {
|
||||
args args
|
||||
want []*Host
|
||||
wantErr bool
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "empty-scope-id",
|
||||
@@ -57,7 +57,7 @@ func TestRepository_AddSetMembers_Parameters(t *testing.T) {
|
||||
version: set.Version,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "empty-set-id",
|
||||
@@ -66,7 +66,7 @@ func TestRepository_AddSetMembers_Parameters(t *testing.T) {
|
||||
version: set.Version,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "zero-version",
|
||||
@@ -75,7 +75,7 @@ func TestRepository_AddSetMembers_Parameters(t *testing.T) {
|
||||
setId: set.PublicId,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "empty-host-ids",
|
||||
@@ -84,7 +84,7 @@ func TestRepository_AddSetMembers_Parameters(t *testing.T) {
|
||||
setId: set.PublicId,
|
||||
version: set.Version,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "invalid-version",
|
||||
@@ -116,8 +116,8 @@ func TestRepository_AddSetMembers_Parameters(t *testing.T) {
|
||||
require.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.AddSetMembers(context.Background(), tt.args.scopeId, tt.args.setId, tt.args.version, tt.args.hostIds, tt.args.opt...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_CREATE), db.WithCreateNotBefore(10*time.Second)))
|
||||
return
|
||||
@@ -239,7 +239,7 @@ func TestRepository_DeleteSetMembers_Parameters(t *testing.T) {
|
||||
args args
|
||||
want int
|
||||
wantErr bool
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "empty-scope-id",
|
||||
@@ -248,7 +248,7 @@ func TestRepository_DeleteSetMembers_Parameters(t *testing.T) {
|
||||
version: set.Version,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "empty-set-id",
|
||||
@@ -257,7 +257,7 @@ func TestRepository_DeleteSetMembers_Parameters(t *testing.T) {
|
||||
version: set.Version,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "zero-version",
|
||||
@@ -266,7 +266,7 @@ func TestRepository_DeleteSetMembers_Parameters(t *testing.T) {
|
||||
setId: set.PublicId,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "empty-host-ids",
|
||||
@@ -275,7 +275,7 @@ func TestRepository_DeleteSetMembers_Parameters(t *testing.T) {
|
||||
setId: set.PublicId,
|
||||
version: set.Version,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "invalid-version",
|
||||
@@ -308,8 +308,8 @@ func TestRepository_DeleteSetMembers_Parameters(t *testing.T) {
|
||||
require.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.DeleteSetMembers(context.Background(), tt.args.scopeId, tt.args.setId, tt.args.version, tt.args.hostIds, tt.args.opt...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Zero(got)
|
||||
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_DELETE), db.WithCreateNotBefore(10*time.Second)))
|
||||
return
|
||||
@@ -437,7 +437,7 @@ func TestRepository_SetSetMembers_Parameters(t *testing.T) {
|
||||
want []*Host
|
||||
wantCount int
|
||||
wantErr bool
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "empty-scope-id",
|
||||
@@ -446,7 +446,7 @@ func TestRepository_SetSetMembers_Parameters(t *testing.T) {
|
||||
version: set.Version,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "empty-set-id",
|
||||
@@ -455,7 +455,7 @@ func TestRepository_SetSetMembers_Parameters(t *testing.T) {
|
||||
version: set.Version,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "zero-version",
|
||||
@@ -464,7 +464,7 @@ func TestRepository_SetSetMembers_Parameters(t *testing.T) {
|
||||
setId: set.PublicId,
|
||||
hostIds: hostIds,
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "invalid-version",
|
||||
@@ -497,8 +497,8 @@ func TestRepository_SetSetMembers_Parameters(t *testing.T) {
|
||||
require.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, gotCount, err := repo.SetSetMembers(context.Background(), tt.args.scopeId, tt.args.setId, tt.args.version, tt.args.hostIds, tt.args.opt...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
assert.Equal(tt.wantCount, gotCount)
|
||||
assert.Error(db.TestVerifyOplog(t, rw, tt.args.setId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second)))
|
||||
|
||||
@@ -33,23 +33,23 @@ func TestRepository_CreateSet(t *testing.T) {
|
||||
in *HostSet
|
||||
opts []Option
|
||||
want *HostSet
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "nil-HostSet",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "nil-embedded-HostSet",
|
||||
in: &HostSet{},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "invalid-no-catalog-id",
|
||||
in: &HostSet{
|
||||
HostSet: &store.HostSet{},
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "invalid-public-id-set",
|
||||
@@ -59,7 +59,7 @@ func TestRepository_CreateSet(t *testing.T) {
|
||||
PublicId: "abcd_OOOOOOOOOO",
|
||||
},
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "valid-no-options",
|
||||
@@ -114,8 +114,8 @@ func TestRepository_CreateSet(t *testing.T) {
|
||||
require.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.CreateSet(context.Background(), prj.GetPublicId(), tt.in, tt.opts...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
return
|
||||
}
|
||||
@@ -264,7 +264,7 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
masks []string
|
||||
want *HostSet
|
||||
wantCount int
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "nil-host-set",
|
||||
@@ -273,7 +273,7 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
},
|
||||
chgFn: makeNil(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "nil-embedded-host-set",
|
||||
@@ -282,7 +282,7 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
},
|
||||
chgFn: makeEmbeddedNil(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "no-public-id",
|
||||
@@ -291,7 +291,7 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
},
|
||||
chgFn: deletePublicId(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "updating-non-existent-host-set",
|
||||
@@ -302,7 +302,7 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
},
|
||||
chgFn: combine(nonExistentPublicId(), changeName("test-update-name-repo")),
|
||||
masks: []string{"Name"},
|
||||
wantIsErr: errors.ErrRecordNotFound,
|
||||
wantIsErr: errors.RecordNotFound,
|
||||
},
|
||||
{
|
||||
name: "empty-field-mask",
|
||||
@@ -312,7 +312,7 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
},
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
wantIsErr: errors.ErrEmptyFieldMask,
|
||||
wantIsErr: errors.EmptyFieldMask,
|
||||
},
|
||||
{
|
||||
name: "read-only-fields-in-field-mask",
|
||||
@@ -323,7 +323,7 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
masks: []string{"PublicId", "CreateTime", "UpdateTime", "CatalogId"},
|
||||
wantIsErr: errors.ErrInvalidFieldMask,
|
||||
wantIsErr: errors.InvalidFieldMask,
|
||||
},
|
||||
{
|
||||
name: "unknown-field-in-field-mask",
|
||||
@@ -334,7 +334,7 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
masks: []string{"Bilbo"},
|
||||
wantIsErr: errors.ErrInvalidFieldMask,
|
||||
wantIsErr: errors.InvalidFieldMask,
|
||||
},
|
||||
{
|
||||
name: "change-name",
|
||||
@@ -480,8 +480,8 @@ func TestRepository_UpdateSet(t *testing.T) {
|
||||
orig = tt.chgFn(orig)
|
||||
}
|
||||
got, gotHosts, gotCount, err := repo.UpdateSet(context.Background(), prj.GetPublicId(), orig, 1, tt.masks)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Equal(tt.wantCount, gotCount, "row count")
|
||||
assert.Nil(got)
|
||||
return
|
||||
@@ -724,11 +724,11 @@ func TestRepository_LookupSet(t *testing.T) {
|
||||
in string
|
||||
want *HostSet
|
||||
wantHosts []*Host
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "with-no-public-id",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "with-non-existing-host-set-id",
|
||||
@@ -756,8 +756,8 @@ func TestRepository_LookupSet(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, gotHosts, err := repo.LookupSet(context.Background(), tt.in)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
return
|
||||
}
|
||||
@@ -864,11 +864,11 @@ func TestRepository_ListSets(t *testing.T) {
|
||||
in string
|
||||
opts []Option
|
||||
want []*HostSet
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "with-no-catalog-id",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "Catalog-with-no-host-sets",
|
||||
@@ -890,8 +890,8 @@ func TestRepository_ListSets(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.ListSets(context.Background(), tt.in, tt.opts...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
return
|
||||
}
|
||||
@@ -992,11 +992,11 @@ func TestRepository_DeleteSet(t *testing.T) {
|
||||
name string
|
||||
in string
|
||||
want int
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "With no public id",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "With non existing host set id",
|
||||
@@ -1018,8 +1018,8 @@ func TestRepository_DeleteSet(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.DeleteSet(context.Background(), prj.PublicId, tt.in)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Zero(got)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -33,23 +33,23 @@ func TestRepository_CreateHost(t *testing.T) {
|
||||
in *Host
|
||||
opts []Option
|
||||
want *Host
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "nil-Host",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "nil-embedded-Host",
|
||||
in: &Host{},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "invalid-no-catalog-id",
|
||||
in: &Host{
|
||||
Host: &store.Host{},
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "invalid-public-id-set",
|
||||
@@ -60,7 +60,7 @@ func TestRepository_CreateHost(t *testing.T) {
|
||||
Address: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "valid-no-options",
|
||||
@@ -118,7 +118,7 @@ func TestRepository_CreateHost(t *testing.T) {
|
||||
CatalogId: catalog.PublicId,
|
||||
},
|
||||
},
|
||||
wantIsErr: ErrInvalidAddress,
|
||||
wantIsErr: errors.InvalidAddress,
|
||||
},
|
||||
{
|
||||
name: "invalid-address-to-short",
|
||||
@@ -128,7 +128,7 @@ func TestRepository_CreateHost(t *testing.T) {
|
||||
Address: "12",
|
||||
},
|
||||
},
|
||||
wantIsErr: ErrInvalidAddress,
|
||||
wantIsErr: errors.InvalidAddress,
|
||||
},
|
||||
{
|
||||
name: "invalid-empty-address",
|
||||
@@ -138,7 +138,18 @@ func TestRepository_CreateHost(t *testing.T) {
|
||||
Address: " ",
|
||||
},
|
||||
},
|
||||
wantIsErr: ErrInvalidAddress,
|
||||
wantIsErr: errors.InvalidAddress,
|
||||
},
|
||||
{
|
||||
name: "invalid_public_id",
|
||||
in: &Host{
|
||||
Host: &store.Host{
|
||||
CatalogId: catalog.PublicId,
|
||||
Address: "127.0.0.1",
|
||||
},
|
||||
},
|
||||
opts: []Option{WithPublicId("bad_prefix")},
|
||||
wantIsErr: errors.InvalidPublicId,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -150,8 +161,8 @@ func TestRepository_CreateHost(t *testing.T) {
|
||||
require.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.CreateHost(context.Background(), prj.GetPublicId(), tt.in, tt.opts...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
return
|
||||
}
|
||||
@@ -309,7 +320,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
masks []string
|
||||
want *Host
|
||||
wantCount int
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "nil-host",
|
||||
@@ -320,7 +331,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: makeNil(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "nil-embedded-host",
|
||||
@@ -331,7 +342,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: makeEmbeddedNil(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "no-public-id",
|
||||
@@ -342,7 +353,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: deletePublicId(),
|
||||
masks: []string{"Name", "Description"},
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "updating-non-existent-host",
|
||||
@@ -354,7 +365,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: combine(nonExistentPublicId(), changeName("test-update-name-repo")),
|
||||
masks: []string{"Name"},
|
||||
wantIsErr: errors.ErrRecordNotFound,
|
||||
wantIsErr: errors.RecordNotFound,
|
||||
},
|
||||
{
|
||||
name: "empty-field-mask",
|
||||
@@ -365,7 +376,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
wantIsErr: errors.ErrEmptyFieldMask,
|
||||
wantIsErr: errors.EmptyFieldMask,
|
||||
},
|
||||
{
|
||||
name: "read-only-fields-in-field-mask",
|
||||
@@ -377,7 +388,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
masks: []string{"PublicId", "CreateTime", "UpdateTime", "CatalogId"},
|
||||
wantIsErr: errors.ErrInvalidFieldMask,
|
||||
wantIsErr: errors.InvalidFieldMask,
|
||||
},
|
||||
{
|
||||
name: "unknown-field-in-field-mask",
|
||||
@@ -389,7 +400,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: changeName("test-update-name-repo"),
|
||||
masks: []string{"Bilbo"},
|
||||
wantIsErr: errors.ErrInvalidFieldMask,
|
||||
wantIsErr: errors.InvalidFieldMask,
|
||||
},
|
||||
{
|
||||
name: "change-name",
|
||||
@@ -550,7 +561,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: changeAddress("11"),
|
||||
masks: []string{"Address"},
|
||||
wantIsErr: ErrInvalidAddress,
|
||||
wantIsErr: errors.InvalidAddress,
|
||||
},
|
||||
{
|
||||
name: "delete-address",
|
||||
@@ -561,7 +572,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: changeAddress(""),
|
||||
masks: []string{"Address"},
|
||||
wantIsErr: ErrInvalidAddress,
|
||||
wantIsErr: errors.InvalidAddress,
|
||||
},
|
||||
{
|
||||
name: "change-empty-address",
|
||||
@@ -572,7 +583,7 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
},
|
||||
chgFn: changeAddress(" "),
|
||||
masks: []string{"Address"},
|
||||
wantIsErr: ErrInvalidAddress,
|
||||
wantIsErr: errors.InvalidAddress,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -596,8 +607,8 @@ func TestRepository_UpdateHost(t *testing.T) {
|
||||
orig = tt.chgFn(orig)
|
||||
}
|
||||
got, gotCount, err := repo.UpdateHost(context.Background(), prj.GetPublicId(), orig, 1, tt.masks)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Equal(tt.wantCount, gotCount, "row count")
|
||||
assert.Nil(got)
|
||||
return
|
||||
@@ -748,11 +759,11 @@ func TestRepository_LookupHost(t *testing.T) {
|
||||
name string
|
||||
in string
|
||||
want *Host
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "with-no-public-id",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "with-non-existing-host-id",
|
||||
@@ -773,8 +784,8 @@ func TestRepository_LookupHost(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.LookupHost(context.Background(), tt.in)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
return
|
||||
}
|
||||
@@ -802,11 +813,11 @@ func TestRepository_ListHosts(t *testing.T) {
|
||||
in string
|
||||
opts []Option
|
||||
want []*Host
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "with-no-catalog-id",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "Catalog-with-no-hosts",
|
||||
@@ -828,8 +839,8 @@ func TestRepository_ListHosts(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.ListHosts(context.Background(), tt.in, tt.opts...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
return
|
||||
}
|
||||
@@ -930,11 +941,11 @@ func TestRepository_DeleteHost(t *testing.T) {
|
||||
name string
|
||||
in string
|
||||
want int
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "With no public id",
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "With non existing host id",
|
||||
@@ -956,8 +967,8 @@ func TestRepository_DeleteHost(t *testing.T) {
|
||||
assert.NoError(err)
|
||||
require.NotNil(repo)
|
||||
got, err := repo.DeleteHost(context.Background(), catalog.ScopeId, tt.in)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Zero(got)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ func TestRepository_New(t *testing.T) {
|
||||
name string
|
||||
args args
|
||||
want *Repository
|
||||
wantIsErr error
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "valid",
|
||||
@@ -67,7 +67,7 @@ func TestRepository_New(t *testing.T) {
|
||||
kms: kmsCache,
|
||||
},
|
||||
want: nil,
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "nil-writer",
|
||||
@@ -77,7 +77,7 @@ func TestRepository_New(t *testing.T) {
|
||||
kms: kmsCache,
|
||||
},
|
||||
want: nil,
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "nil-kms",
|
||||
@@ -87,7 +87,7 @@ func TestRepository_New(t *testing.T) {
|
||||
kms: nil,
|
||||
},
|
||||
want: nil,
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "all-nils",
|
||||
@@ -97,7 +97,7 @@ func TestRepository_New(t *testing.T) {
|
||||
kms: nil,
|
||||
},
|
||||
want: nil,
|
||||
wantIsErr: errors.ErrInvalidParameter,
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
@@ -105,8 +105,8 @@ func TestRepository_New(t *testing.T) {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
got, err := NewRepository(tt.args.r, tt.args.w, tt.args.kms, tt.args.opts...)
|
||||
if tt.wantIsErr != nil {
|
||||
assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
if tt.wantIsErr != 0 {
|
||||
assert.Truef(errors.Match(errors.T(tt.wantIsErr), err), "want err: %q got: %q", tt.wantIsErr, err)
|
||||
assert.Nil(got)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -145,9 +145,10 @@ func backendErrorToApiError(inErr error) error {
|
||||
Kind: codes.Unimplemented.String(),
|
||||
Message: stErr.Message(),
|
||||
}}
|
||||
case errors.Is(inErr, errors.ErrRecordNotFound):
|
||||
case errors.Is(inErr, errors.ErrRecordNotFound), errors.Match(errors.T(errors.RecordNotFound), inErr):
|
||||
return NotFoundErrorf(genericNotFoundMsg)
|
||||
case errors.Is(inErr, errors.ErrInvalidFieldMask), errors.Is(inErr, errors.ErrEmptyFieldMask):
|
||||
case errors.Is(inErr, errors.ErrInvalidFieldMask), errors.Is(inErr, errors.ErrEmptyFieldMask),
|
||||
errors.Match(errors.T(errors.InvalidFieldMask), inErr), errors.Match(errors.T(errors.EmptyFieldMask), inErr):
|
||||
return InvalidArgumentErrorf("Error in provided request", map[string]string{"update_mask": "Invalid update mask provided."})
|
||||
case errors.IsUniqueError(inErr), errors.Is(inErr, errors.ErrNotUnique):
|
||||
return InvalidArgumentErrorf(genericUniquenessMsg, nil)
|
||||
|
||||
@@ -100,7 +100,7 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Kind: "Internal",
|
||||
Message: "Some random error",
|
||||
},
|
||||
},
|
||||
@@ -111,22 +111,44 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Kind: "Internal",
|
||||
Message: fmt.Sprintf("test error: %s", errors.ErrInvalidPublicId),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db invalid parameter",
|
||||
err: errors.E(errors.WithCode(errors.InvalidPublicId)),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Message: "invalid public id, parameter violation: error #102",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db invalid parameter",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrInvalidParameter),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Kind: "Internal",
|
||||
Message: fmt.Sprintf("test error: %s", errors.ErrInvalidParameter),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db invalid parameter",
|
||||
err: errors.E(errors.WithCode(errors.InvalidParameter)),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Message: "invalid parameter, parameter violation: error #100",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db invalid field mask",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrInvalidFieldMask),
|
||||
@@ -139,6 +161,18 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db invalid field mask",
|
||||
err: errors.E(errors.WithCode(errors.InvalidFieldMask)),
|
||||
expected: apiError{
|
||||
status: http.StatusBadRequest,
|
||||
inner: &pb.Error{
|
||||
Kind: "InvalidArgument",
|
||||
Message: "Error in provided request",
|
||||
Details: &pb.ErrorDetails{RequestFields: []*pb.FieldError{{Name: "update_mask", Description: "Invalid update mask provided."}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db empty field mask",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrEmptyFieldMask),
|
||||
@@ -151,6 +185,18 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db empty field mask",
|
||||
err: errors.E(errors.WithCode(errors.EmptyFieldMask)),
|
||||
expected: apiError{
|
||||
status: http.StatusBadRequest,
|
||||
inner: &pb.Error{
|
||||
Kind: "InvalidArgument",
|
||||
Message: "Error in provided request",
|
||||
Details: &pb.ErrorDetails{RequestFields: []*pb.FieldError{{Name: "update_mask", Description: "Invalid update mask provided."}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db not unique",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrNotUnique),
|
||||
@@ -162,6 +208,17 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db not unqiue",
|
||||
err: errors.E(errors.WithCode(errors.NotUnique)),
|
||||
expected: apiError{
|
||||
status: http.StatusBadRequest,
|
||||
inner: &pb.Error{
|
||||
Kind: "InvalidArgument",
|
||||
Message: genericUniquenessMsg,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db record not found",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrRecordNotFound),
|
||||
@@ -173,17 +230,50 @@ func TestApiErrorHandler(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db record not found",
|
||||
err: errors.E(errors.WithCode(errors.RecordNotFound)),
|
||||
expected: apiError{
|
||||
status: http.StatusNotFound,
|
||||
inner: &pb.Error{
|
||||
Kind: "NotFound",
|
||||
Message: genericNotFoundMsg,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Db multiple records",
|
||||
err: fmt.Errorf("test error: %w", errors.ErrMultipleRecords),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Kind: "Internal",
|
||||
Message: fmt.Sprintf("test error: %s", errors.ErrMultipleRecords),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Domain error Db multiple records",
|
||||
err: errors.E(errors.WithCode(errors.MultipleRecords)),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Message: "multiple records, search issue: error #1101",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Wrapped domain error",
|
||||
err: errors.E(errors.WithCode(errors.InvalidAddress), errors.WithMsg("test msg"), errors.WithWrap(errors.E(errors.WithCode(errors.NotNull), errors.WithMsg("inner msg")))),
|
||||
expected: apiError{
|
||||
status: http.StatusInternalServerError,
|
||||
inner: &pb.Error{
|
||||
Kind: "Internal",
|
||||
Message: "test msg: parameter violation: error #101: inner msg: integrity violation: error #1001",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/boundary/internal/auth"
|
||||
"github.com/hashicorp/boundary/internal/errors"
|
||||
pb "github.com/hashicorp/boundary/internal/gen/controller/api/resources/hostcatalogs"
|
||||
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
|
||||
"github.com/hashicorp/boundary/internal/host"
|
||||
@@ -180,6 +181,10 @@ func (s Service) createInRepo(ctx context.Context, projId string, item *pb.HostC
|
||||
}
|
||||
h, err := static.NewHostCatalog(projId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host catalog for creation: %v.", err)
|
||||
}
|
||||
repo, err := s.staticRepoFn()
|
||||
@@ -188,6 +193,10 @@ func (s Service) createInRepo(ctx context.Context, projId string, item *pb.HostC
|
||||
}
|
||||
out, err := repo.CreateCatalog(ctx, h)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to create host catalog: %w", err)
|
||||
}
|
||||
if out == nil {
|
||||
@@ -207,6 +216,10 @@ func (s Service) updateInRepo(ctx context.Context, projId, id string, mask []str
|
||||
version := item.GetVersion()
|
||||
h, err := static.NewHostCatalog(projId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to build host catalog for update: %w", err)
|
||||
}
|
||||
h.PublicId = id
|
||||
@@ -220,6 +233,10 @@ func (s Service) updateInRepo(ctx context.Context, projId, id string, mask []str
|
||||
}
|
||||
out, rowsUpdated, err := repo.UpdateCatalog(ctx, h, version, dbMask)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to update host catalog: %w", err)
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
@@ -235,6 +252,10 @@ func (s Service) deleteFromRepo(ctx context.Context, id string) (bool, error) {
|
||||
}
|
||||
rows, err := repo.DeleteCatalog(ctx, id)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return false, e
|
||||
}
|
||||
return false, fmt.Errorf("unable to delete host: %w", err)
|
||||
}
|
||||
return rows > 0, nil
|
||||
|
||||
@@ -212,6 +212,10 @@ func (s Service) createInRepo(ctx context.Context, scopeId, catalogId string, it
|
||||
}
|
||||
h, err := static.NewHostSet(catalogId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host set for creation: %v.", err)
|
||||
}
|
||||
repo, err := s.staticRepoFn()
|
||||
@@ -220,9 +224,9 @@ func (s Service) createInRepo(ctx context.Context, scopeId, catalogId string, it
|
||||
}
|
||||
out, err := repo.CreateSet(ctx, scopeId, h)
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) || errors.Is(err, errors.ErrNotUnique) {
|
||||
// Push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, err
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to create host set: %w", err)
|
||||
}
|
||||
@@ -242,6 +246,10 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId, id string
|
||||
}
|
||||
h, err := static.NewHostSet(catalogId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host set for update: %v.", err)
|
||||
}
|
||||
h.PublicId = id
|
||||
@@ -255,6 +263,10 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId, id string
|
||||
}
|
||||
out, m, rowsUpdated, err := repo.UpdateSet(ctx, scopeId, h, item.GetVersion(), dbMask)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to update host set: %w.", err)
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
@@ -270,6 +282,10 @@ func (s Service) deleteFromRepo(ctx context.Context, scopeId, id string) (bool,
|
||||
}
|
||||
rows, err := repo.DeleteSet(ctx, scopeId, id)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return false, e
|
||||
}
|
||||
return false, fmt.Errorf("unable to delete host: %w", err)
|
||||
}
|
||||
return rows > 0, nil
|
||||
@@ -298,11 +314,18 @@ func (s Service) addInRepo(ctx context.Context, scopeId, setId string, hostIds [
|
||||
}
|
||||
_, err = repo.AddSetMembers(ctx, scopeId, setId, version, strutil.RemoveDuplicates(hostIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to add hosts to host set: %v.", err)
|
||||
}
|
||||
out, m, err := repo.LookupSet(ctx, setId)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to look up host set after adding hosts: %w", err)
|
||||
}
|
||||
if out == nil {
|
||||
@@ -318,12 +341,19 @@ func (s Service) setInRepo(ctx context.Context, scopeId, setId string, hostIds [
|
||||
}
|
||||
_, _, err = repo.SetSetMembers(ctx, scopeId, setId, version, strutil.RemoveDuplicates(hostIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to set hosts in host set: %v.", err)
|
||||
}
|
||||
|
||||
out, m, err := repo.LookupSet(ctx, setId)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to look up host set after setting hosts: %w", err)
|
||||
}
|
||||
if out == nil {
|
||||
@@ -339,11 +369,18 @@ func (s Service) removeInRepo(ctx context.Context, scopeId, setId string, hostId
|
||||
}
|
||||
_, err = repo.DeleteSetMembers(ctx, scopeId, setId, version, strutil.RemoveDuplicates(hostIds, false))
|
||||
if err != nil {
|
||||
// TODO: Figure out a way to surface more helpful error info beyond the Internal error.
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to remove hosts from host set: %v.", err)
|
||||
}
|
||||
out, m, err := repo.LookupSet(ctx, setId)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to look up host set: %w", err)
|
||||
}
|
||||
if out == nil {
|
||||
|
||||
@@ -169,6 +169,10 @@ func (s Service) createInRepo(ctx context.Context, scopeId, catalogId string, it
|
||||
}
|
||||
h, err := static.NewHost(catalogId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host for creation: %v.", err)
|
||||
}
|
||||
|
||||
@@ -178,9 +182,9 @@ func (s Service) createInRepo(ctx context.Context, scopeId, catalogId string, it
|
||||
}
|
||||
out, err := repo.CreateHost(ctx, scopeId, h)
|
||||
if err != nil {
|
||||
if errors.IsUniqueError(err) || errors.Is(err, errors.ErrNotUnique) {
|
||||
// Push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, err
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to create host: %v.", err)
|
||||
}
|
||||
@@ -207,6 +211,10 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId, id string
|
||||
}
|
||||
h, err := static.NewHost(catalogId, opts...)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, handlers.ApiErrorWithCodeAndMessage(codes.Internal, "Unable to build host for update: %v.", err)
|
||||
}
|
||||
h.PublicId = id
|
||||
@@ -220,6 +228,10 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId, id string
|
||||
}
|
||||
out, rowsUpdated, err := repo.UpdateHost(ctx, scopeId, h, item.GetVersion(), dbMask)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return nil, e
|
||||
}
|
||||
return nil, fmt.Errorf("unable to update host: %w", err)
|
||||
}
|
||||
if rowsUpdated == 0 {
|
||||
@@ -235,6 +247,10 @@ func (s Service) deleteFromRepo(ctx context.Context, scopeId, id string) (bool,
|
||||
}
|
||||
rows, err := repo.DeleteHost(ctx, scopeId, id)
|
||||
if err != nil {
|
||||
if e := errors.Convert(err); e != nil {
|
||||
// This is a domain error, push this error through so the error interceptor can interpret it correctly.
|
||||
return false, e
|
||||
}
|
||||
return false, fmt.Errorf("unable to delete host: %w", err)
|
||||
}
|
||||
return rows > 0, nil
|
||||
|
||||
Reference in new issue
Block a user