diff --git a/cmd/_integration-tests/Makefile b/cmd/_integration-tests/Makefile index 8d05b52..f0b685a 100644 --- a/cmd/_integration-tests/Makefile +++ b/cmd/_integration-tests/Makefile @@ -5,13 +5,15 @@ END_COLOR_LINE=$(UNDER)$(NO_COLOR) TRANSPORT_TEST_MSG=\n$(OK_COLOR)Starting transport end to end test:$(END_COLOR_LINE) +MIDDLEWARES_TEST_MSG=\n$(OK_COLOR)Starting middlewares end to end test:$(END_COLOR_LINE) + CLI_TEST_MSG=\n$(OK_COLOR)Start server and cliclient generate, build, and run test:$(END_COLOR_LINE) export PATH := $(CURDIR):$(PATH) all: test -test: clean test-transport test-cli +test: clean test-transport test-middlewares test-cli truss: go build -o truss github.com/TuneLab/go-truss/cmd/truss @@ -25,6 +27,12 @@ test-transport: protoc-gen-truss-protocast truss $(MAKE) -C transport rm -f ./truss ./protoc-gen-truss-protocast +test-middlewares: protoc-gen-truss-protocast truss + @which truss + @printf '$(MIDDLEWARES_TEST_MSG)' + $(MAKE) -C middlewares + rm -f ./truss ./protoc-gen-truss-protocast + test-cli: protoc-gen-truss-protocast truss @which truss @printf '$(CLI_TEST_MSG)' @@ -35,4 +43,5 @@ clean: rm -f ./truss ./protoc-gen-truss-protocast go test ./cli -clean $(MAKE) -C transport clean + $(MAKE) -C middlewares clean diff --git a/cmd/_integration-tests/README.md b/cmd/_integration-tests/README.md index 33af55f..2b3cac9 100644 --- a/cmd/_integration-tests/README.md +++ b/cmd/_integration-tests/README.md @@ -31,6 +31,13 @@ the test. Then each `transport/{TRANSPORT}_test.go` imports the generated code, runs requests against the server, checking for errors and that the input values add to the expected output value(s). +# ./middlewares + +`middlewares` is very similar to transport, having prewritten handlers and +middlewares, it generates a truss service and copies these into that service. +Then it runs tests against the endpoints (avoiding the transport logic) to see +if middlewares were correctly applied and/or excluded from the endpoints. + # ./cli The truss CLI integration runner does the following tasks: diff --git a/cmd/_integration-tests/middlewares/Makefile b/cmd/_integration-tests/middlewares/Makefile new file mode 100644 index 0000000..6559df4 --- /dev/null +++ b/cmd/_integration-tests/middlewares/Makefile @@ -0,0 +1,22 @@ +NO_COLOR=\e[0m +OK_COLOR=\e[38;5;118m +UNDER=\n________________________________________________________________________________\n +END_COLOR_LINE=$(UNDER)$(NO_COLOR) + +TRUSS_MSG=\n$(OK_COLOR)Running Truss...$(END_COLOR_LINE) + +TEST_RUNNING_MSG=\n$(OK_COLOR)Running middlewares tests:$(END_COLOR_LINE) + +all: test + +test: + @echo -e '$(TRUSS_MSG)' + truss middlewares-test.proto + cp -r middlewares middlewarestest-service + cp -r handlers middlewarestest-service + @echo -e '$(TEST_RUNNING_MSG)' + go test -v + $(MAKE) clean + +clean: + rm -rf middlewarestest-service diff --git a/cmd/_integration-tests/middlewares/handlers/server/server_handler.go b/cmd/_integration-tests/middlewares/handlers/server/server_handler.go new file mode 100644 index 0000000..ce14d0c --- /dev/null +++ b/cmd/_integration-tests/middlewares/handlers/server/server_handler.go @@ -0,0 +1,46 @@ +package handler + +import ( + "golang.org/x/net/context" + + pb "github.com/TuneLab/go-truss/cmd/_integration-tests/middlewares/middlewarestest-service" +) + +// NewService returns a naïve, stateless implementation of Service. +func NewService() pb.MiddlewaresTestServer { + return middlewarestestService{} +} + +type middlewarestestService struct{} + +// AlwaysWrapped implements Service. +func (s middlewarestestService) AlwaysWrapped(ctx context.Context, in *pb.Empty) (*pb.WrapAllTest, error) { + var resp pb.WrapAllTest + + always := ctx.Value("Always") + if a, ok := always.(bool); ok { + resp.Always = a + } + notSometimes := ctx.Value("NotSometimes") + if ns, ok := notSometimes.(bool); ok { + resp.NotSometimes = ns + } + + return &resp, nil +} + +// SometimesWrapped implements Service. +func (s middlewarestestService) SometimesWrapped(ctx context.Context, in *pb.Empty) (*pb.WrapAllTest, error) { + var resp pb.WrapAllTest + + always := ctx.Value("Always") + if a, ok := always.(bool); ok { + resp.Always = a + } + notSometimes := ctx.Value("NotSometimes") + if ns, ok := notSometimes.(bool); ok { + resp.NotSometimes = ns + } + + return &resp, nil +} diff --git a/cmd/_integration-tests/middlewares/middlewares-test.proto b/cmd/_integration-tests/middlewares/middlewares-test.proto new file mode 100644 index 0000000..936020f --- /dev/null +++ b/cmd/_integration-tests/middlewares/middlewares-test.proto @@ -0,0 +1,34 @@ +syntax = "proto3"; + +package middlewares; + +import "github.com/TuneLab/go-truss/deftree/googlethirdparty/annotations.proto"; + +service MiddlewaresTest { + // Test endpoints.WrapAll(middleware, exclude ...) + // AlwaysWrapped will never be excluded in endpoints.WrapAll + rpc AlwaysWrapped (Empty) returns (WrapAllTest) { + option (google.api.http) = { + get: "/alwayswrapped" + }; + } + // SometimesWrapped will be excluded from the middleware that set the + // NotSometimes value + rpc SometimesWrapped (Empty) returns (WrapAllTest) { + option (google.api.http) = { + get: "/sometimeswrapped" + }; + } +} + +message Empty {} + +// WrapAllTest will be populated by middlewares which were wrapped +// around endpoints using WrapAll +message WrapAllTest { + // Always will be set to true + bool Always = 1; + // NotSometimes will be set to true for endpoint AlwaysWrapped and set to + // false for SometimesWrapped + bool NotSometimes = 2; +} diff --git a/cmd/_integration-tests/middlewares/middlewares/endpoints.go b/cmd/_integration-tests/middlewares/middlewares/endpoints.go new file mode 100644 index 0000000..a2a9f1b --- /dev/null +++ b/cmd/_integration-tests/middlewares/middlewares/endpoints.go @@ -0,0 +1,35 @@ +package middlewares + +import ( + "github.com/go-kit/kit/endpoint" + "golang.org/x/net/context" + + svc "github.com/TuneLab/go-truss/cmd/_integration-tests/middlewares/middlewarestest-service/generated" +) + +// WrapEndpoints accepts the service's entire collection of endpoints, so that a +// set of middlewares can be wrapped around every middleware (e.g., access +// logging and instrumentation), and others wrapped selectively around some +// endpoints and not others (e.g., endpoints requiring authenticated access). +// Note that the final middleware applied will be the outermost middleware +// (i.e. applied first) +func WrapEndpoints(in svc.Endpoints) svc.Endpoints { + + // Pass in the middlewares you want applied to every endpoint. + // optionally pass in endpoints by name that you want to be excluded + // e.g. + // in.WrapAll(authMiddleware, "Status", "Ping") + in.WrapAll(addBoolToContext("NotSometimes"), "SometimesWrapped") + in.WrapAll(addBoolToContext("Always")) + + return in +} + +func addBoolToContext(key string) endpoint.Middleware { + return func(next endpoint.Endpoint) endpoint.Endpoint { + return func(ctx context.Context, request interface{}) (interface{}, error) { + ctx = context.WithValue(ctx, key, true) + return next(ctx, request) + } + } +} diff --git a/cmd/_integration-tests/middlewares/middlewares/service.go b/cmd/_integration-tests/middlewares/middlewares/service.go new file mode 100644 index 0000000..7b96b5b --- /dev/null +++ b/cmd/_integration-tests/middlewares/middlewares/service.go @@ -0,0 +1,9 @@ +package middlewares + +import ( + pb "github.com/TuneLab/go-truss/cmd/_integration-tests/middlewares/middlewarestest-service" +) + +func WrapService(in pb.MiddlewaresTestServer) pb.MiddlewaresTestServer { + return in +} diff --git a/cmd/_integration-tests/middlewares/middlewares_test.go b/cmd/_integration-tests/middlewares/middlewares_test.go new file mode 100644 index 0000000..b0fe6d7 --- /dev/null +++ b/cmd/_integration-tests/middlewares/middlewares_test.go @@ -0,0 +1,43 @@ +package test + +import ( + "testing" + + "golang.org/x/net/context" + + pb "github.com/TuneLab/go-truss/cmd/_integration-tests/middlewares/middlewarestest-service" +) + +func TestAlwaysWrapped(t *testing.T) { + ctx := context.Background() + + resp, err := middlewareEndpoints.AlwaysWrapped(ctx, &pb.Empty{}) + if err != nil { + t.Fatal(err) + } + + if !resp.Always { + t.Error("Always middleware did not wrap AlwaysWrap endpoint") + } + + if !resp.NotSometimes { + t.Error("NotSometimes middleware did not wrap AlwaysWrap endpoint") + } +} + +func TestSometimesWrapped(t *testing.T) { + ctx := context.Background() + + resp, err := middlewareEndpoints.SometimesWrapped(ctx, &pb.Empty{}) + if err != nil { + t.Fatal(err) + } + + if !resp.Always { + t.Error("Always middleware did not wrap SometimesWrapped endpoint") + } + + if resp.NotSometimes { + t.Error("NotSometimes middleware did wrap SomtimesWrapped endpoint") + } +} diff --git a/cmd/_integration-tests/middlewares/setup_test.go b/cmd/_integration-tests/middlewares/setup_test.go new file mode 100644 index 0000000..70d641e --- /dev/null +++ b/cmd/_integration-tests/middlewares/setup_test.go @@ -0,0 +1,34 @@ +package test + +import ( + "os" + "testing" + + pb "github.com/TuneLab/go-truss/cmd/_integration-tests/middlewares/middlewarestest-service" + svc "github.com/TuneLab/go-truss/cmd/_integration-tests/middlewares/middlewarestest-service/generated" + handler "github.com/TuneLab/go-truss/cmd/_integration-tests/middlewares/middlewarestest-service/handlers/server" + "github.com/TuneLab/go-truss/cmd/_integration-tests/middlewares/middlewarestest-service/middlewares" +) + +var middlewareEndpoints svc.Endpoints + +func TestMain(m *testing.M) { + + var service pb.MiddlewaresTestServer + { + service = handler.NewService() + } + + // Endpoint domain. + alwaysWrapped := svc.MakeAlwaysWrappedEndpoint(service) + sometimesWrapped := svc.MakeSometimesWrappedEndpoint(service) + + middlewareEndpoints = svc.Endpoints{ + AlwaysWrappedEndpoint: alwaysWrapped, + SometimesWrappedEndpoint: sometimesWrapped, + } + + middlewareEndpoints = middlewares.WrapEndpoints(middlewareEndpoints) + + os.Exit(m.Run()) +} diff --git a/gengokit/middlewares/middlewares_test.go b/gengokit/middlewares/middlewares_test.go index df973ff..43bfe8c 100644 --- a/gengokit/middlewares/middlewares_test.go +++ b/gengokit/middlewares/middlewares_test.go @@ -58,6 +58,8 @@ func TestNewEndpointMiddleware(t *testing.T) { package middlewares import ( + _ "github.com/go-kit/kit/endpoint" + svc "github.com/TuneLab/go-truss/gengokit/general-service/generated" ) @@ -65,12 +67,16 @@ func TestNewEndpointMiddleware(t *testing.T) { // set of middlewares can be wrapped around every middleware (e.g., access // logging and instrumentation), and others wrapped selectively around some // endpoints and not others (e.g., endpoints requiring authenticated access). + // Note that the final middleware applied will be the outermost middleware + // (i.e. applied first) func WrapEndpoints(in svc.Endpoints) svc.Endpoints { // Pass in the middlewares you want applied to every endpoint. - in.WrapAll(/* ...endpoint.Middleware */) + // optionally pass in endpoints by name that you want to be excluded + // e.g. + // in.WrapAll(authMiddleware, "Status", "Ping") - // How to apply a middleware selectively. + // How to apply a middleware to a single endpoint. // in.ExampleEndpoint = authMiddleware(in.ExampleEndpoint) return in diff --git a/gengokit/middlewares/templates/endpoints.go b/gengokit/middlewares/templates/endpoints.go index f5d4c5e..3510c2f 100644 --- a/gengokit/middlewares/templates/endpoints.go +++ b/gengokit/middlewares/templates/endpoints.go @@ -4,6 +4,8 @@ const EndpointsBase = ` package middlewares import ( + _ "github.com/go-kit/kit/endpoint" + svc "{{.ImportPath -}} /generated" ) @@ -11,12 +13,16 @@ import ( // set of middlewares can be wrapped around every middleware (e.g., access // logging and instrumentation), and others wrapped selectively around some // endpoints and not others (e.g., endpoints requiring authenticated access). +// Note that the final middleware applied will be the outermost middleware +// (i.e. applied first) func WrapEndpoints(in svc.Endpoints) svc.Endpoints { // Pass in the middlewares you want applied to every endpoint. - in.WrapAll(/* ...endpoint.Middleware */) + // optionally pass in endpoints by name that you want to be excluded + // e.g. + // in.WrapAll(authMiddleware, "Status", "Ping") - // How to apply a middleware selectively. + // How to apply a middleware to a single endpoint. // in.ExampleEndpoint = authMiddleware(in.ExampleEndpoint) return in diff --git a/gengokit/template/NAME-service/generated/endpoints.gotemplate b/gengokit/template/NAME-service/generated/endpoints.gotemplate index 3a34651..1333bbf 100644 --- a/gengokit/template/NAME-service/generated/endpoints.gotemplate +++ b/gengokit/template/NAME-service/generated/endpoints.gotemplate @@ -6,6 +6,7 @@ package svc // formats. It also includes endpoint middlewares. import ( + "fmt" "golang.org/x/net/context" "github.com/go-kit/kit/endpoint" @@ -25,8 +26,7 @@ import ( // // In a client, it's useful to collect individually constructed endpoints into a // single type that implements the Service interface. For example, you might -// construct individual endpoints using transport/http.NewClient, combine them -// into an Endpoints, and return it to the caller as a Service. +// construct individual endpoints using transport/http.NewClient, combine them into an Endpoints, and return it to the caller as a Service. type Endpoints struct { {{range $i := .Service.Methods}} {{$i.Name}}Endpoint endpoint.Endpoint @@ -63,14 +63,27 @@ type Endpoints struct { // WrapAll wraps each Endpoint field of struct Endpoints with a // go-kit/kit/endpoint.Middleware. // Use this for applying a set of middlewares to every endpoint in the service. -// The middlewares will be applied in the order passed, with the first -// middleware being the outermost middleware. -func (e *Endpoints) WrapAll(middlewares ...endpoint.Middleware) { - if len(middlewares) == 0 { - return +// Optionally, endpoints can be passed in by name to be excluded from being wrapped. +// WrapAll(middleware, "Status", "Ping") +func (e *Endpoints) WrapAll(middleware endpoint.Middleware, excluded ...string) { + included := map[string]struct{}{ + {{- range $i := .Service.Methods}} + "{{$i.Name}}": struct{}{}, + {{- end}} + } + + for _, ex := range excluded { + if _, ok := included[ex]; !ok { + panic(fmt.Sprintf("Excluded endpoint '%s' does not exist; see middlewares/endpoints.go", ex)) + } + delete(included, ex) + } + + for inc, _ := range included { + {{- range $i := .Service.Methods}} + if inc == "{{$i.Name}}" { + e.{{$i.Name}}Endpoint = middleware(e.{{$i.Name}}Endpoint) + } + {{- end}} } - m := endpoint.Chain(middlewares[0], middlewares[1:]...) - {{range $i := .Service.Methods}} - e.{{$i.Name}}Endpoint = m(e.{{$i.Name}}Endpoint) - {{- end}} } diff --git a/gengokit/template/template.go b/gengokit/template/template.go index 74c4ff0..98cafdb 100644 --- a/gengokit/template/template.go +++ b/gengokit/template/template.go @@ -179,7 +179,7 @@ func nameServiceGeneratedClientHttpClientGotemplate() (*asset, error) { return a, nil } -var _nameServiceGeneratedEndpointsGotemplate = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x56\x4d\x6f\xdb\x38\x10\x3d\x5b\xbf\x62\x36\x08\x50\xbb\x70\xe8\xee\xb5\x40\x0e\xbb\xc1\x7e\xe4\x90\xa2\xd8\x76\xb1\x87\xa2\x07\x5a\x1c\x59\x83\x50\x24\x4b\x52\x76\xbc\x82\xfe\xfb\x62\x48\x49\x96\x1b\x61\xd1\x43\xa0\x98\x9a\x79\x33\x7c\x6f\x3e\xe4\x64\xf9\x2c\x0f\x08\xe1\x58\x16\xc5\x6e\x07\x9f\x6b\x0a\x50\x91\x46\x28\xad\x89\x92\x4c\x80\x06\x63\x6d\x55\x80\x68\xa1\x91\xcf\x08\x64\x14\x1d\x49\xb5\x52\x03\x1a\xe5\x2c\x99\x18\xa0\xf2\xb6\x81\x80\xfe\x48\x25\x86\x2d\x23\x79\xfc\xd6\x62\x88\x20\x8d\x02\x8f\xc1\x59\x13\x10\xe2\xd9\x61\x42\x62\x53\x84\x58\xdb\x80\x17\x94\x2d\xc8\x00\x27\xd4\x9a\x9f\x68\x4a\xab\xd0\x07\x06\x60\x3c\x85\xc3\xef\xca\xfa\xc1\x31\xa1\x6d\xd3\x81\xd4\x1a\x6c\x05\xb6\xf5\x10\x5a\xe7\xac\x8f\xa8\x20\x7a\x69\x02\xff\xcf\xe1\x48\x6a\xfa\x57\x46\xb2\x86\xd1\x2a\xeb\x1b\x19\x83\x80\xc7\x08\x52\x07\x0b\x64\x4a\xdd\x2a\x0c\x53\x36\xd0\x90\x52\x1a\x4f\xd2\x63\x10\x45\x41\x4d\x02\x5a\x17\xab\x9b\x83\xd5\xd2\x1c\x84\xf5\x87\xdd\xcb\xce\x60\xdc\x31\x55\xf8\x12\x6f\x0a\x7e\x49\xb1\x6e\xf7\xa2\xb4\xcd\xee\x60\xef\x9e\x29\xee\xf8\x6f\x04\x65\x13\xb7\x87\x9b\xae\x13\x1f\x7f\x7d\x4c\x90\x1f\x65\xac\xe1\xae\xef\x6f\x8a\x4d\x52\xe0\xb7\x89\xd3\xd2\x6a\x8d\x65\x0c\xe3\xe5\x62\x3d\xe3\x0a\x62\x2d\x23\x94\xb6\x71\xcc\x84\x34\x20\x95\x1a\x05\xe0\x5b\xbd\x09\x0c\xd6\xa0\x34\x91\xf9\xde\x23\xb4\x01\x15\x13\x2b\xa1\x46\xed\xd0\x43\x88\xbe\x2d\xe3\x96\x5f\x0f\xa1\x96\x23\x91\x89\x16\x24\xc3\x05\x32\x07\x8d\xe0\xa4\x97\x0d\x46\xf4\xa2\xd8\xed\xf8\xfc\xd1\x80\xcc\x92\xfa\x2d\x50\x7c\x13\x38\x58\xd5\xea\x24\x4d\xd5\x9a\x92\x69\x1f\x52\x36\xc8\xca\x58\xb0\x0e\xbd\x8c\x08\x96\x7d\x1d\xfa\xbb\x31\x20\x03\xee\x65\xa0\x20\xe0\x77\xeb\x01\x5f\x64\xe3\x34\x6e\xe1\x6c\x5b\x68\xe8\x50\x47\x70\x32\x70\x59\xcc\xa8\xe2\x04\xa7\x40\x39\x8e\xf3\x56\xb5\x25\x26\x1a\xa4\x81\x3a\x46\x27\xfe\x94\x46\x69\xce\xf1\x44\xb1\x06\x94\x65\x3d\x54\x37\xac\xc7\xe8\x1b\x38\x91\x47\x05\xad\xcb\xa0\xc1\x61\x49\x15\x95\xe0\x64\xac\x05\xac\x1f\x53\x7e\x14\x18\x7f\x2f\xf7\xfa\x0c\x12\x1a\x0a\x31\x77\x06\x28\x0c\x74\x30\xec\x4a\xe6\x68\x9f\x31\x51\xf9\x29\xcb\x32\x75\x52\x4a\x11\xaf\xc5\xce\x62\x30\xc4\xc8\xa4\xd8\xcc\xd9\x2d\x35\xa1\x89\xd7\xec\xce\x84\xbb\x34\xa5\x3e\x73\xeb\x66\x38\x54\xff\x27\x23\xb7\x4f\xe6\x8a\x98\xe1\x06\x73\x59\x5d\xf2\x25\x13\xd1\x57\x92\x0b\x6a\x59\x09\x06\x9b\x82\x2d\x0f\x86\x96\x83\x5d\x3a\x71\x97\x74\xf8\x80\xa7\x87\xe1\x3e\xa5\x6d\xf6\x64\x12\x4f\x4d\x62\x36\x65\x39\xd3\x76\x3b\x4c\x90\xd8\x7a\x03\x94\x8a\x99\x73\x2c\xa5\xd6\xe8\x73\x3d\x0f\xf9\x8a\x22\xdd\xe8\x15\xa7\x5d\xd1\x75\x5e\x9a\x03\xc2\x2d\xc1\xfb\x7b\x10\xa3\xfd\x53\xd6\xa3\xef\x8b\x55\xd7\xdd\x92\xf8\x20\x1b\xec\xfb\xd1\x1f\x00\xa6\x7b\x88\xf1\xb0\xe8\xba\x3b\x3e\xed\xfb\xa2\xbf\x6e\xd7\x1f\x08\xc2\x05\x0a\xeb\x59\x86\x1b\x98\xc5\x5d\x97\xf1\x05\x86\x51\x22\x1e\xf2\x73\xcb\x05\xf1\xd6\xed\x45\xd7\xfd\x61\xd9\x0c\x6e\x49\xfc\x95\x27\xeb\xe7\xb3\xc3\xc1\x75\x03\xeb\xd7\x46\x79\xe4\xce\xac\xb6\x80\xde\x5b\xbf\x81\xae\x58\xad\xc6\x91\x9c\x0e\x39\x61\x14\x0b\x1c\x70\x4e\x9c\xc3\xa6\x58\xad\xa8\x4a\xa6\x3f\xdd\x83\x21\x9d\x30\x56\x83\x2a\x86\x74\x82\x29\x56\xab\xbe\x98\x4e\xc7\x08\xe2\x47\x72\xdb\x6c\x19\xa5\x58\xf5\x45\xd7\x65\x7a\x99\xdc\x27\xee\xaa\x39\xc3\xa9\x6f\x6f\x23\x26\x86\xb3\x6e\x73\xd2\x6f\x23\x2e\xf1\x9e\x89\x67\xb0\xa5\x2b\x06\x48\xe9\xcd\x7d\xb3\xc5\xa7\xd4\x86\x9b\xd7\x45\x70\x75\x79\xc6\x5e\x96\x6e\xdc\x80\x53\x1b\x75\x2c\xd4\xb4\x0b\x67\xc7\x59\x84\x99\x3a\x8c\xfe\x8d\x6f\x34\x60\x2c\x71\xf8\xaa\x08\x92\xdf\x71\x12\x34\x88\xef\x8a\x2b\x65\x94\xad\x16\xb4\x5c\x52\x33\xeb\x39\xbd\x39\x0e\x22\xe5\xe3\xc4\x7e\xd6\x6a\xae\xd9\x3f\x5e\xba\x5f\xb4\x86\x93\x97\x2e\xe4\x19\x3b\xf1\x56\x11\x6a\xc5\x0b\x66\xe8\xcc\x4b\xab\x26\x61\xd3\x70\x5a\xd8\x9a\xe2\x69\x5a\xc5\xbc\x71\xe0\x6f\xde\xfd\xe9\x43\x85\x37\xbf\x73\xfa\xcc\x33\x86\xe7\x66\x64\xf0\xd9\xe2\xe6\x69\x81\x47\xf4\xe7\xcb\x5a\xa7\x34\x7c\xa7\x55\x99\x3f\x7a\xf0\xca\xe9\x44\x5a\xf3\xc6\x64\x68\x42\x35\xba\x58\xaf\xd0\xa7\xe5\x83\x6a\x58\x21\x7c\x5c\x91\x0f\x69\x12\x5e\x20\x60\x8f\x69\xea\xb1\x53\x1b\xd1\x37\x36\xcc\xbf\x27\x44\x31\x4e\x82\xb7\xb3\x51\x30\x10\xb7\x9e\x67\x22\x84\x58\x20\x21\xd5\x08\x55\xa0\xd1\xcc\xad\x37\x70\x7f\x0f\xef\x86\xee\x66\xc1\xb8\x9d\x56\x4d\x6a\xee\x11\xe4\xa1\x96\x74\xe5\xf4\xe5\xdd\xd7\xed\xfc\xf2\x5f\x7e\x7e\xff\x55\x08\xb1\xf9\xbe\xb5\x16\xfb\x6a\x71\x66\xc0\x3d\x34\xeb\xc5\x37\x09\xf4\x32\x3e\xff\x0b\x00\x00\xff\xff\x53\x09\x93\xa7\x7c\x0a\x00\x00") +var _nameServiceGeneratedEndpointsGotemplate = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x8c\x56\xcd\x6e\xdc\x36\x17\x5d\x4b\x4f\x71\x23\xf8\x83\x47\x81\xcc\xd9\x27\xf0\xe2\x6b\x90\xb6\x5e\x24\x0d\xea\x14\x5d\x04\x41\xc0\x11\xaf\x46\x84\x29\x92\x21\x29\x7b\xa6\x82\xde\xbd\xb8\xa4\xa4\x91\x6b\xa1\xcd\x22\x98\x98\x3f\xe7\x1e\x9e\x73\x7f\x64\x79\xfd\xc0\x8f\x08\xfe\xb1\xce\xf3\xfd\x1e\x3e\xb7\xd2\x43\x23\x15\x42\x6d\x74\xe0\x52\x7b\xe8\x30\xb4\x46\x78\x08\x06\x3a\xfe\x80\x20\xb5\x90\x8f\x52\xf4\x5c\x01\x6a\x61\x8d\xd4\xc1\x43\xe3\x4c\x07\x1e\xdd\xa3\xac\xd1\x57\x84\xe4\xf0\x7b\x8f\x3e\x00\xd7\x02\x1c\x7a\x6b\xb4\x47\x08\x67\x8b\x11\x89\x8e\x22\x84\xd6\x78\xbc\xa0\x54\xc0\x3d\x3c\xa1\x52\xf4\x8b\xba\x36\x02\x9d\x27\x00\xc2\x13\x38\xfd\xdd\x18\x37\x5d\x8c\x68\x55\x5c\xe0\x4a\x81\x69\xc0\xf4\x0e\x7c\x6f\xad\x71\x01\x05\x04\xc7\xb5\xa7\xff\x53\x38\xc9\x95\xfc\x8b\x07\x69\x34\xa1\x35\xc6\x75\x3c\x78\x06\x77\x01\xb8\xf2\x06\xa4\xae\x55\x2f\xd0\x2f\x6c\xa0\x93\x42\x28\x7c\xe2\x0e\x3d\xcb\x73\xd9\x45\xa0\x5d\x9e\x15\x4d\x17\x8a\x3c\x2b\x8e\x46\x71\x7d\x64\xc6\x1d\xf7\xa7\xbd\xc6\xb0\x27\xc5\xf0\x14\x8a\x9c\x36\x65\x68\xfb\x03\xab\x4d\xb7\x3f\x9a\x9b\x07\x19\xf6\xf4\x6f\xc6\xa6\x23\xf6\x00\xc5\x30\xb0\x4f\x3f\xdd\x45\xe4\x4f\x3c\xb4\x70\x33\x8e\x45\x5e\x46\x23\xde\x2f\xd2\xd6\x46\x29\xac\x83\x9f\xdf\x18\xda\x95\x64\x10\x5a\x1e\xa0\x36\x9d\x25\x41\xb8\x06\x2e\xc4\xec\x03\x3d\xee\xda\x13\x58\x87\x5c\x07\x92\xfd\x80\xd0\x7b\x14\xa4\x2f\x87\x16\x95\x45\x07\x3e\xb8\xbe\x0e\x15\x6d\x4f\xa1\xb6\x23\x49\x1d\x0c\x70\x82\xf3\x52\x1f\x15\x82\xe5\x8e\x77\x18\xd0\xb1\x7c\xbf\xa7\xf5\x3b\x0d\x3c\x39\xeb\x2a\x90\xe1\xda\x53\xb0\xa6\x57\xd1\xa1\xa6\xd7\x35\xa9\x3f\x51\xd6\x48\x06\x19\x30\x16\x1d\x0f\x08\x86\xee\x5a\x74\x37\x73\x40\x02\x3c\x70\x2f\x3d\x83\x9f\x8d\x03\x3c\xf1\xce\x2a\xac\xe0\x6c\x7a\xe8\xe4\xb1\x0d\x60\xb9\xa7\xec\x58\x49\x45\x04\x97\x40\x29\x8e\x75\x46\xf4\x35\x46\x19\xb8\x86\x36\x04\xcb\x7e\xe5\x5a\x28\xe2\xf8\x24\x43\x0b\xc8\xeb\x76\x4a\x72\xd8\xcd\xd1\x4b\x78\x92\x0e\x05\xf4\x36\x81\x7a\x8b\xb5\x6c\x64\x0d\x96\x87\x96\xc1\xee\x2e\xf2\x93\x9e\xf0\x0f\xfc\xa0\xce\xc0\xa1\x93\x3e\xa4\x02\x01\x81\x5e\x1e\x35\x5d\x95\xfa\xd1\x3c\x60\x94\xf2\x3e\xd9\xb2\x14\x54\xa4\x88\xcf\xcd\x4e\x66\x10\xc4\xac\x24\x2b\xd7\xea\xd6\x4a\xa2\x0e\xcf\xd5\x5d\x19\x77\xa9\x4d\x75\xa6\x0a\x4e\x70\x28\xfe\xcd\x46\xaa\xa2\xa4\x95\x24\x85\x3b\x4c\x69\x75\xe1\x2b\x75\x40\xd7\x70\x4a\xa8\x6d\x27\x08\x6c\x09\xb6\xdd\x1f\x7a\x0a\x76\x29\xc8\x7d\xf4\xe1\x23\x3e\xbd\x9b\xde\x53\x9b\xee\x20\x75\xd4\xa9\x9b\x28\xae\x8c\xad\xa6\x2e\x12\x7a\xa7\x41\xc6\x4c\x26\x82\x35\x57\x0a\x5d\x4a\xe6\x89\x2c\xcb\xe3\x73\x5e\x08\x3a\xe4\xc3\xe0\xb8\x3e\x22\x5c\x49\x78\x73\x0b\x6c\x3e\xff\x21\x99\x31\x8e\x79\x36\x0c\x57\x92\x7d\xe4\x1d\x8e\xe3\x7c\x1f\x00\x96\x47\xb0\x79\x31\x1f\x86\x1b\x5a\x1d\xc7\x7c\x7c\x5e\xab\x3f\x10\x84\xb2\x13\x76\x2b\x86\x25\xac\xe2\xee\xea\x70\x82\xa9\x8f\xb0\x77\xe9\xb7\xa2\x6c\x78\x6d\x0f\x6c\x18\x7e\x31\x74\x0c\xae\x24\xfb\x3d\x75\xd7\xcf\x67\x8b\xd3\xd5\x12\x76\x2f\x0f\xa5\xb6\xbb\x3a\x55\x01\x3a\x67\x5c\x09\x43\x9e\x65\x73\x5b\x8e\x8b\x44\x18\xd9\x86\x06\xc4\x89\x38\x94\x79\x96\xc9\x26\x1e\x7d\x75\x0b\x5a\xaa\x88\x91\x4d\xae\x68\xa9\x22\x4c\x9e\x65\x63\xbe\xac\xce\x11\xd8\x8f\x70\x2b\x2b\x42\xc9\xb3\x31\x1f\x86\x24\x2f\x89\xfb\x81\x4a\x6a\xad\x70\x2c\xda\xab\x80\x51\xe1\xe4\xdb\x5a\xf4\xab\x80\x5b\xba\x27\xe1\x09\x6c\xeb\x89\x1e\x22\xbd\xf5\xdd\x74\xe2\x3e\xd6\x60\xf9\x32\x09\x9e\x3d\x9e\xb0\xb7\xad\x9b\xa7\xe0\x52\x43\x03\x19\xb5\xcc\xc3\xd5\x72\x32\x61\xe5\x0e\xa1\x7f\xa7\x17\x4d\x18\x5b\x1a\xbe\x48\x82\x78\xef\x71\x31\xd4\xb3\x7f\x24\x57\x64\x94\x4e\x6d\x78\xb9\xe5\x66\xf2\x73\xd9\x79\x9c\x4c\x4a\xcb\x51\xfd\xe4\xd5\xda\xb3\x3f\x1d\xb7\xff\x57\x0a\x9e\x1c\xb7\x3e\x35\xd8\x45\xb7\x46\xa2\x12\x34\x5d\xa6\xca\xbc\x94\x6a\x34\x36\x76\xa6\x8d\x91\xc9\x3e\x2c\xe3\x98\xc6\x0d\xfc\x41\xf3\x3f\x7e\xac\xd0\xf4\xb7\x56\x9d\xa9\xc1\x50\xd3\x0c\x04\xbe\x1a\xde\xd4\x2d\xf0\x11\xdd\xf9\x32\xda\x65\xec\xbc\xcb\x9c\x24\xbc\xdf\x2c\xcd\x0c\xea\x9b\xd5\xaa\x6d\xd5\x5c\xd3\xcc\xa4\x49\x83\x82\xae\x1d\xce\xa0\x49\xfd\x34\x4b\xf1\x14\x3f\x1a\x44\xfa\xfc\x39\x20\x51\xa0\x37\x5b\x14\x6c\xa5\xc3\xee\xc2\xa6\x82\xe2\x3e\xf0\xd0\xfb\xa2\x82\xe2\x93\xd4\xc7\xa2\xcc\xe7\x96\xf0\x7a\xd5\x13\x5e\xde\x84\x0d\x25\xaa\x0b\x03\xc6\x98\x0f\x4e\xea\x63\x4c\x9e\xe9\x6b\x46\x50\x0e\x74\xdc\x7e\x49\x5b\x5f\x93\xe4\xc3\x48\x66\x53\x13\xfb\xaf\x66\x95\x65\xc5\x2a\x7f\x8a\x37\xb0\x00\x8c\xd5\x04\x91\x4c\xcf\xc6\x3c\xcf\xc8\x89\x6f\x44\x29\x26\x6d\x84\x5e\xe8\x0d\xa9\x79\x7c\xab\xc0\x3c\xd0\xf6\x4c\xf0\x0b\x9e\xbe\xbe\x85\x57\xe6\x21\x25\xa0\xe5\x5a\xd6\xbb\xa6\x0b\xec\xde\x3a\xa9\x43\xb3\x2b\xde\xcf\x10\x8b\x7b\xd7\xff\xf3\xd7\x20\x0c\x7a\xd0\x26\x00\x9e\xa4\x0f\x6f\xc1\x23\xae\x4d\x5f\xf2\xc6\xb3\xa3\x29\x88\x54\x59\x4e\xad\x49\xa0\xc2\x80\xbb\x99\x41\xdc\xbb\x3c\x40\xea\xba\x82\x6f\x97\x17\x2c\x4a\xfe\xb8\x66\xb2\xa1\x5b\x70\x7b\x0b\xcf\xd4\x9b\x4a\x6c\xb3\xc7\xc2\xed\x8a\xfc\x6e\xf3\x48\x39\xd7\xdc\x33\xd5\xc7\xfc\xef\x00\x00\x00\xff\xff\xea\x4a\x62\x0e\xc2\x0b\x00\x00") func nameServiceGeneratedEndpointsGotemplateBytes() ([]byte, error) { return bindataRead( @@ -194,7 +194,7 @@ func nameServiceGeneratedEndpointsGotemplate() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "NAME-service/generated/endpoints.gotemplate", size: 2684, mode: os.FileMode(420), modTime: time.Unix(1464111000, 0)} + info := bindataFileInfo{name: "NAME-service/generated/endpoints.gotemplate", size: 3010, mode: os.FileMode(420), modTime: time.Unix(1464111000, 0)} a := &asset{bytes: bytes, info: info} return a, nil }