diff --git a/controller/persistence/migration_initialize.go b/controller/persistence/migration_initialize.go index e5dfb1114..b530a92a5 100644 --- a/controller/persistence/migration_initialize.go +++ b/controller/persistence/migration_initialize.go @@ -416,6 +416,17 @@ var hostV1SchemaSansDefs = map[string]interface{}{ "type": "boolean", "description": "Associate the hosting terminator with the name of the hosting tunneler's identity. Setting this to 'true' is equivalent to setting 'identiy=$tunneler_id.name'", }, + "cost": map[string]interface{}{ + "type": "integer", + "minimum": 0, + "maximum": 65535, + "description": "defaults to 0", + }, + "precedence": map[string]interface{}{ + "type": "string", + "enum": []interface{}{"default", "required", "failed"}, + "description": "defaults to 'default'", + }, }, }, }, diff --git a/controller/persistence/migrations.go b/controller/persistence/migrations.go index 234ef92bb..5230b7238 100644 --- a/controller/persistence/migrations.go +++ b/controller/persistence/migrations.go @@ -22,7 +22,7 @@ import ( ) const ( - CurrentDbVersion = 25 + CurrentDbVersion = 26 FieldVersion = "version" ) @@ -108,7 +108,11 @@ func (m *Migrations) migrate(step *boltz.MigrationStep) int { step.SetError(m.stores.ConfigType.Update(step.Ctx, interceptV1ConfigType, nil)) step.SetError(m.stores.ConfigType.Update(step.Ctx, hostV1ConfigType, nil)) step.SetError(m.stores.ConfigType.Update(step.Ctx, hostV2ConfigType, nil)) + } + if step.CurrentVersion < 26 { + step.SetError(m.stores.ConfigType.Update(step.Ctx, hostV1ConfigType, nil)) + step.SetError(m.stores.ConfigType.Update(step.Ctx, hostV2ConfigType, nil)) } // current version diff --git a/tunnel/entities/host.v1.json b/tunnel/entities/host.v1.json index c97ca8eb9..9b7a593bd 100644 --- a/tunnel/entities/host.v1.json +++ b/tunnel/entities/host.v1.json @@ -242,6 +242,12 @@ "minimum": 0, "type": "integer" }, + "cost": { + "description": "defaults to 0", + "maximum": 65535, + "minimum": 0, + "type": "integer" + }, "identity": { "description": "Associate the hosting terminator with the specified identity. '$tunneler_id.name' resolves to the name of the hosting tunneler's identity. '$tunneler_id.tag[tagName]' resolves to the value of the 'tagName' tag on the hosting tunneler's identity.", "type": "string" @@ -250,6 +256,15 @@ "description": "defaults to 3", "minimum": 1, "type": "integer" + }, + "precedence": { + "description": "defaults to 'default'", + "enum": [ + "default", + "required", + "failed" + ], + "type": "string" } }, "type": "object" diff --git a/tunnel/entities/host.v2.json b/tunnel/entities/host.v2.json index 1f9ddb60b..9d92f5c88 100644 --- a/tunnel/entities/host.v2.json +++ b/tunnel/entities/host.v2.json @@ -364,6 +364,12 @@ "connectTimeout": { "$ref": "#/definitions/duration" }, + "cost": { + "description": "defaults to 0", + "maximum": 65535, + "minimum": 0, + "type": "integer" + }, "identity": { "description": "Associate the hosting terminator with the specified identity. '$tunneler_id.name' resolves to the name of the hosting tunneler's identity. '$tunneler_id.tag[tagName]' resolves to the value of the 'tagName' tag on the hosting tunneler's identity.", "type": "string" @@ -372,6 +378,15 @@ "description": "defaults to 3", "minimum": 1, "type": "integer" + }, + "precedence": { + "description": "defaults to 'default'", + "enum": [ + "default", + "required", + "failed" + ], + "type": "string" } }, "type": "object" diff --git a/tunnel/entities/service.go b/tunnel/entities/service.go index 9eb54ad0f..ece9a1a50 100644 --- a/tunnel/entities/service.go +++ b/tunnel/entities/service.go @@ -72,8 +72,10 @@ func (self *ServiceConfig) ToHostV2Config() *HostV2Config { type HostV1ListenOptions struct { BindUsingEdgeIdentity bool ConnectTimeoutSeconds *int + Cost *uint16 Identity string MaxConnections int + Precedence *string } type HostV1Config struct { @@ -119,8 +121,10 @@ func (self *HostV1Config) ToHostV2Config() *HostV2Config { terminator.ListenOptions = &HostV2ListenOptions{ BindUsingEdgeIdentity: self.ListenOptions.BindUsingEdgeIdentity, ConnectTimeout: timeout, + Cost: self.ListenOptions.Cost, Identity: self.ListenOptions.Identity, MaxConnections: self.ListenOptions.MaxConnections, + Precedence: self.ListenOptions.Precedence, } } @@ -134,8 +138,10 @@ func (self *HostV1Config) ToHostV2Config() *HostV2Config { type HostV2ListenOptions struct { BindUsingEdgeIdentity bool ConnectTimeout *time.Duration + Cost *uint16 Identity string MaxConnections int + Precedence *string } type allowedAddress interface { diff --git a/tunnel/intercept/hosting.go b/tunnel/intercept/hosting.go index f2a5c1cc7..5d7497b45 100644 --- a/tunnel/intercept/hosting.go +++ b/tunnel/intercept/hosting.go @@ -233,6 +233,15 @@ func getDefaultOptions(service *entities.Service, identity *edge.CurrentIdentity options.Precedence = ziti.GetPrecedenceForLabel(identity.DefaultHostingPrecedence) options.Cost = identity.DefaultHostingCost + if config.ListenOptions != nil { + if config.ListenOptions.Cost != nil { + options.Cost = *config.ListenOptions.Cost + } + if config.ListenOptions.Precedence != nil { + options.Precedence = ziti.GetPrecedenceForLabel(*config.ListenOptions.Precedence) + } + } + if val, ok := identity.ServiceHostingPrecedences[service.Id]; ok { if strVal, ok := val.(string); ok { options.Precedence = ziti.GetPrecedenceForLabel(strVal)