diff --git a/dataclients/kubernetes/ingressv1.go b/dataclients/kubernetes/ingressv1.go index ed2431ed5b..94ebbcbbaf 100644 --- a/dataclients/kubernetes/ingressv1.go +++ b/dataclients/kubernetes/ingressv1.go @@ -151,7 +151,7 @@ func convertPathRuleV1( r := &eskip.Route{ Id: routeID(ns, name, host, prule.Path, svcName), BackendType: eskip.LBBackend, - LBEndpoints: eps, + LBEndpoints: eskip.NewLBEndpoints(eps), LBAlgorithm: getLoadBalancerAlgorithm(metadata, defaultLoadBalancerAlgorithm), HostRegexps: hostRegexp, } @@ -397,7 +397,7 @@ func (ing *ingress) convertDefaultBackendV1( return &eskip.Route{ Id: routeID(ns, name, "", "", ""), BackendType: eskip.LBBackend, - LBEndpoints: eps, + LBEndpoints: eskip.NewLBEndpoints(eps), LBAlgorithm: getLoadBalancerAlgorithm(i.Metadata, ing.defaultLoadBalancerAlgorithm), }, true, nil } diff --git a/dataclients/kubernetes/routegroup.go b/dataclients/kubernetes/routegroup.go index 4ec23928f9..50f1d676e5 100644 --- a/dataclients/kubernetes/routegroup.go +++ b/dataclients/kubernetes/routegroup.go @@ -208,7 +208,7 @@ func applyServiceBackend(ctx *routeGroupContext, backend *definitions.SkipperBac } r.BackendType = eskip.LBBackend - r.LBEndpoints = eps + r.LBEndpoints = eskip.NewLBEndpoints(eps) r.LBAlgorithm = ctx.defaultLoadBalancerAlgorithm if backend.Algorithm != loadbalancer.None { r.LBAlgorithm = backend.Algorithm.String() @@ -261,7 +261,7 @@ func applyBackend(ctx *routeGroupContext, backend *definitions.SkipperBackend, r } } - r.LBEndpoints = backend.Endpoints + r.LBEndpoints = eskip.NewLBEndpoints(backend.Endpoints) r.LBAlgorithm = ctx.defaultLoadBalancerAlgorithm if backend.Algorithm != loadbalancer.None { r.LBAlgorithm = backend.Algorithm.String() diff --git a/eskip/copy.go b/eskip/copy.go index ff454b5225..1a2088e0b4 100644 --- a/eskip/copy.go +++ b/eskip/copy.go @@ -65,7 +65,7 @@ func Copy(r *Route) *Route { c.BackendType = r.BackendType c.Backend = r.Backend c.LBAlgorithm = r.LBAlgorithm - c.LBEndpoints = make([]string, len(r.LBEndpoints)) + c.LBEndpoints = make([]*LBEndpoint, len(r.LBEndpoints)) copy(c.LBEndpoints, r.LBEndpoints) return c } diff --git a/eskip/copy_test.go b/eskip/copy_test.go index 132782a34c..0f15249f70 100644 --- a/eskip/copy_test.go +++ b/eskip/copy_test.go @@ -42,7 +42,7 @@ func TestCopy(t *testing.T) { checkFilter(t, c.Filters[i], r.Filters[i]) } - r.LBEndpoints[0] = "test-slice-identity" + r.LBEndpoints[0] = &LBEndpoint{Address: "test-slice-identity"} if c.LBEndpoints[0] == r.LBEndpoints[0] { t.Error("failed to copy LB endpoints") } @@ -132,7 +132,10 @@ func TestCopy(t *testing.T) { }, BackendType: LBBackend, LBAlgorithm: "roundRobin", - LBEndpoints: []string{"10.0.0.1:80", "10.0.0.2:80"}, + LBEndpoints: []*LBEndpoint{ + {Address: "10.0.0.1:80"}, + {Address: "10.0.0.2:80"}, + }, } c := Copy(r) @@ -154,7 +157,10 @@ func TestCopy(t *testing.T) { }, BackendType: LBBackend, LBAlgorithm: "roundRobin", - LBEndpoints: []string{"10.0.1.1:80", "10.0.1.2:80"}, + LBEndpoints: []*LBEndpoint{ + {Address: "10.0.1.1:80"}, + {Address: "10.0.1.2:80"}, + }, }, { Id: "route2", Predicates: []*Predicate{ @@ -169,7 +175,10 @@ func TestCopy(t *testing.T) { }, BackendType: LBBackend, LBAlgorithm: "roundRobin", - LBEndpoints: []string{"10.0.2.1:80", "10.0.2.2:80"}, + LBEndpoints: []*LBEndpoint{ + {Address: "10.0.2.1:80"}, + {Address: "10.0.2.2:80"}, + }, }, { Id: "route3", Predicates: []*Predicate{ @@ -184,7 +193,10 @@ func TestCopy(t *testing.T) { }, BackendType: LBBackend, LBAlgorithm: "roundRobin", - LBEndpoints: []string{"10.0.3.1:80", "10.0.3.2:80"}, + LBEndpoints: []*LBEndpoint{ + {Address: "10.0.3.1:80"}, + {Address: "10.0.3.2:80"}, + }, }} c := CopyRoutes(r) diff --git a/eskip/eq.go b/eskip/eq.go index 49d18658e6..bbe2eb36b9 100644 --- a/eskip/eq.go +++ b/eskip/eq.go @@ -40,13 +40,13 @@ func eqArgs(left, right []interface{}) bool { return true } -func eqStrings(left, right []string) bool { +func eqLBEndpoints(left, right []*LBEndpoint) bool { if len(left) != len(right) { return false } for i := range left { - if left[i] != right[i] { + if left[i].Address != right[i].Address || left[i].Zone != right[i].Zone { return false } } @@ -103,7 +103,7 @@ func eq2(left, right *Route) bool { return false } - if !eqStrings(lc.LBEndpoints, rc.LBEndpoints) { + if !eqLBEndpoints(lc.LBEndpoints, rc.LBEndpoints) { return false } @@ -255,9 +255,11 @@ func Canonical(r *Route) *Route { case LBBackend: // using the LB fields only when apply: c.LBAlgorithm = r.LBAlgorithm - c.LBEndpoints = make([]string, len(r.LBEndpoints)) + c.LBEndpoints = make([]*LBEndpoint, len(r.LBEndpoints)) copy(c.LBEndpoints, r.LBEndpoints) - sort.Strings(c.LBEndpoints) + sort.Slice(c.LBEndpoints, func(i, j int) bool { + return c.LBEndpoints[i].Address < c.LBEndpoints[j].Address + }) } // Name and Namespace stripped diff --git a/eskip/eq_test.go b/eskip/eq_test.go index 5635ed9698..1e739a8386 100644 --- a/eskip/eq_test.go +++ b/eskip/eq_test.go @@ -99,14 +99,14 @@ func TestEq(t *testing.T) { }, { title: "non-eq lb endpoint count", routes: []*Route{ - {BackendType: LBBackend, LBEndpoints: []string{"", ""}}, - {BackendType: LBBackend, LBEndpoints: []string{""}}, + {BackendType: LBBackend, LBEndpoints: []*LBEndpoint{{Address: "https://one.example.org"}, {Address: "https://one.example.org"}}}, + {BackendType: LBBackend, LBEndpoints: []*LBEndpoint{{Address: "https://one.example.org"}}}, }, }, { title: "non-eq lb endpoints", routes: []*Route{ - {BackendType: LBBackend, LBEndpoints: []string{"https://one.example.org"}}, - {BackendType: LBBackend, LBEndpoints: []string{"https://two.example.org"}}, + {BackendType: LBBackend, LBEndpoints: []*LBEndpoint{{Address: "https://one.example.org"}}}, + {BackendType: LBBackend, LBEndpoints: []*LBEndpoint{{Address: "https://two.example.org"}}}, }, }, { title: "all eq", @@ -116,14 +116,14 @@ func TestEq(t *testing.T) { Filters: []*Filter{{Name: "foo", Args: []interface{}{3, 4}}}, BackendType: LBBackend, LBAlgorithm: "random", - LBEndpoints: []string{"https://one.example.org", "https://two.example.org"}, + LBEndpoints: []*LBEndpoint{{Address: "https://one.example.org"}, {Address: "https://two.example.org"}}, }, { Id: "foo", Predicates: []*Predicate{{Name: "Foo", Args: []interface{}{1, 2}}}, Filters: []*Filter{{Name: "foo", Args: []interface{}{3, 4}}}, BackendType: LBBackend, LBAlgorithm: "random", - LBEndpoints: []string{"https://one.example.org", "https://two.example.org"}, + LBEndpoints: []*LBEndpoint{{Address: "https://one.example.org"}, {Address: "https://two.example.org"}}, }}, expect: true, }, { @@ -282,7 +282,7 @@ func TestCanonical(t *testing.T) { expect: &Route{BackendType: NetworkBackend, Backend: "https://www.example.org"}, }, { title: "clear LB when different type", - route: &Route{LBEndpoints: []string{"https://one.example.org", "https://two.example.org"}}, + route: &Route{LBEndpoints: []*LBEndpoint{{Address: "https://one.example.org"}, {Address: "https://two.example.org"}}}, expect: &Route{}, }} { t.Run(test.title, func(t *testing.T) { diff --git a/eskip/eskip.go b/eskip/eskip.go index 229789b873..4d55a3ed4f 100644 --- a/eskip/eskip.go +++ b/eskip/eskip.go @@ -321,7 +321,7 @@ type Route struct { // LBEndpoints stores one or more backend endpoint in case of // load balancing backends. - LBEndpoints []string + LBEndpoints []*LBEndpoint // Name is deprecated and not used. Name string @@ -330,6 +330,43 @@ type Route struct { Namespace string } +func NewLBEndpoints(eps []string) []*LBEndpoint { + if len(eps) == 0 { + return nil + } + result := make([]*LBEndpoint, len(eps)) + + for i := 0; i < len(eps); i++ { + result[i] = &LBEndpoint{ + Address: eps[i], + } + } + + return result +} + +func LBEndpointString(eps []*LBEndpoint) []string { + if len(eps) == 0 { + return nil + } + result := make([]string, len(eps)) + + for i := 0; i < len(eps); i++ { + result[i] = eps[i].String() + } + + return result +} + +type LBEndpoint struct { + Address string + Zone string +} + +func (ep LBEndpoint) String() string { + return ep.Address +} + type RoutePredicate func(*Route) bool // RouteInfo contains a route id, plus the loaded and parsed route or @@ -402,7 +439,7 @@ func (r *Route) Copy() *Route { } if len(r.LBEndpoints) > 0 { - c.LBEndpoints = make([]string, len(r.LBEndpoints)) + c.LBEndpoints = make([]*LBEndpoint, len(r.LBEndpoints)) copy(c.LBEndpoints, r.LBEndpoints) } @@ -561,7 +598,7 @@ func newRouteDefinition(r *parsedRoute) (*Route, error) { rd.Shunt = r.shunt rd.Backend = r.backend rd.LBAlgorithm = r.lbAlgorithm - rd.LBEndpoints = r.lbEndpoints + rd.LBEndpoints = NewLBEndpoints(r.lbEndpoints) switch { case r.shunt: diff --git a/eskip/json.go b/eskip/json.go index 227798fe70..6dc406a50e 100644 --- a/eskip/json.go +++ b/eskip/json.go @@ -37,7 +37,7 @@ func newJSONRoute(r *Route) *jsonRoute { Type: cr.BackendType.String(), Address: cr.Backend, Algorithm: cr.LBAlgorithm, - Endpoints: cr.LBEndpoints, + Endpoints: LBEndpointString(cr.LBEndpoints), } } @@ -94,7 +94,7 @@ func (r *Route) UnmarshalJSON(b []byte) error { } case LBBackend: r.LBAlgorithm = jr.Backend.Algorithm - r.LBEndpoints = jr.Backend.Endpoints + r.LBEndpoints = NewLBEndpoints(jr.Backend.Endpoints) if len(r.LBEndpoints) == 0 { r.LBEndpoints = nil } diff --git a/eskip/json_test.go b/eskip/json_test.go index ec7e4f545c..9efc29f075 100644 --- a/eskip/json_test.go +++ b/eskip/json_test.go @@ -88,7 +88,7 @@ func TestMarshalUnmarshalJSON(t *testing.T) { }, { "lb backend", - []*Route{{Id: "beef", BackendType: LBBackend, LBAlgorithm: "yolo", LBEndpoints: []string{"localhost"}}}, + []*Route{{Id: "beef", BackendType: LBBackend, LBAlgorithm: "yolo", LBEndpoints: []*LBEndpoint{{Address: "localhost"}}}}, `[{"id":"beef","backend":{"type":"lb","algorithm":"yolo","endpoints":["localhost"]}}]`, }, { diff --git a/eskip/parser_test.go b/eskip/parser_test.go index ffe226d0ef..8634670351 100644 --- a/eskip/parser_test.go +++ b/eskip/parser_test.go @@ -255,7 +255,7 @@ func TestLBBackend(t *testing.T) { code: `* -> <"https://example.org">`, expectedResult: []*Route{{ BackendType: LBBackend, - LBEndpoints: []string{"https://example.org"}, + LBEndpoints: []*LBEndpoint{{Address: "https://example.org"}}, }}, }, { title: "multiple endpoints, default algorithm", @@ -264,10 +264,10 @@ func TestLBBackend(t *testing.T) { "https://example3.org">`, expectedResult: []*Route{{ BackendType: LBBackend, - LBEndpoints: []string{ - "https://example1.org", - "https://example2.org", - "https://example3.org", + LBEndpoints: []*LBEndpoint{ + {Address: "https://example1.org"}, + {Address: "https://example2.org"}, + {Address: "https://example3.org"}, }, }}, }, { @@ -276,7 +276,7 @@ func TestLBBackend(t *testing.T) { expectedResult: []*Route{{ BackendType: LBBackend, LBAlgorithm: "algFoo", - LBEndpoints: []string{"https://example.org"}, + LBEndpoints: []*LBEndpoint{{Address: "https://example.org"}}, }}, }, { title: "multiple endpoints, default algorithm", @@ -287,10 +287,10 @@ func TestLBBackend(t *testing.T) { expectedResult: []*Route{{ BackendType: LBBackend, LBAlgorithm: "algFoo", - LBEndpoints: []string{ - "https://example1.org", - "https://example2.org", - "https://example3.org", + LBEndpoints: []*LBEndpoint{ + {Address: "https://example1.org"}, + {Address: "https://example2.org"}, + {Address: "https://example3.org"}, }, }}, }, { @@ -303,10 +303,10 @@ func TestLBBackend(t *testing.T) { Filters: []*Filter{{Name: "foo"}}, BackendType: LBBackend, LBAlgorithm: "algFoo", - LBEndpoints: []string{ - "https://example1.org", - "https://example2.org", - "https://example3.org", + LBEndpoints: []*LBEndpoint{ + {Address: "https://example1.org"}, + {Address: "https://example2.org"}, + {Address: "https://example3.org"}, }, }}, }} { diff --git a/eskip/string.go b/eskip/string.go index fb6c6e4212..6ed32942e4 100644 --- a/eskip/string.go +++ b/eskip/string.go @@ -167,7 +167,7 @@ func lbBackendString(r *Route) string { b.WriteString(", ") } b.WriteByte('"') - b.WriteString(ep) + b.WriteString(ep.String()) b.WriteByte('"') } b.WriteByte('>') diff --git a/eskip/string_test.go b/eskip/string_test.go index 5976852bde..40bc6a8b15 100644 --- a/eskip/string_test.go +++ b/eskip/string_test.go @@ -112,13 +112,16 @@ func TestRouteString(t *testing.T) { BackendType: DynamicBackend}, `* -> filter0("Line 1\r\nLine 2") -> `, }, { - &Route{Method: "GET", BackendType: LBBackend, LBEndpoints: []string{"http://127.0.0.1:9997"}}, + &Route{Method: "GET", BackendType: LBBackend, LBEndpoints: []*LBEndpoint{{Address: "http://127.0.0.1:9997"}}}, `Method("GET") -> <"http://127.0.0.1:9997">`, }, { - &Route{Method: "GET", LBAlgorithm: "random", BackendType: LBBackend, LBEndpoints: []string{"http://127.0.0.1:9997"}}, + &Route{Method: "GET", LBAlgorithm: "random", BackendType: LBBackend, LBEndpoints: []*LBEndpoint{{Address: "http://127.0.0.1:9997"}}}, `Method("GET") -> `, }, { - &Route{Method: "GET", LBAlgorithm: "random", BackendType: LBBackend, LBEndpoints: []string{"http://127.0.0.1:9997", "http://127.0.0.1:9998"}}, + &Route{Method: "GET", LBAlgorithm: "random", BackendType: LBBackend, LBEndpoints: []*LBEndpoint{ + {Address: "http://127.0.0.1:9997"}, + {Address: "http://127.0.0.1:9998"}, + }}, `Method("GET") -> `, }, { // test slash escaping diff --git a/loadbalancer/algorithm.go b/loadbalancer/algorithm.go index a51551ab74..97b0297fd0 100644 --- a/loadbalancer/algorithm.go +++ b/loadbalancer/algorithm.go @@ -312,7 +312,7 @@ func (a Algorithm) String() string { func parseEndpoints(r *routing.Route) error { r.LBEndpoints = make([]routing.LBEndpoint, len(r.Route.LBEndpoints)) for i, e := range r.Route.LBEndpoints { - scheme, host, err := snet.SchemeHost(e) + scheme, host, err := snet.SchemeHost(e.String()) if err != nil { return err } @@ -337,7 +337,7 @@ func setAlgorithm(r *routing.Route) error { initialize = algorithms[t] } - r.LBAlgorithm = initialize(r.Route.LBEndpoints) + r.LBAlgorithm = initialize(eskip.LBEndpointString(r.Route.LBEndpoints)) return nil } diff --git a/loadbalancer/algorithm_test.go b/loadbalancer/algorithm_test.go index e48986c9ee..75945cff04 100644 --- a/loadbalancer/algorithm_test.go +++ b/loadbalancer/algorithm_test.go @@ -35,7 +35,7 @@ func TestSelectAlgorithm(t *testing.T) { r := &routing.Route{ Route: eskip.Route{ BackendType: eskip.LBBackend, - LBEndpoints: []string{"https://www.example.org"}, + LBEndpoints: []*eskip.LBEndpoint{{Address: "https://www.example.org"}}, }, } @@ -65,7 +65,7 @@ func TestSelectAlgorithm(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: "roundRobin", - LBEndpoints: []string{"https://www.example.org"}, + LBEndpoints: []*eskip.LBEndpoint{{Address: "https://www.example.org"}}, }, } @@ -95,7 +95,7 @@ func TestSelectAlgorithm(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: "consistentHash", - LBEndpoints: []string{"https://www.example.org"}, + LBEndpoints: []*eskip.LBEndpoint{{Address: "https://www.example.org"}}, }, } @@ -125,7 +125,7 @@ func TestSelectAlgorithm(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: "random", - LBEndpoints: []string{"https://www.example.org"}, + LBEndpoints: []*eskip.LBEndpoint{{Address: "https://www.example.org"}}, }, } @@ -155,7 +155,7 @@ func TestSelectAlgorithm(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: "powerOfRandomNChoices", - LBEndpoints: []string{"https://www.example.org"}, + LBEndpoints: []*eskip.LBEndpoint{{Address: "https://www.example.org"}}, }, } @@ -183,7 +183,7 @@ func TestSelectAlgorithm(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: "fooBar", - LBEndpoints: []string{"https://www.example.org"}, + LBEndpoints: []*eskip.LBEndpoint{{Address: "https://www.example.org"}}, }, } @@ -214,13 +214,13 @@ func TestSelectAlgorithm(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: "roundRobin", - LBEndpoints: []string{"://www.example.org"}, + LBEndpoints: []*eskip.LBEndpoint{{Address: "://www.example.org"}}, }, } rr := p.Do([]*routing.Route{r}) if len(rr) != 0 { - t.Fatal("failed to drop invalid LB route") + t.Fatalf("failed to drop invalid LB route: %s", rr[0].String()) } }) } @@ -270,7 +270,7 @@ func TestApply(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: tt.algorithmName, - LBEndpoints: eps, + LBEndpoints: eskip.NewLBEndpoints(eps), }, } rt := p.Do([]*routing.Route{r}) @@ -304,7 +304,7 @@ func TestConsistentHashSearch(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: ConsistentHash.String(), - LBEndpoints: endpoints, + LBEndpoints: eskip.NewLBEndpoints(endpoints), }, } p.Do([]*routing.Route{r}) @@ -344,7 +344,7 @@ func TestConsistentHashBoundedLoadSearch(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: ConsistentHash.String(), - LBEndpoints: endpoints, + LBEndpoints: eskip.NewLBEndpoints(endpoints), }, }})[0] @@ -397,7 +397,7 @@ func TestConsistentHashKey(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: ConsistentHash.String(), - LBEndpoints: endpoints, + LBEndpoints: eskip.NewLBEndpoints(endpoints), }, }})[0] @@ -424,7 +424,7 @@ func TestConsistentHashBoundedLoadDistribution(t *testing.T) { Route: eskip.Route{ BackendType: eskip.LBBackend, LBAlgorithm: ConsistentHash.String(), - LBEndpoints: endpoints, + LBEndpoints: eskip.NewLBEndpoints(endpoints), }, }})[0] diff --git a/loadbalancer/concurrency_test.go b/loadbalancer/concurrency_test.go index 027ffc1557..2822e5ce8b 100644 --- a/loadbalancer/concurrency_test.go +++ b/loadbalancer/concurrency_test.go @@ -73,7 +73,7 @@ func TestConcurrencySingleRoute(t *testing.T) { route := &eskip.Route{ Id: "foo", BackendType: eskip.LBBackend, - LBEndpoints: backends, + LBEndpoints: eskip.NewLBEndpoints(backends), LBAlgorithm: "roundRobin", } @@ -175,7 +175,7 @@ func TestConstantlyUpdatingRoutes(t *testing.T) { { Id: "foo", BackendType: eskip.LBBackend, - LBEndpoints: backends, + LBEndpoints: eskip.NewLBEndpoints(backends), LBAlgorithm: "roundRobin", }, } @@ -287,7 +287,7 @@ func TestConcurrencyMultipleRoutes(t *testing.T) { Id: app, Path: fmt.Sprintf("/%s", app), BackendType: eskip.LBBackend, - LBEndpoints: backends[app], + LBEndpoints: eskip.NewLBEndpoints(backends[app]), LBAlgorithm: "roundRobin", }) } diff --git a/proxy/fadein_internal_test.go b/proxy/fadein_internal_test.go index 8ebf92a9f4..43fc7e7fd2 100644 --- a/proxy/fadein_internal_test.go +++ b/proxy/fadein_internal_test.go @@ -70,7 +70,7 @@ func initializeEndpoints(endpointAges []float64, algorithmName string, fadeInDur registry := routing.NewEndpointRegistry(routing.RegistryOptions{}) eskipRoute := eskip.Route{BackendType: eskip.LBBackend, LBAlgorithm: algorithmName} for i := range eps { - eskipRoute.LBEndpoints = append(eskipRoute.LBEndpoints, eps[i]) + eskipRoute.LBEndpoints = append(eskipRoute.LBEndpoints, &eskip.LBEndpoint{Address: eps[i]}) registry.GetMetrics(eps[i]).SetDetected(detectionTimes[i]) } diff --git a/proxy/fadeintesting_test.go b/proxy/fadeintesting_test.go index ff552e4fdb..afcf5b9ea2 100644 --- a/proxy/fadeintesting_test.go +++ b/proxy/fadeintesting_test.go @@ -161,7 +161,7 @@ func (b *fadeInBackend) route() *eskip.Route { } for _, i := range b.instances { - r.LBEndpoints = append(r.LBEndpoints, i.server.URL) + r.LBEndpoints = append(r.LBEndpoints, &eskip.LBEndpoint{Address: i.server.URL}) if !i.created.IsZero() { r.Filters = append(r.Filters, &eskip.Filter{ Name: filters.EndpointCreatedName,