2019-07-30 22:40:45 +00:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
// CheckRestart describes if and when a task should be restarted based on
|
|
|
|
// failing health checks.
|
|
|
|
type CheckRestart struct {
|
|
|
|
Limit int `mapstructure:"limit"`
|
|
|
|
Grace *time.Duration `mapstructure:"grace"`
|
|
|
|
IgnoreWarnings bool `mapstructure:"ignore_warnings"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Canonicalize CheckRestart fields if not nil.
|
|
|
|
func (c *CheckRestart) Canonicalize() {
|
|
|
|
if c == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if c.Grace == nil {
|
|
|
|
c.Grace = timeToPtr(1 * time.Second)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Copy returns a copy of CheckRestart or nil if unset.
|
|
|
|
func (c *CheckRestart) Copy() *CheckRestart {
|
|
|
|
if c == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
nc := new(CheckRestart)
|
|
|
|
nc.Limit = c.Limit
|
|
|
|
if c.Grace != nil {
|
|
|
|
g := *c.Grace
|
|
|
|
nc.Grace = &g
|
|
|
|
}
|
|
|
|
nc.IgnoreWarnings = c.IgnoreWarnings
|
|
|
|
return nc
|
|
|
|
}
|
|
|
|
|
|
|
|
// Merge values from other CheckRestart over default values on this
|
|
|
|
// CheckRestart and return merged copy.
|
|
|
|
func (c *CheckRestart) Merge(o *CheckRestart) *CheckRestart {
|
|
|
|
if c == nil {
|
|
|
|
// Just return other
|
|
|
|
return o
|
|
|
|
}
|
|
|
|
|
|
|
|
nc := c.Copy()
|
|
|
|
|
|
|
|
if o == nil {
|
|
|
|
// Nothing to merge
|
|
|
|
return nc
|
|
|
|
}
|
|
|
|
|
|
|
|
if o.Limit > 0 {
|
|
|
|
nc.Limit = o.Limit
|
|
|
|
}
|
|
|
|
|
|
|
|
if o.Grace != nil {
|
|
|
|
nc.Grace = o.Grace
|
|
|
|
}
|
|
|
|
|
|
|
|
if o.IgnoreWarnings {
|
|
|
|
nc.IgnoreWarnings = o.IgnoreWarnings
|
|
|
|
}
|
|
|
|
|
|
|
|
return nc
|
|
|
|
}
|
|
|
|
|
|
|
|
// ServiceCheck represents the consul health check that Nomad registers.
|
|
|
|
type ServiceCheck struct {
|
|
|
|
//FIXME Id is unused. Remove?
|
2020-08-08 01:22:06 +00:00
|
|
|
Id string
|
|
|
|
Name string
|
|
|
|
Type string
|
|
|
|
Command string
|
|
|
|
Args []string
|
|
|
|
Path string
|
|
|
|
Protocol string
|
|
|
|
PortLabel string `mapstructure:"port"`
|
|
|
|
Expose bool
|
|
|
|
AddressMode string `mapstructure:"address_mode"`
|
|
|
|
Interval time.Duration
|
|
|
|
Timeout time.Duration
|
|
|
|
InitialStatus string `mapstructure:"initial_status"`
|
|
|
|
TLSSkipVerify bool `mapstructure:"tls_skip_verify"`
|
|
|
|
Header map[string][]string
|
|
|
|
Method string
|
|
|
|
CheckRestart *CheckRestart `mapstructure:"check_restart"`
|
|
|
|
GRPCService string `mapstructure:"grpc_service"`
|
|
|
|
GRPCUseTLS bool `mapstructure:"grpc_use_tls"`
|
|
|
|
TaskName string `mapstructure:"task"`
|
|
|
|
SuccessBeforePassing int `mapstructure:"success_before_passing"`
|
|
|
|
FailuresBeforeCritical int `mapstructure:"failures_before_critical"`
|
2019-07-30 22:40:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Service represents a Consul service definition.
|
|
|
|
type Service struct {
|
|
|
|
//FIXME Id is unused. Remove?
|
client: enable configuring enable_tag_override for services
Consul provides a feature of Service Definitions where the tags
associated with a service can be modified through the Catalog API,
overriding the value(s) configured in the agent's service configuration.
To enable this feature, the flag enable_tag_override must be configured
in the service definition.
Previously, Nomad did not allow configuring this flag, and thus the default
value of false was used. Now, it is configurable.
Because Nomad itself acts as a state machine around the the service definitions
of the tasks it manages, it's worth describing what happens when this feature
is enabled and why.
Consider the basic case where there is no Nomad, and your service is provided
to consul as a boring JSON file. The ultimate source of truth for the definition
of that service is the file, and is stored in the agent. Later, Consul performs
"anti-entropy" which synchronizes the Catalog (stored only the leaders). Then
with enable_tag_override=true, the tags field is available for "external"
modification through the Catalog API (rather than directly configuring the
service definition file, or using the Agent API). The important observation
is that if the service definition ever changes (i.e. the file is changed &
config reloaded OR the Agent API is used to modify the service), those
"external" tag values are thrown away, and the new service definition is
once again the source of truth.
In the Nomad case, Nomad itself is the source of truth over the Agent in
the same way the JSON file was the source of truth in the example above.
That means any time Nomad sets a new service definition, any externally
configured tags are going to be replaced. When does this happen? Only on
major lifecycle events, for example when a task is modified because of an
updated job spec from the 'nomad job run <existing>' command. Otherwise,
Nomad's periodic re-sync's with Consul will now no longer try to restore
the externally modified tag values (as long as enable_tag_override=true).
Fixes #2057
2020-02-07 21:22:19 +00:00
|
|
|
Id string
|
|
|
|
Name string
|
|
|
|
Tags []string
|
|
|
|
CanaryTags []string `mapstructure:"canary_tags"`
|
|
|
|
EnableTagOverride bool `mapstructure:"enable_tag_override"`
|
|
|
|
PortLabel string `mapstructure:"port"`
|
|
|
|
AddressMode string `mapstructure:"address_mode"`
|
|
|
|
Checks []ServiceCheck
|
|
|
|
CheckRestart *CheckRestart `mapstructure:"check_restart"`
|
|
|
|
Connect *ConsulConnect
|
|
|
|
Meta map[string]string
|
|
|
|
CanaryMeta map[string]string
|
2020-06-22 17:55:59 +00:00
|
|
|
TaskName string `mapstructure:"task"`
|
2019-07-30 22:40:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Canonicalize the Service by ensuring its name and address mode are set. Task
|
|
|
|
// will be nil for group services.
|
|
|
|
func (s *Service) Canonicalize(t *Task, tg *TaskGroup, job *Job) {
|
|
|
|
if s.Name == "" {
|
|
|
|
if t != nil {
|
|
|
|
s.Name = fmt.Sprintf("%s-%s-%s", *job.Name, *tg.Name, t.Name)
|
|
|
|
} else {
|
|
|
|
s.Name = fmt.Sprintf("%s-%s", *job.Name, *tg.Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Default to AddressModeAuto
|
|
|
|
if s.AddressMode == "" {
|
|
|
|
s.AddressMode = "auto"
|
|
|
|
}
|
|
|
|
|
2020-05-18 22:03:10 +00:00
|
|
|
s.Connect.Canonicalize()
|
|
|
|
|
2019-07-30 22:40:45 +00:00
|
|
|
// Canonicalize CheckRestart on Checks and merge Service.CheckRestart
|
|
|
|
// into each check.
|
|
|
|
for i, check := range s.Checks {
|
|
|
|
s.Checks[i].CheckRestart = s.CheckRestart.Merge(check.CheckRestart)
|
|
|
|
s.Checks[i].CheckRestart.Canonicalize()
|
2020-08-08 01:22:06 +00:00
|
|
|
|
|
|
|
if s.Checks[i].SuccessBeforePassing < 0 {
|
|
|
|
s.Checks[i].SuccessBeforePassing = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
if s.Checks[i].FailuresBeforeCritical < 0 {
|
|
|
|
s.Checks[i].FailuresBeforeCritical = 0
|
|
|
|
}
|
2019-07-30 22:40:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ConsulConnect represents a Consul Connect jobspec stanza.
|
|
|
|
type ConsulConnect struct {
|
2020-06-22 17:55:59 +00:00
|
|
|
Native bool
|
2020-07-28 20:12:08 +00:00
|
|
|
Gateway *ConsulGateway
|
2019-07-30 22:40:45 +00:00
|
|
|
SidecarService *ConsulSidecarService `mapstructure:"sidecar_service"`
|
2019-08-20 05:22:46 +00:00
|
|
|
SidecarTask *SidecarTask `mapstructure:"sidecar_task"`
|
2019-07-30 22:40:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-18 22:03:10 +00:00
|
|
|
func (cc *ConsulConnect) Canonicalize() {
|
|
|
|
if cc == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
cc.SidecarService.Canonicalize()
|
|
|
|
cc.SidecarTask.Canonicalize()
|
2020-07-28 20:12:08 +00:00
|
|
|
cc.Gateway.Canonicalize()
|
2020-05-18 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
2019-07-30 22:40:45 +00:00
|
|
|
// ConsulSidecarService represents a Consul Connect SidecarService jobspec
|
|
|
|
// stanza.
|
|
|
|
type ConsulSidecarService struct {
|
2019-10-08 19:19:09 +00:00
|
|
|
Tags []string
|
2019-07-30 22:40:45 +00:00
|
|
|
Port string
|
|
|
|
Proxy *ConsulProxy
|
|
|
|
}
|
|
|
|
|
2020-05-18 22:03:10 +00:00
|
|
|
func (css *ConsulSidecarService) Canonicalize() {
|
|
|
|
if css == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(css.Tags) == 0 {
|
|
|
|
css.Tags = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
css.Proxy.Canonicalize()
|
|
|
|
}
|
|
|
|
|
2019-08-20 05:22:46 +00:00
|
|
|
// SidecarTask represents a subset of Task fields that can be set to override
|
|
|
|
// the fields of the Task generated for the sidecar
|
|
|
|
type SidecarTask struct {
|
|
|
|
Name string
|
|
|
|
Driver string
|
|
|
|
User string
|
|
|
|
Config map[string]interface{}
|
|
|
|
Env map[string]string
|
|
|
|
Resources *Resources
|
|
|
|
Meta map[string]string
|
|
|
|
KillTimeout *time.Duration `mapstructure:"kill_timeout"`
|
|
|
|
LogConfig *LogConfig `mapstructure:"logs"`
|
|
|
|
ShutdownDelay *time.Duration `mapstructure:"shutdown_delay"`
|
|
|
|
KillSignal string `mapstructure:"kill_signal"`
|
|
|
|
}
|
|
|
|
|
2020-05-18 22:03:10 +00:00
|
|
|
func (st *SidecarTask) Canonicalize() {
|
|
|
|
if st == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(st.Config) == 0 {
|
|
|
|
st.Config = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(st.Env) == 0 {
|
|
|
|
st.Env = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if st.Resources == nil {
|
|
|
|
st.Resources = DefaultResources()
|
|
|
|
} else {
|
|
|
|
st.Resources.Canonicalize()
|
|
|
|
}
|
|
|
|
|
|
|
|
if st.LogConfig == nil {
|
|
|
|
st.LogConfig = DefaultLogConfig()
|
|
|
|
} else {
|
|
|
|
st.LogConfig.Canonicalize()
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(st.Meta) == 0 {
|
|
|
|
st.Meta = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if st.KillTimeout == nil {
|
|
|
|
st.KillTimeout = timeToPtr(5 * time.Second)
|
|
|
|
}
|
|
|
|
|
|
|
|
if st.ShutdownDelay == nil {
|
|
|
|
st.ShutdownDelay = timeToPtr(0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-30 22:40:45 +00:00
|
|
|
// ConsulProxy represents a Consul Connect sidecar proxy jobspec stanza.
|
|
|
|
type ConsulProxy struct {
|
2020-03-07 03:15:22 +00:00
|
|
|
LocalServiceAddress string `mapstructure:"local_service_address"`
|
|
|
|
LocalServicePort int `mapstructure:"local_service_port"`
|
|
|
|
ExposeConfig *ConsulExposeConfig `mapstructure:"expose"`
|
2019-09-23 18:30:48 +00:00
|
|
|
Upstreams []*ConsulUpstream
|
|
|
|
Config map[string]interface{}
|
2019-07-30 22:40:45 +00:00
|
|
|
}
|
|
|
|
|
2020-05-18 22:03:10 +00:00
|
|
|
func (cp *ConsulProxy) Canonicalize() {
|
|
|
|
if cp == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
cp.ExposeConfig.Canonicalize()
|
|
|
|
|
|
|
|
if len(cp.Upstreams) == 0 {
|
|
|
|
cp.Upstreams = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(cp.Config) == 0 {
|
|
|
|
cp.Config = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-30 22:40:45 +00:00
|
|
|
// ConsulUpstream represents a Consul Connect upstream jobspec stanza.
|
|
|
|
type ConsulUpstream struct {
|
|
|
|
DestinationName string `mapstructure:"destination_name"`
|
|
|
|
LocalBindPort int `mapstructure:"local_bind_port"`
|
|
|
|
}
|
2020-03-07 03:15:22 +00:00
|
|
|
|
|
|
|
type ConsulExposeConfig struct {
|
2020-03-12 14:37:31 +00:00
|
|
|
Path []*ConsulExposePath `mapstructure:"path"`
|
2020-03-07 03:15:22 +00:00
|
|
|
}
|
|
|
|
|
2020-05-18 22:03:10 +00:00
|
|
|
func (cec *ConsulExposeConfig) Canonicalize() {
|
|
|
|
if cec == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(cec.Path) == 0 {
|
|
|
|
cec.Path = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-07 03:15:22 +00:00
|
|
|
type ConsulExposePath struct {
|
|
|
|
Path string
|
|
|
|
Protocol string
|
|
|
|
LocalPathPort int `mapstructure:"local_path_port"`
|
|
|
|
ListenerPort string `mapstructure:"listener_port"`
|
|
|
|
}
|
2020-07-28 20:12:08 +00:00
|
|
|
|
|
|
|
// ConsulGateway is used to configure one of the Consul Connect Gateway types.
|
|
|
|
type ConsulGateway struct {
|
|
|
|
// Proxy is used to configure the Envoy instance acting as the gateway.
|
|
|
|
Proxy *ConsulGatewayProxy
|
|
|
|
|
|
|
|
// Ingress represents the Consul Configuration Entry for an Ingress Gateway.
|
|
|
|
Ingress *ConsulIngressConfigEntry
|
|
|
|
|
|
|
|
// Terminating is not yet supported.
|
|
|
|
// Terminating *ConsulTerminatingConfigEntry
|
|
|
|
|
|
|
|
// Mesh is not yet supported.
|
|
|
|
// Mesh *ConsulMeshConfigEntry
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *ConsulGateway) Canonicalize() {
|
|
|
|
if g == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
g.Proxy.Canonicalize()
|
|
|
|
g.Ingress.Canonicalize()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (g *ConsulGateway) Copy() *ConsulGateway {
|
|
|
|
if g == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ConsulGateway{
|
|
|
|
Proxy: g.Proxy.Copy(),
|
|
|
|
Ingress: g.Ingress.Copy(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type ConsulGatewayBindAddress struct {
|
|
|
|
Address string `mapstructure:"address"`
|
|
|
|
Port int `mapstructure:"port"`
|
|
|
|
}
|
|
|
|
|
|
|
|
var (
|
|
|
|
defaultGatewayConnectTimeout = 5 * time.Second
|
|
|
|
)
|
|
|
|
|
|
|
|
// ConsulGatewayProxy is used to tune parameters of the proxy instance acting as
|
|
|
|
// one of the forms of Connect gateways that Consul supports.
|
|
|
|
//
|
|
|
|
// https://www.consul.io/docs/connect/proxies/envoy#gateway-options
|
|
|
|
type ConsulGatewayProxy struct {
|
|
|
|
ConnectTimeout *time.Duration `mapstructure:"connect_timeout"`
|
|
|
|
EnvoyGatewayBindTaggedAddresses bool `mapstructure:"envoy_gateway_bind_tagged_addresses"`
|
|
|
|
EnvoyGatewayBindAddresses map[string]*ConsulGatewayBindAddress `mapstructure:"envoy_gateway_bind_addresses"`
|
|
|
|
EnvoyGatewayNoDefaultBind bool `mapstructure:"envoy_gateway_no_default_bind"`
|
|
|
|
Config map[string]interface{} // escape hatch envoy config
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *ConsulGatewayProxy) Canonicalize() {
|
|
|
|
if p == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.ConnectTimeout == nil {
|
|
|
|
// same as the default from consul
|
|
|
|
p.ConnectTimeout = timeToPtr(defaultGatewayConnectTimeout)
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(p.EnvoyGatewayBindAddresses) == 0 {
|
|
|
|
p.EnvoyGatewayBindAddresses = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(p.Config) == 0 {
|
|
|
|
p.Config = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *ConsulGatewayProxy) Copy() *ConsulGatewayProxy {
|
|
|
|
if p == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var binds map[string]*ConsulGatewayBindAddress = nil
|
|
|
|
if p.EnvoyGatewayBindAddresses != nil {
|
|
|
|
binds = make(map[string]*ConsulGatewayBindAddress, len(p.EnvoyGatewayBindAddresses))
|
|
|
|
for k, v := range p.EnvoyGatewayBindAddresses {
|
|
|
|
binds[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var config map[string]interface{} = nil
|
|
|
|
if p.Config != nil {
|
|
|
|
config = make(map[string]interface{}, len(p.Config))
|
|
|
|
for k, v := range p.Config {
|
|
|
|
config[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ConsulGatewayProxy{
|
|
|
|
ConnectTimeout: timeToPtr(*p.ConnectTimeout),
|
|
|
|
EnvoyGatewayBindTaggedAddresses: p.EnvoyGatewayBindTaggedAddresses,
|
|
|
|
EnvoyGatewayBindAddresses: binds,
|
|
|
|
EnvoyGatewayNoDefaultBind: p.EnvoyGatewayNoDefaultBind,
|
|
|
|
Config: config,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ConsulGatewayTLSConfig is used to configure TLS for a gateway.
|
|
|
|
type ConsulGatewayTLSConfig struct {
|
|
|
|
Enabled bool
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tc *ConsulGatewayTLSConfig) Canonicalize() {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (tc *ConsulGatewayTLSConfig) Copy() *ConsulGatewayTLSConfig {
|
|
|
|
if tc == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ConsulGatewayTLSConfig{
|
|
|
|
Enabled: tc.Enabled,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ConsulIngressService is used to configure a service fronted by the ingress gateway.
|
|
|
|
type ConsulIngressService struct {
|
|
|
|
// Namespace is not yet supported.
|
|
|
|
// Namespace string
|
|
|
|
Name string
|
|
|
|
|
|
|
|
Hosts []string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ConsulIngressService) Canonicalize() {
|
|
|
|
if s == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(s.Hosts) == 0 {
|
|
|
|
s.Hosts = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *ConsulIngressService) Copy() *ConsulIngressService {
|
|
|
|
if s == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var hosts []string = nil
|
|
|
|
if n := len(s.Hosts); n > 0 {
|
|
|
|
hosts = make([]string, n)
|
|
|
|
copy(hosts, s.Hosts)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ConsulIngressService{
|
|
|
|
Name: s.Name,
|
|
|
|
Hosts: hosts,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
defaultIngressListenerProtocol = "tcp"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ConsulIngressListener is used to configure a listener on a Consul Ingress
|
|
|
|
// Gateway.
|
|
|
|
type ConsulIngressListener struct {
|
|
|
|
Port int
|
|
|
|
Protocol string
|
|
|
|
Services []*ConsulIngressService
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *ConsulIngressListener) Canonicalize() {
|
|
|
|
if l == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if l.Protocol == "" {
|
|
|
|
// same as default from consul
|
|
|
|
l.Protocol = defaultIngressListenerProtocol
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(l.Services) == 0 {
|
|
|
|
l.Services = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (l *ConsulIngressListener) Copy() *ConsulIngressListener {
|
|
|
|
if l == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var services []*ConsulIngressService = nil
|
|
|
|
if n := len(l.Services); n > 0 {
|
|
|
|
services = make([]*ConsulIngressService, n)
|
|
|
|
for i := 0; i < n; i++ {
|
|
|
|
services[i] = l.Services[i].Copy()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ConsulIngressListener{
|
|
|
|
Port: l.Port,
|
|
|
|
Protocol: l.Protocol,
|
|
|
|
Services: services,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ConsulIngressConfigEntry represents the Consul Configuration Entry type for
|
|
|
|
// an Ingress Gateway.
|
|
|
|
//
|
|
|
|
// https://www.consul.io/docs/agent/config-entries/ingress-gateway#available-fields
|
|
|
|
type ConsulIngressConfigEntry struct {
|
|
|
|
// Namespace is not yet supported.
|
|
|
|
// Namespace string
|
|
|
|
|
|
|
|
TLS *ConsulGatewayTLSConfig
|
|
|
|
Listeners []*ConsulIngressListener
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ConsulIngressConfigEntry) Canonicalize() {
|
|
|
|
if e == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
e.TLS.Canonicalize()
|
|
|
|
|
|
|
|
if len(e.Listeners) == 0 {
|
|
|
|
e.Listeners = nil
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, listener := range e.Listeners {
|
|
|
|
listener.Canonicalize()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ConsulIngressConfigEntry) Copy() *ConsulIngressConfigEntry {
|
|
|
|
if e == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var listeners []*ConsulIngressListener = nil
|
|
|
|
if n := len(e.Listeners); n > 0 {
|
|
|
|
listeners = make([]*ConsulIngressListener, n)
|
|
|
|
for i := 0; i < n; i++ {
|
|
|
|
listeners[i] = e.Listeners[i].Copy()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ConsulIngressConfigEntry{
|
|
|
|
TLS: e.TLS.Copy(),
|
|
|
|
Listeners: listeners,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ConsulTerminatingConfigEntry is not yet supported.
|
|
|
|
// type ConsulTerminatingConfigEntry struct {
|
|
|
|
// }
|
|
|
|
|
|
|
|
// ConsulMeshConfigEntry is not yet supported.
|
|
|
|
// type ConsulMeshConfigEntry struct {
|
|
|
|
// }
|