Add secrets_hmac to host catalog output (#1712)

Co-authored-by: Jim <jlambert@hashicorp.com>
This commit is contained in:
Jeff MitchellandJim authored and GitHub committed 2021-11-16 18:54:38 -05:00
1 parent 063b613bd1
commit 866bfceefc
24 files changed
+520 -179

No files matched your search

+1
View File
@@ -27,6 +27,7 @@ type HostCatalog struct {
Type string `json:"type,omitempty"`
Attributes map[string]interface{} `json:"attributes,omitempty"`
Secrets map[string]interface{} `json:"secrets,omitempty"`
SecretsHmac string `json:"secrets_hmac,omitempty"`
AuthorizedActions []string `json:"authorized_actions,omitempty"`
AuthorizedCollectionActions map[string][]string `json:"authorized_collection_actions,omitempty"`
+1
View File
@@ -65,6 +65,7 @@ const (
PluginNameField = "plugin_name"
IpAddressesField = "ip_addresses"
DnsNamesField = "dns_names"
SecretsHmacField = "secrets_hmac"
ExternalIdField = "external_id"
EgressCredentialSourceIdsField = "egress_credential_source_ids"
EgressCredentialSourcesField = "egress_credential_sources"
@@ -146,6 +146,9 @@ func printItemTable(result api.GenericResult) string {
if item.Type != "" {
nonAttributeMap["Type"] = item.Type
}
if item.SecretsHmac != "" {
nonAttributeMap["Secrets HMAC"] = item.SecretsHmac
}
maxLength := base.MaxAttributesLength(nonAttributeMap, item.Attributes, keySubstMap)
+22 -19
View File
@@ -508,24 +508,24 @@ func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt ..
// Update an object in the db, fieldMask is required and provides
// field_mask.proto paths for fields that should be updated. The i interface
// parameter is the type the caller wants to update in the db and its
// fields are set to the update values. setToNullPaths is optional and
// provides field_mask.proto paths for the fields that should be set to
// null. fieldMaskPaths and setToNullPaths must not intersect. The caller
// is responsible for the transaction life cycle of the writer and if an
// error is returned the caller must decide what to do with the transaction,
// which almost always should be to rollback. Update returns the number of
// rows updated.
// parameter is the type the caller wants to update in the db and its fields are
// set to the update values. setToNullPaths is optional and provides
// field_mask.proto paths for the fields that should be set to null.
// fieldMaskPaths and setToNullPaths must not intersect. The caller is
// responsible for the transaction life cycle of the writer and if an error is
// returned the caller must decide what to do with the transaction, which almost
// always should be to rollback. Update returns the number of rows updated.
//
// Supported options: WithOplog, NewOplogMsg, WithWhere and WithVersion.
// WithOplog will write an oplog entry for the update. NewOplogMsg
// will return in-memory oplog message. WithOplog and NewOplogMsg cannot be
// used together. If WithVersion is used, then the update will include the
// version number in the update where clause, which basically makes the update
// use optimistic locking and the update will only succeed if the existing rows
// version matches the WithVersion option. Zero is not a valid value for the
// Supported options: WithOplog, NewOplogMsg, WithWhere, WithDebug, and
// WithVersion. WithOplog will write an oplog entry for the update. NewOplogMsg
// will return in-memory oplog message. WithOplog and NewOplogMsg cannot be used
// together. If WithVersion is used, then the update will include the version
// number in the update where clause, which basically makes the update use
// optimistic locking and the update will only succeed if the existing rows
// version matches the WithVersion option. Zero is not a valid value for the
// WithVersion option and will return an error. WithWhere allows specifying an
// additional constraint on the operation in addition to the PKs.
// additional constraint on the operation in addition to the PKs. WithDebug will
// turn on debugging for the update call.
func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string, setToNullPaths []string, opt ...Option) (int, error) {
const op = "db.Update"
if rw.underlying == nil {
@@ -603,16 +603,19 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string
return NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get ticket"))
}
}
var underlying *gorm.DB
underlying := rw.underlying.Model(i)
if opts.withDebug {
underlying = underlying.Debug()
}
switch {
case opts.WithVersion != nil || opts.withWhereClause != "":
where, args, err := rw.whereClausesFromOpts(ctx, i, opts)
if err != nil {
return NoRowsAffected, errors.Wrap(ctx, err, op)
}
underlying = rw.underlying.Model(i).Where(where, args...).Updates(updateFields)
underlying = underlying.Where(where, args...).Updates(updateFields)
default:
underlying = rw.underlying.Model(i).Updates(updateFields)
underlying = underlying.Updates(updateFields)
}
if underlying.Error != nil {
if underlying.Error == gorm.ErrRecordNotFound {
@@ -30,8 +30,7 @@ create view host_plugin_host_set_with_value_obj as
comment on view host_plugin_host_set_with_value_obj is
'host plugin host set with its associated value objects';
-- host_plugin_catalog_with_secret is useful for reading a plugin catalog with
-- its associated persisted data.
-- REPLACED in 10_plugin_host_secrets_hmac.up.sql
create view host_plugin_catalog_with_secret as
select
hc.public_id,
@@ -6,12 +6,11 @@ alter table host_plugin_host
create trigger update_version_column after update on host_plugin_host
for each row execute procedure update_version_column();
drop view host_plugin_host_with_value_obj_and_set_memberships;
-- host_plugin_host_with_value_obj_and_set_memberships is useful for reading a
-- plugin host with its associated value objects (ip addresses, dns names) and
-- set membership as columns with delimited values. The delimiter depends on
-- the value objects (e.g. if they need ordering).
drop view host_plugin_host_with_value_obj_and_set_memberships;
create view host_plugin_host_with_value_obj_and_set_memberships as
select
h.public_id,
@@ -0,0 +1,33 @@
begin;
alter table host_plugin_catalog
add column secrets_hmac bytea
constraint secrets_hmac_null_or_not_empty
check(secrets_hmac is null or length(secrets_hmac) > 0);
-- host_plugin_catalog_with_secret is useful for reading a plugin catalog with
-- its associated persisted data.
drop view host_plugin_catalog_with_secret;
create view host_plugin_catalog_with_secret as
select
hc.public_id,
hc.scope_id,
hc.plugin_id,
hc.name,
hc.description,
hc.create_time,
hc.update_time,
hc.version,
hc.secrets_hmac,
hc.attributes,
hcs.secret,
hcs.key_id,
hcs.create_time as persisted_create_time,
hcs.update_time as persisted_update_time
from
host_plugin_catalog hc
left outer join host_plugin_catalog_secret hcs on hc.public_id = hcs.catalog_id;
comment on view host_plugin_catalog_with_secret is
'host plugin catalog with its associated persisted data';
commit;
+5
View File
@@ -4146,6 +4146,11 @@
"type": "object",
"description": "Secrets specific to the catalog type. These are never output."
},
"secrets_hmac": {
"type": "string",
"description": "Output only. The HMAC of the last secrets supplied via the API, if any.",
"readOnly": true
},
"authorized_actions": {
"type": "array",
"items": {
+35
View File
@@ -5,11 +5,14 @@ package plugin
import (
"context"
"encoding/json"
"github.com/hashicorp/boundary/internal/db/timestamp"
"github.com/hashicorp/boundary/internal/errors"
"github.com/hashicorp/boundary/internal/host/plugin/store"
"github.com/hashicorp/boundary/internal/libs/crypto"
"github.com/hashicorp/boundary/internal/oplog"
wrapping "github.com/hashicorp/go-kms-wrapping"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
)
@@ -42,6 +45,7 @@ func NewHostCatalog(ctx context.Context, scopeId, pluginId string, opt ...Option
Name: opts.withName,
Description: opts.withDescription,
Attributes: attrs,
SecretsHmac: opts.withSecretsHmac,
},
Secrets: opts.withSecrets,
}
@@ -54,6 +58,35 @@ func allocHostCatalog() *HostCatalog {
}
}
// hmacSecrets before writing it to the db
func (c *HostCatalog) hmacSecrets(ctx context.Context, cipher wrapping.Wrapper) error {
const op = "plugin.(HostCatalog).hmacSecrets"
if c.Secrets == nil {
c.SecretsHmac = nil
return nil
}
secretsMap := c.Secrets.AsMap()
if len(secretsMap) == 0 {
c.SecretsHmac = nil
return nil
}
if cipher == nil {
return errors.New(ctx, errors.InvalidParameter, op, "missing cipher")
}
// Go's JSON encoding is stable (that is, it alphabetizes keys) so it's a
// good option to produce an HMAC-able string.
jsonSecrets, err := json.Marshal(secretsMap)
if err != nil {
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Code(errors.Encryption)))
}
hm, err := crypto.HmacSha256(ctx, jsonSecrets, cipher, []byte(c.PublicId), nil)
if err != nil {
return errors.Wrap(ctx, err, op, errors.WithCode(errors.Code(errors.Encryption)))
}
c.SecretsHmac = []byte(hm)
return nil
}
// clone provides a deep copy of the HostCatalog with the exception of the
// secret. The secret shallow copied.
func (c *HostCatalog) clone() *HostCatalog {
@@ -107,6 +140,7 @@ type catalogAgg struct {
CreateTime *timestamp.Timestamp
UpdateTime *timestamp.Timestamp
Version uint32
SecretsHmac []byte
Attributes []byte
Secret []byte
KeyId string
@@ -127,6 +161,7 @@ func (agg *catalogAgg) toCatalogAndPersisted() (*HostCatalog, *HostCatalogSecret
c.CreateTime = agg.CreateTime
c.UpdateTime = agg.UpdateTime
c.Version = agg.Version
c.SecretsHmac = agg.SecretsHmac
c.Attributes = agg.Attributes
var s *HostCatalogSecret
+115
View File
@@ -9,7 +9,11 @@ import (
"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"
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/hashicorp/go-kms-wrapping/wrappers/aead"
"github.com/mr-tron/base58"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"
@@ -326,3 +330,114 @@ func TestHostCatalog_SetTableName(t *testing.T) {
})
}
}
func TestHostCatalog_SecretsHmac(t *testing.T) {
ctx := context.Background()
conn, _ := db.TestSetup(t, "postgres")
rootWrapper := db.TestWrapper(t)
kmsCache := kms.TestKms(t, conn, rootWrapper)
_, prj := iam.TestScopes(t, iam.TestRepo(t, conn, rootWrapper))
databaseWrapper, err := kmsCache.GetWrapper(ctx, prj.PublicId, kms.KeyPurposeDatabase)
require.NoError(t, err)
plg := host.TestPlugin(t, conn, "testplugin")
cat := TestCatalog(t, conn, prj.GetPublicId(), plg.GetPublicId())
// stableValue checks that HMACing the same value returns the same result.
// The first time it's called to match it will be empty and thus assign the
// expected value; the second time it will assert that value.
var stableValue string
tests := []struct {
name string
hcFn func() *HostCatalog
hmacWrapper wrapping.Wrapper
emptyHmac bool
matchStableValue bool
wantHmacErrMatch *errors.Template
}{
{
name: "valid-empty-secrets",
hcFn: func() *HostCatalog {
cat.Secrets = nil
cat.SecretsHmac = []byte("foobar")
return cat
},
emptyHmac: true,
hmacWrapper: databaseWrapper,
},
{
name: "valid",
hcFn: func() *HostCatalog {
cat.Secrets = mustStruct(map[string]interface{}{"foo": "bar"})
cat.SecretsHmac = nil
return cat
},
hmacWrapper: databaseWrapper,
matchStableValue: true,
},
{
name: "valid-different-val",
hcFn: func() *HostCatalog {
cat.Secrets = mustStruct(map[string]interface{}{"zip": "zap"})
cat.SecretsHmac = nil
return cat
},
hmacWrapper: databaseWrapper,
},
{
name: "valid-original-val",
hcFn: func() *HostCatalog {
cat.Secrets = mustStruct(map[string]interface{}{"foo": "bar"})
cat.SecretsHmac = nil
return cat
},
hmacWrapper: databaseWrapper,
matchStableValue: true,
},
{
name: "hmac-missing-wrapper",
hcFn: func() *HostCatalog {
cat.Secrets = mustStruct(map[string]interface{}{"foo": "bar"})
cat.SecretsHmac = []byte("foobar")
return cat
},
wantHmacErrMatch: errors.T(errors.InvalidParameter),
},
{
name: "hmac-bad-wrapper",
hcFn: func() *HostCatalog {
cat.Secrets = mustStruct(map[string]interface{}{"foo": "bar"})
cat.SecretsHmac = nil
return cat
},
hmacWrapper: &aead.Wrapper{},
wantHmacErrMatch: errors.T(errors.InvalidParameter),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
hmacCat := tt.hcFn().clone()
err = hmacCat.hmacSecrets(ctx, tt.hmacWrapper)
if tt.wantHmacErrMatch != nil {
require.Error(err)
return
}
require.NoError(err)
if tt.emptyHmac {
assert.Empty(hmacCat.SecretsHmac)
stableValue = ""
return
}
assert.NotEmpty(hmacCat.SecretsHmac)
if tt.matchStableValue {
if stableValue == "" {
stableValue = base58.Encode(hmacCat.SecretsHmac)
} else {
assert.Equal(stableValue, base58.Encode(hmacCat.SecretsHmac))
}
}
})
}
}
+8
View File
@@ -28,6 +28,7 @@ type options struct {
withDnsNames []string
withLimit int
withSetIds []string
withSecretsHmac []byte
}
func getDefaultOptions() options {
@@ -122,3 +123,10 @@ func WithSetIds(with []string) Option {
o.withSetIds = with
}
}
// WithSecretsHmac provides an optional HMAC of secrets. Used for testing.
func WithSecretsHmac(secretsHmac []byte) Option {
return func(o *options) {
o.withSecretsHmac = secretsHmac
}
}
+6
View File
@@ -68,4 +68,10 @@ func Test_GetOpts(t *testing.T) {
testOpts.withSetIds = []string{"foo"}
assert.EqualValues(t, opts, testOpts)
})
t.Run("WithSecretsHmac", func(t *testing.T) {
opts := getOpts(WithSecretsHmac([]byte("secrets-hmac")))
testOpts := getDefaultOptions()
testOpts.withSecretsHmac = []byte("secrets-hmac")
assert.Equal(t, opts, testOpts)
})
}
@@ -16,6 +16,7 @@ import (
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostcatalogs"
pbset "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostsets"
plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin"
"github.com/mr-tron/base58"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
@@ -68,6 +69,17 @@ func (r *Repository) CreateCatalog(ctx context.Context, c *HostCatalog, _ ...Opt
return nil, nil, errors.Wrap(ctx, err, op)
}
// If secrets were passed in, HMAC 'em
if c.Secrets != nil && len(c.Secrets.GetFields()) > 0 {
databaseWrapper, err := r.kms.GetWrapper(ctx, c.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := c.hmacSecrets(ctx, databaseWrapper); err != nil {
return nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("error hmac'ing passed-in secrets"))
}
}
plgHc, err := toPluginCatalog(ctx, c)
if err != nil {
return nil, nil, errors.Wrap(ctx, err, op)
@@ -226,6 +238,7 @@ func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version
newCatalog := currentCatalog.clone()
var updateAttributes bool
var dbMask, nullFields []string
var alreadySetSecrets bool
for _, f := range fieldMask {
switch {
case strings.EqualFold("name", f) && c.Name == "":
@@ -245,10 +258,29 @@ func (r *Repository) UpdateCatalog(ctx context.Context, c *HostCatalog, version
// sent, we only need to do this once.
updateAttributes = true
case strings.EqualFold("secrets", strings.Split(f, ".")[0]):
if alreadySetSecrets {
continue
}
alreadySetSecrets = true
// While in a similar format, secrets are passed along
// wholesale (for the time being). Don't append this mask
// field, as secrets do not have a database entry.
newCatalog.Secrets = c.Secrets
switch {
case newCatalog.Secrets == nil,
len(newCatalog.Secrets.GetFields()) == 0:
nullFields = append(nullFields, "SecretsHmac")
default:
// If secrets were passed in, HMAC 'em
databaseWrapper, err := r.kms.GetWrapper(ctx, c.ScopeId, kms.KeyPurposeDatabase)
if err != nil {
return nil, nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("unable to get database wrapper"))
}
if err := newCatalog.hmacSecrets(ctx, databaseWrapper); err != nil {
return nil, nil, db.NoRowsAffected, errors.Wrap(ctx, err, op, errors.WithMsg("error hmac'ing passed-in secrets"))
}
dbMask = append(dbMask, "SecretsHmac")
}
default:
return nil, nil, db.NoRowsAffected, errors.New(ctx, errors.InvalidFieldMask, op, fmt.Sprintf("invalid field mask: %s", f))
}
@@ -639,6 +671,9 @@ func toPluginCatalog(ctx context.Context, in *HostCatalog) (*pb.HostCatalog, err
Name: name,
Description: description,
}
if len(in.GetSecretsHmac()) > 0 {
hc.SecretsHmac = base58.Encode(in.GetSecretsHmac())
}
if in.GetAttributes() != nil {
attrs := &structpb.Struct{}
if err := proto.Unmarshal(in.GetAttributes(), attrs); err != nil {
@@ -576,6 +576,18 @@ func TestRepository_UpdateCatalog(t *testing.T) {
}
}
checkSecretsHmac := func(notNil bool) checkFunc {
return func(t *testing.T, ctx context.Context) {
t.Helper()
assert := assert.New(t)
if notNil {
assert.NotEmpty(gotCatalog.SecretsHmac)
} else {
assert.Empty(gotCatalog.SecretsHmac)
}
}
}
checkAttributes := func(want map[string]interface{}) checkFunc {
return func(t *testing.T, ctx context.Context) {
t.Helper()
@@ -804,6 +816,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"name"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentNameNil(),
checkUpdateCatalogRequestNewName("foo"),
checkName("foo"),
@@ -821,6 +834,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"name"},
wantCheckFuncs: []checkFunc{
checkVersion(2), // Version remains same even though row is updated
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentNameNil(),
checkUpdateCatalogRequestNewNameNil(),
checkName(""),
@@ -838,6 +852,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"name"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentNameNil(),
checkUpdateCatalogRequestNewName(testDuplicateCatalogNameAltScope),
checkName(testDuplicateCatalogNameAltScope),
@@ -855,6 +870,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"description"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentDescriptionNil(),
checkUpdateCatalogRequestNewDescription("foo"),
checkDescription("foo"),
@@ -872,6 +888,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"description"},
wantCheckFuncs: []checkFunc{
checkVersion(2), // Version remains same even though row is updated
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentDescriptionNil(),
checkUpdateCatalogRequestNewDescriptionNil(),
checkDescription(""),
@@ -891,6 +908,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"attributes"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentAttributes(map[string]interface{}{
"foo": "bar",
}),
@@ -918,6 +936,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"attributes"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentAttributes(map[string]interface{}{
"foo": "bar",
}),
@@ -943,6 +962,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"attributes"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentAttributes(map[string]interface{}{
"foo": "bar",
}),
@@ -965,6 +985,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"attributes.a", "attributes.foo"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentAttributes(map[string]interface{}{
"foo": "bar",
}),
@@ -993,6 +1014,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"secrets.three", "secrets.five"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestPersistedSecrets(map[string]interface{}{
"one": "two",
}),
@@ -1017,7 +1039,8 @@ func TestRepository_UpdateCatalog(t *testing.T) {
version: 2,
fieldMask: []string{"secrets.three"},
wantCheckFuncs: []checkFunc{
checkVersion(2), // no-op
checkVersion(3), // incremented due to secrets_hmac
checkSecretsHmac(true),
checkUpdateCatalogRequestPersistedSecrets(map[string]interface{}{
"one": "two",
}),
@@ -1037,6 +1060,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"secrets"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(false),
checkUpdateCatalogRequestPersistedSecrets(map[string]interface{}{
"one": "two",
}),
@@ -1058,6 +1082,7 @@ func TestRepository_UpdateCatalog(t *testing.T) {
fieldMask: []string{"name", "secrets.three"},
wantCheckFuncs: []checkFunc{
checkVersion(3),
checkSecretsHmac(true),
checkUpdateCatalogRequestCurrentNameNil(),
checkUpdateCatalogRequestNewName("foo"),
checkUpdateCatalogRequestSecrets(map[string]interface{}{
@@ -1081,22 +1106,15 @@ func TestRepository_UpdateCatalog(t *testing.T) {
require := require.New(t)
cat := TestCatalog(t, dbConn, projectScope.PublicId, testPlugin.GetPublicId())
// Set some (default) attributes on our test catalog
cat.Attributes = mustMarshal(map[string]interface{}{
"foo": "bar",
})
numCatUpdated, err := dbRW.Update(ctx, cat, []string{"attributes"}, []string{})
require.NoError(err)
require.Equal(1, numCatUpdated)
// Set up some secrets
cSecretProto := mustStruct(map[string]interface{}{
scopeWrapper, err := dbKmsCache.GetWrapper(ctx, cat.GetScopeId(), kms.KeyPurposeDatabase)
require.NoError(err)
cat.Secrets = mustStruct(map[string]interface{}{
"one": "two",
})
cSecret, err := newHostCatalogSecret(ctx, cat.GetPublicId(), cSecretProto)
require.NoError(err)
scopeWrapper, err := dbKmsCache.GetWrapper(ctx, cat.GetScopeId(), kms.KeyPurposeDatabase)
require.NoError(cat.hmacSecrets(ctx, scopeWrapper))
cSecret, err := newHostCatalogSecret(ctx, cat.GetPublicId(), cat.Secrets)
require.NoError(err)
require.NoError(cSecret.encrypt(ctx, scopeWrapper))
cSecretQ, cSecretV := cSecret.upsertQuery()
@@ -1104,6 +1122,14 @@ func TestRepository_UpdateCatalog(t *testing.T) {
require.NoError(err)
require.Equal(1, secretsUpdated)
// Set some (default) attributes on our test catalog and update SecretsHmac at the same time
cat.Attributes = mustMarshal(map[string]interface{}{
"foo": "bar",
})
numCatUpdated, err := dbRW.Update(ctx, cat, []string{"attributes", "SecretsHmac"}, []string{})
require.NoError(err)
require.Equal(1, numCatUpdated)
t.Cleanup(func() {
t.Helper()
assert := assert.New(t)
+107 -93
View File
@@ -55,9 +55,14 @@ type HostCatalog struct {
// version allows optimistic locking of the resource
// @inject_tag: `gorm:"default:null"`
Version uint32 `protobuf:"varint,8,opt,name=version,proto3" json:"version,omitempty" gorm:"default:null"`
// secrets_hmac is a sha256-hmac of the unencrypted secrets that is returned
// from the API for read. It is recalculated everytime the raw secrets are
// updated.
// @inject_tag: `gorm:"default:null"`
SecretsHmac []byte `protobuf:"bytes,9,opt,name=secrets_hmac,json=secretsHmac,proto3" json:"secrets_hmac,omitempty" gorm:"default:null"`
// attributes is a jsonb formatted field.
// @inject_tag: `gorm:"not_null"`
Attributes []byte `protobuf:"bytes,9,opt,name=attributes,proto3" json:"attributes,omitempty" gorm:"not_null"`
Attributes []byte `protobuf:"bytes,10,opt,name=attributes,proto3" json:"attributes,omitempty" gorm:"not_null"`
}
func (x *HostCatalog) Reset() {
@@ -148,6 +153,13 @@ func (x *HostCatalog) GetVersion() uint32 {
return 0
}
func (x *HostCatalog) GetSecretsHmac() []byte {
if x != nil {
return x.SecretsHmac
}
return nil
}
func (x *HostCatalog) GetAttributes() []byte {
if x != nil {
return x.Attributes
@@ -644,7 +656,7 @@ var file_controller_storage_host_plugin_store_v1_host_proto_rawDesc = []byte{
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f,
0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9e, 0x03, 0x0a, 0x0b, 0x48, 0x6f, 0x73,
0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc1, 0x03, 0x0a, 0x0b, 0x48, 0x6f, 0x73,
0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c,
0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x49, 0x64, 0x12, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f,
@@ -668,106 +680,108 @@ var file_controller_storage_host_plugin_store_v1_host_proto_rawDesc = []byte{
0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18,
0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x49, 0x64, 0x12,
0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d,
0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74,
0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61,
0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0xb6, 0x05, 0x0a, 0x07, 0x48, 0x6f,
0x73, 0x74, 0x53, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f,
0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x49, 0x64, 0x12, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x63,
0x72, 0x65, 0x74, 0x73, 0x5f, 0x68, 0x6d, 0x61, 0x63, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x0b, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x48, 0x6d, 0x61, 0x63, 0x12, 0x1e, 0x0a, 0x0a,
0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0xb6, 0x05, 0x0a,
0x07, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c,
0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x49, 0x64, 0x12, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f,
0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e,
0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e,
0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69,
0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12,
0x4b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x50, 0x0a, 0x0e,
0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65,
0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b,
0x0a, 0x09, 0x6e, 0x65, 0x65, 0x64, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28,
0x08, 0x52, 0x08, 0x6e, 0x65, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x24, 0x0a, 0x04, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xc2, 0xdd, 0x29, 0x0c, 0x0a,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x12, 0x40, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0xc2, 0xdd, 0x29, 0x1a, 0x0a, 0x0b, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5f, 0x69,
0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67,
0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20,
0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x0a, 0x0a,
0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c,
0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x5e, 0x0a, 0x13,
0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69,
0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x42, 0x2d, 0xc2, 0xdd, 0x29, 0x29, 0x0a,
0x12, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69,
0x6e, 0x74, 0x73, 0x12, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x65,
0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x12, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72,
0x72, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x64, 0x0a, 0x15,
0x73, 0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x73, 0x65,
0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x42, 0x30, 0xc2, 0xdd, 0x29,
0x2c, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x53,
0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x15, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x74,
0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x52, 0x13, 0x73,
0x79, 0x6e, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x6f, 0x6e,
0x64, 0x73, 0x22, 0x98, 0x02, 0x0a, 0x11, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x61, 0x74, 0x61, 0x6c,
0x6f, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x61,
0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61,
0x74, 0x61, 0x6c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74,
0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63,
0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12,
0x50, 0x0a, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x74, 0x69, 0x6d,
0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d,
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
0x61, 0x6d, 0x70, 0x52, 0x0c, 0x6c, 0x61, 0x73, 0x74, 0x53, 0x79, 0x6e, 0x63, 0x54, 0x69, 0x6d,
0x65, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x65, 0x65, 0x64, 0x5f, 0x73, 0x79, 0x6e, 0x63, 0x18, 0x05,
0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6e, 0x65, 0x65, 0x64, 0x53, 0x79, 0x6e, 0x63, 0x12, 0x24,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x42, 0x10, 0xc2, 0xdd,
0x29, 0x0c, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x52, 0x04,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x40, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x42, 0x1e, 0xc2, 0xdd, 0x29, 0x1a, 0x0a,
0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x0b, 0x64, 0x65,
0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f,
0x67, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x74, 0x61,
0x6c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12,
0x1e, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x18, 0x0a, 0x20,
0x01, 0x28, 0x0c, 0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12,
0x5e, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x65, 0x6e, 0x64,
0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x09, 0x42, 0x2d, 0xc2, 0xdd,
0x29, 0x29, 0x0a, 0x12, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x45, 0x6e, 0x64,
0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65,
0x64, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x52, 0x12, 0x70, 0x72, 0x65,
0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12,
0x64, 0x0a, 0x15, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x05, 0x42, 0x30,
0xc2, 0xdd, 0x29, 0x2c, 0x0a, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76,
0x61, 0x6c, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x15, 0x73, 0x79, 0x6e, 0x63, 0x5f,
0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73,
0x52, 0x13, 0x73, 0x79, 0x6e, 0x63, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x53, 0x65,
0x63, 0x6f, 0x6e, 0x64, 0x73, 0x22, 0x98, 0x02, 0x0a, 0x11, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x61,
0x74, 0x61, 0x6c, 0x6f, 0x67, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x63,
0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x4b, 0x0a, 0x0b, 0x63, 0x72,
0x65, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f,
0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76,
0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65,
0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74,
0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
0x54, 0x69, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x04,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09,
0x63, 0x74, 0x5f, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52,
0x08, 0x63, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79,
0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64,
0x22, 0x8d, 0x03, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62,
0x6c, 0x69, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75,
0x62, 0x6c, 0x69, 0x63, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74,
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x49, 0x64, 0x12, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74,
0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63,
0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67,
0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65,
0x54, 0x69, 0x6d, 0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d,
0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0c, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x74, 0x5f,
0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x74,
0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x12, 0x15, 0x0a, 0x06, 0x6b, 0x65, 0x79, 0x5f, 0x69, 0x64,
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6b, 0x65, 0x79, 0x49, 0x64, 0x22, 0x8d, 0x03,
0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x75, 0x62, 0x6c, 0x69,
0x63, 0x49, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f,
0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e,
0x61, 0x6c, 0x49, 0x64, 0x12, 0x4b, 0x0a, 0x0b, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x74,
0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74,
0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d,
0x65, 0x12, 0x4b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65,
0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c,
0x6c, 0x65, 0x72, 0x2e, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2e, 0x74, 0x69, 0x6d, 0x65,
0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61,
0x6d, 0x70, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x12,
0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5f,
0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f,
0x67, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x08,
0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a,
0x0c, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x09, 0x20,
0x03, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73,
0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x0a, 0x20,
0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0x5e, 0x0a,
0x0d, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17,
0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65, 0x74, 0x5f, 0x69,
0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x65, 0x74, 0x49, 0x64, 0x12, 0x1d,
0x0a, 0x0a, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01,
0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x49, 0x64, 0x42, 0x40, 0x5a,
0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68,
0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69,
0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x2f, 0x70, 0x6c, 0x75,
0x67, 0x69, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63,
0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x61, 0x6c,
0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x74,
0x61, 0x6c, 0x6f, 0x67, 0x49, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x21, 0x0a, 0x0c, 0x69, 0x70, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73,
0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x70, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73,
0x73, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x6e, 0x73, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73,
0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x64, 0x6e, 0x73, 0x4e, 0x61, 0x6d, 0x65, 0x73,
0x22, 0x5e, 0x0a, 0x0d, 0x48, 0x6f, 0x73, 0x74, 0x53, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65,
0x72, 0x12, 0x17, 0x0a, 0x07, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x06, 0x68, 0x6f, 0x73, 0x74, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x73, 0x65,
0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x65, 0x74, 0x49,
0x64, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x49, 0x64,
0x42, 0x40, 0x5a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68,
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72,
0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x2f,
0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73, 0x74, 0x6f,
0x72, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
+6 -3
View File
@@ -10,6 +10,7 @@ import (
"io"
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/mr-tron/base58"
"golang.org/x/crypto/blake2b"
)
@@ -81,10 +82,12 @@ func HmacSha256(ctx context.Context, data []byte, cipher wrapping.Wrapper, salt,
hmac := mac.Sum(nil)
var hmacString string
switch opts.withBase64Encoding {
case true:
switch {
case opts.withBase64Encoding:
hmacString = base64.RawURLEncoding.EncodeToString(hmac)
case false:
case opts.withBase58Encoding:
hmacString = base58.Encode(hmac)
default:
hmacString = string(hmac)
}
if opts.withPrefix != "" {
+14 -4
View File
@@ -10,6 +10,7 @@ import (
"testing"
wrapping "github.com/hashicorp/go-kms-wrapping"
"github.com/mr-tron/base58"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/blake2b"
@@ -65,12 +66,19 @@ func Test_HmacSha256(t *testing.T) {
wantHmac: testWithBlake2b(t, []byte("test"), testWrapper, nil, nil, WithPrefix("prefix:")),
},
{
name: "blake2b-with-prefix-with-bas64",
name: "blake2b-with-prefix-with-base64",
data: []byte("test"),
wrapper: testWrapper,
opts: []Option{WithPrefix("prefix:"), WithBase64Encoding()},
wantHmac: testWithBlake2b(t, []byte("test"), testWrapper, nil, nil, WithPrefix("prefix:"), WithBase64Encoding()),
},
{
name: "blake2b-with-prefix-with-base58",
data: []byte("test"),
wrapper: testWrapper,
opts: []Option{WithPrefix("prefix:"), WithBase58Encoding()},
wantHmac: testWithBlake2b(t, []byte("test"), testWrapper, nil, nil, WithPrefix("prefix:"), WithBase58Encoding()),
},
{
name: "with-prk",
data: []byte("test"),
@@ -155,10 +163,12 @@ func testHmac(t *testing.T, key, data []byte, opt ...Option) string {
var hmacString string
opts, err := getOpts(opt...)
require.NoError(err)
switch opts.withBase64Encoding {
case true:
switch {
case opts.withBase64Encoding:
hmacString = base64.RawURLEncoding.EncodeToString(hmac)
case false:
case opts.withBase58Encoding:
hmacString = base58.Encode(hmac)
default:
hmacString = string(hmac)
}
if opts.withPrefix != "" {
+9
View File
@@ -22,6 +22,7 @@ type options struct {
withPrk []byte
withEd25519 bool
withBase64Encoding bool
withBase58Encoding bool
}
func getDefaultOptions() *options {
@@ -61,3 +62,11 @@ func WithBase64Encoding() Option {
return nil
}
}
// WithBase58Encoding allows an optional request to base58 encode the data returned
func WithBase58Encoding() Option {
return func(o *options) error {
o.withBase58Encoding = true
return nil
}
}
+8
View File
@@ -42,4 +42,12 @@ func Test_GetOpts(t *testing.T) {
testOpts.withBase64Encoding = true
assert.Equal(opts, testOpts)
})
t.Run("WithBase58Encoding", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
opts, err := getOpts(WithBase58Encoding())
require.NoError(err)
testOpts := getDefaultOptions()
testOpts.withBase58Encoding = true
assert.Equal(opts, testOpts)
})
}
@@ -53,6 +53,9 @@ message HostCatalog {
// Secrets specific to the catalog type. These are never output.
google.protobuf.Struct secrets = 110 [(custom_options.v1.generate_sdk_option) = true];
// Output only. The HMAC of the last secrets supplied via the API, if any.
string secrets_hmac = 120;
// Output only. The available actions on this resource for this user.
repeated string authorized_actions = 300 [json_name="authorized_actions"];
@@ -42,9 +42,15 @@ message HostCatalog {
// @inject_tag: `gorm:"default:null"`
uint32 version = 8;
// secrets_hmac is a sha256-hmac of the unencrypted secrets that is returned
// from the API for read. It is recalculated everytime the raw secrets are
// updated.
// @inject_tag: `gorm:"default:null"`
bytes secrets_hmac = 9;
// attributes is a jsonb formatted field.
// @inject_tag: `gorm:"not_null"`
bytes attributes = 9;
bytes attributes = 10;
}
message HostSet {
@@ -184,4 +190,4 @@ message HostSetMember {
// @inject_tag: `gorm:"default:null"`
string catalog_id = 3;
}
}
@@ -9,6 +9,7 @@ import (
pbs "github.com/hashicorp/boundary/internal/gen/controller/api/services"
"github.com/hashicorp/boundary/internal/host"
"github.com/hashicorp/boundary/internal/host/plugin"
pluginstore "github.com/hashicorp/boundary/internal/host/plugin/store"
"github.com/hashicorp/boundary/internal/host/static"
"github.com/hashicorp/boundary/internal/host/static/store"
"github.com/hashicorp/boundary/internal/perms"
@@ -26,6 +27,7 @@ import (
"github.com/hashicorp/boundary/internal/types/subtypes"
pb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/hostcatalogs"
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/plugins"
"github.com/mr-tron/base58"
"google.golang.org/grpc/codes"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/structpb"
@@ -33,7 +35,8 @@ import (
)
var (
maskManager handlers.MaskManager
staticMaskManager handlers.MaskManager
pluginMaskManager handlers.MaskManager
// IdActions contains the set of actions that can be performed on
// individual resources
@@ -67,7 +70,10 @@ var (
func init() {
var err error
if maskManager, err = handlers.NewMaskManager(handlers.MaskDestination{&store.HostCatalog{}}, handlers.MaskSource{&pb.HostCatalog{}}); err != nil {
if staticMaskManager, err = handlers.NewMaskManager(handlers.MaskDestination{&store.HostCatalog{}}, handlers.MaskSource{&pb.HostCatalog{}}); err != nil {
panic(err)
}
if pluginMaskManager, err = handlers.NewMaskManager(handlers.MaskDestination{&pluginstore.HostCatalog{}}, handlers.MaskSource{&pb.HostCatalog{}}); err != nil {
panic(err)
}
}
@@ -521,7 +527,7 @@ func (s Service) updateStaticInRepo(ctx context.Context, projId, id string, mask
}
version := item.GetVersion()
h.PublicId = id
dbMask := maskManager.Translate(mask)
dbMask := staticMaskManager.Translate(mask)
if len(dbMask) == 0 {
return nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
}
@@ -547,7 +553,7 @@ func (s Service) updatePluginInRepo(ctx context.Context, projId, id string, mask
}
version := item.GetVersion()
h.PublicId = id
dbMask := maskManager.Translate(mask, "attributes", "secrets")
dbMask := pluginMaskManager.Translate(mask, "attributes", "secrets")
if len(dbMask) == 0 {
return nil, nil, handlers.InvalidArgumentErrorf("No valid fields included in the update mask.", map[string]string{"update_mask": "No valid fields provided in the update mask."})
}
@@ -693,12 +699,6 @@ func toProto(ctx context.Context, in host.Catalog, opt ...handlers.Option) (*pb.
if outputFields.Has(globals.ScopeIdField) {
out.ScopeId = in.GetScopeId()
}
if outputFields.Has(globals.PluginIdField) {
switch hc := in.(type) {
case *plugin.HostCatalog:
out.PluginId = hc.GetPluginId()
}
}
if outputFields.Has(globals.TypeField) {
switch in.(type) {
case *static.HostCatalog:
@@ -734,9 +734,15 @@ func toProto(ctx context.Context, in host.Catalog, opt ...handlers.Option) (*pb.
if outputFields.Has(globals.AuthorizedCollectionActionsField) {
out.AuthorizedCollectionActions = opts.WithAuthorizedCollectionActions
}
if outputFields.Has(globals.AttributesField) {
switch h := in.(type) {
case *plugin.HostCatalog:
switch h := in.(type) {
case *plugin.HostCatalog:
if outputFields.Has(globals.PluginIdField) {
out.PluginId = h.GetPluginId()
}
if outputFields.Has(globals.SecretsHmacField) {
out.SecretsHmac = base58.Encode(h.GetSecretsHmac())
}
if outputFields.Has(globals.AttributesField) {
attrs := &structpb.Struct{}
err := proto.Unmarshal(h.Attributes, attrs)
if err != nil {
@@ -27,6 +27,7 @@ import (
"github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/plugins"
scopepb "github.com/hashicorp/boundary/sdk/pbs/controller/api/resources/scopes"
plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin"
"github.com/mr-tron/base58"
"google.golang.org/genproto/protobuf/field_mask"
"google.golang.org/grpc/codes"
"google.golang.org/protobuf/proto"
@@ -183,7 +184,7 @@ func TestGet_Plugin(t *testing.T) {
}
name := "test"
plg := host.TestPlugin(t, conn, name)
hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId())
hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId(), plugin.WithSecretsHmac([]byte("foobar")))
toMerge := &pbs.GetHostCatalogRequest{
Id: hc.GetPublicId(),
@@ -208,6 +209,7 @@ func TestGet_Plugin(t *testing.T) {
Type: plugin.Subtype.String(),
AuthorizedActions: testAuthorizedActions,
AuthorizedCollectionActions: authorizedCollectionActions[plugin.Subtype],
SecretsHmac: base58.Encode([]byte("foobar")),
}
cases := []struct {
@@ -59,6 +59,8 @@ type HostCatalog struct {
Attributes *structpb.Struct `protobuf:"bytes,100,opt,name=attributes,proto3" json:"attributes,omitempty"`
// Secrets specific to the catalog type. These are never output.
Secrets *structpb.Struct `protobuf:"bytes,110,opt,name=secrets,proto3" json:"secrets,omitempty"`
// Output only. The HMAC of the last secrets supplied via the API, if any.
SecretsHmac string `protobuf:"bytes,120,opt,name=secrets_hmac,json=secretsHmac,proto3" json:"secrets_hmac,omitempty"`
// Output only. The available actions on this resource for this user.
AuthorizedActions []string `protobuf:"bytes,300,rep,name=authorized_actions,proto3" json:"authorized_actions,omitempty"`
// Output only. The authorized actions for the scope's collections.
@@ -188,6 +190,13 @@ func (x *HostCatalog) GetSecrets() *structpb.Struct {
return nil
}
func (x *HostCatalog) GetSecretsHmac() string {
if x != nil {
return x.SecretsHmac
}
return ""
}
func (x *HostCatalog) GetAuthorizedActions() []string {
if x != nil {
return x.AuthorizedActions
@@ -226,7 +235,7 @@ var file_controller_api_resources_hostcatalogs_v1_host_catalog_proto_rawDesc = [
0x69, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x2a, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f,
0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x6f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x22, 0xfa, 0x07, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x61, 0x74,
0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9d, 0x08, 0x0a, 0x0b, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x61, 0x74,
0x61, 0x6c, 0x6f, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09,
0x52, 0x02, 0x69, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64,
0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x6f, 0x70, 0x65, 0x5f, 0x69, 0x64,
@@ -270,33 +279,35 @@ var file_controller_api_resources_hostcatalogs_v1_host_catalog_proto_rawDesc = [
0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x18, 0x6e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53,
0x74, 0x72, 0x75, 0x63, 0x74, 0x42, 0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, 0x07, 0x73, 0x65, 0x63,
0x72, 0x65, 0x74, 0x73, 0x12, 0x2f, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xac, 0x02, 0x20, 0x03, 0x28,
0x09, 0x52, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x1d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72,
0x69, 0x7a, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb6, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x56,
0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x68, 0x6f, 0x73, 0x74, 0x63, 0x61,
0x74, 0x61, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x73, 0x74, 0x43, 0x61,
0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x1d, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x6a, 0x0a, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
0x72, 0x65, 0x74, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x5f,
0x68, 0x6d, 0x61, 0x63, 0x18, 0x78, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x65, 0x63, 0x72,
0x65, 0x74, 0x73, 0x48, 0x6d, 0x61, 0x63, 0x12, 0x2f, 0x0a, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xac, 0x02,
0x20, 0x03, 0x28, 0x09, 0x52, 0x12, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64,
0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x9d, 0x01, 0x0a, 0x1d, 0x61, 0x75, 0x74,
0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb6, 0x02, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x56, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2e, 0x68, 0x6f, 0x73,
0x74, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x48, 0x6f, 0x73,
0x74, 0x43, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30, 0x0a, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f,
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73,
0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
0x01, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61,
0x72, 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x72,
0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x73,
0x3b, 0x68, 0x6f, 0x73, 0x74, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x73, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x1d, 0x61, 0x75, 0x74, 0x68, 0x6f,
0x72, 0x69, 0x7a, 0x65, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x6a, 0x0a, 0x20, 0x41, 0x75, 0x74, 0x68,
0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x30,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e,
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
0x4c, 0x69, 0x73, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x3a, 0x02, 0x38, 0x01, 0x42, 0x5a, 0x5a, 0x58, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63,
0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75,
0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x62, 0x73, 0x2f, 0x63, 0x6f,
0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x2f, 0x68, 0x6f, 0x73, 0x74, 0x63, 0x61, 0x74, 0x61, 0x6c,
0x6f, 0x67, 0x73, 0x3b, 0x68, 0x6f, 0x73, 0x74, 0x63, 0x61, 0x74, 0x61, 0x6c, 0x6f, 0x67, 0x73,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (