Add sync interval to host sets (#1680)
This adds a parameter to host sets allowing the sync interval to be user-specified on a per-host-set basis. A value of -1 disables syncing; a value of null uses the current default.
This commit is contained in:
1 parent
dba7c6b531
commit
30e9f944a2
27 files changed
+752
-231
No files matched your search
@@ -14,20 +14,21 @@ import (
|
||||
)
|
||||
|
||||
type HostSet struct {
|
||||
Id string `json:"id,omitempty"`
|
||||
HostCatalogId string `json:"host_catalog_id,omitempty"`
|
||||
Scope *scopes.ScopeInfo `json:"scope,omitempty"`
|
||||
Plugin *plugins.PluginInfo `json:"plugin,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
CreatedTime time.Time `json:"created_time,omitempty"`
|
||||
UpdatedTime time.Time `json:"updated_time,omitempty"`
|
||||
Version uint32 `json:"version,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
HostIds []string `json:"host_ids,omitempty"`
|
||||
PreferredEndpoints []string `json:"preferred_endpoints,omitempty"`
|
||||
Attributes map[string]interface{} `json:"attributes,omitempty"`
|
||||
AuthorizedActions []string `json:"authorized_actions,omitempty"`
|
||||
Id string `json:"id,omitempty"`
|
||||
HostCatalogId string `json:"host_catalog_id,omitempty"`
|
||||
Scope *scopes.ScopeInfo `json:"scope,omitempty"`
|
||||
Plugin *plugins.PluginInfo `json:"plugin,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
CreatedTime time.Time `json:"created_time,omitempty"`
|
||||
UpdatedTime time.Time `json:"updated_time,omitempty"`
|
||||
Version uint32 `json:"version,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
HostIds []string `json:"host_ids,omitempty"`
|
||||
PreferredEndpoints []string `json:"preferred_endpoints,omitempty"`
|
||||
SyncIntervalSeconds int32 `json:"sync_interval_seconds,omitempty"`
|
||||
Attributes map[string]interface{} `json:"attributes,omitempty"`
|
||||
AuthorizedActions []string `json:"authorized_actions,omitempty"`
|
||||
|
||||
response *api.Response
|
||||
}
|
||||
|
||||
@@ -121,3 +121,15 @@ func DefaultPreferredEndpoints() Option {
|
||||
o.postMap["preferred_endpoints"] = nil
|
||||
}
|
||||
}
|
||||
|
||||
func WithSyncIntervalSeconds(inSyncIntervalSeconds int32) Option {
|
||||
return func(o *options) {
|
||||
o.postMap["sync_interval_seconds"] = inSyncIntervalSeconds
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultSyncIntervalSeconds() Option {
|
||||
return func(o *options) {
|
||||
o.postMap["sync_interval_seconds"] = nil
|
||||
}
|
||||
}
|
||||
@@ -59,6 +59,7 @@ const (
|
||||
ApplicationCredentialSourceIdsField = "application_credential_source_ids"
|
||||
ApplicationCredentialSourcesField = "application_credential_sources"
|
||||
PreferredEndpointsField = "preferred_endpoints"
|
||||
SyncIntervalSecondsField = "sync_interval_seconds"
|
||||
PluginIdField = "plugin_id"
|
||||
PluginField = "plugin"
|
||||
PluginNameField = "plugin_name"
|
||||
|
||||
@@ -215,6 +215,11 @@ func (c *Command) printListTable(items []*hostsets.HostSet) string {
|
||||
fmt.Sprintf(" Description: %s", item.Description),
|
||||
)
|
||||
}
|
||||
if item.SyncIntervalSeconds != 0 {
|
||||
output = append(output,
|
||||
fmt.Sprintf(" Sync Interval: %d seconds", item.SyncIntervalSeconds),
|
||||
)
|
||||
}
|
||||
if len(item.AuthorizedActions) > 0 {
|
||||
output = append(output,
|
||||
" Authorized Actions:",
|
||||
@@ -256,6 +261,9 @@ func printItemTable(result api.GenericResult) string {
|
||||
if item.PreferredEndpoints != nil {
|
||||
nonAttributeMap["Preferred Endpoints"] = item.PreferredEndpoints
|
||||
}
|
||||
if item.SyncIntervalSeconds != 0 {
|
||||
nonAttributeMap["Sync Interval"] = fmt.Sprintf("%d seconds", item.SyncIntervalSeconds)
|
||||
}
|
||||
|
||||
maxLength := base.MaxAttributesLength(nonAttributeMap, item.Attributes, keySubstMap)
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/hashicorp/boundary/api/hostsets"
|
||||
"github.com/hashicorp/boundary/internal/cmd/base"
|
||||
"github.com/hashicorp/boundary/internal/libs/endpoint"
|
||||
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -16,12 +17,13 @@ func init() {
|
||||
|
||||
type extraPluginCmdVars struct {
|
||||
flagPreferredEndpoints []string
|
||||
flagSyncInterval string
|
||||
}
|
||||
|
||||
func extraPluginActionsFlagsMapFuncImpl() map[string][]string {
|
||||
return map[string][]string{
|
||||
"create": {"preferred-endpoint"},
|
||||
"update": {"preferred-endpoint"},
|
||||
"create": {"preferred-endpoint", "sync-interval"},
|
||||
"update": {"preferred-endpoint", "sync-interval"},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,8 +70,19 @@ func extraPluginFlagsFuncImpl(c *PluginCommand, set *base.FlagSets, f *base.Flag
|
||||
`or "dns:<globbed name>", specifying which IP address or DNS name out ` +
|
||||
`of a host's available possibilities should be preferred. May be specified ` +
|
||||
`multiple times, which will build up an in-order set of preferences. ` +
|
||||
`If no preferences are specified, a value will be chosen _at random_ from ` +
|
||||
`all available values. May not be valid for all plugin types.`,
|
||||
`If no preferences are specified, a value will be chosen from among all ` +
|
||||
`available values using a built-in priority order. May not be valid ` +
|
||||
`for all plugin types.`,
|
||||
})
|
||||
case "sync-interval":
|
||||
fs.StringVar(&base.StringVar{
|
||||
Name: "sync-interval",
|
||||
Target: &c.flagSyncInterval,
|
||||
Usage: `An interger number of seconds, or a string such as "400s", "5m", or "6h", ` +
|
||||
"indicating the amount of time that should elapse between syncs of the host set. " +
|
||||
"The interval will be applied to the end of the previous sync operation, not the start. " +
|
||||
"Setting to any negative value will disable syncing for that host set; setting to null " +
|
||||
"will cause the set to use Boundary's default. The default may change between releases.",
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -93,5 +106,19 @@ func extraPluginFlagsHandlingFuncImpl(c *PluginCommand, _ *base.FlagSets, opts *
|
||||
*opts = append(*opts, hostsets.WithPreferredEndpoints(c.flagPreferredEndpoints))
|
||||
}
|
||||
|
||||
switch c.flagSyncInterval {
|
||||
case "":
|
||||
case "null":
|
||||
*opts = append(*opts, hostsets.DefaultSyncIntervalSeconds())
|
||||
|
||||
default:
|
||||
interval, err := parseutil.ParseDurationSecond(c.flagSyncInterval)
|
||||
if err != nil {
|
||||
c.UI.Error(fmt.Sprintf("Unable to successfully parse given sync interval: %s", err))
|
||||
return false
|
||||
}
|
||||
*opts = append(*opts, hostsets.WithSyncIntervalSeconds(int32(interval.Seconds())))
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -1137,7 +1137,7 @@ func (rw *Db) LookupWhere(ctx context.Context, resource interface{}, where strin
|
||||
//
|
||||
// Supports the WithLimit option. If WithLimit < 0, then unlimited results are returned.
|
||||
// If WithLimit == 0, then default limits are used for results.
|
||||
// Supports the WithOrder option.
|
||||
// Supports the WithOrder and WithDebug options.
|
||||
func (rw *Db) SearchWhere(ctx context.Context, resources interface{}, where string, args []interface{}, opt ...Option) error {
|
||||
const op = "db.SearchWhere"
|
||||
opts := GetOpts(opt...)
|
||||
@@ -1155,6 +1155,9 @@ func (rw *Db) SearchWhere(ctx context.Context, resources interface{}, where stri
|
||||
if opts.withOrder != "" {
|
||||
db = db.Order(opts.withOrder)
|
||||
}
|
||||
if opts.withDebug {
|
||||
db = db.Debug()
|
||||
}
|
||||
// Perform limiting
|
||||
switch {
|
||||
case opts.WithLimit < 0: // any negative number signals unlimited results
|
||||
|
||||
@@ -125,6 +125,11 @@ begin;
|
||||
update_time wt_timestamp,
|
||||
last_sync_time wt_timestamp,
|
||||
need_sync bool not null,
|
||||
sync_interval_seconds int
|
||||
constraint sync_interval_seconds_not_equal_zero
|
||||
check(sync_interval_seconds != 0)
|
||||
constraint sync_interval_seconds_not_less_then_negative_one
|
||||
check(sync_interval_seconds >= -1),
|
||||
version wt_version,
|
||||
attributes bytea not null,
|
||||
constraint host_plugin_set_catalog_id_name_uq
|
||||
@@ -148,7 +153,7 @@ begin;
|
||||
for each row execute procedure default_create_time();
|
||||
|
||||
create trigger immutable_columns before update on host_plugin_set
|
||||
for each row execute procedure immutable_columns('public_id', 'catalog_id','create_time');
|
||||
for each row execute procedure immutable_columns('public_id', 'catalog_id', 'create_time');
|
||||
|
||||
create trigger insert_host_set_subtype before insert on host_plugin_set
|
||||
for each row execute procedure insert_host_set_subtype();
|
||||
|
||||
@@ -60,6 +60,7 @@ create view host_plugin_host_set_with_value_obj as
|
||||
hs.update_time,
|
||||
hs.last_sync_time,
|
||||
hs.need_sync,
|
||||
hs.sync_interval_seconds,
|
||||
hs.version,
|
||||
hs.attributes,
|
||||
-- the string_agg(..) column will be null if there are no associated value objects
|
||||
|
||||
@@ -4322,7 +4322,12 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "An ordered list of endpoint preferences used to choose from among\nmultiple possible endpoints for a host."
|
||||
"description": "An ordered list of endpoint preferences used to choose from among\nmultiple possible endpoints for a host. Preferences are specified by\n\"cidr:\u003cvalid IPv4/6 CIDR\u003e\" or \"dns:\u003cglobbed name\u003e\", specifying which IP\naddress or DNS name out of a host's available possibilities should be\npreferred. If no preferences are specified, a value will be chosen from\namong all avialable values using a built-in priority order. May not be\nvalid for all plugin types."
|
||||
},
|
||||
"sync_interval_seconds": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"description": "An interger number of seconds indicating the amount of time that should\nelapse between syncs of the host set. The interval will be applied to the\nend of the previous sync operation, not the start. Setting to any\nnegative value will disable syncing for that host set; setting to zero\nwill cause the set to use Boundary's default. The default may change\nbetween releases. May not be valid for all plugin types."
|
||||
},
|
||||
"attributes": {
|
||||
"type": "object",
|
||||
|
||||
@@ -17,9 +17,10 @@ import (
|
||||
// A HostSet is a collection of hosts from the set's catalog.
|
||||
type HostSet struct {
|
||||
*store.HostSet
|
||||
PluginId string `gorm:"-"`
|
||||
HostIds []string `gorm:"-"`
|
||||
tableName string `gorm:"-"`
|
||||
PluginId string `gorm:"-"`
|
||||
HostIds []string `gorm:"-"`
|
||||
PreferredEndpoints []string `gorm:"-"`
|
||||
tableName string `gorm:"-"`
|
||||
}
|
||||
|
||||
// NewHostSet creates a new in memory HostSet assigned to catalogId. Attributes,
|
||||
@@ -35,12 +36,13 @@ func NewHostSet(ctx context.Context, catalogId string, opt ...Option) (*HostSet,
|
||||
|
||||
set := &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: catalogId,
|
||||
Name: opts.withName,
|
||||
Description: opts.withDescription,
|
||||
Attributes: attrs,
|
||||
PreferredEndpoints: opts.withPreferredEndpoints,
|
||||
CatalogId: catalogId,
|
||||
Name: opts.withName,
|
||||
Description: opts.withDescription,
|
||||
SyncIntervalSeconds: opts.withSyncIntervalSeconds,
|
||||
Attributes: attrs,
|
||||
},
|
||||
PreferredEndpoints: opts.withPreferredEndpoints,
|
||||
}
|
||||
|
||||
return set, nil
|
||||
@@ -69,7 +71,8 @@ func allocHostSet() *HostSet {
|
||||
func (s *HostSet) clone() *HostSet {
|
||||
cp := proto.Clone(s.HostSet)
|
||||
hs := &HostSet{
|
||||
HostSet: cp.(*store.HostSet),
|
||||
HostSet: cp.(*store.HostSet),
|
||||
PreferredEndpoints: s.PreferredEndpoints,
|
||||
}
|
||||
if s.Attributes != nil && len(s.Attributes) == 0 && hs.Attributes == nil {
|
||||
hs.Attributes = []byte{}
|
||||
@@ -92,19 +95,20 @@ func (s *HostSet) oplog(op oplog.OpType) oplog.Metadata {
|
||||
// hostSetAgg is a view that aggregates the host set's value objects in to
|
||||
// string fields delimited with the aggregateDelimiter of "|"
|
||||
type hostSetAgg struct {
|
||||
PublicId string `gorm:"primary_key"`
|
||||
CatalogId string
|
||||
PluginId string
|
||||
Name string
|
||||
Description string
|
||||
CreateTime *timestamp.Timestamp
|
||||
UpdateTime *timestamp.Timestamp
|
||||
LastSyncTime *timestamp.Timestamp
|
||||
NeedSync bool
|
||||
Version uint32
|
||||
Attributes []byte
|
||||
PreferredEndpoints string
|
||||
HostIds string
|
||||
PublicId string `gorm:"primary_key"`
|
||||
CatalogId string
|
||||
PluginId string
|
||||
Name string
|
||||
Description string
|
||||
CreateTime *timestamp.Timestamp
|
||||
UpdateTime *timestamp.Timestamp
|
||||
LastSyncTime *timestamp.Timestamp
|
||||
NeedSync bool
|
||||
SyncIntervalSeconds int32
|
||||
Version uint32
|
||||
Attributes []byte
|
||||
PreferredEndpoints string
|
||||
HostIds string
|
||||
}
|
||||
|
||||
func (agg *hostSetAgg) toHostSet(ctx context.Context) (*HostSet, error) {
|
||||
@@ -121,6 +125,7 @@ func (agg *hostSetAgg) toHostSet(ctx context.Context) (*HostSet, error) {
|
||||
hs.UpdateTime = agg.UpdateTime
|
||||
hs.LastSyncTime = agg.LastSyncTime
|
||||
hs.NeedSync = agg.NeedSync
|
||||
hs.SyncIntervalSeconds = agg.SyncIntervalSeconds
|
||||
hs.Version = agg.Version
|
||||
hs.Attributes = agg.Attributes
|
||||
if agg.HostIds != "" {
|
||||
|
||||
@@ -150,10 +150,10 @@ func TestHostSet_Create(t *testing.T) {
|
||||
},
|
||||
want: &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: cat.GetPublicId(),
|
||||
PreferredEndpoints: []string{"cidr:1.2.3.4"},
|
||||
Attributes: []byte{},
|
||||
CatalogId: cat.GetPublicId(),
|
||||
Attributes: []byte{},
|
||||
},
|
||||
PreferredEndpoints: []string{"cidr:1.2.3.4"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ func (r *SetSyncJob) Run(ctx context.Context) error {
|
||||
// Fetch all sets that will reach their sync point within the syncWindow.
|
||||
// This is done to avoid constantly scheduling the set sync job when there
|
||||
// are multiple sets to sync in sequence.
|
||||
err := r.reader.SearchWhere(ctx, &setAggs, `need_sync or last_sync_time <= wt_add_seconds_to_now(?)`, []interface{}{-1 * setSyncJobRunInterval.Seconds()}, db.WithLimit(r.limit))
|
||||
err := r.reader.SearchWhere(ctx, &setAggs, setSyncJobQuery, []interface{}{-1 * setSyncJobRunInterval.Seconds()}, db.WithLimit(r.limit))
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op)
|
||||
}
|
||||
@@ -152,23 +152,35 @@ func nextSync(j scheduler.Job) (time.Duration, error) {
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
type NextResync struct {
|
||||
SyncNow bool
|
||||
ResyncIn time.Duration
|
||||
}
|
||||
var n NextResync
|
||||
err = r.ScanRows(rows, &n)
|
||||
if err != nil {
|
||||
return 0, errors.WrapDeprecated(err, op)
|
||||
}
|
||||
if n.SyncNow || n.ResyncIn < 0 {
|
||||
// If we are past the next renewal time, return 0 to schedule immediately
|
||||
return 0, nil
|
||||
}
|
||||
return n.ResyncIn * time.Second, nil
|
||||
if !rows.Next() {
|
||||
return setSyncJobRunInterval, nil
|
||||
}
|
||||
return setSyncJobRunInterval, nil
|
||||
|
||||
type NextResync struct {
|
||||
SyncNow bool
|
||||
SyncIntervalSeconds int32
|
||||
ResyncIn time.Duration
|
||||
}
|
||||
var n NextResync
|
||||
err = r.ScanRows(rows, &n)
|
||||
if err != nil {
|
||||
return 0, errors.WrapDeprecated(err, op)
|
||||
}
|
||||
switch {
|
||||
case n.SyncNow:
|
||||
// Immediate
|
||||
return 0, nil
|
||||
case n.SyncIntervalSeconds < 0:
|
||||
// In this case automatic syncing is disabled; we still sync if SyncNow
|
||||
// but otherwise do not. We schedule the job at the default cadence but
|
||||
// it will do nothing, just calculate a next run time to ensure it
|
||||
// should stay disabled.
|
||||
return setSyncJobRunInterval, nil
|
||||
case n.ResyncIn < 0:
|
||||
// Immediate
|
||||
return 0, nil
|
||||
}
|
||||
return n.ResyncIn * time.Second, nil
|
||||
}
|
||||
|
||||
// syncSets retrieves from their plugins all the host and membership information
|
||||
@@ -226,7 +238,7 @@ func (r *SetSyncJob) syncSets(ctx context.Context, setIds []string) error {
|
||||
if !ok {
|
||||
si = &setInfo{}
|
||||
}
|
||||
si.preferredEndpoint = endpoint.WithPreferenceOrder(s.GetPreferredEndpoints())
|
||||
si.preferredEndpoint = endpoint.WithPreferenceOrder(s.PreferredEndpoints)
|
||||
si.plgSet, err = toPluginSet(ctx, s)
|
||||
if err != nil {
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("converting set %q to plugin set", s.GetPublicId())))
|
||||
@@ -288,7 +300,7 @@ func (r *SetSyncJob) syncSets(ctx context.Context, setIds []string) error {
|
||||
}
|
||||
|
||||
if _, err := r.upsertHosts(ctx, ci.storeCat, catSetIds, resp.GetHosts()); err != nil {
|
||||
errors.Wrap(ctx, err, op, errors.WithMsg("upserting hosts"))
|
||||
return errors.Wrap(ctx, err, op, errors.WithMsg("upserting hosts"))
|
||||
}
|
||||
|
||||
updateSyncDataQuery := `
|
||||
|
||||
@@ -13,8 +13,8 @@ import (
|
||||
hostplg "github.com/hashicorp/boundary/internal/plugin/host"
|
||||
"github.com/hashicorp/boundary/internal/scheduler"
|
||||
plgpb "github.com/hashicorp/boundary/sdk/pbs/plugin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
assertpkg "github.com/stretchr/testify/assert"
|
||||
requirepkg "github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewSetSyncJob(t *testing.T) {
|
||||
@@ -109,7 +109,7 @@ func TestNewSetSyncJob(t *testing.T) {
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
assert, require := assertpkg.New(t), requirepkg.New(t)
|
||||
|
||||
got, err := newSetSyncJob(ctx, tt.args.r, tt.args.w, tt.args.kms, tt.args.plgm, tt.options...)
|
||||
if tt.wantErr {
|
||||
@@ -130,7 +130,7 @@ func TestNewSetSyncJob(t *testing.T) {
|
||||
|
||||
func TestSetSyncJob_Run(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
assert, require := assertpkg.New(t), requirepkg.New(t)
|
||||
ctx := context.Background()
|
||||
conn, _ := db.TestSetup(t, "postgres")
|
||||
rw := db.New(conn)
|
||||
@@ -215,6 +215,136 @@ func TestSetSyncJob_Run(t *testing.T) {
|
||||
require.NoError(rw.LookupByPublicId(ctx, hs))
|
||||
assert.Greater(hs.GetLastSyncTime().AsTime().UnixNano(), firstSyncTime.AsTime().UnixNano())
|
||||
assert.False(hs.GetNeedSync())
|
||||
|
||||
// Now, run a battery of tests with values for SyncIntervalSeconds
|
||||
type setArgs struct {
|
||||
syncIntervalSeconds int32
|
||||
lastSyncTime *timestamp.Timestamp
|
||||
needsSync bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
setArgs setArgs
|
||||
expectSync bool
|
||||
}{
|
||||
{
|
||||
name: "never-synced-before-needs-sync-false",
|
||||
setArgs: setArgs{
|
||||
lastSyncTime: timestamp.New(time.Unix(0, 0)),
|
||||
needsSync: false,
|
||||
},
|
||||
expectSync: true,
|
||||
},
|
||||
{
|
||||
name: "never-synced-before-needs-sync-true",
|
||||
setArgs: setArgs{
|
||||
lastSyncTime: timestamp.New(time.Unix(0, 0)),
|
||||
needsSync: true,
|
||||
},
|
||||
expectSync: true,
|
||||
},
|
||||
{
|
||||
name: "never-synced-before-sync-disabled",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: -1,
|
||||
lastSyncTime: timestamp.New(time.Unix(0, 0)),
|
||||
needsSync: true,
|
||||
},
|
||||
expectSync: true,
|
||||
},
|
||||
{
|
||||
name: "synced-just-now",
|
||||
setArgs: setArgs{
|
||||
lastSyncTime: timestamp.Now(),
|
||||
needsSync: false,
|
||||
},
|
||||
expectSync: false,
|
||||
},
|
||||
{
|
||||
name: "synced-just-now-need-sync",
|
||||
setArgs: setArgs{
|
||||
lastSyncTime: timestamp.Now(),
|
||||
needsSync: true,
|
||||
},
|
||||
expectSync: true,
|
||||
},
|
||||
{
|
||||
name: "synced-just-now-need-sync-but-sync-disabled",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: -1,
|
||||
lastSyncTime: timestamp.Now(),
|
||||
needsSync: true,
|
||||
},
|
||||
expectSync: true,
|
||||
},
|
||||
{
|
||||
name: "synced-30-seconds-ago-default-time",
|
||||
setArgs: setArgs{
|
||||
lastSyncTime: timestamp.New(time.Now().Add(-60 * time.Second)),
|
||||
needsSync: false,
|
||||
},
|
||||
expectSync: false,
|
||||
},
|
||||
{
|
||||
name: "synced-30-seconds-ago-custom-time",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: 5,
|
||||
lastSyncTime: timestamp.New(time.Now().Add(-60 * time.Second)),
|
||||
needsSync: false,
|
||||
},
|
||||
expectSync: true,
|
||||
},
|
||||
{
|
||||
name: "synced-30-seconds-ago-custom-larger-time",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: 90,
|
||||
lastSyncTime: timestamp.New(time.Now().Add(-60 * time.Second)),
|
||||
needsSync: false,
|
||||
},
|
||||
expectSync: false,
|
||||
},
|
||||
{
|
||||
name: "synced-30-seconds-ago-custom-larger-time-need-sync",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: 60,
|
||||
lastSyncTime: timestamp.New(time.Now().Add(-60 * time.Second)),
|
||||
needsSync: true,
|
||||
},
|
||||
expectSync: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assertpkg.New(t), requirepkg.New(t)
|
||||
|
||||
// Update set
|
||||
hs.LastSyncTime = tt.setArgs.lastSyncTime
|
||||
hs.NeedSync = tt.setArgs.needsSync
|
||||
hs.SyncIntervalSeconds = tt.setArgs.syncIntervalSeconds
|
||||
fieldMaskPaths := []string{"LastSyncTime", "NeedSync"}
|
||||
var setToNullPaths []string
|
||||
if hs.SyncIntervalSeconds == 0 {
|
||||
setToNullPaths = []string{"SyncIntervalSeconds"}
|
||||
} else {
|
||||
fieldMaskPaths = append(fieldMaskPaths, "SyncIntervalSeconds")
|
||||
}
|
||||
count, err := rw.Update(ctx, hs, fieldMaskPaths, setToNullPaths)
|
||||
require.NoError(err)
|
||||
assert.Equal(1, count)
|
||||
|
||||
// Run job
|
||||
err = r.Run(context.Background())
|
||||
require.NoError(err)
|
||||
|
||||
// Validate results
|
||||
var expNum int
|
||||
if tt.expectSync {
|
||||
expNum = 1
|
||||
}
|
||||
assert.Equal(expNum, r.numSets)
|
||||
assert.Equal(expNum, r.numProcessed)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetSyncJob_NextRunIn(t *testing.T) {
|
||||
@@ -235,8 +365,9 @@ func TestSetSyncJob_NextRunIn(t *testing.T) {
|
||||
hostSet := TestSet(t, conn, kmsCache, sched, catalog, plgm)
|
||||
|
||||
type setArgs struct {
|
||||
lastSyncTime *timestamp.Timestamp
|
||||
needsSync bool
|
||||
syncIntervalSeconds int32
|
||||
lastSyncTime *timestamp.Timestamp
|
||||
needsSync bool
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -252,6 +383,15 @@ func TestSetSyncJob_NextRunIn(t *testing.T) {
|
||||
},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "never-synced-before-with-sync-interval",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: 60,
|
||||
lastSyncTime: timestamp.New(time.Unix(0, 0)),
|
||||
needsSync: false,
|
||||
},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "synced-just-now",
|
||||
setArgs: setArgs{
|
||||
@@ -260,6 +400,15 @@ func TestSetSyncJob_NextRunIn(t *testing.T) {
|
||||
},
|
||||
want: setSyncJobRunInterval,
|
||||
},
|
||||
{
|
||||
name: "synced-just-now-with-sync-interval",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: 180,
|
||||
lastSyncTime: timestamp.Now(),
|
||||
needsSync: false,
|
||||
},
|
||||
want: 3 * time.Minute,
|
||||
},
|
||||
{
|
||||
name: "synced-just-now-need-sync",
|
||||
setArgs: setArgs{
|
||||
@@ -268,24 +417,67 @@ func TestSetSyncJob_NextRunIn(t *testing.T) {
|
||||
},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "synced-just-now-need-sync-with-sync-interval",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: 60,
|
||||
lastSyncTime: timestamp.Now(),
|
||||
needsSync: true,
|
||||
},
|
||||
want: 0,
|
||||
},
|
||||
{
|
||||
name: "synced-a-bit-ago",
|
||||
setArgs: setArgs{
|
||||
lastSyncTime: timestamp.New(time.Now().Add(-4 * time.Minute)),
|
||||
needsSync: false,
|
||||
},
|
||||
want: time.Until(time.Now().Add(setSyncJobRunInterval - (4 * time.Minute))),
|
||||
},
|
||||
{
|
||||
name: "synced-a-bit-ago-with-sync-interval",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: 300,
|
||||
lastSyncTime: timestamp.New(time.Now().Add(-4 * time.Minute)),
|
||||
needsSync: false,
|
||||
},
|
||||
want: time.Minute,
|
||||
},
|
||||
{
|
||||
name: "automatic-sync-disabled",
|
||||
setArgs: setArgs{
|
||||
syncIntervalSeconds: -1,
|
||||
lastSyncTime: timestamp.New(time.Now().Add(-4 * time.Minute)),
|
||||
needsSync: false,
|
||||
},
|
||||
want: setSyncJobRunInterval,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
assert, require := assertpkg.New(t), requirepkg.New(t)
|
||||
r, err := newSetSyncJob(ctx, rw, rw, kmsCache, plgm)
|
||||
assert.NoError(err)
|
||||
require.NotNil(r)
|
||||
|
||||
hostSet.NeedSync = tt.setArgs.needsSync
|
||||
hostSet.LastSyncTime = tt.setArgs.lastSyncTime
|
||||
_, err = rw.Update(ctx, hostSet, []string{"LastSyncTime", "NeedSync"}, nil)
|
||||
hostSet.SyncIntervalSeconds = tt.setArgs.syncIntervalSeconds
|
||||
fieldMaskPaths := []string{"LastSyncTime", "NeedSync"}
|
||||
var setToNullPaths []string
|
||||
if hostSet.SyncIntervalSeconds == 0 {
|
||||
setToNullPaths = []string{"SyncIntervalSeconds"}
|
||||
} else {
|
||||
fieldMaskPaths = append(fieldMaskPaths, "SyncIntervalSeconds")
|
||||
}
|
||||
_, err = rw.Update(ctx, hostSet, fieldMaskPaths, setToNullPaths)
|
||||
require.NoError(err)
|
||||
|
||||
got, err := r.NextRunIn()
|
||||
require.NoError(err)
|
||||
// Round to time.Minute to account for lost time between updating set and determining next run
|
||||
assert.Equal(tt.want.Round(time.Minute), got.Round(time.Minute))
|
||||
// Round to five seconds to account for lost time between updating set and determining next run
|
||||
assert.Equal(tt.want.Round(5*time.Second), got.Round(5*time.Second))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -16,17 +16,18 @@ type Option func(*options)
|
||||
|
||||
// options = how options are represented
|
||||
type options struct {
|
||||
withPublicId string
|
||||
withPluginId string
|
||||
withName string
|
||||
withDescription string
|
||||
withAttributes *structpb.Struct
|
||||
withSecrets *structpb.Struct
|
||||
withPreferredEndpoints []string
|
||||
withIpAddresses []string
|
||||
withDnsNames []string
|
||||
withLimit int
|
||||
withSetIds []string
|
||||
withPublicId string
|
||||
withPluginId string
|
||||
withName string
|
||||
withDescription string
|
||||
withAttributes *structpb.Struct
|
||||
withSecrets *structpb.Struct
|
||||
withPreferredEndpoints []string
|
||||
withSyncIntervalSeconds int32
|
||||
withIpAddresses []string
|
||||
withDnsNames []string
|
||||
withLimit int
|
||||
withSetIds []string
|
||||
}
|
||||
|
||||
func getDefaultOptions() options {
|
||||
@@ -84,6 +85,13 @@ func WithPreferredEndpoints(with []string) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// WithSyncIntervalSeconds provides an optional sync interval, in seconds
|
||||
func WithSyncIntervalSeconds(with int32) Option {
|
||||
return func(o *options) {
|
||||
o.withSyncIntervalSeconds = with
|
||||
}
|
||||
}
|
||||
|
||||
// withIpAddresses provides an optional list of ip addresses.
|
||||
func withIpAddresses(with []string) Option {
|
||||
return func(o *options) {
|
||||
|
||||
@@ -20,6 +20,12 @@ func Test_GetOpts(t *testing.T) {
|
||||
testOpts.withName = "test"
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithSyncIntervalSeconds", func(t *testing.T) {
|
||||
opts := getOpts(WithSyncIntervalSeconds(5))
|
||||
testOpts := getDefaultOptions()
|
||||
testOpts.withSyncIntervalSeconds = 5
|
||||
assert.Equal(t, opts, testOpts)
|
||||
})
|
||||
t.Run("WithPluginId", func(t *testing.T) {
|
||||
opts := getOpts(withPluginId("test"))
|
||||
testOpts := getDefaultOptions()
|
||||
|
||||
@@ -19,10 +19,28 @@ delete from host_plugin_catalog_secret
|
||||
|
||||
setSyncNextRunInQuery = `
|
||||
select
|
||||
need_sync as sync_now,
|
||||
extract(epoch from (least(now(), last_sync_time) + ?) - now())::int as resync_in
|
||||
need_sync as sync_now,
|
||||
sync_interval_seconds,
|
||||
case
|
||||
when sync_interval_seconds is null
|
||||
then
|
||||
extract(epoch from (least(now(), last_sync_time) + ?) - now())::int
|
||||
when sync_interval_seconds > 0
|
||||
then
|
||||
extract(epoch from (least(now(), last_sync_time)) - now())::int + sync_interval_seconds
|
||||
else
|
||||
0
|
||||
end resync_in
|
||||
from host_plugin_set
|
||||
order by need_sync desc, last_sync_time desc
|
||||
limit 1;
|
||||
`
|
||||
|
||||
setSyncJobQuery = `
|
||||
need_sync
|
||||
or
|
||||
sync_interval_seconds is null and last_sync_time <= wt_add_seconds_to_now(?)
|
||||
or
|
||||
sync_interval_seconds > 0 and wt_add_seconds(sync_interval_seconds, last_sync_time) <= current_timestamp
|
||||
`
|
||||
)
|
||||
@@ -49,6 +49,9 @@ func (r *Repository) CreateSet(ctx context.Context, scopeId string, s *HostSet,
|
||||
if scopeId == "" {
|
||||
return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "no scope id")
|
||||
}
|
||||
if s.SyncIntervalSeconds < -1 {
|
||||
return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "invalid sync interval")
|
||||
}
|
||||
if s.Attributes == nil {
|
||||
return nil, nil, errors.New(ctx, errors.InvalidParameter, op, "nil attributes")
|
||||
}
|
||||
@@ -779,7 +782,7 @@ func (r *Repository) Endpoints(ctx context.Context, setIds []string) ([]*host.En
|
||||
h := ha.toHost()
|
||||
for _, sId := range hostIdToSetIds[h.GetPublicId()] {
|
||||
s := setIdToSet[sId]
|
||||
pref, err := endpoint.NewPreferencer(ctx, endpoint.WithPreferenceOrder(s.GetPreferredEndpoints()))
|
||||
pref, err := endpoint.NewPreferencer(ctx, endpoint.WithPreferenceOrder(s.PreferredEndpoints))
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg(fmt.Sprintf("getting preferencer for set %q", sId)))
|
||||
}
|
||||
|
||||
@@ -46,12 +46,12 @@ func TestRepository_CreateSet(t *testing.T) {
|
||||
attrs := []byte{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
in *HostSet
|
||||
opts []Option
|
||||
want *HostSet
|
||||
name string
|
||||
in *HostSet
|
||||
opts []Option
|
||||
want *HostSet
|
||||
wantPluginCalled bool
|
||||
wantIsErr errors.Code
|
||||
wantIsErr errors.Code
|
||||
}{
|
||||
{
|
||||
name: "nil-HostSet",
|
||||
@@ -91,6 +91,17 @@ func TestRepository_CreateSet(t *testing.T) {
|
||||
},
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "invalid-sync-interval-too-negative",
|
||||
in: &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: catalog.PublicId,
|
||||
SyncIntervalSeconds: -99,
|
||||
Attributes: attrs,
|
||||
},
|
||||
},
|
||||
wantIsErr: errors.InvalidParameter,
|
||||
},
|
||||
{
|
||||
name: "valid-no-options",
|
||||
in: &HostSet{
|
||||
@@ -111,17 +122,17 @@ func TestRepository_CreateSet(t *testing.T) {
|
||||
name: "valid-preferred-endpoints",
|
||||
in: &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: catalog.PublicId,
|
||||
Attributes: attrs,
|
||||
PreferredEndpoints: []string{"cidr:1.2.3.4/32", "dns:a.b.c"},
|
||||
CatalogId: catalog.PublicId,
|
||||
Attributes: attrs,
|
||||
},
|
||||
PreferredEndpoints: []string{"cidr:1.2.3.4/32", "dns:a.b.c"},
|
||||
},
|
||||
want: &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: catalog.PublicId,
|
||||
Attributes: attrs,
|
||||
PreferredEndpoints: []string{"cidr:1.2.3.4/32", "dns:a.b.c"},
|
||||
CatalogId: catalog.PublicId,
|
||||
Attributes: attrs,
|
||||
},
|
||||
PreferredEndpoints: []string{"cidr:1.2.3.4/32", "dns:a.b.c"},
|
||||
},
|
||||
wantPluginCalled: true,
|
||||
},
|
||||
@@ -143,6 +154,42 @@ func TestRepository_CreateSet(t *testing.T) {
|
||||
},
|
||||
wantPluginCalled: true,
|
||||
},
|
||||
{
|
||||
name: "valid-sync-interval-disabled",
|
||||
in: &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: catalog.PublicId,
|
||||
SyncIntervalSeconds: -1,
|
||||
Attributes: attrs,
|
||||
},
|
||||
},
|
||||
want: &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: catalog.PublicId,
|
||||
SyncIntervalSeconds: -1,
|
||||
Attributes: attrs,
|
||||
},
|
||||
},
|
||||
wantPluginCalled: true,
|
||||
},
|
||||
{
|
||||
name: "valid-sync-interval-positive",
|
||||
in: &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: catalog.PublicId,
|
||||
SyncIntervalSeconds: 60,
|
||||
Attributes: attrs,
|
||||
},
|
||||
},
|
||||
want: &HostSet{
|
||||
HostSet: &store.HostSet{
|
||||
CatalogId: catalog.PublicId,
|
||||
SyncIntervalSeconds: 60,
|
||||
Attributes: attrs,
|
||||
},
|
||||
},
|
||||
wantPluginCalled: true,
|
||||
},
|
||||
{
|
||||
name: "valid-unimplemented-plugin",
|
||||
in: &HostSet{
|
||||
@@ -187,7 +234,7 @@ func TestRepository_CreateSet(t *testing.T) {
|
||||
Description: ("test-description-repo"),
|
||||
Attributes: func() []byte {
|
||||
st, err := structpb.NewStruct(map[string]interface{}{
|
||||
"k1": "foo",
|
||||
"k1": "foo",
|
||||
"removed": nil,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -1129,7 +1176,7 @@ func TestRepository_LookupSet(t *testing.T) {
|
||||
return &plgpb.ListHostsResponse{}, nil
|
||||
},
|
||||
}),
|
||||
})
|
||||
}, WithSyncIntervalSeconds(5))
|
||||
hostSetId, err := newHostSetId(ctx)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -1192,9 +1239,9 @@ func TestRepository_Endpoints(t *testing.T) {
|
||||
}
|
||||
|
||||
catalog := TestCatalog(t, conn, prj.PublicId, plg.GetPublicId())
|
||||
hostSet10 := TestSet(t, conn, kms, sched, catalog, plgm, WithPreferredEndpoints([]string{"cidr:10.0.0.1/24"}))
|
||||
hostSet192 := TestSet(t, conn, kms, sched, catalog, plgm, WithPreferredEndpoints([]string{"cidr:192.168.0.1/24"}))
|
||||
hostSet100 := TestSet(t, conn, kms, sched, catalog, plgm, WithPreferredEndpoints([]string{"cidr:100.100.100.100/24"}))
|
||||
hostSet10 := TestSet(t, conn, kms, sched, catalog, plgm, WithName("hostSet10"), WithPreferredEndpoints([]string{"cidr:10.0.0.1/24"}))
|
||||
hostSet192 := TestSet(t, conn, kms, sched, catalog, plgm, WithName("hostSet192"), WithPreferredEndpoints([]string{"cidr:192.168.0.1/24"}))
|
||||
hostSet100 := TestSet(t, conn, kms, sched, catalog, plgm, WithName("hostSet100"), WithPreferredEndpoints([]string{"cidr:100.100.100.100/24"}))
|
||||
hostlessSet := TestSet(t, conn, kms, sched, hostlessCatalog, plgm)
|
||||
|
||||
h1 := TestHost(t, conn, catalog.GetPublicId(), "test", withIpAddresses([]string{"10.0.0.5", "192.168.0.5"}))
|
||||
|
||||
@@ -195,6 +195,9 @@ type HostSet struct {
|
||||
// preferred_endpoints stores string preference values
|
||||
// @inject_tag: `gorm:"-"`
|
||||
PreferredEndpoints []string `protobuf:"bytes,11,rep,name=preferred_endpoints,json=preferredEndpoints,proto3" json:"preferred_endpoints,omitempty" gorm:"-"`
|
||||
// Sync interval is a value representing a duration in seconds
|
||||
// @inject_tag: `gorm:"default:null"`
|
||||
SyncIntervalSeconds int32 `protobuf:"varint,12,opt,name=sync_interval_seconds,json=syncIntervalSeconds,proto3" json:"sync_interval_seconds,omitempty" gorm:"default:null"`
|
||||
}
|
||||
|
||||
func (x *HostSet) Reset() {
|
||||
@@ -306,6 +309,13 @@ func (x *HostSet) GetPreferredEndpoints() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *HostSet) GetSyncIntervalSeconds() int32 {
|
||||
if x != nil {
|
||||
return x.SyncIntervalSeconds
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
type HostCatalogSecret struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
@@ -659,7 +669,7 @@ var file_controller_storage_host_plugin_store_v1_host_proto_rawDesc = []byte{
|
||||
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, 0xa1, 0x04, 0x0a, 0x07, 0x48, 0x6f,
|
||||
0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x22, 0x87, 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,
|
||||
@@ -693,61 +703,67 @@ var file_controller_storage_host_plugin_store_v1_host_proto_rawDesc = []byte{
|
||||
0x52, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x73, 0x12, 0x2f, 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, 0x52, 0x12, 0x70, 0x72, 0x65, 0x66, 0x65,
|
||||
0x72, 0x72, 0x65, 0x64, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 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,
|
||||
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, 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, 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, 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,
|
||||
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,
|
||||
}
|
||||
|
||||
var (
|
||||
|
||||
@@ -433,6 +433,56 @@ func (x *HostSetMember) GetCatalogId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
// These fields are not implemented yet on the host set. They are captured
|
||||
// here for the purpose of identifying the mask maps which are on the top level
|
||||
// api set resource but aren't present in the static host set storage.
|
||||
type UnimplementedSetFields struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
SyncIntervalSeconds int32 `protobuf:"varint,22,opt,name=sync_interval_seconds,json=syncIntervalSeconds,proto3" json:"sync_interval_seconds,omitempty"`
|
||||
}
|
||||
|
||||
func (x *UnimplementedSetFields) Reset() {
|
||||
*x = UnimplementedSetFields{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_controller_storage_host_static_store_v1_static_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
}
|
||||
|
||||
func (x *UnimplementedSetFields) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*UnimplementedSetFields) ProtoMessage() {}
|
||||
|
||||
func (x *UnimplementedSetFields) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_controller_storage_host_static_store_v1_static_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use UnimplementedSetFields.ProtoReflect.Descriptor instead.
|
||||
func (*UnimplementedSetFields) Descriptor() ([]byte, []int) {
|
||||
return file_controller_storage_host_static_store_v1_static_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *UnimplementedSetFields) GetSyncIntervalSeconds() int32 {
|
||||
if x != nil {
|
||||
return x.SyncIntervalSeconds
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
var File_controller_storage_host_static_store_v1_static_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_controller_storage_host_static_store_v1_static_proto_rawDesc = []byte{
|
||||
@@ -524,7 +574,15 @@ var file_controller_storage_host_static_store_v1_static_proto_rawDesc = []byte{
|
||||
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,
|
||||
0x49, 0x64, 0x22, 0x7e, 0x0a, 0x16, 0x55, 0x6e, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x65, 0x64, 0x53, 0x65, 0x74, 0x46, 0x69, 0x65, 0x6c, 0x64, 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, 0x16, 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, 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, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x3b, 0x73,
|
||||
@@ -543,21 +601,22 @@ func file_controller_storage_host_static_store_v1_static_proto_rawDescGZIP() []b
|
||||
return file_controller_storage_host_static_store_v1_static_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_controller_storage_host_static_store_v1_static_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_controller_storage_host_static_store_v1_static_proto_msgTypes = make([]protoimpl.MessageInfo, 5)
|
||||
var file_controller_storage_host_static_store_v1_static_proto_goTypes = []interface{}{
|
||||
(*HostCatalog)(nil), // 0: controller.storage.host.static.store.v1.HostCatalog
|
||||
(*Host)(nil), // 1: controller.storage.host.static.store.v1.Host
|
||||
(*HostSet)(nil), // 2: controller.storage.host.static.store.v1.HostSet
|
||||
(*HostSetMember)(nil), // 3: controller.storage.host.static.store.v1.HostSetMember
|
||||
(*timestamp.Timestamp)(nil), // 4: controller.storage.timestamp.v1.Timestamp
|
||||
(*HostCatalog)(nil), // 0: controller.storage.host.static.store.v1.HostCatalog
|
||||
(*Host)(nil), // 1: controller.storage.host.static.store.v1.Host
|
||||
(*HostSet)(nil), // 2: controller.storage.host.static.store.v1.HostSet
|
||||
(*HostSetMember)(nil), // 3: controller.storage.host.static.store.v1.HostSetMember
|
||||
(*UnimplementedSetFields)(nil), // 4: controller.storage.host.static.store.v1.UnimplementedSetFields
|
||||
(*timestamp.Timestamp)(nil), // 5: controller.storage.timestamp.v1.Timestamp
|
||||
}
|
||||
var file_controller_storage_host_static_store_v1_static_proto_depIdxs = []int32{
|
||||
4, // 0: controller.storage.host.static.store.v1.HostCatalog.create_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
4, // 1: controller.storage.host.static.store.v1.HostCatalog.update_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
4, // 2: controller.storage.host.static.store.v1.Host.create_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
4, // 3: controller.storage.host.static.store.v1.Host.update_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
4, // 4: controller.storage.host.static.store.v1.HostSet.create_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
4, // 5: controller.storage.host.static.store.v1.HostSet.update_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
5, // 0: controller.storage.host.static.store.v1.HostCatalog.create_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
5, // 1: controller.storage.host.static.store.v1.HostCatalog.update_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
5, // 2: controller.storage.host.static.store.v1.Host.create_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
5, // 3: controller.storage.host.static.store.v1.Host.update_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
5, // 4: controller.storage.host.static.store.v1.HostSet.create_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
5, // 5: controller.storage.host.static.store.v1.HostSet.update_time:type_name -> controller.storage.timestamp.v1.Timestamp
|
||||
6, // [6:6] is the sub-list for method output_type
|
||||
6, // [6:6] is the sub-list for method input_type
|
||||
6, // [6:6] is the sub-list for extension type_name
|
||||
@@ -619,6 +678,18 @@ func file_controller_storage_host_static_store_v1_static_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_controller_storage_host_static_store_v1_static_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*UnimplementedSetFields); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
return &v.sizeCache
|
||||
case 2:
|
||||
return &v.unknownFields
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
@@ -626,7 +697,7 @@ func file_controller_storage_host_static_store_v1_static_proto_init() {
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_controller_storage_host_static_store_v1_static_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 4,
|
||||
NumMessages: 5,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
|
||||
@@ -81,7 +81,7 @@ var testCases = []testCase{
|
||||
},
|
||||
{
|
||||
name: "nested with nil",
|
||||
dst: nil,
|
||||
dst: nil,
|
||||
src: map[string]interface{}{
|
||||
"a": "b",
|
||||
"nested": map[string]interface{}{
|
||||
|
||||
@@ -48,9 +48,22 @@ message HostSet {
|
||||
repeated string host_ids = 100 [json_name="host_ids"];
|
||||
|
||||
// An ordered list of endpoint preferences used to choose from among
|
||||
// multiple possible endpoints for a host.
|
||||
// multiple possible endpoints for a host. Preferences are specified by
|
||||
// "cidr:<valid IPv4/6 CIDR>" or "dns:<globbed name>", specifying which IP
|
||||
// address or DNS name out of a host's available possibilities should be
|
||||
// preferred. If no preferences are specified, a value will be chosen from
|
||||
// among all avialable values using a built-in priority order. May not be
|
||||
// valid for all plugin types.
|
||||
repeated string preferred_endpoints = 101 [json_name="preferred_endpoints", (custom_options.v1.generate_sdk_option) = true];
|
||||
|
||||
// An interger number of seconds indicating the amount of time that should
|
||||
// elapse between syncs of the host set. The interval will be applied to the
|
||||
// end of the previous sync operation, not the start. Setting to any
|
||||
// negative value will disable syncing for that host set; setting to zero
|
||||
// will cause the set to use Boundary's default. The default may change
|
||||
// between releases. May not be valid for all plugin types.
|
||||
google.protobuf.Int32Value sync_interval_seconds = 102 [json_name="sync_interval_seconds", (custom_options.v1.generate_sdk_option) = true, (custom_options.v1.mask_mapping) = {this:"sync_interval_seconds" that: "SyncIntervalSeconds"}];
|
||||
|
||||
// The attributes that are applicable for the specific Host Set type.
|
||||
google.protobuf.Struct attributes = 110 [(custom_options.v1.generate_sdk_option) = true];
|
||||
|
||||
|
||||
@@ -93,6 +93,10 @@ message HostSet {
|
||||
// preferred_endpoints stores string preference values
|
||||
// @inject_tag: `gorm:"-"`
|
||||
repeated string preferred_endpoints = 11;
|
||||
|
||||
// Sync interval is a value representing a duration in seconds
|
||||
// @inject_tag: `gorm:"default:null"`
|
||||
int32 sync_interval_seconds = 12 [(custom_options.v1.mask_mapping) = {this: "SyncIntervalSeconds" that: "sync_interval_seconds"}];
|
||||
}
|
||||
|
||||
message HostCatalogSecret {
|
||||
|
||||
@@ -117,3 +117,10 @@ message HostSetMember {
|
||||
// @inject_tag: `gorm:"default:null"`
|
||||
string catalog_id = 3;
|
||||
}
|
||||
|
||||
// These fields are not implemented yet on the host set. They are captured
|
||||
// here for the purpose of identifying the mask maps which are on the top level
|
||||
// api set resource but aren't present in the static host set storage.
|
||||
message UnimplementedSetFields {
|
||||
int32 sync_interval_seconds = 22 [(custom_options.v1.mask_mapping) = {this: "SyncIntervalSeconds" that: "sync_interval_seconds"}];
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"github.com/hashicorp/boundary/internal/host/plugin"
|
||||
plugstore "github.com/hashicorp/boundary/internal/host/plugin/store"
|
||||
"github.com/hashicorp/boundary/internal/host/static"
|
||||
"github.com/hashicorp/boundary/internal/host/static/store"
|
||||
staticstore "github.com/hashicorp/boundary/internal/host/static/store"
|
||||
"github.com/hashicorp/boundary/internal/libs/endpoint"
|
||||
"github.com/hashicorp/boundary/internal/perms"
|
||||
hostplugin "github.com/hashicorp/boundary/internal/plugin/host"
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
maskManager handlers.MaskManager
|
||||
maskManager = map[subtypes.Subtype]handlers.MaskManager{}
|
||||
|
||||
// IdActions contains the set of actions that can be performed on
|
||||
// individual resources
|
||||
@@ -64,7 +64,10 @@ var (
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
if maskManager, err = handlers.NewMaskManager(handlers.MaskDestination{&store.HostSet{}}, handlers.MaskSource{&pb.HostSet{}}); err != nil {
|
||||
if maskManager[static.Subtype], err = handlers.NewMaskManager(handlers.MaskDestination{&staticstore.HostSet{}, &staticstore.UnimplementedSetFields{}}, handlers.MaskSource{&pb.HostSet{}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if maskManager[plugin.Subtype], err = handlers.NewMaskManager(handlers.MaskDestination{&plugstore.HostSet{}}, handlers.MaskSource{&pb.HostSet{}}); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -517,7 +520,7 @@ func (s Service) updateInRepo(ctx context.Context, scopeId, catalogId string, re
|
||||
return nil, nil, errors.Wrap(ctx, err, op, errors.WithMsg("Unable to build host set for update"))
|
||||
}
|
||||
h.PublicId = req.GetId()
|
||||
dbMask := maskManager.Translate(req.GetUpdateMask().GetPaths())
|
||||
dbMask := maskManager[static.Subtype].Translate(req.GetUpdateMask().GetPaths())
|
||||
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."})
|
||||
}
|
||||
@@ -817,7 +820,10 @@ func toProto(ctx context.Context, in host.Set, hosts []host.Host, opt ...handler
|
||||
switch h := in.(type) {
|
||||
case *plugin.HostSet:
|
||||
if outputFields.Has(globals.PreferredEndpointsField) {
|
||||
out.PreferredEndpoints = h.GetPreferredEndpoints()
|
||||
out.PreferredEndpoints = h.PreferredEndpoints
|
||||
}
|
||||
if outputFields.Has(globals.SyncIntervalSecondsField) && h.GetSyncIntervalSeconds() != 0 {
|
||||
out.SyncIntervalSeconds = &wrapperspb.Int32Value{Value: h.GetSyncIntervalSeconds()}
|
||||
}
|
||||
if outputFields.Has(globals.AttributesField) {
|
||||
attrs := &structpb.Struct{}
|
||||
@@ -865,6 +871,9 @@ func toStoragePluginSet(ctx context.Context, catalogId string, item *pb.HostSet)
|
||||
if item.GetPreferredEndpoints() != nil {
|
||||
opts = append(opts, plugin.WithPreferredEndpoints(item.GetPreferredEndpoints()))
|
||||
}
|
||||
if item.GetSyncIntervalSeconds() != nil {
|
||||
opts = append(opts, plugin.WithSyncIntervalSeconds(item.GetSyncIntervalSeconds().GetValue()))
|
||||
}
|
||||
hs, err := plugin.NewHostSet(ctx, catalogId, opts...)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(ctx, err, op, errors.WithMsg("Unable to build host set for creation"))
|
||||
@@ -904,6 +913,11 @@ func validateCreateRequest(ctx context.Context, req *pbs.CreateHostSetRequest) e
|
||||
if req.GetItem().GetType() != "" && req.GetItem().GetType() != plugin.Subtype.String() {
|
||||
badFields[globals.TypeField] = "Doesn't match the parent resource's type."
|
||||
}
|
||||
if val := req.GetItem().GetSyncIntervalSeconds(); val != nil {
|
||||
if val.GetValue() == 0 || val.GetValue() < -1 {
|
||||
badFields[globals.SyncIntervalSecondsField] = "Must be -1 or a positive integer."
|
||||
}
|
||||
}
|
||||
}
|
||||
return badFields
|
||||
})
|
||||
@@ -923,6 +937,12 @@ func validateUpdateRequest(ctx context.Context, req *pbs.UpdateHostSetRequest) e
|
||||
if req.GetItem().GetType() != "" && req.GetItem().GetType() != static.Subtype.String() {
|
||||
badFields[globals.TypeField] = "Cannot modify the resource type."
|
||||
}
|
||||
case plugin.Subtype:
|
||||
if val := req.GetItem().GetSyncIntervalSeconds(); val != nil {
|
||||
if val.GetValue() == 0 || val.GetValue() < -1 {
|
||||
badFields[globals.SyncIntervalSecondsField] = "Must be -1 or a positive integer."
|
||||
}
|
||||
}
|
||||
}
|
||||
return badFields
|
||||
}, static.HostSetPrefix, plugin.HostSetPrefix)
|
||||
|
||||
@@ -37,6 +37,7 @@ import (
|
||||
"google.golang.org/protobuf/testing/protocmp"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
"google.golang.org/protobuf/types/known/wrapperspb"
|
||||
)
|
||||
|
||||
var testAuthorizedActions = map[subtypes.Subtype][]string{
|
||||
@@ -168,7 +169,7 @@ func TestGet_Plugin(t *testing.T) {
|
||||
}
|
||||
|
||||
hc := plugin.TestCatalog(t, conn, proj.GetPublicId(), plg.GetPublicId())
|
||||
hs := plugin.TestSet(t, conn, kms, sche, hc, plgm, plugin.WithPreferredEndpoints(prefEndpoints))
|
||||
hs := plugin.TestSet(t, conn, kms, sche, hc, plgm, plugin.WithPreferredEndpoints(prefEndpoints), plugin.WithSyncIntervalSeconds(-1))
|
||||
|
||||
toMerge := &pbs.GetHostSetRequest{}
|
||||
|
||||
@@ -184,8 +185,9 @@ func TestGet_Plugin(t *testing.T) {
|
||||
Name: plg.GetName(),
|
||||
Description: plg.GetDescription(),
|
||||
},
|
||||
PreferredEndpoints: prefEndpoints,
|
||||
AuthorizedActions: testAuthorizedActions[plugin.Subtype],
|
||||
PreferredEndpoints: prefEndpoints,
|
||||
SyncIntervalSeconds: &wrappers.Int32Value{Value: -1},
|
||||
AuthorizedActions: testAuthorizedActions[plugin.Subtype],
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
@@ -373,7 +375,7 @@ func TestList_Plugin(t *testing.T) {
|
||||
|
||||
var wantHs []*pb.HostSet
|
||||
for i := 0; i < 10; i++ {
|
||||
h := plugin.TestSet(t, conn, kms, sche, hc, plgm, plugin.WithPreferredEndpoints(preferredEndpoints))
|
||||
h := plugin.TestSet(t, conn, kms, sche, hc, plgm, plugin.WithPreferredEndpoints(preferredEndpoints), plugin.WithSyncIntervalSeconds(5))
|
||||
wantHs = append(wantHs, &pb.HostSet{
|
||||
Id: h.GetPublicId(),
|
||||
HostCatalogId: h.GetCatalogId(),
|
||||
@@ -383,12 +385,13 @@ func TestList_Plugin(t *testing.T) {
|
||||
Name: plg.GetName(),
|
||||
Description: plg.GetDescription(),
|
||||
},
|
||||
CreatedTime: h.GetCreateTime().GetTimestamp(),
|
||||
UpdatedTime: h.GetUpdateTime().GetTimestamp(),
|
||||
Version: h.GetVersion(),
|
||||
Type: plugin.Subtype.String(),
|
||||
AuthorizedActions: testAuthorizedActions[plugin.Subtype],
|
||||
PreferredEndpoints: preferredEndpoints,
|
||||
CreatedTime: h.GetCreateTime().GetTimestamp(),
|
||||
UpdatedTime: h.GetUpdateTime().GetTimestamp(),
|
||||
Version: h.GetVersion(),
|
||||
Type: plugin.Subtype.String(),
|
||||
AuthorizedActions: testAuthorizedActions[plugin.Subtype],
|
||||
PreferredEndpoints: preferredEndpoints,
|
||||
SyncIntervalSeconds: &wrappers.Int32Value{Value: 5},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -856,10 +859,11 @@ func TestCreate_Plugin(t *testing.T) {
|
||||
{
|
||||
name: "No Attributes",
|
||||
req: &pbs.CreateHostSetRequest{Item: &pb.HostSet{
|
||||
HostCatalogId: hc.GetPublicId(),
|
||||
Name: &wrappers.StringValue{Value: "No Attributes"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: plugin.Subtype.String(),
|
||||
HostCatalogId: hc.GetPublicId(),
|
||||
Name: &wrappers.StringValue{Value: "No Attributes"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: plugin.Subtype.String(),
|
||||
SyncIntervalSeconds: &wrapperspb.Int32Value{Value: -1},
|
||||
}},
|
||||
res: &pbs.CreateHostSetResponse{
|
||||
Uri: fmt.Sprintf("host-sets/%s_", plugin.HostSetPrefix),
|
||||
@@ -871,21 +875,23 @@ func TestCreate_Plugin(t *testing.T) {
|
||||
Name: plg.GetName(),
|
||||
Description: plg.GetDescription(),
|
||||
},
|
||||
Name: &wrappers.StringValue{Value: "No Attributes"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: plugin.Subtype.String(),
|
||||
AuthorizedActions: testAuthorizedActions[plugin.Subtype],
|
||||
Name: &wrappers.StringValue{Value: "No Attributes"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: plugin.Subtype.String(),
|
||||
AuthorizedActions: testAuthorizedActions[plugin.Subtype],
|
||||
SyncIntervalSeconds: &wrapperspb.Int32Value{Value: -1},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "With Attributes",
|
||||
req: &pbs.CreateHostSetRequest{Item: &pb.HostSet{
|
||||
HostCatalogId: hc.GetPublicId(),
|
||||
Name: &wrappers.StringValue{Value: "With Attributes"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: plugin.Subtype.String(),
|
||||
Attributes: testInputAttrs,
|
||||
HostCatalogId: hc.GetPublicId(),
|
||||
Name: &wrappers.StringValue{Value: "With Attributes"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: plugin.Subtype.String(),
|
||||
SyncIntervalSeconds: &wrapperspb.Int32Value{Value: 90},
|
||||
Attributes: testInputAttrs,
|
||||
}},
|
||||
res: &pbs.CreateHostSetResponse{
|
||||
Uri: fmt.Sprintf("host-sets/%s_", plugin.HostSetPrefix),
|
||||
@@ -897,11 +903,12 @@ func TestCreate_Plugin(t *testing.T) {
|
||||
Name: plg.GetName(),
|
||||
Description: plg.GetDescription(),
|
||||
},
|
||||
Name: &wrappers.StringValue{Value: "With Attributes"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: plugin.Subtype.String(),
|
||||
AuthorizedActions: testAuthorizedActions[plugin.Subtype],
|
||||
Attributes: testOutputAttrs,
|
||||
Name: &wrappers.StringValue{Value: "With Attributes"},
|
||||
Description: &wrappers.StringValue{Value: "desc"},
|
||||
Type: plugin.Subtype.String(),
|
||||
SyncIntervalSeconds: &wrapperspb.Int32Value{Value: 90},
|
||||
AuthorizedActions: testAuthorizedActions[plugin.Subtype],
|
||||
Attributes: testOutputAttrs,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -56,8 +56,20 @@ type HostSet struct {
|
||||
// Output only. A list of Hosts in this Host Set.
|
||||
HostIds []string `protobuf:"bytes,100,rep,name=host_ids,proto3" json:"host_ids,omitempty"`
|
||||
// An ordered list of endpoint preferences used to choose from among
|
||||
// multiple possible endpoints for a host.
|
||||
// multiple possible endpoints for a host. Preferences are specified by
|
||||
// "cidr:<valid IPv4/6 CIDR>" or "dns:<globbed name>", specifying which IP
|
||||
// address or DNS name out of a host's available possibilities should be
|
||||
// preferred. If no preferences are specified, a value will be chosen from
|
||||
// among all avialable values using a built-in priority order. May not be
|
||||
// valid for all plugin types.
|
||||
PreferredEndpoints []string `protobuf:"bytes,101,rep,name=preferred_endpoints,proto3" json:"preferred_endpoints,omitempty"`
|
||||
// An interger number of seconds indicating the amount of time that should
|
||||
// elapse between syncs of the host set. The interval will be applied to the
|
||||
// end of the previous sync operation, not the start. Setting to any
|
||||
// negative value will disable syncing for that host set; setting to zero
|
||||
// will cause the set to use Boundary's default. The default may change
|
||||
// between releases. May not be valid for all plugin types.
|
||||
SyncIntervalSeconds *wrapperspb.Int32Value `protobuf:"bytes,102,opt,name=sync_interval_seconds,proto3" json:"sync_interval_seconds,omitempty"`
|
||||
// The attributes that are applicable for the specific Host Set type.
|
||||
Attributes *structpb.Struct `protobuf:"bytes,110,opt,name=attributes,proto3" json:"attributes,omitempty"`
|
||||
// Output only. The available actions on this resource for this user.
|
||||
@@ -180,6 +192,13 @@ func (x *HostSet) GetPreferredEndpoints() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *HostSet) GetSyncIntervalSeconds() *wrapperspb.Int32Value {
|
||||
if x != nil {
|
||||
return x.SyncIntervalSeconds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *HostSet) GetAttributes() *structpb.Struct {
|
||||
if x != nil {
|
||||
return x.Attributes
|
||||
@@ -217,7 +236,7 @@ var file_controller_api_resources_hostsets_v1_host_set_proto_rawDesc = []byte{
|
||||
0x70, 0x6c, 0x75, 0x67, 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, 0xef, 0x05, 0x0a, 0x07, 0x48, 0x6f, 0x73,
|
||||
0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xf9, 0x06, 0x0a, 0x07, 0x48, 0x6f, 0x73,
|
||||
0x74, 0x53, 0x65, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x02, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x63, 0x61, 0x74,
|
||||
0x61, 0x6c, 0x6f, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x14, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x68,
|
||||
@@ -257,20 +276,28 @@ var file_controller_api_resources_hostsets_v1_host_set_proto_rawDesc = []byte{
|
||||
0x64, 0x73, 0x12, 0x36, 0x0a, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f,
|
||||
0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x18, 0x65, 0x20, 0x03, 0x28, 0x09, 0x42,
|
||||
0x04, 0xa0, 0xda, 0x29, 0x01, 0x52, 0x13, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64,
|
||||
0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x3d, 0x0a, 0x0a, 0x61, 0x74,
|
||||
0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 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, 0x0a, 0x61,
|
||||
0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 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, 0x42, 0x52, 0x5a, 0x50, 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, 0x73, 0x65, 0x74, 0x73, 0x3b, 0x68, 0x6f, 0x73, 0x74, 0x73, 0x65, 0x74, 0x73, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x73, 0x12, 0x87, 0x01, 0x0a, 0x15, 0x73,
|
||||
0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x63,
|
||||
0x6f, 0x6e, 0x64, 0x73, 0x18, 0x66, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74,
|
||||
0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x34, 0xa0, 0xda, 0x29, 0x01, 0xc2, 0xdd, 0x29,
|
||||
0x2c, 0x0a, 0x15, 0x73, 0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
|
||||
0x5f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x13, 0x53, 0x79, 0x6e, 0x63, 0x49, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x52, 0x15, 0x73,
|
||||
0x79, 0x6e, 0x63, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x73, 0x65, 0x63,
|
||||
0x6f, 0x6e, 0x64, 0x73, 0x12, 0x3d, 0x0a, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74,
|
||||
0x65, 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, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75,
|
||||
0x74, 0x65, 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, 0x42, 0x52, 0x5a, 0x50, 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, 0x73, 0x65, 0x74, 0x73, 0x3b,
|
||||
0x68, 0x6f, 0x73, 0x74, 0x73, 0x65, 0x74, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -292,7 +319,8 @@ var file_controller_api_resources_hostsets_v1_host_set_proto_goTypes = []interfa
|
||||
(*plugins.PluginInfo)(nil), // 2: controller.api.resources.plugins.v1.PluginInfo
|
||||
(*wrapperspb.StringValue)(nil), // 3: google.protobuf.StringValue
|
||||
(*timestamppb.Timestamp)(nil), // 4: google.protobuf.Timestamp
|
||||
(*structpb.Struct)(nil), // 5: google.protobuf.Struct
|
||||
(*wrapperspb.Int32Value)(nil), // 5: google.protobuf.Int32Value
|
||||
(*structpb.Struct)(nil), // 6: google.protobuf.Struct
|
||||
}
|
||||
var file_controller_api_resources_hostsets_v1_host_set_proto_depIdxs = []int32{
|
||||
1, // 0: controller.api.resources.hostsets.v1.HostSet.scope:type_name -> controller.api.resources.scopes.v1.ScopeInfo
|
||||
@@ -301,12 +329,13 @@ var file_controller_api_resources_hostsets_v1_host_set_proto_depIdxs = []int32{
|
||||
3, // 3: controller.api.resources.hostsets.v1.HostSet.description:type_name -> google.protobuf.StringValue
|
||||
4, // 4: controller.api.resources.hostsets.v1.HostSet.created_time:type_name -> google.protobuf.Timestamp
|
||||
4, // 5: controller.api.resources.hostsets.v1.HostSet.updated_time:type_name -> google.protobuf.Timestamp
|
||||
5, // 6: controller.api.resources.hostsets.v1.HostSet.attributes:type_name -> google.protobuf.Struct
|
||||
7, // [7:7] is the sub-list for method output_type
|
||||
7, // [7:7] is the sub-list for method input_type
|
||||
7, // [7:7] is the sub-list for extension type_name
|
||||
7, // [7:7] is the sub-list for extension extendee
|
||||
0, // [0:7] is the sub-list for field type_name
|
||||
5, // 6: controller.api.resources.hostsets.v1.HostSet.sync_interval_seconds:type_name -> google.protobuf.Int32Value
|
||||
6, // 7: controller.api.resources.hostsets.v1.HostSet.attributes:type_name -> google.protobuf.Struct
|
||||
8, // [8:8] is the sub-list for method output_type
|
||||
8, // [8:8] is the sub-list for method input_type
|
||||
8, // [8:8] is the sub-list for extension type_name
|
||||
8, // [8:8] is the sub-list for extension extendee
|
||||
0, // [0:8] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_controller_api_resources_hostsets_v1_host_set_proto_init() }
|
||||
|
||||
Reference in new issue
Block a user