* Remove Prefix Id and Plugin Name fields. Creating catalogs now require either the plugin id or the name of the plugin resource (but not both). Host Catalogs and Host Sets API resources now have a read only plugin field populated with plugin info. Host Catalogs have a plugin id field as a top level field.
175 lines
5.1 KiB
Go
175 lines
5.1 KiB
Go
package plugin
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/hashicorp/boundary/internal/db"
|
|
"github.com/hashicorp/boundary/internal/errors"
|
|
"github.com/hashicorp/boundary/internal/host/plugin/store"
|
|
"github.com/hashicorp/boundary/internal/iam"
|
|
"github.com/hashicorp/boundary/internal/kms"
|
|
"github.com/hashicorp/boundary/internal/plugin/host"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/protobuf/proto"
|
|
"google.golang.org/protobuf/testing/protocmp"
|
|
"google.golang.org/protobuf/types/known/structpb"
|
|
)
|
|
|
|
func TestHostCatalogSecret_New(t *testing.T) {
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
wrapper := db.TestWrapper(t)
|
|
kkms := kms.TestKms(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
|
|
plg := host.TestPlugin(t, conn, "test")
|
|
cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId())
|
|
|
|
type args struct {
|
|
catalogId string
|
|
attrs *structpb.Struct
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want *HostCatalogSecret
|
|
wantErr bool
|
|
wantEncryptErr bool
|
|
}{
|
|
{
|
|
name: "blank-catalog-id",
|
|
args: args{
|
|
catalogId: "",
|
|
},
|
|
want: &HostCatalogSecret{
|
|
HostCatalogSecret: &store.HostCatalogSecret{},
|
|
},
|
|
wantEncryptErr: true,
|
|
},
|
|
{
|
|
name: "no-attributes",
|
|
args: args{
|
|
catalogId: cat.GetPublicId(),
|
|
},
|
|
want: &HostCatalogSecret{
|
|
HostCatalogSecret: &store.HostCatalogSecret{
|
|
CatalogId: cat.GetPublicId(),
|
|
},
|
|
},
|
|
wantEncryptErr: true,
|
|
},
|
|
{
|
|
name: "valid",
|
|
args: args{
|
|
catalogId: cat.GetPublicId(),
|
|
attrs: func() *structpb.Struct {
|
|
st, err := structpb.NewStruct(map[string]interface{}{"foo": "bar"})
|
|
require.NoError(t, err)
|
|
return st
|
|
}(),
|
|
},
|
|
want: &HostCatalogSecret{
|
|
HostCatalogSecret: &store.HostCatalogSecret{
|
|
CatalogId: cat.GetPublicId(),
|
|
Secret: func() []byte {
|
|
st, err := structpb.NewStruct(map[string]interface{}{"foo": "bar"})
|
|
require.NoError(t, err)
|
|
b, err := proto.Marshal(st)
|
|
require.NoError(t, err)
|
|
return b
|
|
}(),
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
tt := tt
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
ctx := context.Background()
|
|
|
|
databaseWrapper, err := kkms.GetWrapper(ctx, prj.PublicId, kms.KeyPurposeDatabase)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, databaseWrapper)
|
|
|
|
got, err := newHostCatalogSecret(context.Background(), tt.args.catalogId, tt.args.attrs)
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
require.Nil(t, got)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
require.NotNil(t, got)
|
|
|
|
assert.Empty(t, got.CtSecret)
|
|
assert.Equal(t, tt.want, got)
|
|
|
|
err = got.encrypt(ctx, databaseWrapper)
|
|
if tt.wantEncryptErr {
|
|
require.Error(t, err)
|
|
return
|
|
}
|
|
require.NoError(t, err)
|
|
require.NoError(t, got.decrypt(ctx, databaseWrapper))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHostCatalogSecret_Custom_Queries(t *testing.T) {
|
|
ctx := context.Background()
|
|
conn, _ := db.TestSetup(t, "postgres")
|
|
rw := db.New(conn)
|
|
wrapper := db.TestWrapper(t)
|
|
kkms := kms.TestKms(t, conn, wrapper)
|
|
|
|
_, prj := iam.TestScopes(t, iam.TestRepo(t, conn, wrapper))
|
|
plg := host.TestPlugin(t, conn, "test")
|
|
cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId())
|
|
databaseWrapper, err := kkms.GetWrapper(ctx, prj.PublicId, kms.KeyPurposeDatabase)
|
|
require.NoError(t, err)
|
|
|
|
hcs, err := newHostCatalogSecret(ctx, cat.GetPublicId(),
|
|
&structpb.Struct{Fields: map[string]*structpb.Value{"foo": structpb.NewStringValue("bar")}})
|
|
require.NoError(t, err)
|
|
assert.NoError(t, hcs.encrypt(ctx, databaseWrapper))
|
|
q, v := hcs.insertQuery()
|
|
_, err = rw.Exec(ctx, q, v)
|
|
assert.NoError(t, err)
|
|
|
|
found, err := newHostCatalogSecret(ctx, cat.GetPublicId(), nil)
|
|
require.NoError(t, err)
|
|
assert.NoError(t, rw.LookupWhere(ctx, found, "catalog_id=?", found.GetCatalogId()))
|
|
require.NoError(t, found.decrypt(ctx, databaseWrapper))
|
|
require.NoError(t, hcs.decrypt(ctx, databaseWrapper))
|
|
// update the created/updated time from the original
|
|
hcs.CreateTime, hcs.UpdateTime = found.CreateTime, found.UpdateTime
|
|
assert.Empty(t, cmp.Diff(hcs, found, protocmp.Transform()))
|
|
|
|
// Update the secret and see the value updated.
|
|
updated, err := newHostCatalogSecret(ctx, cat.GetPublicId(),
|
|
&structpb.Struct{Fields: map[string]*structpb.Value{"updated": structpb.NewStringValue("value")}})
|
|
require.NoError(t, err)
|
|
assert.NoError(t, updated.encrypt(ctx, databaseWrapper))
|
|
q, v = updated.insertQuery()
|
|
_, err = rw.Exec(ctx, q, v)
|
|
assert.NoError(t, err)
|
|
|
|
assert.NoError(t, rw.LookupWhere(ctx, found, "catalog_id=?", found.GetCatalogId()))
|
|
require.NoError(t, found.decrypt(ctx, databaseWrapper))
|
|
require.NoError(t, updated.decrypt(ctx, databaseWrapper))
|
|
// set the created time to the first and update time from the newly found
|
|
updated.CreateTime, updated.UpdateTime = hcs.CreateTime, found.UpdateTime
|
|
assert.Empty(t, cmp.Diff(updated, found, protocmp.Transform()))
|
|
|
|
// Try to delete this secret.
|
|
q, v = updated.deleteQuery()
|
|
_, err = rw.Exec(ctx, q, v)
|
|
assert.NoError(t, err)
|
|
err = rw.LookupWhere(ctx, found, "catalog_id=?", found.GetCatalogId())
|
|
assert.Error(t, err)
|
|
assert.True(t, errors.IsNotFoundError(err))
|
|
}
|