The response has been limited to 50k tokens of the smallest files in the repo. You can remove this limitation by removing the max tokens filter.
├── .circleci
    └── config.yml
├── .github
    └── CODEOWNERS
├── .gitignore
├── ADOPTERS.md
├── BUILD.md
├── CHANGES.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── DCO
├── GOVERNANCE.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── MAINTAINERS.md
├── PLUGINS.md
├── README.md
├── admin
    ├── names
    │   └── src
    │   │   └── main
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── admin
    │   │                       └── names
    │   │                           ├── BoundNamesHandler.scala
    │   │                           ├── DelegateApiHandler.scala
    │   │                           └── DelegateHandler.scala
    └── src
    │   ├── main
    │       ├── resources
    │       │   └── io
    │       │   │   └── buoyant
    │       │   │       └── admin
    │       │   │           ├── .eslintignore
    │       │   │           ├── .eslintrc.json
    │       │   │           ├── .gitignore
    │       │   │           ├── README.md
    │       │   │           ├── css
    │       │   │               ├── dashboard.css
    │       │   │               ├── delegator.css
    │       │   │               ├── fonts.css
    │       │   │               ├── fonts
    │       │   │               │   ├── OFL.txt
    │       │   │               │   ├── SourceSansPro-300.woff2
    │       │   │               │   ├── SourceSansPro-400.woff2
    │       │   │               │   ├── SourceSansPro-600.woff2
    │       │   │               │   └── glyphicons-halflings-regular.woff
    │       │   │               ├── lib
    │       │   │               │   └── bootstrap.min.css
    │       │   │               └── logger.css
    │       │   │           ├── images
    │       │   │               ├── favicon.png
    │       │   │               └── linkerd-horizontal-white-transbg-vectorized.svg
    │       │   │           ├── js
    │       │   │               ├── lib
    │       │   │               │   ├── bootstrap.min.js
    │       │   │               │   ├── handlebars.runtime.js
    │       │   │               │   ├── jquery-3.1.1.min.js
    │       │   │               │   ├── lodash.min.js
    │       │   │               │   ├── require.js
    │       │   │               │   ├── smoothie.js
    │       │   │               │   └── text.js
    │       │   │               ├── main-linkerd.js
    │       │   │               ├── main-namerd.js
    │       │   │               ├── spec
    │       │   │               │   ├── BarChartSpec.js
    │       │   │               │   ├── MetricsCollectorSpec.js
    │       │   │               │   ├── RouterClientsSpec.js
    │       │   │               │   ├── RouterServicesSpec.js
    │       │   │               │   ├── RouterSummarySpec.js
    │       │   │               │   ├── UtilsSpec.js
    │       │   │               │   ├── fixtures
    │       │   │               │   │   └── metrics.js
    │       │   │               │   └── test-main.js
    │       │   │               ├── src
    │       │   │               │   ├── admin.js
    │       │   │               │   ├── bar_chart.js
    │       │   │               │   ├── colors.js
    │       │   │               │   ├── combined_client_graph.js
    │       │   │               │   ├── dashboard.js
    │       │   │               │   ├── dashboard_delegate.js
    │       │   │               │   ├── delegate.js
    │       │   │               │   ├── delegator.js
    │       │   │               │   ├── dtab_viewer.js
    │       │   │               │   ├── latency_color_util.js
    │       │   │               │   ├── logging.js
    │       │   │               │   ├── metrics_collector.js
    │       │   │               │   ├── namerd.js
    │       │   │               │   ├── process_info.js
    │       │   │               │   ├── request_totals.js
    │       │   │               │   ├── router_client.js
    │       │   │               │   ├── router_client_dashboard.js
    │       │   │               │   ├── router_clients.js
    │       │   │               │   ├── router_server.js
    │       │   │               │   ├── router_servers.js
    │       │   │               │   ├── router_service.js
    │       │   │               │   ├── router_service_dashboard.js
    │       │   │               │   ├── router_summary.js
    │       │   │               │   ├── success_rate_graph.js
    │       │   │               │   └── utils.js
    │       │   │               └── template
    │       │   │               │   ├── barchart.handlebars
    │       │   │               │   ├── compiled_templates.js
    │       │   │               │   ├── delegatenode.handlebars
    │       │   │               │   ├── delegator.handlebars
    │       │   │               │   ├── dentry.handlebars
    │       │   │               │   ├── error_modal.handlebars
    │       │   │               │   ├── latencies.partial.handlebars
    │       │   │               │   ├── logging_row.handlebars
    │       │   │               │   ├── metric.partial.handlebars
    │       │   │               │   ├── namerd_namespace.handlebars
    │       │   │               │   ├── namerd_stats.handlebars
    │       │   │               │   ├── process_info.handlebars
    │       │   │               │   ├── rate_metric.partial.handlebars
    │       │   │               │   ├── request_stats.handlebars
    │       │   │               │   ├── request_totals.handlebars
    │       │   │               │   ├── router_client.handlebars
    │       │   │               │   ├── router_client_container.handlebars
    │       │   │               │   ├── router_container.handlebars
    │       │   │               │   ├── router_option.handlebars
    │       │   │               │   ├── router_server.handlebars
    │       │   │               │   ├── router_server_container.handlebars
    │       │   │               │   ├── router_service_container.handlebars
    │       │   │               │   ├── router_service_metrics.handlebars
    │       │   │               │   ├── router_services_container.handlebars
    │       │   │               │   └── router_summary.handlebars
    │       │   │           ├── karma.conf.js
    │       │   │           ├── openssl.cnf
    │       │   │           ├── package-lock.json
    │       │   │           ├── package.json
    │       │   │           └── twitter-server
    │       │   │               ├── images
    │       │   │                   └── favicon.ico
    │       │   │               ├── jquery-ui.min.js
    │       │   │               └── js
    │       │   │                   └── threads.js
    │       └── scala
    │       │   └── io
    │       │       └── buoyant
    │       │           └── admin
    │       │               ├── Admin.scala
    │       │               ├── AdminAssetsFilter.scala
    │       │               ├── AdminConfig.scala
    │       │               ├── App.scala
    │       │               ├── Build.scala
    │       │               ├── ConfigHandler.scala
    │       │               ├── HtmlView.scala
    │       │               ├── IndexTxtHandler.scala
    │       │               ├── LoggingHandler.scala
    │       │               ├── SecurityFilter.scala
    │       │               ├── StaticFilter.scala
    │       │               └── TimeZoneLogFormat.scala
    │   └── test
    │       └── scala
    │           └── io
    │               └── buoyant
    │                   └── admin
    │                       ├── LogFormatterTest.scala
    │                       └── SecurityFilterTest.scala
├── ci
    ├── coverage-publish.sh
    ├── docker-publish.sh
    ├── h2.sh
    ├── test.sh
    ├── twitter-develop.sh
    └── update.sh
├── config
    └── src
    │   ├── main
    │       ├── resources
    │       │   └── META-INF
    │       │   │   └── services
    │       │   │       ├── io.buoyant.config.ConfigDeserializer
    │       │   │       └── io.buoyant.config.ConfigSerializer
    │       └── scala
    │       │   └── io
    │       │       └── buoyant
    │       │           └── config
    │       │               ├── ConfigError.scala
    │       │               ├── ConfigInitializer.scala
    │       │               ├── JsonStreamParser.scala
    │       │               ├── Parser.scala
    │       │               ├── PolymorphicConfig.scala
    │       │               └── types
    │       │                   ├── ByteBufferSerializer.scala
    │       │                   ├── DirectoryDeserializer.scala
    │       │                   ├── DtabDeserializer.scala
    │       │                   ├── FileDeserializer.scala
    │       │                   ├── HostAndPort.scala
    │       │                   ├── InetAddressDeserializer.scala
    │       │                   ├── LogLevelDeserializer.scala
    │       │                   ├── PathDeserializer.scala
    │       │                   ├── PathMatcherDeserializer.scala
    │       │                   └── PortDeserializer.scala
    │   └── test
    │       └── scala
    │           └── io
    │               └── buoyant
    │                   └── config
    │                       └── ParserTest.scala
├── consul
    └── src
    │   ├── main
    │       ├── resources
    │       │   └── META-INF
    │       │   │   └── services
    │       │   │       ├── io.buoyant.config.ConfigDeserializer
    │       │   │       └── io.buoyant.config.ConfigSerializer
    │       └── scala
    │       │   └── io
    │       │       └── buoyant
    │       │           └── consul
    │       │               ├── SetAuthTokenFilter.scala
    │       │               ├── SetHostFilter.scala
    │       │               ├── package.scala
    │       │               ├── utils.scala
    │       │               └── v1
    │       │                   ├── AgentApi.scala
    │       │                   ├── BaseApi.scala
    │       │                   ├── ConsistencyMode.scala
    │       │                   ├── ConsulApi.scala
    │       │                   ├── HealthStatus.scala
    │       │                   ├── Instrumentation.scala
    │       │                   ├── KvApi.scala
    │       │                   └── package.scala
    │   └── test
    │       └── scala
    │           └── io
    │               └── buoyant
    │                   └── consul
    │                       └── v1
    │                           ├── AgentApiTest.scala
    │                           ├── BaseApiTest.scala
    │                           ├── CatalogApiTest.scala
    │                           ├── ConsistencyModeTest.scala
    │                           ├── HealthApiTest.scala
    │                           ├── HealthStatusTest.scala
    │                           └── KvApiTest.scala
├── etcd
    ├── README.md
    └── src
    │   ├── integration
    │       └── scala
    │       │   └── io
    │       │       └── buoyant
    │       │           └── etcd
    │       │               ├── EtcdFixture.scala
    │       │               └── EtcdIntegrationTest.scala
    │   ├── main
    │       └── scala
    │       │   └── io
    │       │       └── buoyant
    │       │           └── etcd
    │       │               ├── ApiError.scala
    │       │               ├── Etcd.scala
    │       │               ├── Key.scala
    │       │               ├── Node.scala
    │       │               └── NodeOp.scala
    │   └── test
    │       └── scala
    │           └── io
    │               └── buoyant
    │                   └── etcd
    │                       └── KeyTest.scala
├── finagle
    ├── README.md
    ├── benchmark
    │   └── src
    │   │   └── main
    │   │       └── scala
    │   │           └── com
    │   │               └── twitter
    │   │                   └── finagle
    │   │                       └── buoyant
    │   │                           └── h2
    │   │                               └── BufferedStreamBenchmark.scala
    ├── buoyant
    │   └── src
    │   │   ├── main
    │   │       └── scala
    │   │       │   └── com
    │   │       │       └── twitter
    │   │       │           └── finagle
    │   │       │               ├── buoyant
    │   │       │                   ├── ExistentialStability.scala
    │   │       │                   ├── PathMatcher.scala
    │   │       │                   ├── RetryFilter.scala
    │   │       │                   ├── SocketOptionsConfig.scala
    │   │       │                   ├── TlsClientConfig.scala
    │   │       │                   ├── TlsServerConfig.scala
    │   │       │                   └── package.scala
    │   │       │               └── netty4
    │   │       │                   └── buoyant
    │   │       │                       └── BufferingConnectDelay.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── com
    │   │               └── twitter
    │   │                   └── finagle
    │   │                       └── buoyant
    │   │                           ├── ExistentialStabilityTest.scala
    │   │                           └── PathMatcherTest.scala
    └── h2
    │   ├── README.md
    │   └── src
    │       ├── e2e
    │           ├── resources
    │           │   ├── cacert.pem
    │           │   ├── linkerd-tls-e2e-cert.pem
    │           │   └── linkerd-tls-e2e-key.pem
    │           └── scala
    │           │   └── com
    │           │       └── twitter
    │           │           └── finagle
    │           │               └── buoyant
    │           │                   └── h2
    │           │                       └── TlsEndToEndTest.scala
    │       ├── main
    │           └── scala
    │           │   ├── com
    │           │       └── twitter
    │           │       │   └── finagle
    │           │       │       ├── buoyant
    │           │       │           ├── H2.scala
    │           │       │           └── h2
    │           │       │           │   ├── AccessLogger.scala
    │           │       │           │   ├── BufferedStream.scala
    │           │       │           │   ├── ConnectionHeaders.scala
    │           │       │           │   ├── DelayedReleaseService.scala
    │           │       │           │   ├── Error.scala
    │           │       │           │   ├── H2ApplicationProtocol.scala
    │           │       │           │   ├── H2Transport.scala
    │           │       │           │   ├── Message.scala
    │           │       │           │   ├── Method.scala
    │           │       │           │   ├── Status.scala
    │           │       │           │   ├── Stream.scala
    │           │       │           │   ├── StreamProxy.scala
    │           │       │           │   ├── TracingFilter.scala
    │           │       │           │   ├── netty4
    │           │       │           │       ├── DebugHandler.scala
    │           │       │           │       ├── Netty4ClientDispatcher.scala
    │           │       │           │       ├── Netty4DispatcherBase.scala
    │           │       │           │       ├── Netty4H2Listener.scala
    │           │       │           │       ├── Netty4H2Settings.scala
    │           │       │           │       ├── Netty4H2Transporter.scala
    │           │       │           │       ├── Netty4H2Writer.scala
    │           │       │           │       ├── Netty4Message.scala
    │           │       │           │       ├── Netty4ServerDispatcher.scala
    │           │       │           │       ├── Netty4StreamTransport.scala
    │           │       │           │       └── ServerUpgradeHandler.scala
    │           │       │           │   ├── param.scala
    │           │       │           │   └── service
    │           │       │           │       ├── H2Classifier.scala
    │           │       │           │       ├── H2Classifiers.scala
    │           │       │           │       └── H2ReqRepFrame.scala
    │           │       │       └── netty4
    │           │       │           └── transport
    │           │       │               └── buoyant
    │           │       │                   └── BufferingChannelTransport.scala
    │           │   └── io
    │           │       └── netty
    │           │           └── handler
    │           │               └── codec
    │           │                   └── http2
    │           │                       ├── H2FrameCodec.scala
    │           │                       ├── H2FrameStream.scala
    │           │                       └── Http2FrameCodecServerUpgrader.scala
    │       └── test
    │           └── scala
    │               ├── com
    │                   └── twitter
    │                   │   └── finagle
    │                   │       └── buoyant
    │                   │           └── h2
    │                   │               ├── BufferedStreamTest.scala
    │                   │               ├── TracingFilterTest.scala
    │                   │               └── netty4
    │                   │                   ├── Netty4ClientDispatcherTest.scala
    │                   │                   ├── Netty4ServerDispatcherTest.scala
    │                   │                   └── Netty4StreamTransportTest.scala
    │               └── io
    │                   └── buoyant
    │                       └── test
    │                           └── h2
    │                               └── StreamTestUtils.scala
├── grpc
    ├── README.md
    ├── eg
    │   └── src
    │   │   ├── main
    │   │       └── protobuf
    │   │       │   ├── base.proto
    │   │       │   └── eg.proto
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── grpc
    │   │                       └── EgTest.scala
    ├── gen
    │   └── src
    │   │   └── main
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── grpc
    │   │                       └── gen
    │   │                           ├── Generator.scala
    │   │                           ├── Main.scala
    │   │                           └── ProtoFile.scala
    ├── interop
    │   ├── README.md
    │   └── src
    │   │   ├── main
    │   │       ├── protobuf
    │   │       │   ├── empty.proto
    │   │       │   ├── messages.proto
    │   │       │   └── test.proto
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── grpc
    │   │       │               └── interop
    │   │       │                   ├── Client.scala
    │   │       │                   └── Server.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── grpc
    │   │                       └── interop
    │   │                           ├── InteropTestBase.scala
    │   │                           ├── LocalInteropTest.scala
    │   │                           └── NetworkedEndToEndTest.scala
    └── runtime
    │   └── src
    │       ├── main
    │           └── scala
    │           │   └── io
    │           │       └── buoyant
    │           │           └── grpc
    │           │               └── runtime
    │           │                   ├── ClientDispatcher.scala
    │           │                   ├── Codec.scala
    │           │                   ├── DecodingStream.scala
    │           │                   ├── GrpcStatus.scala
    │           │                   ├── H2Headers.scala
    │           │                   ├── ServerDispatcher.scala
    │           │                   ├── Stream.scala
    │           │                   └── VarEventStream.scala
    │       └── test
    │           └── scala
    │               └── io
    │                   └── buoyant
    │                       └── grpc
    │                           └── runtime
    │                               ├── DecodingStreamTest.scala
    │                               ├── GrpcStatusTest.scala
    │                               ├── UnaryToUnaryTest.scala
    │                               └── VarEventStreamTest.scala
├── interpreter
    ├── consul
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.InterpreterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── interpreter
    │   │       │               └── consul
    │   │       │                   └── ConsulInterpreterInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── interpreter
    │   │                       └── consul
    │   │                           └── ConsulInterpreterTest.scala
    ├── fs
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.InterpreterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── interpreter
    │   │       │               └── fs
    │   │       │                   ├── FsInterpreterConfig.scala
    │   │       │                   └── FsInterpreterInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── interpreter
    │   │                       └── fs
    │   │                           └── FsInterpreterTest.scala
    ├── istio
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.InterpreterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── interpreter
    │   │       │               └── k8s
    │   │       │                   └── istio
    │   │       │                       ├── IstioInterpreter.scala
    │   │       │                       └── IstioInterpreterInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── IstioInterpreterTest.scala
    ├── k8s
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       ├── io.buoyant.namer.InterpreterInitializer
    │   │       │   │       └── io.buoyant.namer.TransformerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           ├── interpreter
    │   │       │               └── k8s
    │   │       │               │   └── ConfigMapInterpreterInitializer.scala
    │   │       │           └── transformer
    │   │       │               └── k8s
    │   │       │                   ├── DaemonSetTransformerInitializer.scala
    │   │       │                   └── LocalNodeTransformerInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   ├── interpreter
    │   │                       └── k8s
    │   │                       │   └── ConfigMapInterpreterTest.scala
    │   │                   └── transformer
    │   │                       └── k8s
    │   │                           ├── DaemonSetTransformerTest.scala
    │   │                           └── LocalnodeTransformerTest.scala
    ├── mesh
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       ├── io.buoyant.config.ConfigSerializer
    │   │       │   │       └── io.buoyant.namer.InterpreterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── interpreter
    │   │       │               ├── MeshInterpreterInitializer.scala
    │   │       │               └── mesh
    │   │       │                   ├── BoundNameTreeSerializer.scala
    │   │       │                   ├── BufSerializers.scala
    │   │       │                   ├── Client.scala
    │   │       │                   ├── EndpointSerializer.scala
    │   │       │                   ├── PathSerializer.scala
    │   │       │                   └── StreamState.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── interpreter
    │   │                       ├── MeshInterpreterInitializerTest.scala
    │   │                       └── mesh
    │   │                           ├── BufSerializersTest.scala
    │   │                           └── ClientTest.scala
    ├── namerd
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.InterpreterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namerd
    │   │       │               └── iface
    │   │       │                   ├── NamerdHandler.scala
    │   │       │                   ├── NamerdHttpInterpreterInitializer.scala
    │   │       │                   └── NamerdInterpreterInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namerd
    │   │                       └── iface
    │   │                           ├── NamerdHttpTest.scala
    │   │                           └── NamerdTest.scala
    ├── per-host
    │   └── src
    │   │   └── main
    │   │       ├── resources
    │   │           └── META-INF
    │   │           │   └── services
    │   │           │       └── io.buoyant.namer.TransformerInitializer
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── transformer
    │   │                       └── perHost
    │   │                           ├── LocalhostTransformerInitializer.scala
    │   │                           ├── PortTransformer.scala
    │   │                           ├── PortTransformerInitializer.scala
    │   │                           └── SpecificHostTransformerInitializer.scala
    └── subnet
    │   └── src
    │       ├── main
    │           └── scala
    │           │   └── io
    │           │       └── buoyant
    │           │           └── transformer
    │           │               ├── Netmask.scala
    │           │               ├── SubnetGatewayTransformer.scala
    │           │               └── SubnetLocalTransformer.scala
    │       └── test
    │           └── scala
    │               └── io
    │                   └── buoyant
    │                       └── transformer
    │                           └── NetmaskTest.scala
├── istio-proto
    └── src
    │   └── main
    │       ├── README.md
    │       ├── protobuf
    │           ├── gogoproto
    │           │   └── gogo.proto
    │           ├── google
    │           │   ├── protobuf
    │           │   │   ├── any.proto
    │           │   │   ├── descriptor.proto
    │           │   │   ├── duration.proto
    │           │   │   └── timestamp.proto
    │           │   └── rpc
    │           │   │   ├── README.md
    │           │   │   ├── code.proto
    │           │   │   ├── error_details.proto
    │           │   │   └── status.proto
    │           ├── mixer
    │           │   └── v1
    │           │   │   ├── attributes.proto
    │           │   │   ├── check.proto
    │           │   │   ├── quota.proto
    │           │   │   ├── report.proto
    │           │   │   └── service.proto
    │           └── proxy
    │           │   └── v1
    │           │       └── config
    │           │           ├── dest_policy.proto
    │           │           ├── http_fault.proto
    │           │           ├── l4_fault.proto
    │           │           ├── proxy_mesh.proto
    │           │           └── route_rule.proto
    │       └── resources
    │           └── mixer
    │               └── v1
    │                   └── global_dictionary.yaml
├── istio
    └── src
    │   ├── main
    │       └── scala
    │       │   └── io
    │       │       └── buoyant
    │       │           └── k8s
    │       │               └── istio
    │       │                   ├── ApiserverClient.scala
    │       │                   ├── ClusterCache.scala
    │       │                   ├── CurrentIstioPath.scala
    │       │                   ├── DiscoveryClient.scala
    │       │                   ├── IstioAttribute.scala
    │       │                   ├── IstioNamer.scala
    │       │                   ├── IstioRequest.scala
    │       │                   ├── IstioRequestAuthorizerFilter.scala
    │       │                   ├── IstioResponse.scala
    │       │                   ├── IstioServices.scala
    │       │                   ├── PollingApiClient.scala
    │       │                   ├── RouteCache.scala
    │       │                   ├── identifiers
    │       │                       ├── IngresssTrafficIdentifier.scala
    │       │                       ├── InternalTrafficIdentifier.scala
    │       │                       ├── IstioIdentifierBase.scala
    │       │                       └── IstioProtocolSpecificRequestHandler.scala
    │       │                   ├── mixer
    │       │                       ├── MixerApiRequests.scala
    │       │                       └── MixerClient.scala
    │       │                   └── package.scala
    │   └── test
    │       └── scala
    │           └── io
    │               └── buoyant
    │                   └── k8s
    │                       └── istio
    │                           ├── ApiserverClientTest.scala
    │                           ├── CurrentIstioPathTest.scala
    │                           ├── IstioRequestAuthorizerFilterTest.scala
    │                           ├── identifiers
    │                               ├── IngressTrafficIdentifierTest.scala
    │                               └── InternalTrafficIdentifierTest.scala
    │                           └── mixer
    │                               ├── MixerApiRequestsTest.scala
    │                               └── MixerClientTest.scala
├── k8s
    └── src
    │   ├── main
    │       └── scala
    │       │   └── io
    │       │       └── buoyant
    │       │           └── k8s
    │       │               ├── Api.scala
    │       │               ├── AuthFilter.scala
    │       │               ├── ClientConfig.scala
    │       │               ├── EndpointsNamer.scala
    │       │               ├── IngressCache.scala
    │       │               ├── InstrumentedWatch.scala
    │       │               ├── PortMapLogger.scala
    │       │               ├── SerializationModule.scala
    │       │               ├── ServiceNamer.scala
    │       │               ├── SetHostFilter.scala
    │       │               ├── Watchable.scala
    │       │               ├── package.scala
    │       │               ├── resources.scala
    │       │               ├── v1.scala
    │       │               └── v1beta1.scala
    │   └── test
    │       └── scala
    │           └── io
    │               └── buoyant
    │                   └── k8s
    │                       ├── CustomResourceTest.scala
    │                       ├── EndpointsNamerTest.scala
    │                       ├── IngressCacheTest.scala
    │                       ├── JsonTest.scala
    │                       ├── ServiceNamerTest.scala
    │                       ├── v1
    │                           └── ApiTest.scala
    │                       └── v1beta1
    │                           └── ApiTest.scala
├── linkerd
    ├── README.md
    ├── admin
    │   └── src
    │   │   ├── main
    │   │       └── scala
    │   │       │   ├── com
    │   │       │       └── twitter
    │   │       │       │   └── finagle
    │   │       │       │       └── client
    │   │       │       │           └── buoyant
    │   │       │       │               └── ClientStateHandler.scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── linkerd
    │   │       │               └── admin
    │   │       │                   ├── AdminFilter.scala
    │   │       │                   ├── AdminHandler.scala
    │   │       │                   ├── DashboardHandler.scala
    │   │       │                   ├── HelpPageHandler.scala
    │   │       │                   ├── HttpIdentifierHandler.scala
    │   │       │                   └── LinkerdAdmin.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── linkerd
    │   │                       └── admin
    │   │                           ├── AdminHandlerTest.scala
    │   │                           ├── ConfigHandlerTest.scala
    │   │                           ├── DashboardHandlerTest.scala
    │   │                           ├── LinkerdAdminTest.scala
    │   │                           └── names
    │   │                               ├── DelegateApiHandlerTest.scala
    │   │                               └── DelegatorTest.scala
    ├── announcer
    │   └── serversets
    │   │   └── src
    │   │       └── main
    │   │           ├── resources
    │   │               └── META-INF
    │   │               │   └── services
    │   │               │       └── io.buoyant.linkerd.AnnouncerInitializer
    │   │           └── scala
    │   │               ├── com
    │   │                   └── twitter
    │   │                   │   └── finagle
    │   │                   │       └── zookeeper
    │   │                   │           └── buoyant
    │   │                   │               └── ZkAnnouncer.scala
    │   │               └── io
    │   │                   └── buoyant
    │   │                       └── linkerd
    │   │                           └── announcer
    │   │                               └── serversets
    │   │                                   └── ServersetsAnnouncerInitializer.scala
    ├── core
    │   └── src
    │   │   ├── e2e
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── linkerd
    │   │       │               └── telemeter
    │   │       │                   └── UsageDataTelemeterEndToEndTest.scala
    │   │   ├── main
    │   │       ├── protobuf
    │   │       │   └── usage.proto
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── linkerd
    │   │       │               ├── AddForwardedHeaderConfig.scala
    │   │       │               ├── Announcer.scala
    │   │       │               ├── AnnouncerInitializer.scala
    │   │       │               ├── ClearContext.scala
    │   │       │               ├── Client.scala
    │   │       │               ├── ClientConfig.scala
    │   │       │               ├── FailureAccrualInitializer.scala
    │   │       │               ├── IdentifierInitializer.scala
    │   │       │               ├── LabelerConfig.scala
    │   │       │               ├── Linker.scala
    │   │       │               ├── LoadBalancerConfig.scala
    │   │       │               ├── MetricsPruningModule.scala
    │   │       │               ├── ProtocolException.scala
    │   │       │               ├── ProtocolInitializer.scala
    │   │       │               ├── RequestAuthorizerInitializer.scala
    │   │       │               ├── ResponseClassifierInitializer.scala
    │   │       │               ├── Router.scala
    │   │       │               ├── RouterContextFormatter.scala
    │   │       │               ├── Server.scala
    │   │       │               ├── SessionConfig.scala
    │   │       │               ├── Svc.scala
    │   │       │               ├── SvcConfig.scala
    │   │       │               ├── TracePropagator.scala
    │   │       │               ├── TracePropagatorInitializer.scala
    │   │       │               ├── package.scala
    │   │       │               └── telemeter
    │   │       │                   └── UsageDataTelemeter.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── linkerd
    │   │                       ├── AddForwardedHeaderConfigTest.scala
    │   │                       ├── ClientConfigTest.scala
    │   │                       ├── ClientSessionConfigTest.scala
    │   │                       ├── ClientTest.scala
    │   │                       ├── HostConnectionPoolTest.scala
    │   │                       ├── LinkerTest.scala
    │   │                       ├── LoadBalancerTest.scala
    │   │                       ├── RetriesConfigTest.scala
    │   │                       ├── RouterTest.scala
    │   │                       ├── ServerTest.scala
    │   │                       ├── SocketOptionsTest.scala
    │   │                       ├── SvcTest.scala
    │   │                       ├── TestAnnouncer.scala
    │   │                       ├── TestProtocol.scala
    │   │                       └── telemeter
    │   │                           └── UsageDataTelemeterTest.scala
    ├── docs
    │   ├── announcer.md
    │   ├── client_tls.md
    │   ├── config.md
    │   ├── failure_accrual.md
    │   ├── interpreter.md
    │   ├── load_balancer.md
    │   ├── namer.md
    │   ├── protocol-h2.md
    │   ├── protocol-http.md
    │   ├── protocol-mux.md
    │   ├── protocol-thrift.md
    │   ├── protocol-thriftmux.md
    │   ├── response_classifier.md
    │   ├── retries.md
    │   ├── routers.md
    │   ├── telemetry.md
    │   └── transformer.md
    ├── examples
    │   ├── access-logs.yaml
    │   ├── admin-tls.yaml
    │   ├── admin.yaml
    │   ├── client-options.yaml
    │   ├── consul-interpreter.yaml
    │   ├── consul.yaml
    │   ├── curator.yaml
    │   ├── disable-tls.yaml
    │   ├── example.dtab
    │   ├── fs.yaml
    │   ├── h2.yaml
    │   ├── h2spec.yaml
    │   ├── http.yaml
    │   ├── influxdb.yaml
    │   ├── io.l5d.fs
    │   │   ├── cat
    │   │   ├── default
    │   │   ├── dog
    │   │   └── thrift
    │   ├── k8s-servicemesh.yaml
    │   ├── k8s.yaml
    │   ├── loadbalancer.yaml
    │   ├── marathon-leader.yaml
    │   ├── marathon.yaml
    │   ├── mutualTls.yaml
    │   ├── namerd-http.yaml
    │   ├── namerd-mesh.yaml
    │   ├── namerd-tls.yaml
    │   ├── namerd.yaml
    │   ├── prometheus.yaml
    │   ├── proxy.yaml
    │   ├── recent-requests.yaml
    │   ├── retries.yaml
    │   ├── rewriting.yaml
    │   ├── serversets.yaml
    │   ├── service-options.yaml
    │   ├── servicemesh.yaml
    │   ├── socket-options.yaml
    │   ├── src
    │   │   └── test
    │   │   │   └── scala
    │   │   │       └── io
    │   │   │           └── buoyant
    │   │   │               └── linkerd
    │   │   │                   └── examples
    │   │   │                       └── ExamplesTest.scala
    │   ├── static_namer.yaml
    │   ├── statsd.yaml
    │   ├── thrift.yaml
    │   ├── thriftmux.yaml
    │   ├── tls.yaml
    │   ├── tracelog.yaml
    │   └── zipkin.yaml
    ├── failure-accrual
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.linkerd.FailureAccrualInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── linkerd
    │   │       │               └── failureAccrual
    │   │       │                   ├── ConsecutiveFailuresInitializer.scala
    │   │       │                   ├── NoneInitializer.scala
    │   │       │                   ├── SuccessRateInitializer.scala
    │   │       │                   └── SuccessRateWindowedInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── linkerd
    │   │                       └── failureAccrual
    │   │                           ├── ConfigTest.scala
    │   │                           ├── ConsecutiveFailuresTest.scala
    │   │                           ├── NoneTest.scala
    │   │                           ├── SuccessRateTest.scala
    │   │                           └── SuccessRateWindowedTest.scala
    ├── main
    │   └── src
    │   │   ├── e2e
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── linkerd
    │   │       │               └── EndToEndTest.scala
    │   │   └── main
    │   │       ├── resources
    │   │           └── log4j.properties
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── linkerd
    │   │                       └── Main.scala
    ├── protocol
    │   ├── benchmark
    │   │   └── src
    │   │   │   └── main
    │   │   │       └── scala
    │   │   │           └── io
    │   │   │               └── buoyant
    │   │   │                   └── protocol
    │   │   │                       └── AccessLoggerBenchmark.scala
    │   ├── h2
    │   │   └── src
    │   │   │   ├── e2e
    │   │   │       └── scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── linkerd
    │   │   │       │               └── protocol
    │   │   │       │                   └── h2
    │   │   │       │                       ├── H2EndToEndTest.scala
    │   │   │       │                       └── StreamClassificationEndToEndTest.scala
    │   │   │   ├── integration
    │   │   │       └── scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── linkerd
    │   │   │       │               └── protocol
    │   │   │       │                   └── h2
    │   │   │       │                       └── ForwardClientCertTest.scala
    │   │   │   ├── main
    │   │   │       ├── resources
    │   │   │       │   └── META-INF
    │   │   │       │   │   └── services
    │   │   │       │   │       ├── io.buoyant.linkerd.IdentifierInitializer
    │   │   │       │   │       ├── io.buoyant.linkerd.ProtocolInitializer
    │   │   │       │   │       ├── io.buoyant.linkerd.RequestAuthorizerInitializer
    │   │   │       │   │       ├── io.buoyant.linkerd.ResponseClassifierInitializer
    │   │   │       │   │       └── io.buoyant.linkerd.TracePropagatorInitializer
    │   │   │       └── scala
    │   │   │       │   ├── com
    │   │   │       │       └── twitter
    │   │   │       │       │   └── finagle
    │   │   │       │       │       └── buoyant
    │   │   │       │       │           └── h2
    │   │   │       │       │               └── LinkerdHeaders.scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── linkerd
    │   │   │       │               └── protocol
    │   │   │       │                   ├── H2Config.scala
    │   │   │       │                   └── h2
    │   │   │       │                       ├── ClientConfig.scala
    │   │   │       │                       ├── ErrorReseter.scala
    │   │   │       │                       ├── H2AccessLogger.scala
    │   │   │       │                       ├── H2ClassifierConfig.scala
    │   │   │       │                       ├── H2Classifiers.scala
    │   │   │       │                       ├── H2DiagnosticTracer.scala
    │   │   │       │                       ├── H2RequestAuthorizerConfig.scala
    │   │   │       │                       ├── H2TracePropagatorConfig.scala
    │   │   │       │                       ├── HeaderPathIdentifier.scala
    │   │   │       │                       ├── HeaderTokenIdentifier.scala
    │   │   │       │                       ├── IngressIdentifier.scala
    │   │   │       │                       ├── LinkerdTracePropagator.scala
    │   │   │       │                       ├── ZipkinTracePropagator.scala
    │   │   │       │                       ├── grpc
    │   │   │       │                           ├── GrpcClassifier.scala
    │   │   │       │                           └── GrpcClassifierConfig.scala
    │   │   │       │                       └── istio
    │   │   │       │                           ├── H2IstioRequest.scala
    │   │   │       │                           ├── H2IstioRequestHandler.scala
    │   │   │       │                           ├── H2IstioResponse.scala
    │   │   │       │                           ├── IstioIdentifier.scala
    │   │   │       │                           ├── IstioIngressIdentifier.scala
    │   │   │       │                           └── IstioRequestAuthorizer.scala
    │   │   │   └── test
    │   │   │       └── scala
    │   │   │           └── io
    │   │   │               └── buoyant
    │   │   │                   └── linkerd
    │   │   │                       └── protocol
    │   │   │                           └── h2
    │   │   │                               ├── CompliantGrpcClassifierTest.scala
    │   │   │                               ├── Downstream.scala
    │   │   │                               ├── ErrorReseterTest.scala
    │   │   │                               ├── GrpcClassifierTest.scala
    │   │   │                               ├── H2ClassifiersTest.scala
    │   │   │                               ├── H2ConfigTest.scala
    │   │   │                               ├── H2DiagnosticTracerTest.scala
    │   │   │                               ├── H2InitializerTest.scala
    │   │   │                               ├── HeaderPathIdentifierTest.scala
    │   │   │                               ├── HeaderTokenIdentifierTest.scala
    │   │   │                               ├── IngressIdentifierConfigTest.scala
    │   │   │                               ├── IngressIdentifierTest.scala
    │   │   │                               ├── Upstream.scala
    │   │   │                               └── istio
    │   │   │                                   ├── H2IstioRequestTest.scala
    │   │   │                                   ├── H2IstioResponseTest.scala
    │   │   │                                   ├── IstioIdentifierTest.scala
    │   │   │                                   └── IstioRequestAuthorizerConfigTest.scala
    │   ├── http
    │   │   └── src
    │   │   │   ├── e2e
    │   │   │       ├── resources
    │   │   │       │   ├── cacert.pem
    │   │   │       │   ├── linkerd-tls-e2e-cert.pem
    │   │   │       │   └── linkerd-tls-e2e-key.pem
    │   │   │       └── scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── linkerd
    │   │   │       │               └── protocol
    │   │   │       │                   ├── HttpEndToEndTest.scala
    │   │   │       │                   ├── HttpStreamingTest.scala
    │   │   │       │                   ├── HttpTlsEndToEndTest.scala
    │   │   │       │                   ├── ResponseClassificationEndToEndTest.scala
    │   │   │       │                   └── RetriesEndToEndTest.scala
    │   │   │   ├── integration
    │   │   │       └── scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── linkerd
    │   │   │       │               └── protocol
    │   │   │       │                   ├── ClientAuthTest.scala
    │   │   │       │                   ├── Downstream.scala
    │   │   │       │                   ├── ForwardClientCertTest.scala
    │   │   │       │                   ├── TlsBoundPathTest.scala
    │   │   │       │                   ├── TlsCertReloadingTest.scala
    │   │   │       │                   ├── TlsNoValidationTest.scala
    │   │   │       │                   ├── TlsStaticValidationTest.scala
    │   │   │       │                   ├── TlsTerminationTest.scala
    │   │   │       │                   └── Upstream.scala
    │   │   │   ├── main
    │   │   │       ├── resources
    │   │   │       │   └── META-INF
    │   │   │       │   │   └── services
    │   │   │       │   │       ├── io.buoyant.linkerd.IdentifierInitializer
    │   │   │       │   │       ├── io.buoyant.linkerd.ProtocolInitializer
    │   │   │       │   │       ├── io.buoyant.linkerd.RequestAuthorizerInitializer
    │   │   │       │   │       ├── io.buoyant.linkerd.ResponseClassifierInitializer
    │   │   │       │   │       └── io.buoyant.linkerd.TracePropagatorInitializer
    │   │   │       └── scala
    │   │   │       │   ├── com
    │   │   │       │       └── twitter
    │   │   │       │       │   └── finagle
    │   │   │       │       │       └── buoyant
    │   │   │       │       │           └── linkerd
    │   │   │       │       │               ├── DelayedRelease.scala
    │   │   │       │       │               └── LinkerdHeaders.scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── linkerd
    │   │   │       │               └── protocol
    │   │   │       │                   ├── HttpConfig.scala
    │   │   │       │                   ├── HttpIdentifierConfig.scala
    │   │   │       │                   ├── HttpRequestAuthorizerConfig.scala
    │   │   │       │                   ├── HttpTracePropagatorConfig.scala
    │   │   │       │                   ├── LinkerdTracePropagator.scala
    │   │   │       │                   ├── ZipkinTracePropagator.scala
    │   │   │       │                   └── http
    │   │   │       │                       ├── AccessLogger.scala
    │   │   │       │                       ├── DiagnosticTracer.scala
    │   │   │       │                       ├── ErrorResponder.scala
    │   │   │       │                       ├── FramingFilter.scala
    │   │   │       │                       ├── HeaderIdentifierConfig.scala
    │   │   │       │                       ├── HeaderTokenIdentifierConfig.scala
    │   │   │       │                       ├── IngressIdentifier.scala
    │   │   │       │                       ├── MethodAndHostIdentifierConfig.scala
    │   │   │       │                       ├── PathIdentifierConfig.scala
    │   │   │       │                       ├── ResponseClassifiers.scala
    │   │   │       │                       ├── RewriteHostHeader.scala
    │   │   │       │                       ├── StaticIdentifierConfig.scala
    │   │   │       │                       ├── StatusCodeStatsFilter.scala
    │   │   │       │                       └── istio
    │   │   │       │                           ├── HttpIstioRequest.scala
    │   │   │       │                           ├── HttpIstioRequestHandler.scala
    │   │   │       │                           ├── HttpIstioResponse.scala
    │   │   │       │                           ├── IstioIdentifier.scala
    │   │   │       │                           ├── IstioIngressIdentifier.scala
    │   │   │       │                           └── IstioRequestAuthorizer.scala
    │   │   │   └── test
    │   │   │       └── scala
    │   │   │           ├── com
    │   │   │               └── twitter
    │   │   │               │   └── finagle
    │   │   │               │       └── buoyant
    │   │   │               │           └── linkerd
    │   │   │               │               └── HeadersTest.scala
    │   │   │           └── io
    │   │   │               └── buoyant
    │   │   │                   └── linkerd
    │   │   │                       └── protocol
    │   │   │                           ├── HttpInitializerTest.scala
    │   │   │                           └── http
    │   │   │                               ├── AccessLoggerTest.scala
    │   │   │                               ├── DiagnosticTracerTest.scala
    │   │   │                               ├── ErrorResponderTest.scala
    │   │   │                               ├── HeaderIdentifierConfigTest.scala
    │   │   │                               ├── HeaderTokenIdentifierConfigTest.scala
    │   │   │                               ├── HttpConfigTest.scala
    │   │   │                               ├── IngressIdentifierConfigTest.scala
    │   │   │                               ├── IngressIdentifierTest.scala
    │   │   │                               ├── MethodAndHostIdentifierConfigTest.scala
    │   │   │                               ├── PathIdentifierConfigTest.scala
    │   │   │                               ├── ResponseClassifiersTest.scala
    │   │   │                               ├── RewriteHostHeaderTest.scala
    │   │   │                               ├── StaticIdentifierConfigTest.scala
    │   │   │                               ├── StatusCodeStatsFilterTest.scala
    │   │   │                               └── istio
    │   │   │                                   ├── HttpIstioRequestTest.scala
    │   │   │                                   ├── HttpIstioResponseTest.scala
    │   │   │                                   ├── IstioIdentifierTest.scala
    │   │   │                                   └── IstioRequestAuthorizerInitializerConfigTest.scala
    │   ├── mux
    │   │   └── src
    │   │   │   └── main
    │   │   │       ├── resources
    │   │   │           └── META-INF
    │   │   │           │   └── services
    │   │   │           │       └── io.buoyant.linkerd.ProtocolInitializer
    │   │   │       └── scala
    │   │   │           └── io
    │   │   │               └── buoyant
    │   │   │                   └── linkerd
    │   │   │                       └── protocol
    │   │   │                           └── MuxInitializer.scala
    │   ├── thrift
    │   │   └── src
    │   │   │   ├── e2e
    │   │   │       └── scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── linkerd
    │   │   │       │               └── protocol
    │   │   │       │                   └── ThriftEndToEndTest.scala
    │   │   │   ├── main
    │   │   │       ├── resources
    │   │   │       │   └── META-INF
    │   │   │       │   │   └── services
    │   │   │       │   │       ├── io.buoyant.config.ConfigDeserializer
    │   │   │       │   │       ├── io.buoyant.config.ConfigSerializer
    │   │   │       │   │       └── io.buoyant.linkerd.ProtocolInitializer
    │   │   │       └── scala
    │   │   │       │   ├── com
    │   │   │       │       └── twitter
    │   │   │       │       │   └── finagle
    │   │   │       │       │       └── buoyant
    │   │   │       │       │           └── linkerd
    │   │   │       │       │               ├── TTwitterClientFilter.scala
    │   │   │       │       │               ├── TTwitterServerFilter.scala
    │   │   │       │       │               ├── ThriftClientPrep.scala
    │   │   │       │       │               ├── ThriftServerPrep.scala
    │   │   │       │       │               └── ThriftTraceInitializer.scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           ├── config
    │   │   │       │               └── types
    │   │   │       │               │   └── ThriftProtocolDeserializer.scala
    │   │   │       │           └── linkerd
    │   │   │       │               └── protocol
    │   │   │       │                   └── ThriftInitializer.scala
    │   │   │   └── test
    │   │   │       └── scala
    │   │   │           └── io
    │   │   │               └── buoyant
    │   │   │                   └── linkerd
    │   │   │                       └── protocol
    │   │   │                           └── ThriftInitializerTest.scala
    │   └── thriftmux
    │   │   └── src
    │   │       ├── main
    │   │           ├── resources
    │   │           │   └── META-INF
    │   │           │   │   └── services
    │   │           │   │       └── io.buoyant.linkerd.ProtocolInitializer
    │   │           └── scala
    │   │           │   ├── com
    │   │           │       └── twitter
    │   │           │       │   └── finagle
    │   │           │       │       └── buoyant
    │   │           │       │           └── linkerd
    │   │           │       │               └── ThriftMuxServerPrep.scala
    │   │           │   └── io
    │   │           │       └── buoyant
    │   │           │           └── linkerd
    │   │           │               └── protocol
    │   │           │                   └── ThriftMuxInitializer.scala
    │   │       └── test
    │   │           └── scala
    │   │               └── io
    │   │                   └── buoyant
    │   │                       └── linkerd
    │   │                           └── protocol
    │   │                               └── ThriftMuxInitializerTest.scala
    ├── telemeter
    │   └── usage
    │   │   └── src
    │   │       └── main
    │   │           └── resources
    │   │               └── META-INF
    │   │                   └── services
    │   │                       └── io.buoyant.telemetry.TelemeterInitializer
    └── tls
    │   └── src
    │       └── main
    │           └── scala
    │               └── io
    │                   └── buoyant
    │                       └── linkerd
    │                           └── tls
    │                               └── TlsUtils.scala
├── marathon
    └── src
    │   ├── main
    │       └── scala
    │       │   └── io
    │       │       └── buoyant
    │       │           └── marathon
    │       │               └── v2
    │       │                   ├── Api.scala
    │       │                   └── WatchState.scala
    │   └── test
    │       └── scala
    │           └── io
    │               └── buoyant
    │                   └── marathon
    │                       └── v2
    │                           └── ApiTest.scala
├── mesh
    ├── README.md
    └── core
    │   └── src
    │       └── main
    │           ├── protobuf
    │               ├── codec.proto
    │               ├── delegator.proto
    │               ├── dtab.proto
    │               ├── interpreter.proto
    │               └── resolver.proto
    │           └── scala
    │               └── io
    │                   └── linkerd
    │                       └── mesh
    │                           └── Converters.scala
├── namer
    ├── consul
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── consul
    │   │       │                   ├── ConsulInitializer.scala
    │   │       │                   ├── ConsulNamer.scala
    │   │       │                   ├── LookupCache.scala
    │   │       │                   ├── SvcAddr.scala
    │   │       │                   └── package.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── consul
    │   │                           ├── ConsulNamerTest.scala
    │   │                           ├── ConsulTest.scala
    │   │                           └── SvcAddrTest.scala
    ├── core
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       ├── io.buoyant.namer.NamerInitializer
    │   │       │   │       └── io.buoyant.namer.TransformerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           ├── RewritingNamer.scala
    │   │       │           ├── hostport.scala
    │   │       │           ├── http.scala
    │   │       │           ├── namer
    │   │       │               ├── BackoffConfig.scala
    │   │       │               ├── ConfiguredDtabNamer.scala
    │   │       │               ├── ConstTransformer.scala
    │   │       │               ├── ConstTransformerInitializer.scala
    │   │       │               ├── DefaultInterpreterInitializer.scala
    │   │       │               ├── DelegateTree.scala
    │   │       │               ├── Delegator.scala
    │   │       │               ├── EnumeratingNamer.scala
    │   │       │               ├── InstrumentedVar.scala
    │   │       │               ├── InterpreterInitializer.scala
    │   │       │               ├── JNamer.scala
    │   │       │               ├── Metadata.scala
    │   │       │               ├── NameTreeTransformer.scala
    │   │       │               ├── NamerInitializer.scala
    │   │       │               ├── Param.scala
    │   │       │               ├── Paths.scala
    │   │       │               ├── ReplaceTransformer.scala
    │   │       │               ├── ReplaceTransformerInitializer.scala
    │   │       │               ├── RewritingNamer.scala
    │   │       │               ├── RewritingNamerInitializer.scala
    │   │       │               ├── TransformerConfig.scala
    │   │       │               └── package.scala
    │   │       │           └── rinet.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   ├── HostPortTest.scala
    │   │                   ├── HttpTest.scala
    │   │                   ├── RinetTest.scala
    │   │                   └── namer
    │   │                       ├── DelegateTreeTest.scala
    │   │                       ├── InstrumentedVarTest.scala
    │   │                       ├── InterpreterInitializerTest.scala
    │   │                       ├── NamerInitializerTest.scala
    │   │                       ├── NamerInitializersTest.scala
    │   │                       ├── NamerTestUtil.scala
    │   │                       ├── RewritingNamerTest.scala
    │   │                       ├── TestInterpreter.scala
    │   │                       ├── TestNamer.scala
    │   │                       ├── TestTransformer.scala
    │   │                       ├── booNamer.scala
    │   │                       ├── booNamerInitializer.scala
    │   │                       ├── booUrnsNamer.scala
    │   │                       └── booUrnsNamerInitializer.scala
    ├── curator
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── curator
    │   │       │                   ├── CuratorInitializer.scala
    │   │       │                   └── CuratorNamer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── curator
    │   │                           └── CuratorTest.scala
    ├── dnssrv
    │   └── src
    │   │   ├── integration
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── dnssrv
    │   │       │                   └── DnsSrvNamerIntegrationTest.scala
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── dnssrv
    │   │       │                   ├── DnsSrvNamer.scala
    │   │       │                   └── DnsSrvNamerInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── dnssrv
    │   │                           └── DnsSrvNamerTest.scala
    ├── fs
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       ├── io.buoyant.config.ConfigSerializer
    │   │       │   │       └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── fs
    │   │       │                   ├── FsInitializer.scala
    │   │       │                   ├── UpRegSerializer.scala
    │   │       │                   ├── WatchState.scala
    │   │       │                   ├── Watcher.scala
    │   │       │                   └── WatchingNamer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── fs
    │   │                           └── FsTest.scala
    ├── istio
    │   └── src
    │   │   └── main
    │   │       ├── resources
    │   │           └── services
    │   │           │   └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── k8s
    │   │                           └── istio
    │   │                               └── IstioInitializer.scala
    ├── k8s
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── k8s
    │   │       │                   ├── K8sExternalInitializer.scala
    │   │       │                   ├── K8sInitializer.scala
    │   │       │                   └── K8sNamespacedInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── k8s
    │   │                           ├── K8sExternalTest.scala
    │   │                           └── K8sTest.scala
    ├── marathon
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── marathon
    │   │       │                   ├── AppIdNamer.scala
    │   │       │                   ├── Authenticator.scala
    │   │       │                   ├── BasicAuthenticatorFilter.scala
    │   │       │                   └── MarathonInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── marathon
    │   │                           ├── AppIdNamerTest.scala
    │   │                           ├── AuthenticatorTest.scala
    │   │                           └── MarathonTest.scala
    ├── rancher
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── rancher
    │   │       │                   ├── RancherClient.scala
    │   │       │                   ├── RancherInitializer.scala
    │   │       │                   └── RancherNamer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── rancher
    │   │                           └── RancherTest.scala
    ├── serversets
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.namer.NamerInitializer
    │   │       └── scala
    │   │       │   ├── com
    │   │       │       └── twitter
    │   │       │       │   └── finagle
    │   │       │       │       └── serversets2
    │   │       │       │           └── BouyantZkResolver.scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namer
    │   │       │               └── serversets
    │   │       │                   ├── ServersetNamer.scala
    │   │       │                   └── ServersetsInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namer
    │   │                       └── serversets
    │   │                           ├── ServersetNamerTest.scala
    │   │                           └── ServersetsTest.scala
    └── zk-leader
    │   └── src
    │       ├── main
    │           ├── java
    │           │   └── com
    │           │   │   └── twitter
    │           │   │       └── common
    │           │   │           └── zookeeper
    │           │   │               ├── Candidate.java
    │           │   │               ├── CandidateImpl.java
    │           │   │               └── ExceptionalCommand.java
    │           ├── resources
    │           │   └── META-INF
    │           │   │   └── services
    │           │   │       └── io.buoyant.namer.NamerInitializer
    │           └── scala
    │           │   └── io
    │           │       └── buoyant
    │           │           └── namer
    │           │               └── zk
    │           │                   ├── ZkLeaderNamer.scala
    │           │                   ├── ZkLeaderNamerInitializer.scala
    │           │                   └── leader.scala
    │       └── test
    │           └── scala
    │               └── io
    │                   └── buoyant
    │                       └── namer
    │                           └── zk
    │                               └── ZkLeaderTest.scala
├── namerd
    ├── README.md
    ├── core
    │   └── src
    │   │   ├── main
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── namerd
    │   │       │               ├── DtabCodec.scala
    │   │       │               ├── DtabStore.scala
    │   │       │               ├── DtabStoreInitializer.scala
    │   │       │               ├── InterfaceConfig.scala
    │   │       │               ├── InterpreterInterfaceConfig.scala
    │   │       │               ├── Namerd.scala
    │   │       │               ├── NamerdConfig.scala
    │   │       │               └── package.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namerd
    │   │                       ├── ConfiguredDtabNamerTest.scala
    │   │                       ├── DtabStoreTest.scala
    │   │                       ├── NamerdConfigTest.scala
    │   │                       ├── NullDtabStore.scala
    │   │                       └── TestNamerInterface.scala
    ├── dcos-bootstrap
    │   └── src
    │   │   └── main
    │   │       └── scala
    │   │           ├── com
    │   │               └── twitter
    │   │               │   └── finagle
    │   │               │       └── serverset2
    │   │               │           └── ZkClient.scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namerd
    │   │                       └── DcosBootstrap.scala
    ├── docs
    │   ├── config.md
    │   ├── interface.md
    │   └── storage.md
    ├── examples
    │   ├── all.yaml
    │   ├── basic.yaml
    │   ├── certs
    │   │   ├── namerd-cacert.pem
    │   │   ├── namerd-cakey.pk8
    │   │   ├── namerd-cert.pem
    │   │   └── namerd-key.pk8
    │   ├── consul-storage.yaml
    │   ├── consul.yaml
    │   ├── destination.yaml
    │   ├── disco
    │   │   └── default
    │   ├── etcd.yaml
    │   ├── k8s-mesh.yaml
    │   ├── k8s.yaml
    │   ├── k8s
    │   │   └── 3rdparty.yaml
    │   ├── mesh.yaml
    │   ├── minimal.yaml
    │   ├── src
    │   │   └── test
    │   │   │   └── scala
    │   │   │       └── io
    │   │   │           └── buoyant
    │   │   │               └── namerd
    │   │   │                   └── examples
    │   │   │                       └── ExamplesTest.scala
    │   ├── static.yaml
    │   ├── tls.yaml
    │   └── zk.yaml
    ├── iface
    │   ├── control-http
    │   │   └── src
    │   │   │   ├── main
    │   │   │       ├── resources
    │   │   │       │   └── META-INF
    │   │   │       │   │   └── services
    │   │   │       │   │       └── io.buoyant.namerd.InterfaceInitializer
    │   │   │       └── scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── namerd
    │   │   │       │               └── iface
    │   │   │       │                   ├── AddrHandler.scala
    │   │   │       │                   ├── BindHandler.scala
    │   │   │       │                   ├── BoundNamesHandler.scala
    │   │   │       │                   ├── DelegateHandler.scala
    │   │   │       │                   ├── DtabHandler.scala
    │   │   │       │                   ├── HttpControlService.scala
    │   │   │       │                   ├── HttpControlServiceConfig.scala
    │   │   │       │                   ├── Json.scala
    │   │   │       │                   ├── NameInterpreterCache.scala
    │   │   │       │                   ├── ResolveHandler.scala
    │   │   │       │                   └── StreamingNamerClient.scala
    │   │   │   └── test
    │   │   │       └── scala
    │   │   │           └── io
    │   │   │               └── buoyant
    │   │   │                   └── namerd
    │   │   │                       └── iface
    │   │   │                           ├── HttpControlServiceConfigTest.scala
    │   │   │                           ├── HttpControlServiceTest.scala
    │   │   │                           └── HttpNamerEndToEndTest.scala
    │   ├── destination
    │   │   └── src
    │   │   │   ├── main
    │   │   │       ├── protobuf
    │   │   │       │   ├── destination.proto
    │   │   │       │   └── net.proto
    │   │   │       ├── resources
    │   │   │       │   ├── META-INF
    │   │   │       │   │   └── services
    │   │   │       │   │   │   └── io.buoyant.namerd.InterfaceInitializer
    │   │   │       │   └── pull-destination-proto.sh
    │   │   │       └── scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── namerd
    │   │   │       │               └── iface
    │   │   │       │                   ├── DestinationIfaceInitializer.scala
    │   │   │       │                   └── destination
    │   │   │       │                       └── DestinationService.scala
    │   │   │   └── test
    │   │   │       └── scala
    │   │   │           └── io
    │   │   │               └── buoyant
    │   │   │                   └── namerd
    │   │   │                       └── iface
    │   │   │                           ├── DestinationIfaceInitializerTest.scala
    │   │   │                           └── destination
    │   │   │                               └── DestinationServiceTest.scala
    │   ├── interpreter-thrift-idl
    │   │   └── src
    │   │   │   └── main
    │   │   │       └── thrift
    │   │   │           └── namer.thrift
    │   ├── interpreter-thrift
    │   │   └── src
    │   │   │   ├── main
    │   │   │       ├── resources
    │   │   │       │   └── META-INF
    │   │   │       │   │   └── services
    │   │   │       │   │       ├── io.buoyant.config.ConfigSerializer
    │   │   │       │   │       └── io.buoyant.namerd.InterfaceInitializer
    │   │   │       └── scala
    │   │   │       │   └── io
    │   │   │       │       └── buoyant
    │   │   │       │           └── namerd
    │   │   │       │               └── iface
    │   │   │       │                   ├── AddrReqSerializer.scala
    │   │   │       │                   ├── AddrSerializer.scala
    │   │   │       │                   ├── BindReqSerializer.scala
    │   │   │       │                   ├── BoundSerializer.scala
    │   │   │       │                   ├── ByteBufferSerializers.scala
    │   │   │       │                   ├── ObserverCache.scala
    │   │   │       │                   ├── PollState.scala
    │   │   │       │                   ├── ThriftInterpreterInterfaceConfig.scala
    │   │   │       │                   ├── ThriftNamerClient.scala
    │   │   │       │                   └── ThriftNamerInterface.scala
    │   │   │   └── test
    │   │   │       └── scala
    │   │   │           └── io
    │   │   │               └── buoyant
    │   │   │                   └── namerd
    │   │   │                       └── iface
    │   │   │                           ├── ByteBufferSerializersTest.scala
    │   │   │                           ├── ObserverCacheTest.scala
    │   │   │                           ├── ThriftInterpreterInterfaceConfigTest.scala
    │   │   │                           ├── ThriftNamerClientTest.scala
    │   │   │                           ├── ThriftNamerEndToEndTest.scala
    │   │   │                           └── ThriftNamerInterfaceTest.scala
    │   └── mesh
    │   │   └── src
    │   │       ├── main
    │   │           ├── resources
    │   │           │   └── META-INF
    │   │           │   │   └── services
    │   │           │   │       └── io.buoyant.namerd.InterfaceInitializer
    │   │           └── scala
    │   │           │   └── io
    │   │           │       └── buoyant
    │   │           │           └── namerd
    │   │           │               └── iface
    │   │           │                   ├── MeshIfaceInitializer.scala
    │   │           │                   └── mesh
    │   │           │                       ├── CodecService.scala
    │   │           │                       ├── DelegatorService.scala
    │   │           │                       ├── Errors.scala
    │   │           │                       ├── InterpreterService.scala
    │   │           │                       └── ResolverService.scala
    │   │       └── test
    │   │           └── scala
    │   │               └── io
    │   │                   └── buoyant
    │   │                       └── namerd
    │   │                           └── iface
    │   │                               ├── MeshIfaceInitializerTest.scala
    │   │                               └── mesh
    │   │                                   ├── DelegatorServiceTest.scala
    │   │                                   └── ResolverServiceTest.scala
    ├── main
    │   └── src
    │   │   └── main
    │   │       ├── resources
    │   │           └── log4j.properties
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── namerd
    │   │                       ├── DtabHandler.scala
    │   │                       ├── DtabListHandler.scala
    │   │                       ├── Main.scala
    │   │                       └── NamerdAdmin.scala
    └── storage
    │   ├── consul
    │       └── src
    │       │   ├── main
    │       │       ├── resources
    │       │       │   └── META-INF
    │       │       │   │   └── services
    │       │       │   │       └── io.buoyant.namerd.DtabStoreInitializer
    │       │       └── scala
    │       │       │   └── io
    │       │       │       └── buoyant
    │       │       │           └── namerd
    │       │       │               └── storage
    │       │       │                   └── consul
    │       │       │                       ├── ConsulDtabStore.scala
    │       │       │                       └── ConsulDtabStoreInitializer.scala
    │       │   └── test
    │       │       └── scala
    │       │           └── io
    │       │               └── buoyant
    │       │                   └── namerd
    │       │                       └── storage
    │       │                           └── consul
    │       │                               ├── ConsulConfigTest.scala
    │       │                               └── ConsulDtabStoreTest.scala
    │   ├── etcd
    │       └── src
    │       │   ├── integration
    │       │       └── scala
    │       │       │   └── io
    │       │       │       └── buoyant
    │       │       │           └── namerd
    │       │       │               └── storage
    │       │       │                   └── etcd
    │       │       │                       └── EtcdDtabStoreIntegrationTest.scala
    │       │   ├── main
    │       │       ├── resources
    │       │       │   └── META-INF
    │       │       │   │   └── services
    │       │       │   │       └── io.buoyant.namerd.DtabStoreInitializer
    │       │       └── scala
    │       │       │   └── io
    │       │       │       └── buoyant
    │       │       │           └── namerd
    │       │       │               └── storage
    │       │       │                   └── etcd
    │       │       │                       ├── EtcdDtabStore.scala
    │       │       │                       └── EtcdDtabStoreInitializer.scala
    │       │   └── test
    │       │       └── scala
    │       │           └── io
    │       │               └── buoyant
    │       │                   └── namerd
    │       │                       └── storage
    │       │                           └── etcd
    │       │                               └── EtcdConfigTest.scala
    │   ├── in-memory
    │       └── src
    │       │   ├── main
    │       │       ├── resources
    │       │       │   └── META-INF
    │       │       │   │   └── services
    │       │       │   │       └── io.buoyant.namerd.DtabStoreInitializer
    │       │       └── scala
    │       │       │   └── io
    │       │       │       └── buoyant
    │       │       │           └── namerd
    │       │       │               └── storage
    │       │       │                   ├── InMemoryDtabStore.scala
    │       │       │                   └── InMemoryDtabStoreInitializer.scala
    │       │   └── test
    │       │       └── scala
    │       │           └── io
    │       │               └── buoyant
    │       │                   └── namerd
    │       │                       └── storage
    │       │                           └── InMemoryDtabStoreTest.scala
    │   ├── k8s
    │       └── src
    │       │   ├── main
    │       │       ├── resources
    │       │       │   └── META-INF
    │       │       │   │   └── services
    │       │       │   │       ├── io.buoyant.k8s.SerializationModule
    │       │       │   │       └── io.buoyant.namerd.DtabStoreInitializer
    │       │       └── scala
    │       │       │   └── io
    │       │       │       └── buoyant
    │       │       │           └── namerd
    │       │       │               └── storage
    │       │       │                   ├── K8sDtabStore.scala
    │       │       │                   ├── K8sDtabStoreInitializer.scala
    │       │       │                   └── kubernetes
    │       │       │                       ├── Dtab.scala
    │       │       │                       ├── DtabDescriptor.scala
    │       │       │                       ├── DtabList.scala
    │       │       │                       ├── DtabSerializationModule.scala
    │       │       │                       ├── DtabWatch.scala
    │       │       │                       └── resources.scala
    │       │   └── test
    │       │       └── scala
    │       │           └── io
    │       │               └── buoyant
    │       │                   └── namerd
    │       │                       └── storage
    │       │                           └── K8sConfigTest.scala
    │   └── zk
    │       └── src
    │           ├── main
    │               ├── resources
    │               │   └── META-INF
    │               │   │   └── services
    │               │   │       └── io.buoyant.namerd.DtabStoreInitializer
    │               └── scala
    │               │   ├── com
    │               │       └── twitter
    │               │       │   └── finagle
    │               │       │       └── serverset2
    │               │       │           └── client
    │               │       │               ├── apache
    │               │       │                   └── buoyant
    │               │       │                   │   └── ApacheZooKeeper.scala
    │               │       │               └── buoyant
    │               │       │                   ├── ZkDtabStore.scala
    │               │       │                   └── ZkSession.scala
    │               │   └── io
    │               │       └── buoyant
    │               │           └── namerd
    │               │               └── storage
    │               │                   └── ZkDtabStoreInitializer.scala
    │           └── test
    │               └── scala
    │                   └── io
    │                       └── buoyant
    │                           └── namerd
    │                               └── storage
    │                                   └── AclTest.scala
├── project
    ├── Base.scala
    ├── Deps.scala
    ├── Finagle.scala
    ├── Grpc.scala
    ├── LinkerdBuild.scala
    ├── build.properties
    └── plugins.sbt
├── protoc
├── router
    ├── base-http
    │   └── src
    │   │   ├── main
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               └── http
    │   │       │                   ├── ForwardClientCertFilter.scala
    │   │       │                   ├── HeadersLike.scala
    │   │       │                   ├── MaxCallDepthFilter.scala
    │   │       │                   └── RequestLike.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── router
    │   │                       └── http
    │   │                           └── MaxCallDepthFilterTest.scala
    ├── core
    │   └── src
    │   │   ├── e2e
    │   │       └── scala
    │   │       │   ├── com
    │   │       │       └── twitter
    │   │       │       │   └── finagle
    │   │       │       │       └── buoyant
    │   │       │       │           └── Echo.scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               └── EchoEndToEndTest.scala
    │   │   ├── main
    │   │       └── scala
    │   │       │   ├── com
    │   │       │       └── twitter
    │   │       │       │   └── finagle
    │   │       │       │       ├── buoyant
    │   │       │       │           ├── Dst.scala
    │   │       │       │           ├── DstTracing.scala
    │   │       │       │           ├── EncodeResidual.scala
    │   │       │       │           ├── FailureAccrualFactory.scala
    │   │       │       │           ├── Sampler.scala
    │   │       │       │           ├── TotalTimeout.scala
    │   │       │       │           ├── TraceInitializer.scala
    │   │       │       │           └── package.scala
    │   │       │       │       ├── loadbalancer
    │   │       │       │           └── buoyant
    │   │       │       │           │   └── DeregisterLoadBalancerFactory.scala
    │   │       │       │       └── naming
    │   │       │       │           └── buoyant
    │   │       │       │               ├── DstBindingFactory.scala
    │   │       │       │               ├── DynBoundFactory.scala
    │   │       │       │               ├── RichConnectionFailedException.scala
    │   │       │       │               ├── RichConnectionFailedModule.scala
    │   │       │       │               └── RichNoBrokersAvailableException.scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               ├── ClassifiedRetries.scala
    │   │       │               ├── ClassifiedTracing.scala
    │   │       │               ├── DiscardingFactoryToService.scala
    │   │       │               ├── ForwardedHeaderLabeler.scala
    │   │       │               ├── LocalClassifierStatsFilter.scala
    │   │       │               ├── Originator.scala
    │   │       │               ├── PathRegistry.scala
    │   │       │               ├── PerDstPathFilter.scala
    │   │       │               ├── PerDstPathStatsFilter.scala
    │   │       │               ├── RetryBudgetModule.scala
    │   │       │               ├── Router.scala
    │   │       │               ├── RouterLabel.scala
    │   │       │               ├── RoutingFactory.scala
    │   │       │               └── context
    │   │       │                   ├── LocalKey.scala
    │   │       │                   ├── dst.scala
    │   │       │                   └── responseClassifier.scala
    │   │   └── test
    │   │       └── scala
    │   │           ├── com
    │   │               └── twitter
    │   │               │   └── finagle
    │   │               │       ├── buoyant
    │   │               │           └── TraceInitializerTest.scala
    │   │               │       └── naming
    │   │               │           └── buoyant
    │   │               │               └── DstBindingFactoryTest.scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── router
    │   │                       ├── ClassifiedRetriesTest.scala
    │   │                       ├── ClassifiedTracingTest.scala
    │   │                       ├── DiscardingFactoryToServiceTest.scala
    │   │                       ├── PerDstPathFilterTest.scala
    │   │                       ├── PerDstPathStatsFilterTest.scala
    │   │                       ├── RouterTest.scala
    │   │                       └── RoutingFactoryTest.scala
    ├── h2
    │   └── src
    │   │   ├── e2e
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               └── h2
    │   │       │                   ├── ClientServerHelpers.scala
    │   │       │                   ├── ConcurrentStreamsEndToEndTest.scala
    │   │       │                   ├── FlowControlEndToEndTest.scala
    │   │       │                   ├── LargeStreamEndToEndTest.scala
    │   │       │                   └── RouterEndToEndTest.scala
    │   │   ├── main
    │   │       └── scala
    │   │       │   ├── com
    │   │       │       └── twitter
    │   │       │       │   └── finagle
    │   │       │       │       └── buoyant
    │   │       │       │           └── h2
    │   │       │       │               └── H2FailureAccrualFactory.scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               ├── H2.scala
    │   │       │               ├── H2Instances.scala
    │   │       │               ├── context
    │   │       │                   └── h2
    │   │       │                   │   └── H2ClassifierCtx.scala
    │   │       │               └── h2
    │   │       │                   ├── ClassifiedRetries.scala
    │   │       │                   ├── ClassifiedRetryFilter.scala
    │   │       │                   ├── ClassifierFilter.scala
    │   │       │                   ├── DupRequest.scala
    │   │       │                   ├── H2AddForwardedHeader.scala
    │   │       │                   ├── LocalClassifierStreamStatsFilter.scala
    │   │       │                   ├── PerDstPathStreamStatsFilter.scala
    │   │       │                   ├── ProxyRewriteFilter.scala
    │   │       │                   ├── StreamStatsFilter.scala
    │   │       │                   └── ViaHeaderFilter.scala
    │   │   └── test
    │   │       └── scala
    │   │           ├── com
    │   │               └── twitter
    │   │               │   └── finagle
    │   │               │       └── buoyant
    │   │               │           └── h2
    │   │               │               └── H2FailureAccrualFactoryTest.scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── router
    │   │                       ├── H2Test.scala
    │   │                       └── h2
    │   │                           ├── ClassifiedRetryFilterTest.scala
    │   │                           ├── DupRequestTest.scala
    │   │                           ├── H2AddForwardedHeaderTest.scala
    │   │                           ├── PerDstPathStreamStatsFilterTest.scala
    │   │                           └── StreamTestStatsFilterTest.scala
    ├── http
    │   └── src
    │   │   ├── e2e
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               └── HttpEndToEndTest.scala
    │   │   ├── main
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           ├── http
    │   │       │               └── status.scala
    │   │       │           └── router
    │   │       │               ├── Http.scala
    │   │       │               ├── HttpInstances.scala
    │   │       │               └── http
    │   │       │                   ├── AddForwardedHeader.scala
    │   │       │                   ├── ClassifierFilter.scala
    │   │       │                   ├── ContentLengthFilter.scala
    │   │       │                   ├── HeaderIdentifier.scala
    │   │       │                   ├── MethodAndHostIdentifier.scala
    │   │       │                   ├── PathIdentifier.scala
    │   │       │                   ├── ProxyRewriteFilter.scala
    │   │       │                   ├── StaticIdentifier.scala
    │   │       │                   ├── StripHopByHopHeadersFilter.scala
    │   │       │                   ├── TimestampHeaderFilter.scala
    │   │       │                   ├── TracingFilter.scala
    │   │       │                   └── ViaHeaderAppenderFilter.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   ├── http
    │   │                       └── StatusTest.scala
    │   │                   └── router
    │   │                       └── http
    │   │                           ├── AddForwardedHeaderTest.scala
    │   │                           ├── HeaderIdentifierTest.scala
    │   │                           ├── MethodAndHostIdentifierTest.scala
    │   │                           ├── PathIdentifierTest.scala
    │   │                           ├── ProxyRewriteFilterTest.scala
    │   │                           ├── StripHopByHopHeadersFilterTest.scala
    │   │                           ├── TimestampHeaderFilterTest.scala
    │   │                           ├── TracingFilterTest.scala
    │   │                           └── ViaHeaderAppenderFilterTest.scala
    ├── mux
    │   └── src
    │   │   ├── e2e
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               └── MuxEndToEndTest.scala
    │   │   └── main
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── router
    │   │                       ├── Mux.scala
    │   │                       └── MuxEncodeResidual.scala
    ├── thrift-idl
    │   └── src
    │   │   └── main
    │   │       └── thrift
    │   │           └── ping.thrift
    ├── thrift
    │   └── src
    │   │   ├── e2e
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               └── ThriftEndToEndTest.scala
    │   │   ├── main
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── router
    │   │       │               ├── Thrift.scala
    │   │       │               └── thrift
    │   │       │                   ├── Dest.scala
    │   │       │                   ├── Identifier.scala
    │   │       │                   └── TracingFilter.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── router
    │   │                       └── thrift
    │   │                           └── IdentifierTest.scala
    └── thriftmux
    │   └── src
    │       ├── e2e
    │           └── scala
    │           │   └── io
    │           │       └── buoyant
    │           │           └── router
    │           │               └── ThriftMuxEndToEndTest.scala
    │       └── main
    │           └── scala
    │               └── io
    │                   └── buoyant
    │                       └── router
    │                           └── ThriftMux.scala
├── sbt
├── telemetry
    ├── admin-metrics-export
    │   └── src
    │   │   ├── main
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── telemetry
    │   │       │               └── admin
    │   │       │                   └── AdminMetricsExportTelemeter.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── telemetry
    │   │                       └── admin
    │   │                           └── AdminMetricsExportTelemeterTest.scala
    ├── core
    │   └── src
    │   │   ├── main
    │   │       └── scala
    │   │       │   ├── com
    │   │       │       └── twitter
    │   │       │       │   └── finagle
    │   │       │       │       └── stats
    │   │       │       │           └── buoyant
    │   │       │       │               └── Metric.scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── telemetry
    │   │       │               ├── MetricsTree.scala
    │   │       │               ├── MetricsTreeStatsReceiver.scala
    │   │       │               ├── Telemeter.scala
    │   │       │               └── TelemeterInitializer.scala
    │   │   └── test
    │   │       ├── resources
    │   │           └── META-INF
    │   │           │   └── services
    │   │           │       └── io.buoyant.telemetry.TelemeterInitializer
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── telemetry
    │   │                       └── TelemeterInitializerTest.scala
    ├── influxdb
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.telemetry.TelemeterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── telemetry
    │   │       │               └── influxdb
    │   │       │                   ├── InfluxDbTelemeter.scala
    │   │       │                   └── InfluxDbTelemeterInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── telemetry
    │   │                       └── influxdb
    │   │                           ├── InfluxDbTelemeterInitializerTest.scala
    │   │                           └── InfluxDbTelemeterTest.scala
    ├── prometheus
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.telemetry.TelemeterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── telemetry
    │   │       │               └── prometheus
    │   │       │                   ├── PrometheusTelemeter.scala
    │   │       │                   └── PrometheusTelemeterInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── telemetry
    │   │                       └── prometheus
    │   │                           ├── PrometheusTelemeterInitializerTest.scala
    │   │                           └── PrometheusTelemeterTest.scala
    ├── recent-requests
    │   └── src
    │   │   └── main
    │   │       ├── resources
    │   │           └── META-INF
    │   │           │   └── services
    │   │           │       └── io.buoyant.telemetry.TelemeterInitializer
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── telemetry
    │   │                       └── recentRequests
    │   │                           ├── RecentRequestsAdminHandler.scala
    │   │                           ├── RecentRequestsInitializer.scala
    │   │                           ├── RecentRequestsTelemeter.scala
    │   │                           └── RecentRequetsTracer.scala
    ├── statsd
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.telemetry.TelemeterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── telemetry
    │   │       │               ├── StatsDInitializer.scala
    │   │       │               └── statsd
    │   │       │                   ├── Metric.scala
    │   │       │                   ├── StatsDStatsReceiver.scala
    │   │       │                   └── StatsDTelemeter.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── telemetry
    │   │                       ├── StatsDInitializerTest.scala
    │   │                       └── statsd
    │   │                           ├── MetricTest.scala
    │   │                           ├── MockStatsDClient.scala
    │   │                           ├── StatsDStatsReceiverTest.scala
    │   │                           └── StatsDTelemeterTest.scala
    ├── tracelog
    │   └── src
    │   │   ├── main
    │   │       ├── resources
    │   │       │   └── META-INF
    │   │       │   │   └── services
    │   │       │   │       └── io.buoyant.telemetry.TelemeterInitializer
    │   │       └── scala
    │   │       │   └── io
    │   │       │       └── buoyant
    │   │       │           └── telemetry
    │   │       │               └── TracelogInitializer.scala
    │   │   └── test
    │   │       └── scala
    │   │           └── io
    │   │               └── buoyant
    │   │                   └── telemetry
    │   │                       └── TracelogInitializerTest.scala
    └── zipkin
    │   └── src
    │       ├── main
    │           ├── resources
    │           │   └── META-INF
    │           │   │   └── services
    │           │   │       └── io.buoyant.telemetry.TelemeterInitializer
    │           └── scala
    │           │   ├── com
    │           │       └── twitter
    │           │       │   └── finagle
    │           │       │       └── buoyant
    │           │       │           └── zipkin
    │           │       │               └── ZipkinTracer.scala
    │           │   └── io
    │           │       └── buoyant
    │           │           └── telemetry
    │           │               └── ZipkinInitializer.scala
    │       └── test
    │           └── scala
    │               └── io
    │                   └── buoyant
    │                       └── telemetry
    │                           └── ZipkinInitializerTest.scala
├── test-util
    └── src
    │   └── main
    │       └── scala
    │           └── io
    │               └── buoyant
    │                   └── test
    │                       ├── ActivityValues.scala
    │                       ├── Awaits.scala
    │                       ├── BudgetedRetries.scala
    │                       ├── Events.scala
    │                       ├── Exceptions.scala
    │                       ├── FunSuite.scala
    │                       ├── Json.scala
    │                       └── Logging.scala
└── validator
    └── src
        └── main
            └── scala
                └── io
                    └── buoyant
                        └── namerd
                            └── Validator.scala


/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @adleong @olix0r @zaharidichev
2 | 
3 | # William and Oliver should approve all changelog entries.
4 | CHANGES.md @wmorgan @olix0r @admc
5 | 
6 | # The DNS SRV namer
7 | /namer/dnssrv/ @ccmtaylor
8 | 


--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
 1 | target/
 2 | dist/
 3 | logs/
 4 | project/boot/
 5 | project/plugins/project/
 6 | project/plugins/src_managed/
 7 | http.pid
 8 | npm-debug.log
 9 | .sbt-launch.jar
10 | .protoc
11 | .idea
12 | .iml
13 | .DS_Store
14 | 
15 | **/*.iml
16 | 


--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
 1 | # Thanks for your help improving the project! #
 2 | 
 3 | ## Getting Help ##
 4 | 
 5 | Github issues are for bug reports and feature requests. For questions about
 6 | Linkerd, how to use it, or debugging assistance, start by
 7 | [asking a question in the forums](https://discourse.linkerd.io/) or join us on
 8 | [Slack](https://slack.linkerd.io/).
 9 | 
10 | Full details at [CONTRIBUTING.md](https://github.com/linkerd/linkerd/blob/main/CONTRIBUTING.md).
11 | 
12 | ## Filing a Linkerd issue ##
13 | 
14 | Issue Type:
15 | 
16 | - [ ] Bug report
17 | - [ ] Feature request
18 | 
19 | **What happened**:
20 | 
21 | **What you expected to happen**:
22 | 
23 | **How to reproduce it (as minimally and precisely as possible)**:
24 | 
25 | **Anything else we need to know?**:
26 | 
27 | **Environment**:
28 | - linkerd/namerd version, config files:
29 | - Platform, version, and config files (Kubernetes, DC/OS, etc):
30 | - Cloud provider or hardware configuration:
31 | 


--------------------------------------------------------------------------------
/MAINTAINERS.md:
--------------------------------------------------------------------------------
 1 | The Linkerd maintainers are:
 2 | 
 3 | * Oliver Gould <ver@buoyant.io> @olix0r (super-maintainer)
 4 | * Alex Leong <alex@buoyant.io> @adleong (super-maintainer)
 5 | * Zarahi Dichev <zahari@buoyant.io> @zaharidichev (super-maintainer)
 6 | * Risha Mars <mars@buoyant.io> @rmars: Admin UI
 7 | * William Morgan <william@buoyant.io> @wmorgan: docs and governance
 8 | * Adam Christian <adam@buoyant.io> @admc: docs and governance
 9 | * Borys Pierov <pierovbg@ncbi.nlm.nih.gov> @Ashald: Consul integration
10 | * Zack Angelo <zack.angelo@bigcommerce.com> @zackangelo: H2 codec
11 | * Christopher Taylor <ccmtaylor+linkerd@gmail.com> @ccmtaylor: DNS SRV namer
12 | 
13 | 
14 | <!--
15 | # Adding a new maintainer
16 | 
17 | * Submit a PR modifying this file
18 | * Add maintainer to .github/CODEOWNERS
19 | * Obtain approvals per GOVERNANCE.md
20 | * Invite maintainer to https://github.com/orgs/linkerd/teams/linkerd-maintainers/members
21 | * Invite maintainer to https://github.com/orgs/linkerd/people
22 | -->
23 | 


--------------------------------------------------------------------------------
/PLUGINS.md:
--------------------------------------------------------------------------------
 1 | # External Linkerd Plugins
 2 | 
 3 | A list of Linkerd plugins that exist outside of the Linkerd repo.  If you have
 4 | developed a Linkerd plugin, we'd love a pull request that adds it to this list.
 5 | 
 6 | * [linkerd-zipkin telemeter](https://github.com/linkerd/linkerd-zipkin)
 7 | * [Open Policy Agent identifier](https://github.com/open-policy-agent/contrib/tree/master/linkerd_authz)
 8 | * [Path to Host identifier](https://github.com/Attest/linkerd-plugins)
 9 | * [Static Namer Plugin](https://github.com/megogo/linkerd-static-namer)
10 | 


--------------------------------------------------------------------------------
/admin/names/src/main/scala/io/buoyant/admin/names/BoundNamesHandler.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin.names
 2 | 
 3 | import com.twitter.finagle.Service
 4 | import com.twitter.finagle.http.{MediaType, Request, Response}
 5 | import com.twitter.util.{Activity, Future}
 6 | import io.buoyant.namer.{EnumeratingNamer, RichActivity}
 7 | 
 8 | class BoundNamesHandler(namers: Seq[EnumeratingNamer]) extends Service[Request, Response] {
 9 |   override def apply(req: Request): Future[Response] = {
10 |     Activity.collect(namers.map(_.getAllNames))
11 |       .toFuture
12 |       .map { names =>
13 |         val json = names.toSet.flatten.map(_.show).mkString("[\"", "\",\"", "\"]")
14 |         val rsp = Response()
15 |         rsp.contentString = json
16 |         rsp.contentType = MediaType.Json
17 |         rsp
18 |       }
19 |   }
20 | }
21 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/.eslintignore:
--------------------------------------------------------------------------------
1 | js/lib
2 | js/template/compiled_templates.js
3 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/.eslintrc.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "env": {
 3 |     "browser": true,
 4 |     "jasmine": true,
 5 |     "jquery": true
 6 |   },
 7 |   "extends": [
 8 |     "eslint:recommended",
 9 |     "plugin:jasmine/recommended",
10 |     "plugin:requirejs/recommended"
11 |   ],
12 |   "globals": {
13 |     "_": true,
14 |     "Handlebars": true
15 |   },
16 |   "plugins": [
17 |     "eslint-plugin-requirejs",
18 |     "jasmine"
19 |   ],
20 |   "rules": {
21 |     "no-console": ["warn", { "allow": ["warn", "error"] }],
22 |     "no-unused-vars": ["error", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }]
23 |   },
24 |   "parserOptions": {
25 |     "ecmaVersion": 6
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/css/fonts.css:
--------------------------------------------------------------------------------
 1 | @font-face {
 2 |   font-family: 'Source Sans Pro';
 3 |   font-style: normal;
 4 |   font-weight: 300;
 5 |   src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), url(fonts/SourceSansPro-300.woff2) format('woff2');
 6 | }
 7 | @font-face {
 8 |   font-family: 'Source Sans Pro';
 9 |   font-style: normal;
10 |   font-weight: 400;
11 |   src: local('Source Sans Pro'), local('SourceSansPro'), url(fonts/SourceSansPro-400.woff2) format('woff2');
12 | }
13 | @font-face {
14 |   font-family: 'Source Sans Pro';
15 |   font-style: normal;
16 |   font-weight: 600;
17 |   src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), url(fonts/SourceSansPro-600.woff2) format('woff2');
18 | }
19 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/css/fonts/SourceSansPro-300.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linkerd/linkerd/ea82499d386e44e8958be58e0386f593e639645b/admin/src/main/resources/io/buoyant/admin/css/fonts/SourceSansPro-300.woff2


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/css/fonts/SourceSansPro-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linkerd/linkerd/ea82499d386e44e8958be58e0386f593e639645b/admin/src/main/resources/io/buoyant/admin/css/fonts/SourceSansPro-400.woff2


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/css/fonts/SourceSansPro-600.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linkerd/linkerd/ea82499d386e44e8958be58e0386f593e639645b/admin/src/main/resources/io/buoyant/admin/css/fonts/SourceSansPro-600.woff2


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/css/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linkerd/linkerd/ea82499d386e44e8958be58e0386f593e639645b/admin/src/main/resources/io/buoyant/admin/css/fonts/glyphicons-halflings-regular.woff


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/css/logger.css:
--------------------------------------------------------------------------------
 1 | .table-striped>tbody>tr:nth-child(odd)>td, .table-striped>tbody>tr:nth-child(odd)>th {
 2 |   background-color: #161963;
 3 | }
 4 | 
 5 | .table-striped>tbody>tr>td {
 6 |   border-top: 1px solid dimgray
 7 | }
 8 | 
 9 | .table-striped>thead>tr {
10 |   border-bottom: 1px solid dimgray
11 | }
12 | 
13 | .table>thead>tr>th {
14 |   border-bottom: none;
15 | }
16 | 
17 | .table h5 {
18 |   color: white;
19 | }
20 | 
21 | table>caption{
22 |   color: red;
23 | }
24 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/images/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linkerd/linkerd/ea82499d386e44e8958be58e0386f593e639645b/admin/src/main/resources/io/buoyant/admin/images/favicon.png


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/main-namerd.js:
--------------------------------------------------------------------------------
 1 | require.config({
 2 |   paths: {
 3 |     'jQuery': 'lib/jquery-3.1.1.min',
 4 |     'lodash': 'lib/lodash.min',
 5 |     'handlebars.runtime': 'lib/handlebars.runtime',
 6 |     'bootstrap': 'lib/bootstrap.min',
 7 |     'text': 'lib/text'
 8 |   },
 9 |   shim: {
10 |     'jQuery': {
11 |       exports: '
#39;
12 |     },
13 |     'lodash': {
14 |       exports: '_'
15 |     },
16 |     'bootstrap': {
17 |       deps : ['jQuery'],
18 |       exports: 'Bootstrap'
19 |     }
20 |   }
21 | });
22 | 
23 | require([
24 |   'jQuery',
25 |   'bootstrap',
26 |   'src/dashboard_delegate',
27 |   'src/logging'
28 | ], function ($, bootstrap, namerdDtabPlayground, loggingConfig) {
29 |   if(window.location.pathname.indexOf("/dtab") >= 0){
30 |     new namerdDtabPlayground();
31 |   } else if(window.location.pathname.endsWith("/logging")){
32 |     new loggingConfig();
33 |   }
34 | });
35 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/src/dashboard_delegate.js:
--------------------------------------------------------------------------------
 1 | "use strict";
 2 | 
 3 | define([
 4 |   'jQuery',
 5 |   'src/delegator'
 6 | ], function(
 7 |   $,
 8 |   Delegator
 9 | ) {
10 |   return function() {
11 |     var dtab = JSON.parse($("#data").html());
12 |     Delegator($(".delegator"), dtab.namespace, [], dtab.dtab);
13 |   }
14 | });
15 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/src/delegate.js:
--------------------------------------------------------------------------------
 1 | "use strict";
 2 | 
 3 | define([
 4 |   'jQuery',
 5 |   'src/admin',
 6 |   'src/delegator'
 7 | ], function(
 8 |   $,
 9 |   AdminHelpers,
10 |   Delegator
11 | ) {
12 |   return function() {
13 |     var dtabMap = JSON.parse($("#dtab-data").html());
14 |     var dtabBaseMap = JSON.parse($("#dtab-base-data").html());
15 | 
16 |     var selectedRouter = AdminHelpers.getSelectedRouter();
17 |     var dtab = dtabMap[selectedRouter];
18 |     var dtabBase = dtabBaseMap[selectedRouter];
19 | 
20 |     if (!dtab) {
21 |       var defaultRouter = $(".router-menu-option:first").text();
22 |       if (dtabMap[defaultRouter]) {
23 |         AdminHelpers.selectRouter(defaultRouter);
24 |       } else {
25 |         console.warn("undefined router:", selectedRouter);
26 |       }
27 |     } else {
28 |       $(".router-label-title").text("Router \"" + selectedRouter + "\"");
29 | 
30 |       Delegator($(".delegator"), selectedRouter, dtab, dtabBase);
31 |     }
32 |   }
33 | });
34 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/src/latency_color_util.js:
--------------------------------------------------------------------------------
 1 | "use strict";
 2 | 
 3 | define(['lodash'], function(_) {
 4 |   var latencyMetricToColorShade = {
 5 |     "max": "light",
 6 |     "p9990": "tint",
 7 |     "p99": "neutral",
 8 |     "p95": "shade",
 9 |     "p50": "dark"
10 |   }
11 |   var latencyKeys = _.keys(latencyMetricToColorShade);
12 | 
13 |   function createLatencyLegend(colorLookup) {
14 |     return _.mapValues(latencyMetricToColorShade, function(shade) {
15 |       return colorLookup[shade];
16 |     });
17 |   }
18 | 
19 |   function getLatencyData(latencyData, latencyLegend) {
20 |     return _.map(latencyKeys, function(key) {
21 |       return {
22 |         latencyLabel: key,
23 |         latencyValue: _.get(latencyData, "stat." + key),
24 |         latencyColor: latencyLegend[key]
25 |       };
26 |     });
27 |   }
28 | 
29 |   return {
30 |     createLatencyLegend: createLatencyLegend,
31 |     getLatencyData: getLatencyData
32 |   };
33 | });
34 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/src/router_servers.js:
--------------------------------------------------------------------------------
 1 | "use strict";
 2 | 
 3 | define([
 4 |   'jQuery',
 5 |   'lodash',
 6 |   'handlebars.runtime',
 7 |   'src/router_server',
 8 |   'template/compiled_templates'
 9 | ], function($, _, Handlebars, RouterServer, templates) {
10 |     var serverContainerTemplate = templates.router_server_container;
11 |     var rateMetricPartial = templates["rate_metric.partial"];
12 | 
13 |     var RouterServers = (function() {
14 |     return function (metricsCollector, initialData, $serverEl, routerName) {
15 |       var servers = initialData[routerName].servers;
16 |       Handlebars.registerPartial('rateMetricPartial', rateMetricPartial);
17 | 
18 |       _.map(servers, function(server) {
19 |         var $el = $(serverContainerTemplate({server: server}));
20 |         $serverEl.append($el);
21 |         RouterServer(metricsCollector, server, $el, routerName);
22 |       });
23 |     }
24 |   })();
25 |   return RouterServers;
26 | });
27 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/src/router_service.js:
--------------------------------------------------------------------------------
 1 | "use strict";
 2 | 
 3 | define([
 4 |   'jQuery',
 5 |   'template/compiled_templates',
 6 |   'bootstrap'
 7 | ], function($, templates) {
 8 | 
 9 |   function render(svcClientMetrics, $container) {
10 |     var clientsHtml = templates.router_service_metrics({
11 |       clients: svcClientMetrics
12 |     });
13 | 
14 |     $container.html(clientsHtml);
15 |   }
16 | 
17 |   return function(metricsCollector, $routerContainer, service) {
18 |     var $svcContainer = $(templates.router_service_container({
19 |       service: service
20 |     }));
21 |     $routerContainer.append($svcContainer);
22 | 
23 |     var $metricsContainer = $($svcContainer.find(".svc-metrics")[0]);
24 | 
25 |     function onMetricsUpdate(metrics) {
26 |       render(metrics, $metricsContainer);
27 |     }
28 | 
29 |     return {
30 |       onMetricsUpdate: onMetricsUpdate
31 |     }
32 |   };
33 | });
34 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/barchart.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="metrics-bar-chart-container">
 2 |   <div class="bar-chart-label metric-header pull-left">
 3 |     {{label.description}}: {{label.value}}
 4 |   </div>
 5 | 
 6 |   {{#if warningLabel}}
 7 |     <div class="bar-chart-label metric-header warning pull-left">
 8 |     {{warningLabel}}
 9 |     </div>
10 |   {{/if}}
11 | 
12 |   <div class="clearfix"></div>
13 |   <div class="overlay-bars bar-container graph-gradient {{color}}" style="width:{{barContainerWidth}}px;"></div>
14 |   <div class="overlay-bars bar graph-gradient {{color}}" style="width:{{barWidth}}px;"></div>
15 | </div>
16 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/dentry.handlebars:
--------------------------------------------------------------------------------
 1 | <div class='dentry'>
 2 |   <div class='dentry-part dentry-prefix' data-dentry-prefix='{{prefix}}'>
 3 |     <span class='prefix-content'>{{prefix}}</span>
 4 |   </div>
 5 |   <div class='fake-column text-center'>=></div>
 6 |   <div class='dentry-part dentry-dst' data-dentry-dst='{{dst}}'>
 7 |     <span class='dst-content'>{{dst}}</span>
 8 |   </div>
 9 |   <div class='fake-column'>;</div>
10 | </div>
11 | <div class='clearfix'></div>
12 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/error_modal.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="modal-dialog modal-sm">
 2 |   <div class="modal-content">
 3 |     <div class="modal-header">
 4 |       <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
 5 |       <h4 class="modal-title">Whoops!</h4>
 6 |     </div>
 7 |     <div class="modal-body">
 8 |       <p>Looks like there was an issue completing your request.</p>
 9 |       <pre>{{.}}</pre>
10 |     </div>
11 |   </div>
12 | </div>
13 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/latencies.partial.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="col-md-2 router-latencies-container">
 2 |   <div class="metric-header">Latencies</div>
 3 |   <div class="router-latencies">
 4 |     {{#each this}}
 5 |       <div>
 6 |         <span class="latency-label">
 7 |           <span class="latency-legend" style="background-color:{{latencyColor}};">&nbsp;</span>{{latencyLabel}}
 8 |         </span>
 9 |         <span class="pull-right latency-value">{{latencyValue}} ms</span>
10 |       </div>
11 |     {{/each}}
12 |   </div>
13 | </div>
14 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/logging_row.handlebars:
--------------------------------------------------------------------------------
 1 | <tr>
 2 |   <td><h5>{{logger}}</h5></td>
 3 |   <td>
 4 |     <div class="btn-group pull-right" role="group">
 5 |       {{#each logLevels}}
 6 |         <a class="btn btn-sm
 7 |           {{#if this.isActive}}
 8 |             btn-primary active disabled" {{else}} btn-default" {{/if}}
 9 |           data-level={{this.level}} data-logger={{@root.logger}} href="#">
10 |           {{this.level}}
11 |         </a>
12 |       {{/each}}
13 |     </div>
14 |   </td>
15 | </tr>
16 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/metric.partial.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="{{containerClass}}">
 2 |   <div class="metric-header">
 3 |     {{#if description}}
 4 |       {{description}}
 5 |     {{else}}
 6 |       metric
 7 |     {{/if}}
 8 |   </div>
 9 |   <div class="{{metricClass}} {{style}}">
10 |     {{#if value}}
11 |       {{value}}
12 |     {{else}}
13 |       0
14 |     {{/if}}
15 |   </div>
16 | </div>
17 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/namerd_namespace.handlebars:
--------------------------------------------------------------------------------
 1 | <div class='namespace-container container-fluid'>
 2 |   <h3>{{namespace}}
 3 |     <small>used by
 4 |       {{#each routers}}
 5 |         <a class="router-list-item" href="/delegator?router={{.}}">{{.}}</a>
 6 |       {{/each}}
 7 |     </small>
 8 |   </h3>
 9 | </div>
10 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/namerd_stats.handlebars:
--------------------------------------------------------------------------------
1 | <h2>Namerd stats</h2>
2 | <div class="namerd-metrics-container">
3 |   {{> metricPartial connections containerClass="metric-container" metricClass="metric-large"}}
4 |   {{> metricPartial bindcache containerClass="metric-container" metricClass="metric-large"}}
5 |   {{> metricPartial addrcache containerClass="metric-container" metricClass="metric-large"}}
6 | </div>
7 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/process_info.handlebars:
--------------------------------------------------------------------------------
 1 | <div id="process-info">
 2 |   <ul class="list-inline topline-stats">
 3 |     {{#each stats}}
 4 |       <li class="col-md-2" data-key="{{dataKey}}">
 5 |         <strong class="stat-label">{{description}}</strong>
 6 |         <span id="{{elemId}}" class="stat">{{value}}</span>
 7 |       </li>
 8 |     {{/each}}
 9 |   </ul>
10 | </div>
11 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/rate_metric.partial.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="{{containerClass}}">
 2 |   <div class="metric-header">
 3 |     {{description}}
 4 |   </div>
 5 |   <div>
 6 |     <span class="{{metricClass}}">
 7 |       {{#if value}}
 8 |         {{value}}
 9 |       {{else}}
10 |         0
11 |       {{/if}}
12 |     </span>
13 | 
14 |     <span class="metric-small">
15 |       {{#if rate}}
16 |         {{rate}}
17 |       {{/if}}
18 |     </span>
19 |   </div>
20 | </div>
21 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/request_stats.handlebars:
--------------------------------------------------------------------------------
1 | {{#each keys}}
2 |   <dt>{{@this}}</dt>
3 |   <dd data-key="{{@this}}">...</dd>
4 | {{/each}}
5 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/request_totals.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="row">
 2 |   {{#each metrics}}
 3 |     <div class="col-md-2">
 4 |       <div class="metric-header">
 5 |         {{description}}
 6 |       </div>
 7 |       <div class="request-total">
 8 |         {{#if value}}
 9 |           {{value}}
10 |         {{else}}
11 |           0
12 |         {{/if}}
13 |       </div>
14 |     </div>
15 |   {{/each}}
16 | </div>
17 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_client.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="client-metrics row">
 2 |   <div class="col-md-2">
 3 |     {{> rateMetricPartial data.successRate containerClass="metric-container" metricClass="metric-large success-metric"}}
 4 |     {{> metricPartial data.requests containerClass="metric-container" metricClass="metric-large"}}
 5 |   </div>
 6 | 
 7 |   <div class="col-md-2">
 8 |     {{> metricPartial data.failures containerClass="metric-container" metricClass="failure-metric metric-large"}}
 9 |     {{> metricPartial data.connections containerClass="metric-container" metricClass="metric-large"}}
10 |   </div>
11 | 
12 |   {{> latencyPartial latencies}}
13 | </div>
14 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_client_container.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="client-container clearfix">
 2 |   <div class="header-line">&nbsp;</div>
 3 |   <div class="router-header-large">
 4 |     <div class="client-id">
 5 |       <div class="pull-left transformer-prefix" style="display: none">{{prefix}}</div>
 6 |       <div class="pull-left client-suffix is-first">{{client}}</div>
 7 |     </div>
 8 |     <div class="client-toggle pull-right">
 9 |       <a class="client-expand" target="blank">expand</a>
10 |       <a class="client-collapse" target="blank">collapse</a>
11 |     </div>
12 |   </div>
13 |   <div class="client-content-container">
14 |     <div class="metrics-container col-md-6"></div>
15 |     <div class="chart-container col-md-6">
16 |       <div class="router-graph-header">Client success rate</div>
17 |       <div class="client-success-rate"></div>
18 |     </div>
19 |     <div class="clearfix"></div>
20 |     <div class="bar-chart-container row">
21 |       <div class="col-md-6 lb-bar-chart"></div>
22 |     </div>
23 |   </div>
24 | </div>
25 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_container.handlebars:
--------------------------------------------------------------------------------
 1 | {{#each routers}}
 2 |   <div class="router router-{{this}} row" data-router="{{this}}">
 3 |     <div class="summary row"></div>
 4 | 
 5 |     <div class="combined-client-graph">
 6 |       <div class="router-graph-header">Requests per client</div>
 7 |       <canvas class="router-graph" height="181"></canvas>
 8 |     </div>
 9 | 
10 |     <div class="router-stats row">
11 |       <div class="retries-bar-chart col-md-6"></div>
12 |       <div class="retries-stats col-md-6"></div>
13 |       <div class="clearfix"></div>
14 |     </div>
15 | 
16 |     <div class="clients router-clients">
17 |       <div class="pull-left router-subsection-title">Clients</div>
18 |       <div class="pull-right client-toggle">
19 |         <a target="blank" class="expand-all">expand all</a> &middot;
20 |         <a target="blank" class="collapse-all">collapse all</a>
21 |       </div>
22 |     </div>
23 |     <div class="servers router-servers row">
24 |       <div class="router-subsection-title">Servers</div>
25 |     </div>
26 |   </div>
27 | {{/each}}
28 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_option.handlebars:
--------------------------------------------------------------------------------
1 | <li><a href='#' class='router-menu-option'>{{#if label}}{{label}}{{else}}{{protocol}}{{/if}}</a></li>
2 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_server.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="client-metrics row">
 2 |   <div class="col-md-2">
 3 |     {{> rateMetricPartial metrics.success containerClass="success-metric-container metric-container col-md-2" metricClass="metric-large success-metric"}}
 4 |     {{> rateMetricPartial metrics.requests containerClass="neutral-metric-container metric-container col-md-2" metricClass="metric-large"}}
 5 |   </div>
 6 | 
 7 |   <div class="col-md-2">
 8 |     {{> rateMetricPartial metrics.failures containerClass="failure-metric-container metric-container col-md-2" metricClass="metric-large failure-metric"}}
 9 |     {{> rateMetricPartial metrics.connections containerClass="neutral-metric-container metric-container col-md-2" metricClass="metric-large"}}
10 |   </div>
11 | 
12 |   {{> latencyPartial latencies}}
13 | </div>
14 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_server_container.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="server-header router-header-large">
 2 |   {{server}}
 3 | </div>
 4 | 
 5 | <div class="router-server clearfix">
 6 |   <div class="server-metrics metrics-container col-md-6"></div>
 7 |   <div class="server-success-chart col-md-6">
 8 |     <div class="router-graph-header">Server success rate</div>
 9 |   </div>
10 | </div>
11 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_service_container.handlebars:
--------------------------------------------------------------------------------
1 | <div class="svc-container" data-service="{{service}}">
2 |   <div class="metric-large">{{service}}</div>
3 |   <div class="svc-metrics"></div>
4 | </div>
5 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_service_metrics.handlebars:
--------------------------------------------------------------------------------
 1 | <div class="service-client-metrics row">
 2 |   <div class="service-subsection-header">Requests per client</div>
 3 |   {{#each clients}}
 4 |   <div class="client-metrics row">
 5 |     <div class="col-md-1 trail-in">
 6 |       {{#if requests}}
 7 |         {{requests}}
 8 |       {{else}}
 9 |         0
10 |       {{/if}}
11 |     </div>
12 |     <div class="col-md-2">{{client}}</div>
13 |   </div>
14 |   {{/each}}
15 | </div>
16 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/js/template/router_services_container.handlebars:
--------------------------------------------------------------------------------
1 | <div class="router row" data-router="{{router}}">
2 |   <div class="router-subsection-title">Router</div>
3 |   <div class="metric-large">{{router}}</div>
4 | 
5 |   <div class="router-subsection-title svc-subsection">Services</div>
6 | </div>
7 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/openssl.cnf:
--------------------------------------------------------------------------------
1 | # Empty openssl.cnf to satisfy phantomjs


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/package.json:
--------------------------------------------------------------------------------
 1 | {
 2 |   "devDependencies": {
 3 |     "eslint": "^6.8.0",
 4 |     "eslint-plugin-jasmine": "^4.1.1",
 5 |     "eslint-plugin-requirejs": "^4.0.0",
 6 |     "handlebars": "^4.7.7",
 7 |     "jasmine": "^3.5.0",
 8 |     "karma": "^5.0.4",
 9 |     "karma-cli": "^2.0.0",
10 |     "karma-jasmine": "^3.1.1",
11 |     "karma-mocha-reporter": "^2.2.5",
12 |     "karma-phantomjs-launcher": "^1.0.4",
13 |     "karma-requirejs": "^1.1.0",
14 |     "requirejs": "^2.3.6",
15 |     "text": "git+https://git@github.com/requirejs/text.git"
16 |   },
17 |   "scripts": {
18 |     "eslint": "eslint js",
19 |     "test": "karma start --single-run"
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/admin/src/main/resources/io/buoyant/admin/twitter-server/images/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linkerd/linkerd/ea82499d386e44e8958be58e0386f593e639645b/admin/src/main/resources/io/buoyant/admin/twitter-server/images/favicon.ico


--------------------------------------------------------------------------------
/admin/src/main/scala/io/buoyant/admin/AdminAssetsFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin
 2 | 
 3 | import com.twitter.finagle.{Service, SimpleFilter}
 4 | import com.twitter.finagle.http.{Request, Response}
 5 | 
 6 | class AdminAssetsFilter(additionalElements: String = "") extends SimpleFilter[Request, Response] {
 7 |   def apply(req: Request, svc: Service[Request, Response]) = {
 8 |     val serviced = svc(req)
 9 |     serviced.map { res =>
10 |       val wrappedHtml = s"""
11 |           <script src="files/js/lib/jquery.min.js"></script>
12 |           <script src="files/jquery-ui.min.js"></script>
13 |           <script src='files/js/lib/bootstrap.min.js'></script>
14 |           <link href="files/css/lib/bootstrap.min.css" rel="stylesheet">
15 |           ${additionalElements}
16 |           <div class="container">${res.contentString}</div>
17 |           """.stripMargin
18 | 
19 |       res.contentString = wrappedHtml
20 |       res
21 |     }
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/admin/src/main/scala/io/buoyant/admin/App.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin
 2 | 
 3 | import com.twitter.app.{App => TApp}
 4 | import com.twitter.logging.Logging
 5 | import com.twitter.server._
 6 | 
 7 | trait App extends TApp
 8 |   with Linters
 9 |   with Logging
10 |   with TimeZoneLogFormat
11 |   with Hooks
12 |   with Stats
13 | 


--------------------------------------------------------------------------------
/admin/src/main/scala/io/buoyant/admin/Build.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin
 2 | 
 3 | import java.io.InputStream
 4 | import java.util.Properties
 5 | 
 6 | /** Build metadata for a linker */
 7 | case class Build(version: String, revision: String, name: String)
 8 | 
 9 | object Build {
10 |   val unknown = Build("?", "?", "?")
11 | 
12 |   def load(resource: String): Build =
13 |     load(getClass.getResourceAsStream(resource))
14 | 
15 |   def load(stream: InputStream): Build =
16 |     Option(stream) match {
17 |       case None => unknown
18 |       case Some(resource) =>
19 |         val props = new Properties
20 |         try props.load(resource) finally resource.close()
21 |         Build(
22 |           props.getProperty("version", "?"),
23 |           props.getProperty("build_revision", "?"),
24 |           props.getProperty("build_name", "?")
25 |         )
26 |     }
27 | }
28 | 


--------------------------------------------------------------------------------
/admin/src/main/scala/io/buoyant/admin/ConfigHandler.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin
 2 | 
 3 | import com.twitter.finagle.Service
 4 | import com.twitter.finagle.http.{MediaType, Request, Response}
 5 | import com.twitter.util.Future
 6 | import io.buoyant.config.{ConfigInitializer, Parser}
 7 | 
 8 | class ConfigHandler(config: Any, configInitializers: Iterable[Seq[ConfigInitializer]])
 9 |   extends Service[Request, Response] {
10 | 
11 |   val mapper = Parser.jsonObjectMapper(configInitializers)
12 | 
13 |   override def apply(request: Request): Future[Response] = {
14 |     val response = Response()
15 |     response.contentType = MediaType.Json + ";charset=UTF-8"
16 |     response.contentString = mapper.writeValueAsString(config)
17 |     Future.value(response)
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/admin/src/main/scala/io/buoyant/admin/HtmlView.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin
 2 | 
 3 | import com.twitter.finagle.http.{Response, MediaType}
 4 | import com.twitter.util.Future
 5 | 
 6 | trait HtmlView {
 7 |   def html(
 8 |     content: String,
 9 |     tailContent: String = "",
10 |     csses: Seq[String] = Nil,
11 |     navHighlight: String = "",
12 |     showRouterDropdown: Boolean = false
13 |   ): String
14 | 
15 |   def mkResponse(
16 |     content: String,
17 |     mediaType: String = MediaType.Html
18 |   ): Future[Response]
19 | }
20 | 


--------------------------------------------------------------------------------
/admin/src/main/scala/io/buoyant/admin/IndexTxtHandler.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin
 2 | 
 3 | import com.twitter.finagle.Service
 4 | import com.twitter.finagle.http.{MediaType, Request, Response}
 5 | import com.twitter.io.Buf
 6 | import com.twitter.util.Future
 7 | 
 8 | class IndexTxtHandler(paths: Seq[String])
 9 |   extends Service[Request, Response] {
10 | 
11 |   def apply(req: Request): Future[Response] = {
12 |     val rsp = Response()
13 |     rsp.version = req.version
14 |     rsp.contentType = MediaType.Txt
15 |     rsp.content = Buf.Utf8(paths.mkString("", "\n", "\n"))
16 |     Future.value(rsp)
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/admin/src/main/scala/io/buoyant/admin/StaticFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin
 2 | 
 3 | import com.twitter.finagle.{Service, SimpleFilter}
 4 | import com.twitter.finagle.http.{MediaType, Response, Request}
 5 | import com.twitter.util.Future
 6 | 
 7 | object StaticFilter extends SimpleFilter[Request, Response] {
 8 | 
 9 |   private[this] val contentTypes: Map[String, String] = Map(
10 |     "css" -> "text/css",
11 |     "gif" -> MediaType.Gif,
12 |     "html" -> MediaType.Html,
13 |     "jpeg" -> MediaType.Jpeg,
14 |     "jpg" -> MediaType.Jpeg,
15 |     "js" -> MediaType.Javascript,
16 |     "json" -> MediaType.Json,
17 |     "png" -> MediaType.Png,
18 |     "svg" -> "image/svg+xml",
19 |     "txt" -> MediaType.Txt
20 |   )
21 | 
22 |   def apply(req: Request, svc: Service[Request, Response]) = {
23 |     svc(req).flatMap { res =>
24 |       val contentType = contentTypes.getOrElse(req.fileExtension, "application/octet-stream")
25 |       res.contentType = contentType + ";charset=UTF-8"
26 |       Future.value(res)
27 |     }
28 |   }
29 | }
30 | 


--------------------------------------------------------------------------------
/admin/src/test/scala/io/buoyant/admin/LogFormatterTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.admin
 2 | 
 3 | import java.util.TimeZone
 4 | import java.util.logging.{Level, LogRecord}
 5 | 
 6 | import com.twitter.util.TimeFormat
 7 | import io.buoyant.test.FunSuite
 8 | 
 9 | class LogFormatterTest extends FunSuite {
10 | 
11 |   val record = new LogRecord(Level.INFO, "Logging useful info")
12 |   record.setMillis(1519468460239L)
13 |   record.setThreadID(10)
14 | 
15 |   test("uses UTC timezone") {
16 |     val utcFormatter = new LogFormatter(
17 |       new TimeFormat(" MMdd HH:mm:ss.SSS z", TimeZone.getTimeZone("UTC"))
18 |     )
19 |     assert(
20 |       utcFormatter
21 |         .format(record) == "I 0224 10:34:20.239 UTC THREAD10: Logging useful info\n"
22 |     )
23 |   }
24 | 
25 |   test("uses non UTC timezone") {
26 |     val gmtFormatter = new LogFormatter(
27 |       new TimeFormat(" MMdd HH:mm:ss.SSS z", TimeZone.getTimeZone("GMT+8"))
28 |     )
29 |     assert(
30 |       gmtFormatter
31 |         .format(record) == "I 0224 18:34:20.239 GMT+08:00 THREAD10: Logging useful info\n"
32 |     )
33 |   }
34 | }
35 | 


--------------------------------------------------------------------------------
/ci/coverage-publish.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/sh
 2 | 
 3 | set -eu
 4 | 
 5 | if [ -z "${COVERALLS_REPO_TOKEN:-}" ]; then
 6 |   echo "COVERALLS_REPO_TOKEN must be set" >&2
 7 |   exit 1
 8 | fi
 9 | 
10 | ./sbt coverageAggregate
11 | ./sbt coveralls
12 | 


--------------------------------------------------------------------------------
/ci/docker-publish.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/sh
 2 | 
 3 | set -eu
 4 | 
 5 | # usage: docker-publish.sh [tag]
 6 | 
 7 | tag=""
 8 | if [ -n "${1:-}" ]; then
 9 |   tag="$1"
10 | fi
11 | 
12 | # if DOCKER_CREDENTIALS is set, save it locally.
13 | if [ -n "${DOCKER_CREDENTIALS:-}" ]; then
14 |   mkdir -p ~/.docker
15 |   echo "$DOCKER_CREDENTIALS" > ~/.docker/config.json
16 | fi
17 | 
18 | # For debugging, allow this to be run without pushing.
19 | docker_target="dockerBuildAndPush"
20 | if [ "${NO_PUSH:-}" = "1" ]; then
21 |   docker_target="docker"
22 | fi
23 | 
24 | if [ -n "$tag" ]; then
25 |   ./sbt "set Base.dockerTag in (linkerd, Bundle) := \"${tag}\"" "linkerd/bundle:${docker_target}" \
26 |         "set Base.dockerTag in (namerd, Bundle) := \"${tag}\"" "namerd/bundle:${docker_target}" \
27 |         "set Base.dockerTag in (namerd, Dcos) := \"dcos-${tag}\"" "namerd/dcos:${docker_target}"
28 | else
29 |   ./sbt "linkerd/bundle:${docker_target}" \
30 |         "namerd/bundle:${docker_target}" \
31 |         "namerd/dcos:${docker_target}"
32 | fi
33 | 


--------------------------------------------------------------------------------
/ci/update.sh:
--------------------------------------------------------------------------------
 1 | #!/bin/sh
 2 | 
 3 | set -eu
 4 | 
 5 | if [ "${TWITTER_DEVELOP:-}" = "1" ]; then
 6 |   export GIT_SHA_DIR=$HOME/.gitshas
 7 |   mkdir -p "$GIT_SHA_DIR"
 8 |   ./ci/twitter-develop.sh
 9 | fi
10 | 
11 | ./sbt update
12 | 


--------------------------------------------------------------------------------
/config/src/main/resources/META-INF/services/io.buoyant.config.ConfigDeserializer:
--------------------------------------------------------------------------------
1 | io.buoyant.config.types.DirectoryDeserializer
2 | io.buoyant.config.types.DtabDeserializer
3 | io.buoyant.config.types.FileDeserializer
4 | io.buoyant.config.types.InetAddressDeserializer
5 | io.buoyant.config.types.LogLevelDeserializer
6 | io.buoyant.config.types.PathDeserializer
7 | io.buoyant.config.types.PathMatcherDeserializer
8 | io.buoyant.config.types.PortDeserializer


--------------------------------------------------------------------------------
/config/src/main/resources/META-INF/services/io.buoyant.config.ConfigSerializer:
--------------------------------------------------------------------------------
 1 | io.buoyant.config.types.ByteBufferSerializer
 2 | io.buoyant.config.types.DirectorySerializer
 3 | io.buoyant.config.types.DtabSerializer
 4 | io.buoyant.config.types.FileSerializer
 5 | io.buoyant.config.types.InetAddressSerializer
 6 | io.buoyant.config.types.LogLevelSerializer
 7 | io.buoyant.config.types.PathSerializer
 8 | io.buoyant.config.types.PortSerializer
 9 | io.buoyant.config.types.PathMatcherSerializer
10 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/ConfigError.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config
 2 | 
 3 | import com.fasterxml.jackson.databind.jsontype.NamedType
 4 | import java.net.InetSocketAddress
 5 | import scala.util.control.NoStackTrace
 6 | 
 7 | trait ConfigError extends NoStackTrace
 8 | 
 9 | object NoRoutersSpecified extends ConfigError {
10 |   def message = "At least one router must be specified in the configuration."
11 | }
12 | 
13 | case class ConflictingSubtypes(t0: NamedType, t1: NamedType) extends ConfigError {
14 |   def message = s"Conflicting subtypes: $t0, $t1"
15 | }
16 | 
17 | case class ConflictingLabels(name: String) extends ConfigError {
18 |   def message = s"Multiple routers with the label $name"
19 | }
20 | case class ConflictingStreamingOptions(name: String) extends ConfigError {
21 |   def message = s"Conflicting streaming options set. Can't disable streaming and set streamAfterContentLengthKB in $name"
22 | }
23 | 
24 | case class ConflictingPorts(
25 |   addr0: InetSocketAddress,
26 |   addr1: InetSocketAddress
27 | ) extends ConfigError {
28 |   def message = s"Server conflict on port ${addr0.getPort}"
29 | }
30 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/ConfigInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config
 2 | 
 3 | import com.fasterxml.jackson.databind.ObjectMapper
 4 | import com.fasterxml.jackson.databind.jsontype.NamedType
 5 | 
 6 | trait ConfigInitializer {
 7 | 
 8 |   def configClass: Class[_]
 9 |   def configId: String = configClass.getName
10 | 
11 |   lazy val namedType = new NamedType(configClass, configId)
12 | 
13 |   def registerSubtypes(mapper: ObjectMapper): Unit =
14 |     mapper.registerSubtypes(namedType)
15 | }
16 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/PolymorphicConfig.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config
 2 | 
 3 | import com.fasterxml.jackson.annotation.{JsonProperty, JsonTypeInfo}
 4 | 
 5 | /**
 6 |  * An abstract class that defines the property "kind" as both a var on
 7 |  * the object and as type information for JSON de/serialization.
 8 |  *
 9 |  * Config objects that expect to be subclassed by multiple other configs
10 |  *   with different "kind" values should extend this trait.
11 |  */
12 | @JsonTypeInfo(
13 |   use = JsonTypeInfo.Id.NAME,
14 |   include = JsonTypeInfo.As.EXISTING_PROPERTY,
15 |   property = "kind",
16 |   visible = true
17 | )
18 | abstract class PolymorphicConfig {
19 |   @JsonProperty("kind")
20 |   var kind: String = ""
21 | }
22 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/ByteBufferSerializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config.types
 2 | 
 3 | import com.fasterxml.jackson.core.JsonGenerator
 4 | import com.fasterxml.jackson.databind.SerializerProvider
 5 | import com.twitter.io.Buf
 6 | import io.buoyant.config.ConfigSerializer
 7 | import java.nio.ByteBuffer
 8 | 
 9 | class ByteBufferSerializer extends ConfigSerializer[ByteBuffer] {
10 |   override def serialize(
11 |     value: ByteBuffer,
12 |     jgen: JsonGenerator,
13 |     provider: SerializerProvider
14 |   ): Unit = {
15 |     val Buf.Utf8(s) = Buf.ByteBuffer.Shared(value)
16 |     jgen.writeString(s)
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/DirectoryDeserializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config.types
 2 | 
 3 | import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
 4 | import com.fasterxml.jackson.databind.{SerializerProvider, DeserializationContext}
 5 | import io.buoyant.config.{ConfigSerializer, ConfigDeserializer}
 6 | import java.nio.file.Paths
 7 | 
 8 | case class Directory(path: java.nio.file.Path) {
 9 |   require(path.toFile.isDirectory, s"$path is not a directory")
10 | }
11 | 
12 | class DirectoryDeserializer extends ConfigDeserializer[Directory] {
13 |   override def deserialize(jp: JsonParser, ctxt: DeserializationContext): Directory =
14 |     Directory(Paths.get(_parseString(jp, ctxt)))
15 | }
16 | 
17 | class DirectorySerializer extends ConfigSerializer[Directory] {
18 |   override def serialize(
19 |     value: Directory,
20 |     jgen: JsonGenerator,
21 |     provider: SerializerProvider
22 |   ): Unit = jgen.writeString(value.path.toString)
23 | }
24 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/DtabDeserializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config.types
 2 | 
 3 | import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
 4 | import com.fasterxml.jackson.databind.{SerializerProvider, DeserializationContext}
 5 | import com.twitter.finagle.Dtab
 6 | import io.buoyant.config.{ConfigSerializer, ConfigDeserializer}
 7 | 
 8 | class DtabDeserializer extends ConfigDeserializer[Dtab] {
 9 |   override def deserialize(parser: JsonParser, ctx: DeserializationContext): Dtab =
10 |     Dtab.read(_parseString(parser, ctx))
11 | }
12 | 
13 | class DtabSerializer extends ConfigSerializer[Dtab] {
14 |   override def serialize(
15 |     value: Dtab,
16 |     jgen: JsonGenerator,
17 |     provider: SerializerProvider
18 |   ): Unit = jgen.writeString(value.show)
19 | }
20 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/FileDeserializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config.types
 2 | 
 3 | import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
 4 | import com.fasterxml.jackson.databind.{SerializerProvider, DeserializationContext}
 5 | import io.buoyant.config.{ConfigSerializer, ConfigDeserializer}
 6 | import java.nio.file.Paths
 7 | 
 8 | case class File(path: java.nio.file.Path) {
 9 |   require(path.toFile.isFile, s"$path is not a file")
10 | }
11 | 
12 | class FileDeserializer extends ConfigDeserializer[File] {
13 |   override def deserialize(jp: JsonParser, ctxt: DeserializationContext): File =
14 |     File(Paths.get(_parseString(jp, ctxt)))
15 | }
16 | 
17 | class FileSerializer extends ConfigSerializer[File] {
18 |   override def serialize(
19 |     value: File,
20 |     jgen: JsonGenerator,
21 |     provider: SerializerProvider
22 |   ): Unit = jgen.writeString(value.path.toString)
23 | }
24 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/InetAddressDeserializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config.types
 2 | 
 3 | import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
 4 | import com.fasterxml.jackson.databind.{DeserializationContext, SerializerProvider}
 5 | import com.google.common.net.InetAddresses
 6 | import io.buoyant.config.{ConfigDeserializer, ConfigSerializer}
 7 | import java.net.InetAddress
 8 | 
 9 | class InetAddressDeserializer extends ConfigDeserializer[InetAddress] {
10 |   override def deserialize(jp: JsonParser, ctxt: DeserializationContext): InetAddress =
11 |     InetAddresses.forString(_parseString(jp, ctxt))
12 | }
13 | 
14 | class InetAddressSerializer extends ConfigSerializer[InetAddress] {
15 |   override def serialize(
16 |     value: InetAddress,
17 |     jgen: JsonGenerator,
18 |     provider: SerializerProvider
19 |   ): Unit = jgen.writeString(value.getHostName)
20 | }
21 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/LogLevelDeserializer.scala:
--------------------------------------------------------------------------------
 1 | 
 2 | package io.buoyant.config.types
 3 | 
 4 | import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
 5 | import com.fasterxml.jackson.databind.{SerializerProvider, DeserializationContext}
 6 | import com.twitter.logging.Level
 7 | import io.buoyant.config.{ConfigSerializer, ConfigDeserializer}
 8 | 
 9 | class LogLevelDeserializer extends ConfigDeserializer[Level] {
10 | 
11 |   override def deserialize(jp: JsonParser, ctxt: DeserializationContext): Level = {
12 |     val lname = _parseString(jp, ctxt)
13 |     Level.parse(lname.toUpperCase).getOrElse {
14 |       throw new IllegalArgumentException(s"Illegal log level: $lname")
15 |     }
16 |   }
17 | }
18 | 
19 | class LogLevelSerializer extends ConfigSerializer[Level] {
20 |   override def serialize(
21 |     level: Level,
22 |     jgen: JsonGenerator,
23 |     provider: SerializerProvider
24 |   ): Unit = jgen.writeString(level.name)
25 | }
26 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/PathDeserializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config.types
 2 | 
 3 | import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
 4 | import com.fasterxml.jackson.databind.{SerializerProvider, DeserializationContext}
 5 | import com.twitter.finagle.Path
 6 | import io.buoyant.config.{ConfigSerializer, ConfigDeserializer}
 7 | 
 8 | class PathDeserializer extends ConfigDeserializer[Path] {
 9 |   override def deserialize(jp: JsonParser, ctxt: DeserializationContext): Path =
10 |     Path.read(_parseString(jp, ctxt))
11 | }
12 | 
13 | class PathSerializer extends ConfigSerializer[Path] {
14 |   override def serialize(
15 |     value: Path,
16 |     jgen: JsonGenerator,
17 |     provider: SerializerProvider
18 |   ): Unit = jgen.writeString(value.show)
19 | }
20 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/PathMatcherDeserializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config.types
 2 | 
 3 | import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
 4 | import com.fasterxml.jackson.databind.{SerializerProvider, DeserializationContext}
 5 | import com.twitter.finagle.buoyant.PathMatcher
 6 | import io.buoyant.config.{ConfigSerializer, ConfigDeserializer}
 7 | 
 8 | class PathMatcherDeserializer extends ConfigDeserializer[PathMatcher] {
 9 |   override def deserialize(jp: JsonParser, ctxt: DeserializationContext): PathMatcher =
10 |     PathMatcher(_parseString(jp, ctxt))
11 | }
12 | 
13 | class PathMatcherSerializer extends ConfigSerializer[PathMatcher] {
14 |   override def serialize(
15 |     value: PathMatcher,
16 |     jgen: JsonGenerator,
17 |     provider: SerializerProvider
18 |   ): Unit = jgen.writeString(value.toString)
19 | }
20 | 


--------------------------------------------------------------------------------
/config/src/main/scala/io/buoyant/config/types/PortDeserializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.config.types
 2 | 
 3 | import com.fasterxml.jackson.core.{JsonGenerator, JsonParser}
 4 | import com.fasterxml.jackson.databind.{SerializerProvider, DeserializationContext}
 5 | import io.buoyant.config.{ConfigSerializer, ConfigDeserializer}
 6 | 
 7 | case class Port(port: Int) {
 8 |   val MinValue = 0
 9 |   val MaxValue = math.pow(2, 16) - 1
10 |   require((MinValue <= port) && (port <= MaxValue), s"$port outside valid range for ports")
11 | }
12 | 
13 | class PortDeserializer extends ConfigDeserializer[Port] {
14 |   override def deserialize(jp: JsonParser, ctxt: DeserializationContext): Port =
15 |     Port(jp.getIntValue)
16 | }
17 | 
18 | class PortSerializer extends ConfigSerializer[Port] {
19 |   override def serialize(
20 |     value: Port,
21 |     jgen: JsonGenerator,
22 |     provider: SerializerProvider
23 |   ): Unit = jgen.writeNumber(value.port)
24 | }
25 | 


--------------------------------------------------------------------------------
/consul/src/main/resources/META-INF/services/io.buoyant.config.ConfigDeserializer:
--------------------------------------------------------------------------------
1 | io.buoyant.consul.v1.ConsistencyModeDeserializer
2 | io.buoyant.consul.v1.HealthStatusDeserializer
3 | 


--------------------------------------------------------------------------------
/consul/src/main/resources/META-INF/services/io.buoyant.config.ConfigSerializer:
--------------------------------------------------------------------------------
1 | io.buoyant.consul.v1.ConsistencyModeSerializer
2 | io.buoyant.consul.v1.HealthStatusSerializer
3 | 


--------------------------------------------------------------------------------
/consul/src/main/scala/io/buoyant/consul/SetAuthTokenFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.consul
 2 | 
 3 | import com.twitter.finagle.http.{Request, Response}
 4 | import com.twitter.finagle.{Service, SimpleFilter}
 5 | 
 6 | class SetAuthTokenFilter(token: String) extends SimpleFilter[Request, Response] {
 7 | 
 8 |   def apply(req: Request, svc: Service[Request, Response]) = {
 9 |     req.headerMap.set("X-Consul-Token", token)
10 |     svc(req)
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/consul/src/main/scala/io/buoyant/consul/SetHostFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.consul
 2 | 
 3 | import com.twitter.finagle.{Service, SimpleFilter}
 4 | import com.twitter.finagle.http.{Request, Response}
 5 | import java.net.InetSocketAddress
 6 | 
 7 | class SetHostFilter(hostname: String, port: Int) extends SimpleFilter[Request, Response] {
 8 |   def this(addr: InetSocketAddress) = this(addr.getHostString, addr.getPort)
 9 | 
10 |   val host: String = port match {
11 |     case 80 | 443 => hostname
12 |     case port => s"$hostname:$port"
13 |   }
14 | 
15 |   def apply(req: Request, svc: Service[Request, Response]) = {
16 |     req.host = host
17 |     svc(req)
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/consul/src/main/scala/io/buoyant/consul/package.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant
2 | 
3 | import com.twitter.logging.Logger
4 | 
5 | package object consul {
6 |   private[consul] val log = Logger.get("consul")
7 | }
8 | 


--------------------------------------------------------------------------------
/consul/src/test/scala/io/buoyant/consul/v1/AgentApiTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.consul.v1
 2 | 
 3 | import com.twitter.finagle.Service
 4 | import com.twitter.finagle.http.{Request, Response}
 5 | import com.twitter.io.Buf
 6 | import com.twitter.util.Future
 7 | import io.buoyant.test.{Awaits, Exceptions}
 8 | import org.scalatest.FunSuite
 9 | 
10 | class AgentApiTest extends FunSuite with Awaits with Exceptions {
11 |   val localAgentBuf = Buf.Utf8("""{ "Config": { "Domain": "acme.co." } }""")
12 |   var lastUri = ""
13 | 
14 |   def stubService(buf: Buf) = Service.mk[Request, Response] { req =>
15 |     val rsp = Response()
16 |     rsp.setContentTypeJson()
17 |     rsp.content = buf
18 |     rsp.headerMap.set("X-Consul-Index", "4")
19 |     lastUri = req.uri
20 |     Future.value(rsp)
21 |   }
22 | 
23 |   test("localAgent returns LocalAgent instance") {
24 |     val service = stubService(localAgentBuf)
25 | 
26 |     val result = await(AgentApi(service).localAgent())
27 |     assert(result.Config.get.Domain.get == "acme.co.")
28 |   }
29 | }
30 | 


--------------------------------------------------------------------------------
/consul/src/test/scala/io/buoyant/consul/v1/ConsistencyModeTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.consul.v1
 2 | 
 3 | import io.buoyant.config.Parser
 4 | import io.buoyant.test.Awaits
 5 | import org.scalatest.FunSuite
 6 | 
 7 | class ConsistencyModeTest extends FunSuite with Awaits {
 8 | 
 9 |   test("consistency nodes can be deserialized from lowercase names") {
10 |     val yaml = "[default, consistent, stale]"
11 |     val mapper = Parser.objectMapper(yaml, Iterable.empty)
12 |     val modes = mapper.readValue[Seq[ConsistencyMode]](yaml)
13 |     assert(modes == Seq(ConsistencyMode.Default, ConsistencyMode.Consistent, ConsistencyMode.Stale))
14 |   }
15 | 
16 | }
17 | 


--------------------------------------------------------------------------------
/etcd/README.md:
--------------------------------------------------------------------------------
 1 | # Finagle Etcd client #
 2 | 
 3 | ## `io.buoyant.etcd` ##
 4 | 
 5 | The `io.buoyant.etcd` package contains a generically useful Etcd
 6 | client built on finagle-http. The client supports a variety of
 7 | asynchronous `key` operations on etcd.  It goes beyond the basic etcd
 8 | operations to provide a `watch` utility that models a key's (or
 9 | tree's) state as an `com.twitter.util.Activity`.
10 | 
11 | ### TODO ###
12 | 
13 | - `compareAndDelete` isn't yet implemented.  minor oversight.
14 | - Use residual paths on the client to instrument chrooted key
15 | operations
16 | - Admin/Stats APIs
17 | - move to gRPC api
18 | 


--------------------------------------------------------------------------------
/finagle/README.md:
--------------------------------------------------------------------------------
1 | # Linkerd: Finagle extensions #
2 | 
3 | This directory contains protocol extensions to Finagle published under
4 | the `io.buoyant` organization.
5 | 


--------------------------------------------------------------------------------
/finagle/h2/README.md:
--------------------------------------------------------------------------------
1 | # io.buoyant:finagle-h2 #
2 | 
3 | Status: **Pre-production** -- currently testing for production-readiness
4 | 
5 | 


--------------------------------------------------------------------------------
/finagle/h2/src/main/scala/com/twitter/finagle/buoyant/h2/netty4/Netty4H2Settings.scala:
--------------------------------------------------------------------------------
 1 | package com.twitter.finagle.buoyant.h2.netty4
 2 | 
 3 | import com.twitter.finagle.Stack
 4 | import com.twitter.finagle.buoyant.h2.param.Settings._
 5 | import io.netty.handler.codec.http2.Http2Settings
 6 | 
 7 | object Netty4H2Settings {
 8 |   def mk(params: Stack.Params): Http2Settings = {
 9 |     val s = new Http2Settings
10 |     params[HeaderTableSize].size.foreach { n => s.headerTableSize(n.inBytes.toInt); () }
11 |     params[InitialStreamWindowSize].size.foreach { n => s.initialWindowSize(n.inBytes.toInt); () }
12 |     params[MaxConcurrentStreams].streams.foreach { n => s.maxConcurrentStreams(n); () }
13 |     params[MaxFrameSize].size.foreach { n => s.maxFrameSize(n.inBytes.toInt); () }
14 |     params[MaxHeaderListSize].size.foreach { n => s.maxHeaderListSize(n.inBytes.toInt); () }
15 |     s
16 |   }
17 | }
18 | 


--------------------------------------------------------------------------------
/finagle/h2/src/main/scala/io/netty/handler/codec/http2/H2FrameStream.scala:
--------------------------------------------------------------------------------
 1 | package io.netty.handler.codec.http2
 2 | 
 3 | case class H2FrameStream(streamId: Int, streamState: Http2Stream.State) extends Http2FrameStream {
 4 |   override def state(): Http2Stream.State = streamState
 5 | 
 6 |   override def id(): Int = streamId
 7 | }
 8 | 
 9 | object H2FrameStream {
10 |   def apply(stream: Http2FrameStream): H2FrameStream =
11 |     H2FrameStream(stream.id(), stream.state())
12 | }


--------------------------------------------------------------------------------
/finagle/h2/src/main/scala/io/netty/handler/codec/http2/Http2FrameCodecServerUpgrader.scala:
--------------------------------------------------------------------------------
 1 | package io.netty.handler.codec.http2
 2 | 
 3 | import io.netty.channel.ChannelHandler
 4 | 
 5 | /**
 6 |  * Adapt Http2ServerUpgradeCodec to be instantiated with an Http2FrameCodec
 7 |  */
 8 | class Http2FrameCodecServerUpgrader(name: String, framer: H2FrameCodec, handler: ChannelHandler)
 9 |   extends Http2ServerUpgradeCodec(framer.connectionHandler) {
10 |   def this(framer: H2FrameCodec) = this(null, framer, framer.connectionHandler)
11 | }
12 | 


--------------------------------------------------------------------------------
/grpc/eg/src/main/protobuf/base.proto:
--------------------------------------------------------------------------------
1 | syntax = "proto3";
2 | 
3 | package io.buoyant.eg.base;
4 | 
5 | message Unit {}
6 | message Exception {
7 |   string message = 1;
8 | }
9 | 


--------------------------------------------------------------------------------
/grpc/gen/src/main/scala/io/buoyant/grpc/gen/Main.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.grpc.gen
 2 | 
 3 | import com.twitter.app.App
 4 | 
 5 | object Main extends App {
 6 | 
 7 |   def main(): Unit = {
 8 |     val req = Generator.parseRequest(System.in)
 9 |     val rsp = Generator.gen(req)
10 |     rsp.writeTo(System.out)
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/grpc/interop/src/test/scala/io/buoyant/grpc/interop/LocalInteropTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.grpc.interop
 2 | 
 3 | import com.twitter.util.Future
 4 | import io.buoyant.test.FunSuite
 5 | 
 6 | class LocalInteropTest extends FunSuite with InteropTestBase {
 7 | 
 8 |   override def withClient(f: Client => Future[Unit]): Future[Unit] =
 9 |     f(new Client(new Server))
10 | }
11 | 


--------------------------------------------------------------------------------
/grpc/runtime/src/main/scala/io/buoyant/grpc/runtime/H2Headers.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.grpc.runtime
 2 | 
 3 | import com.twitter.finagle.buoyant.h2
 4 | 
 5 | private[runtime] object H2Headers {
 6 |   private[this] val AuthorityHeader = h2.Headers.Authority -> ""
 7 |   private[this] val ContentTypeHeader = "content-type" -> "application/grpc+proto"
 8 |   private[this] val MethodHeader = h2.Headers.Method -> h2.Method.Post.toString
 9 |   private[this] val SchemeHeader = h2.Headers.Scheme -> "http"
10 | 
11 |   def responseHeaders(http2Status: h2.Status = h2.Status.Ok): h2.Headers = h2.Headers(
12 |     h2.Headers.Status -> http2Status.toString,
13 |     ContentTypeHeader
14 |   )
15 | 
16 |   def requestHeaders(path: String): h2.Headers = h2.Headers(
17 |     h2.Headers.Path -> path,
18 |     AuthorityHeader,
19 |     ContentTypeHeader,
20 |     MethodHeader,
21 |     SchemeHeader
22 |   )
23 | }
24 | 


--------------------------------------------------------------------------------
/grpc/runtime/src/test/scala/io/buoyant/grpc/runtime/GrpcStatusTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.grpc.runtime
 2 | 
 3 | import com.twitter.concurrent.AsyncQueue
 4 | import com.twitter.finagle.buoyant.h2
 5 | import com.twitter.io.Buf
 6 | import com.twitter.util._
 7 | import io.buoyant.test.FunSuite
 8 | 
 9 | class GrcpStatusTest extends FunSuite {
10 |   test("null message doesn't break trailers") {
11 |     val s = GrpcStatus.Ok(null)
12 |     val t = s.toTrailers
13 |     assert(t.contains("grpc-status"))
14 |     assert(!t.contains("grpc-message"))
15 |   }
16 | 
17 |   test("empty message doesn't break trailers") {
18 |     val s = GrpcStatus.Ok(null)
19 |     val t = s.toTrailers
20 |     assert(t.contains("grpc-status"))
21 |     assert(!t.contains("grpc-message"))
22 |   }
23 | 
24 |   test("message included in trailers") {
25 |     val s = GrpcStatus.Ok("just a message")
26 |     val t = s.toTrailers
27 |     assert(t.contains("grpc-status"))
28 |     assert(t.contains("grpc-message"))
29 |   }
30 | }
31 | 


--------------------------------------------------------------------------------
/interpreter/consul/src/main/resources/META-INF/services/io.buoyant.namer.InterpreterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.interpreter.consul.ConsulInterpreterInitializer
2 | 


--------------------------------------------------------------------------------
/interpreter/fs/src/main/resources/META-INF/services/io.buoyant.namer.InterpreterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.interpreter.fs.FsInterpreterInitializer
2 | 


--------------------------------------------------------------------------------
/interpreter/fs/src/main/scala/io/buoyant/interpreter/fs/FsInterpreterInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.interpreter.fs
 2 | 
 3 | import io.buoyant.namer.InterpreterInitializer
 4 | 
 5 | class FsInterpreterInitializer extends InterpreterInitializer {
 6 |   override def configClass: Class[_] = classOf[FsInterpreterConfig]
 7 |   override def configId: String = "io.l5d.fs"
 8 | }
 9 | 
10 | object FsInterpreterInitializer extends FsInterpreterInitializer
11 | 


--------------------------------------------------------------------------------
/interpreter/fs/src/test/scala/io/buoyant/interpreter/fs/FsInterpreterTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.interpreter.fs
 2 | 
 3 | import com.twitter.finagle.util.LoadService
 4 | import io.buoyant.config.Parser
 5 | import io.buoyant.namer.{InterpreterConfig, InterpreterInitializer}
 6 | import java.io.File
 7 | import org.scalatest.FunSuite
 8 | 
 9 | class FsInterpreterTest extends FunSuite {
10 | 
11 |   test("interpreter registration") {
12 |     assert(LoadService[InterpreterInitializer]().exists(_.isInstanceOf[FsInterpreterInitializer]))
13 |   }
14 | 
15 |   test("parse config") {
16 |     val dtabFile = File.createTempFile("example", ".dtab")
17 |     try {
18 |       val yaml =
19 |         s"""|kind: io.l5d.fs
20 |             |dtabFile: ${dtabFile.getPath}
21 |             |""".stripMargin
22 | 
23 |       val mapper = Parser.objectMapper(yaml, Iterable(Seq(FsInterpreterInitializer)))
24 |       val fs = mapper.readValue[InterpreterConfig](yaml).asInstanceOf[FsInterpreterConfig]
25 |       assert(fs.dtabFile.path.toString == dtabFile.getPath)
26 |     } finally {
27 |       val _ = dtabFile.delete()
28 |     }
29 |   }
30 | }
31 | 
32 | 


--------------------------------------------------------------------------------
/interpreter/istio/src/main/resources/META-INF/services/io.buoyant.namer.InterpreterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.interpreter.k8s.istio.IstioInterpreterInitializer
2 | 


--------------------------------------------------------------------------------
/interpreter/k8s/src/main/resources/META-INF/services/io.buoyant.namer.InterpreterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.interpreter.k8s.ConfigMapInterpreterInitializer
2 | 


--------------------------------------------------------------------------------
/interpreter/k8s/src/main/resources/META-INF/services/io.buoyant.namer.TransformerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.transformer.k8s.DaemonSetTransformerInitializer
2 | io.buoyant.transformer.k8s.LocalNodeTransformerInitializer
3 | 


--------------------------------------------------------------------------------
/interpreter/mesh/src/main/resources/META-INF/services/io.buoyant.config.ConfigSerializer:
--------------------------------------------------------------------------------
1 | io.buoyant.interpreter.mesh.BoundNameTreeSerializer
2 | io.buoyant.interpreter.mesh.EndpointSerializer
3 | io.buoyant.interpreter.mesh.PathSerializer
4 | 


--------------------------------------------------------------------------------
/interpreter/mesh/src/main/resources/META-INF/services/io.buoyant.namer.InterpreterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.interpreter.MeshInterpreterInitializer
2 | 


--------------------------------------------------------------------------------
/interpreter/mesh/src/main/scala/io/buoyant/interpreter/mesh/BufSerializers.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.interpreter.mesh
 2 | 
 3 | import com.twitter.io.Buf
 4 | 
 5 | object BufSerializers {
 6 | 
 7 |   def utf8(buf: Buf): String = Buf.Utf8.unapply(buf).get
 8 | 
 9 |   def path(path: Seq[Buf]): String = path.map(utf8).mkString("/", "/", "")
10 | 
11 |   def ipv4(addr: Buf): String = {
12 |     val bytes = Buf.ByteArray.Owned.extract(addr).map(_ & (-1 >>> 24))
13 | 
14 |     s"${bytes(0)}.${bytes(1)}.${bytes(2)}.${bytes(3)}"
15 |   }
16 | 
17 | }
18 | 


--------------------------------------------------------------------------------
/interpreter/mesh/src/main/scala/io/buoyant/interpreter/mesh/EndpointSerializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.interpreter.mesh
 2 | 
 3 | import com.fasterxml.jackson.core.JsonGenerator
 4 | import com.fasterxml.jackson.databind.SerializerProvider
 5 | import io.buoyant.config.ConfigSerializer
 6 | import io.linkerd.mesh
 7 | import io.linkerd.mesh.Endpoint
 8 | 
 9 | class EndpointSerializer extends ConfigSerializer[mesh.Endpoint] {
10 | 
11 |   override def serialize(
12 |     value: Endpoint,
13 |     gen: JsonGenerator,
14 |     provider: SerializerProvider
15 |   ): Unit = {
16 |     gen.writeStartObject()
17 |     for (iaf <- value.inetAf) gen.writeObjectField("inetAf", iaf)
18 |     for (addr <- value.address) gen.writeStringField("address", BufSerializers.ipv4(addr))
19 |     for (meta <- value.meta) gen.writeObjectField("meta", meta)
20 |     for (metadata <- value.metadata) gen.writeObjectField("metadata", metadata)
21 |     for (port <- value.port) gen.writeStringField("port", port.toString)
22 |     gen.writeEndObject()
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/interpreter/mesh/src/main/scala/io/buoyant/interpreter/mesh/PathSerializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.interpreter.mesh
 2 | 
 3 | import com.fasterxml.jackson.core.JsonGenerator
 4 | import com.fasterxml.jackson.databind.SerializerProvider
 5 | import io.buoyant.config.ConfigSerializer
 6 | import io.linkerd.mesh
 7 | 
 8 | class PathSerializer extends ConfigSerializer[mesh.Path] {
 9 | 
10 |   override def serialize(
11 |     value: mesh.Path,
12 |     gen: JsonGenerator,
13 |     provider: SerializerProvider
14 |   ): Unit = {
15 |     gen.writeString(BufSerializers.path(value.elems))
16 |   }
17 | }
18 | 


--------------------------------------------------------------------------------
/interpreter/mesh/src/test/scala/io/buoyant/interpreter/mesh/BufSerializersTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.interpreter.mesh
 2 | 
 3 | import com.twitter.io.Buf
 4 | import io.buoyant.test.FunSuite
 5 | 
 6 | class BufSerializersTest extends FunSuite {
 7 | 
 8 |   test("Converts string ip byte array to string representation"){
 9 |     val ipTable = Seq(
10 |       (Buf.ByteArray(Seq(10, 120, 1, 137).map(_.toByte):_*), "10.120.1.137"),
11 |       (Buf.ByteArray(Seq(127, 0, 0, 1).map(_.toByte):_*), "127.0.0.1"),
12 |       (Buf.ByteArray(Seq(255, 255, 255, 255).map(_.toByte):_*),"255.255.255.255"),
13 |       (Buf.ByteArray(Seq(1, 2, 3, 4).map(_.toByte):_*), "1.2.3.4"),
14 |       (Buf.ByteArray(Seq(192, 168, 203, 255).map(_.toByte):_*), "192.168.203.255"),
15 |       (Buf.ByteArray(Seq(0, 0, 0, 0).map(_.toByte):_*), "0.0.0.0")
16 |     )
17 | 
18 |     for(ip <- ipTable){
19 |       assert(BufSerializers.ipv4(ip._1) == ip._2)
20 |     }
21 |   }
22 | 
23 | 
24 | }
25 | 


--------------------------------------------------------------------------------
/interpreter/namerd/src/main/resources/META-INF/services/io.buoyant.namer.InterpreterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.iface.NamerdHttpInterpreterInitializer
2 | io.buoyant.namerd.iface.NamerdInterpreterInitializer
3 | 


--------------------------------------------------------------------------------
/interpreter/namerd/src/main/scala/io/buoyant/namerd/iface/NamerdHandler.scala:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linkerd/linkerd/ea82499d386e44e8958be58e0386f593e639645b/interpreter/namerd/src/main/scala/io/buoyant/namerd/iface/NamerdHandler.scala


--------------------------------------------------------------------------------
/interpreter/per-host/src/main/resources/META-INF/services/io.buoyant.namer.TransformerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.transformer.perHost.LocalhostTransformerInitializer
2 | io.buoyant.transformer.perHost.PortTransformerInitializer
3 | io.buoyant.transformer.perHost.SpecificHostTransformerInitializer
4 | 


--------------------------------------------------------------------------------
/interpreter/per-host/src/main/scala/io/buoyant/transformer/perHost/PortTransformerInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.transformer.perHost
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.{Path, Stack}
 5 | import io.buoyant.config.types.Port
 6 | import io.buoyant.namer.{NameTreeTransformer, TransformerConfig, TransformerInitializer}
 7 | 
 8 | class PortTransformerInitializer extends TransformerInitializer {
 9 |   val configClass = classOf[PortTransformerConfig]
10 |   override val configId = "io.l5d.port"
11 | }
12 | 
13 | case class PortTransformerConfig(port: Port) extends TransformerConfig {
14 | 
15 |   @JsonIgnore
16 |   val defaultPrefix = Path.read(s"/io.l5d.port/${port.port}")
17 | 
18 |   override def mk(params: Stack.Params): NameTreeTransformer = new PortTransformer(prefix, port.port)
19 | }
20 | 


--------------------------------------------------------------------------------
/interpreter/per-host/src/main/scala/io/buoyant/transformer/perHost/SpecificHostTransformerInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.transformer
 2 | package perHost
 3 | 
 4 | import com.fasterxml.jackson.annotation.JsonIgnore
 5 | import com.twitter.finagle.{Path, Stack}
 6 | import io.buoyant.namer.{NameTreeTransformer, TransformerConfig, TransformerInitializer}
 7 | import java.net.InetAddress
 8 | 
 9 | class SpecificHostTransformerInitializer extends TransformerInitializer {
10 |   val configClass = classOf[SpecificHostTransformerConfig]
11 |   override val configId = "io.l5d.specificHost"
12 | }
13 | 
14 | case class SpecificHostTransformerConfig(host: String) extends TransformerConfig {
15 |   assert(host != null, "io.l5d.specificHost: host property is required")
16 | 
17 |   @JsonIgnore
18 |   val defaultPrefix = Path.read("/io.l5d.specificHost")
19 | 
20 |   @JsonIgnore
21 |   override def mk(params: Stack.Params): NameTreeTransformer = {
22 |     new SubnetLocalTransformer(prefix, Seq(InetAddress.getByName(host)), Netmask("255.255.255.255"))
23 |   }
24 | 
25 | }
26 | 


--------------------------------------------------------------------------------
/interpreter/subnet/src/main/scala/io/buoyant/transformer/SubnetLocalTransformer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.transformer
 2 | 
 3 | import com.twitter.finagle.{Address, Path}
 4 | import java.net.InetAddress
 5 | import io.buoyant.namer.FilteringNameTreeTransformer
 6 | 
 7 | /**
 8 |  * The subnet local transformer filters the list of addresses down to
 9 |  * only addresses that are on the same subnet as a given local IP.
10 |  */
11 | class SubnetLocalTransformer(val prefix: Path, localIP: Seq[InetAddress], netmask: Netmask)
12 |   extends FilteringNameTreeTransformer {
13 | 
14 |   /** Use all addresses in the same subnet as localIP. */
15 |   override protected val predicate: Address => Boolean = {
16 |     case Address.Inet(addr, _) => localIP.exists(netmask.local(addr.getAddress, _))
17 |     case address => true // non-inet addresses assumed to be local (pipes, etc)
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/istio-proto/src/main/protobuf/google/rpc/README.md:
--------------------------------------------------------------------------------
1 | # Google RPC
2 | 
3 | This package contains type definitions for general RPC systems. While
4 | [gRPC](https://github.com/grpc) is using these defintions, they
5 | are not designed specifically to support gRPC.


--------------------------------------------------------------------------------
/istio/src/main/scala/io/buoyant/k8s/istio/IstioResponse.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.k8s.istio
 2 | 
 3 | import com.twitter.util.Duration
 4 | 
 5 | case class IstioResponse[Resp](statusCode: Int, duration: Duration, resp: Option[Resp]) {
 6 | 
 7 |   def responseCode: ResponseCodeIstioAttribute = ResponseCodeIstioAttribute(statusCode)
 8 | 
 9 |   def responseDuration: ResponseDurationIstioAttribute = ResponseDurationIstioAttribute(duration)
10 | 
11 | }
12 | 


--------------------------------------------------------------------------------
/istio/src/main/scala/io/buoyant/k8s/istio/identifiers/IstioProtocolSpecificRequestHandler.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.k8s.istio.identifiers
 2 | 
 3 | import com.twitter.util.Future
 4 | import istio.proxy.v1.config.HTTPRedirect
 5 | 
 6 | trait IstioProtocolSpecificRequestHandler[Req] {
 7 |   def redirectRequest(redir: HTTPRedirect, req: Req): Future[Nothing]
 8 |   def rewriteRequest(uri: String, authority: Option[String], req: Req): Unit
 9 | }
10 | 


--------------------------------------------------------------------------------
/istio/src/main/scala/io/buoyant/k8s/istio/package.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.k8s
 2 | 
 3 | package object istio {
 4 |   val DefaultDiscoveryHost = "istio-pilot"
 5 |   val DefaultDiscoveryPort = 8080
 6 | 
 7 |   val DefaultApiserverHost = "istio-pilot"
 8 |   val DefaultApiserverPort = 8081
 9 | 
10 |   val DefaultMixerHost = "istio-mixer"
11 |   val DefaultMixerPort = 9091
12 | 
13 |   val IngressAnnotationClass = "istio"
14 | }
15 | 


--------------------------------------------------------------------------------
/k8s/src/main/scala/io/buoyant/k8s/AuthFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.k8s
 2 | 
 3 | import com.twitter.finagle.http.{Request, Response}
 4 | import com.twitter.finagle.{Service, SimpleFilter}
 5 | 
 6 | class AuthFilter(token: String) extends SimpleFilter[Request, Response] {
 7 |   def apply(req: Request, service: Service[Request, Response]) = {
 8 |     req.headerMap("Authorization") = s"Bearer $token"
 9 |     service(req)
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/k8s/src/main/scala/io/buoyant/k8s/SerializationModule.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.k8s
 2 | 
 3 | import com.fasterxml.jackson.databind.module.SimpleModule
 4 | 
 5 | /**
 6 |  * Class used to provide LoadService-compatible serialization/deserialization plugins to k8s JSON parsing.
 7 |  */
 8 | abstract class SerializationModule {
 9 |   def module: SimpleModule
10 | }
11 | 


--------------------------------------------------------------------------------
/k8s/src/main/scala/io/buoyant/k8s/SetHostFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.k8s
 2 | 
 3 | import com.twitter.finagle.http.{Request, Response}
 4 | import com.twitter.finagle.{Service, SimpleFilter}
 5 | import java.net.InetSocketAddress
 6 | 
 7 | class SetHostFilter(hostname: String, port: Int) extends SimpleFilter[Request, Response] {
 8 |   def this(addr: InetSocketAddress) = this(addr.getHostString, addr.getPort)
 9 | 
10 |   val host: String = port match {
11 |     case 80 | 443 => hostname
12 |     case port => s"$hostname:$port"
13 |   }
14 | 
15 |   def apply(req: Request, svc: Service[Request, Response]) = {
16 |     req.host = host
17 |     svc(req)
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/linkerd/admin/src/main/scala/io/buoyant/linkerd/admin/AdminFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.admin
 2 | 
 3 | import com.twitter.finagle.{Service, SimpleFilter}
 4 | import com.twitter.finagle.http.{MediaType, Request, Response}
 5 | import com.twitter.util.Future
 6 | 
 7 | /**
 8 |  * This filter builds a linkerd admin page by wrapping an html content blob with the linkerd
 9 |  * admin chome (navbar, stylesheets, etc.)
10 |  */
11 | class AdminFilter(adminHandler: AdminHandler, css: Seq[String] = Nil) extends SimpleFilter[Request, Response] {
12 |   override def apply(
13 |     request: Request,
14 |     service: Service[Request, Response]
15 |   ): Future[Response] = {
16 |     service(request).map { rsp =>
17 |       val itemToHighlight = request.path.replace("/", "")
18 |       if (rsp.contentType.contains(MediaType.Html))
19 |         rsp.contentString = adminHandler.html(rsp.contentString, csses = css, navHighlight = itemToHighlight)
20 |       rsp
21 |     }
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/linkerd/admin/src/test/scala/io/buoyant/linkerd/admin/AdminHandlerTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.admin
 2 | 
 3 | import org.scalatest.FunSuite
 4 | 
 5 | class AdminHandlerTest extends FunSuite {
 6 |   test("handles empty content") {
 7 |     val adminHandler = new AdminHandler(Nil)
 8 |     assert(adminHandler.html("").contains("linkerd admin"))
 9 |   }
10 | 
11 |   test("handles populated params") {
12 |     val adminHandler = new AdminHandler(Nil)
13 |     val content = "fake content"
14 |     val tailContent = "fake tail content"
15 |     val csses = Seq("foo.css", "bar.css")
16 | 
17 |     val html = adminHandler.html(
18 |       content = content,
19 |       tailContent = tailContent,
20 |       csses = csses
21 |     )
22 | 
23 |     assert(html.contains(content))
24 |     assert(html.contains(tailContent))
25 |     csses.foreach { css =>
26 |       assert(html.contains(s"""css/$css"""))
27 |     }
28 |   }
29 | }
30 | 


--------------------------------------------------------------------------------
/linkerd/admin/src/test/scala/io/buoyant/linkerd/admin/DashboardHandlerTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.admin
 2 | 
 3 | import com.twitter.finagle.http.{Request, Status}
 4 | import io.buoyant.admin.Build
 5 | import io.buoyant.linkerd.{Linker, TestProtocol}
 6 | import io.buoyant.test.Awaits
 7 | import org.scalatest.FunSuite
 8 | 
 9 | class DashboardHandlerTest extends FunSuite with Awaits {
10 |   val handler = new DashboardHandler(new AdminHandler(Nil))
11 | 
12 |   test("serves ok on /") {
13 |     val rsp = await(handler(Request("/")))
14 |     assert(rsp.status == Status.Ok)
15 |   }
16 | 
17 |   test("serves 404 other routes") {
18 |     val rsp = await(handler(Request("/foo")))
19 |     assert(rsp.status == Status.NotFound)
20 |   }
21 | 
22 |   test("serves linkerd admin and version") {
23 |     val rsp = await(handler(Request("/")))
24 |     assert(rsp.contentString.contains("linkerd admin"))
25 |     assert(rsp.contentString.contains(Build.load("/io/buoyant/linkerd/build.properties").version))
26 |   }
27 | }
28 | 


--------------------------------------------------------------------------------
/linkerd/announcer/serversets/src/main/resources/META-INF/services/io.buoyant.linkerd.AnnouncerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.announcer.serversets.ServersetsAnnouncerInitializer
2 | 


--------------------------------------------------------------------------------
/linkerd/announcer/serversets/src/main/scala/com/twitter/finagle/zookeeper/buoyant/ZkAnnouncer.scala:
--------------------------------------------------------------------------------
 1 | package com.twitter.finagle.zookeeper.buoyant
 2 | 
 3 | import com.twitter.finagle.{Path, Announcement}
 4 | import com.twitter.finagle.zookeeper.{ZkAnnouncer => FZkAnnouncer, DefaultZkClientFactory}
 5 | import com.twitter.util.Future
 6 | import io.buoyant.config.types.HostAndPort
 7 | import io.buoyant.linkerd.FutureAnnouncer
 8 | import java.net.InetSocketAddress
 9 | 
10 | class ZkAnnouncer(zkAddrs: Seq[HostAndPort], pathPrefix: Path) extends FutureAnnouncer {
11 |   val scheme: String = "zk-serversets"
12 | 
13 |   private[this] val underlying = new FZkAnnouncer(DefaultZkClientFactory)
14 | 
15 |   private[this] val connect = zkAddrs.map(_.toString).mkString(",")
16 | 
17 |   protected def announceAsync(addr: InetSocketAddress, name: Path): Future[Announcement] =
18 |     underlying.announce(addr, s"$connect!${(pathPrefix ++ name).show}!0")
19 | }
20 | 


--------------------------------------------------------------------------------
/linkerd/announcer/serversets/src/main/scala/io/buoyant/linkerd/announcer/serversets/ServersetsAnnouncerInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.announcer.serversets
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.{Path, Stack}
 5 | import com.twitter.finagle.zookeeper.buoyant.ZkAnnouncer
 6 | import io.buoyant.config.types.HostAndPort
 7 | import io.buoyant.linkerd.{Announcer, AnnouncerConfig, AnnouncerInitializer}
 8 | 
 9 | class ServersetsAnnouncerInitializer extends AnnouncerInitializer {
10 |   override def configClass = classOf[ServersetsConfig]
11 |   override def configId = "io.l5d.serversets"
12 | }
13 | 
14 | case class ServersetsConfig(zkAddrs: Seq[HostAndPort], pathPrefix: Option[Path]) extends AnnouncerConfig {
15 | 
16 |   @JsonIgnore
17 |   override def defaultPrefix: Path = Path.read("/io.l5d.serversets")
18 | 
19 |   override def mk(params: Stack.Params): Announcer = new ZkAnnouncer(zkAddrs, pathPrefix.getOrElse(Path.read("/discovery")))
20 | 
21 | }
22 | 


--------------------------------------------------------------------------------
/linkerd/core/src/main/protobuf/usage.proto:
--------------------------------------------------------------------------------
 1 | syntax = "proto3";
 2 | 
 3 | package io.buoyant.linkerd.usage;
 4 | 
 5 | /**
 6 |  * For use by the UsageTelemeter
 7 |  */
 8 | 
 9 | message Router {
10 |   string protocol = 1;
11 |   string interpreter = 2;
12 |   repeated string identifiers = 3;
13 |   repeated string transformers = 4;
14 | }
15 | 
16 | message Counter {
17 |   string name = 1;
18 |   uint64 value = 2;
19 | }
20 | 
21 | message Gauge {
22 |   string name = 1;
23 |   double value = 2;
24 | }
25 | 
26 | message UsageMessage {
27 |   string pid = 1;
28 |   string org_id = 2;
29 |   string linkerd_version = 3;
30 |   string container_manager = 4;
31 |   string os_name = 5;
32 |   string os_version = 6;
33 |   string start_time = 7; // ISO 8601
34 |   repeated Router routers = 8;
35 |   repeated string namers = 9;
36 |   repeated Counter counters = 10;
37 |   repeated Gauge gauges = 11;
38 | }
39 | 


--------------------------------------------------------------------------------
/linkerd/core/src/main/scala/io/buoyant/linkerd/AnnouncerInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd
 2 | 
 3 | import com.fasterxml.jackson.annotation.{JsonIgnore, JsonProperty}
 4 | import com.twitter.finagle.{Path, Stack}
 5 | import io.buoyant.config.{ConfigInitializer, PolymorphicConfig}
 6 | import io.buoyant.namer.Paths
 7 | 
 8 | abstract class AnnouncerConfig extends PolymorphicConfig {
 9 | 
10 |   @JsonProperty("prefix")
11 |   var _prefix: Option[Path] = None
12 | 
13 |   @JsonIgnore
14 |   def defaultPrefix: Path
15 | 
16 |   @JsonIgnore
17 |   def prefix: Path = Paths.ConfiguredNamerPrefix ++ _prefix.getOrElse(defaultPrefix)
18 | 
19 |   @JsonIgnore
20 |   def mk(): Announcer = mk(Stack.Params.empty)
21 | 
22 |   @JsonIgnore
23 |   def mk(params: Stack.Params): Announcer
24 | }
25 | 
26 | trait AnnouncerInitializer extends ConfigInitializer
27 | 


--------------------------------------------------------------------------------
/linkerd/core/src/main/scala/io/buoyant/linkerd/IdentifierInitializer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.linkerd
2 | 
3 | import io.buoyant.config.ConfigInitializer
4 | 
5 | abstract class IdentifierInitializer extends ConfigInitializer
6 | 


--------------------------------------------------------------------------------
/linkerd/core/src/main/scala/io/buoyant/linkerd/ProtocolException.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd
 2 | 
 3 | import scala.util.control.NoStackTrace
 4 | 
 5 | /**
 6 |  * An exception indicating an error in protocol compliance
 7 |  *
 8 |  * @param reason a message describing the cause of the error
 9 |  */
10 | abstract class ProtocolException(reason: String)
11 |   extends Exception(reason)
12 |   with NoStackTrace
13 | 


--------------------------------------------------------------------------------
/linkerd/core/src/main/scala/io/buoyant/linkerd/RequestAuthorizerInitializer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.linkerd
2 | 
3 | import io.buoyant.config.ConfigInitializer
4 | 
5 | abstract class RequestAuthorizerInitializer extends ConfigInitializer
6 | 


--------------------------------------------------------------------------------
/linkerd/core/src/main/scala/io/buoyant/linkerd/ResponseClassifierInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.service.ResponseClassifier
 5 | import io.buoyant.config.{PolymorphicConfig, ConfigInitializer}
 6 | 
 7 | abstract class ResponseClassifierInitializer extends ConfigInitializer
 8 | 
 9 | abstract class ResponseClassifierConfig extends PolymorphicConfig {
10 |   @JsonIgnore
11 |   def mk: ResponseClassifier
12 | }
13 | 


--------------------------------------------------------------------------------
/linkerd/core/src/main/scala/io/buoyant/linkerd/SessionConfig.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.conversions.DurationOps._
 5 | import com.twitter.finagle.service.ExpiringService
 6 | 
 7 | trait SessionConfig {
 8 | 
 9 |   def lifeTimeMs: Option[Int]
10 |   def idleTimeMs: Option[Int]
11 | 
12 |   @JsonIgnore
13 |   private[this] val default = ExpiringService.Param.param.default
14 | 
15 |   @JsonIgnore
16 |   def param = ExpiringService.Param(
17 |     lifeTime = lifeTimeMs.map(_.millis).getOrElse(default.lifeTime),
18 |     idleTime = idleTimeMs.map(_.millis).getOrElse(default.idleTime)
19 |   )
20 | 
21 | }
22 | 


--------------------------------------------------------------------------------
/linkerd/core/src/main/scala/io/buoyant/linkerd/TracePropagatorInitializer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.linkerd
2 | 
3 | import io.buoyant.config.ConfigInitializer
4 | 
5 | abstract class TracePropagatorInitializer extends ConfigInitializer
6 | 


--------------------------------------------------------------------------------
/linkerd/docs/protocol-mux.md:
--------------------------------------------------------------------------------
 1 | # Mux Protocol (experimental)
 2 | 
 3 | >A mux router configuration that routes requests to port 9001
 4 | 
 5 | ```yaml
 6 | 
 7 | routers:
 8 | - protocol: mux
 9 |   label: power-level-router
10 |   dstPrefix: /overNineThousand
11 |   dtab: |
12 |     /overNineThousand => /$/inet/127.0.1/9001;
13 | ```
14 | 
15 | protocol: `mux`
16 | 
17 | Linkerd experimentally supports the [mux
18 | protocol](https://twitter.github.io/finagle/guide/Protocols.html#mux).
19 | 
20 | ## Mux Router Parameters
21 | 
22 | Key | Default Value | Description
23 | --- | ------------- | -----------
24 | dstPrefix | `/svc` | A path prefix used in `dtab`.
25 | 
26 | ## Mux Server Parameters
27 | 
28 | Key | Default Value | Description
29 | --- | ------------- | -----------
30 | port | `4141` | The TCP port number.
31 | 
32 | 
33 | 
34 | 


--------------------------------------------------------------------------------
/linkerd/examples/access-logs.yaml:
--------------------------------------------------------------------------------
 1 | # Simple config for testing multiple access logs.
 2 | # `curl localhost:4140`:
 3 | #   linkerd1:4140 -> linkerd2:4141 -> admin:9990
 4 | 
 5 | admin:
 6 |   ip: 0.0.0.0
 7 |   port: 9990
 8 | 
 9 | telemetry:
10 | - kind: io.l5d.recentRequests
11 |   sampleRate: 1.0
12 | 
13 | routers:
14 | - protocol: http
15 |   httpAccessLog: logs/access1.log
16 |   label: linkerd1
17 |   dtab: |
18 |     /svc => /$/inet/127.1/4141;
19 |   servers:
20 |   - port: 4140
21 |     ip: 0.0.0.0
22 | - protocol: http
23 |   httpAccessLog: logs/access2.log
24 |   label: linkerd2
25 |   dtab: |
26 |     /svc => /$/inet/127.1/9990;
27 |   servers:
28 |   - port: 4141
29 |     ip: 0.0.0.0
30 | 


--------------------------------------------------------------------------------
/linkerd/examples/admin-tls.yaml:
--------------------------------------------------------------------------------
 1 | # Config for serving linkerd admin page over TLS
 2 | 
 3 | admin:
 4 |   ip: 0.0.0.0
 5 |   port: 9990
 6 |   tls:
 7 |     certPath: finagle/h2/src/e2e/resources/linkerd-tls-e2e-cert.pem
 8 |     keyPath: finagle/h2/src/e2e/resources/linkerd-tls-e2e-key.pem
 9 |     caCertPath: finagle/h2/src/e2e/resources/cacert.pem
10 | 
11 | telemetry:
12 | - kind: io.l5d.recentRequests
13 |   sampleRate: 1.0
14 | 
15 | routers:
16 | - protocol: http
17 |   label: linkerd-admin
18 |   dtab: |
19 |     /svc/* => /$/inet/127.1/9990;
20 |   servers:
21 |   - port: 4140
22 |     ip: 0.0.0.0
23 | 


--------------------------------------------------------------------------------
/linkerd/examples/consul-interpreter.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   ip: 0.0.0.0
 3 |   port: 9990
 4 | namers:
 5 | - kind: io.l5d.consul
 6 |   includeTag: false
 7 |   useHealthCheck: false
 8 | routers:
 9 | - protocol: http
10 |   servers:
11 |     - port: 4140
12 |       ip: 0.0.0.0
13 |   interpreter:
14 |     kind: io.l5d.consul.interpreter
15 |     host: localhost
16 |     port: 8500
17 |     namespace: internal
18 | 


--------------------------------------------------------------------------------
/linkerd/examples/consul.yaml:
--------------------------------------------------------------------------------
 1 | # Do service discovery lookups against the Consul service catalog.
 2 | namers:
 3 | - kind: io.l5d.consul
 4 |   includeTag: true
 5 |   useHealthCheck: false
 6 | 
 7 | routers:
 8 | - protocol: http
 9 |   dtab: |
10 |     /svc     => /#/io.l5d.consul/dc1/prod;
11 |   servers:
12 |   - port: 4140
13 |     ip: 0.0.0.0
14 | 


--------------------------------------------------------------------------------
/linkerd/examples/curator.yaml:
--------------------------------------------------------------------------------
 1 | # Do service discovery lookups against Curator.
 2 | namers:
 3 | - kind: io.l5d.curator
 4 |   experimental: true
 5 |   zkAddrs:
 6 |   - host: localhost
 7 |     port: 2181
 8 |   basePath: /curator
 9 | 
10 | routers:
11 | - protocol: http
12 |   dtab: |
13 |     /svc => /#/io.l5d.curator;
14 |   servers:
15 |   - port: 4140
16 |     ip: 0.0.0.0
17 | 


--------------------------------------------------------------------------------
/linkerd/examples/disable-tls.yaml:
--------------------------------------------------------------------------------
 1 | namers: []
 2 | 
 3 | routers:
 4 | - protocol: http
 5 |   dtab: |
 6 |     /svc/foo => /$/inet/www.google.com/443 ;
 7 |     /svc/bar => /$/inet/localhost/7777
 8 | 
 9 |   servers:
10 |   - port: 4140
11 | 
12 |   client:
13 |     kind: io.l5d.static
14 |     configs:
15 |     - prefix: "/$/inet/{service}"
16 |       tls:
17 |         commonName: "{service}"
18 |     - prefix: /$/inet/localhost
19 |       tls:
20 |         enabled: false
21 | 


--------------------------------------------------------------------------------
/linkerd/examples/example.dtab:
--------------------------------------------------------------------------------
1 | /svc/* => /$/inet/127.1/9999;
2 | 


--------------------------------------------------------------------------------
/linkerd/examples/fs.yaml:
--------------------------------------------------------------------------------
 1 | # This config loads both the dtab and the service discovery registry from the
 2 | # local filesystem.  It establishes watches on the filesystem so that updates
 3 | # will be respected at runtime.
 4 | namers:
 5 | - kind: io.l5d.fs
 6 |   rootDir: linkerd/examples/io.l5d.fs
 7 | 
 8 | routers:
 9 | - protocol: http
10 |   interpreter:
11 |     kind: io.l5d.fs
12 |     dtabFile: linkerd/examples/example.dtab
13 |   servers:
14 |   - port: 4140
15 | 


--------------------------------------------------------------------------------
/linkerd/examples/h2.yaml:
--------------------------------------------------------------------------------
 1 | # HTTP/2 protocol.
 2 | namers:
 3 | - kind: io.l5d.fs
 4 |   rootDir: linkerd/examples/io.l5d.fs
 5 | 
 6 | routers:
 7 | - protocol: h2
 8 |   h2AccessLog: logs/access.log
 9 |   h2AccessLogRollPolicy: daily
10 |   h2AccessLogAppend: true
11 |   h2AccessLogRotateCount: -1
12 |   dtab: |
13 |     /srv => /#/io.l5d.fs;
14 |     /svc/localhost:4142 => /$/inet/127.1/8888;
15 |     /svc => /srv;
16 |   identifier:
17 |     kind: io.l5d.header.token
18 |     header: ":authority"
19 |   servers:
20 |   - port: 4142
21 |     maxConcurrentStreamsPerConnection: 300
22 |     addForwardedHeader:
23 |       by: {kind: "ip:port"}
24 |       for: {kind: "ip:port"}
25 |     initialStreamWindowBytes: 1048576 # 1MB
26 |   client:
27 |     initialStreamWindowBytes: 1048576 # 1MB
28 | 


--------------------------------------------------------------------------------
/linkerd/examples/h2spec.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   port: 9990
 3 |   ip: 0.0.0.0
 4 | 
 5 | usage:
 6 |   enabled: false
 7 | 
 8 | routers:
 9 | - protocol: h2
10 |   label: h2
11 |   servers:
12 |   - port: 4140
13 |     ip: 0.0.0.0
14 |   dtab: /svc => /$/inet/127.1/8080
15 | 


--------------------------------------------------------------------------------
/linkerd/examples/http.yaml:
--------------------------------------------------------------------------------
 1 | # HTTP protocol
 2 | namers:
 3 | - kind: io.l5d.fs
 4 |   rootDir: linkerd/examples/io.l5d.fs
 5 | 
 6 | routers:
 7 | - protocol: http
 8 |   httpAccessLog: logs/access.log
 9 |   httpAccessLogRollPolicy: daily
10 |   httpAccessLogAppend: true
11 |   httpAccessLogRotateCount: -1
12 |   maxHeadersKB: 16
13 |   maxInitialLineKB: 16
14 |   streamAfterContentLengthKB: 102400 # 100MB
15 |   compressionLevel: 9
16 |   identifier: {kind: io.l5d.header}
17 |   dtab: |
18 |     /svc => /#/io.l5d.fs;
19 |   servers:
20 |   - port: 4140
21 |     ip: 0.0.0.0
22 |     addForwardedHeader:
23 |       by: {kind: "ip:port"}
24 |       for: {kind: "ip"}
25 | 


--------------------------------------------------------------------------------
/linkerd/examples/influxdb.yaml:
--------------------------------------------------------------------------------
 1 | namers:
 2 | - kind: io.l5d.fs
 3 |   rootDir: linkerd/examples/io.l5d.fs
 4 | 
 5 | routers:
 6 | - protocol: http
 7 |   dtab: /svc => /#/io.l5d.fs;
 8 |   servers:
 9 |   - port: 4140
10 | 
11 | telemetry:
12 | - kind: io.l5d.influxdb
13 | 


--------------------------------------------------------------------------------
/linkerd/examples/io.l5d.fs/cat:
--------------------------------------------------------------------------------
1 | 127.1 8888
2 | 


--------------------------------------------------------------------------------
/linkerd/examples/io.l5d.fs/default:
--------------------------------------------------------------------------------
1 | 127.1 9990
2 | 


--------------------------------------------------------------------------------
/linkerd/examples/io.l5d.fs/dog:
--------------------------------------------------------------------------------
1 | 127.1 8888
2 | 


--------------------------------------------------------------------------------
/linkerd/examples/io.l5d.fs/thrift:
--------------------------------------------------------------------------------
1 | 127.1 9991


--------------------------------------------------------------------------------
/linkerd/examples/k8s.yaml:
--------------------------------------------------------------------------------
 1 | # Do service discovery lookups against the k8s endpoints API.
 2 | namers:
 3 |   # This namer resolves to the internal IP of the destination pod.
 4 | - kind: io.l5d.k8s
 5 |   host: localhost
 6 |   port: 8001
 7 |   # This namer resolves to the external facing load balancer IP of the service
 8 | - kind: io.l5d.k8s.external
 9 |   experimental: true
10 |   host: localhost
11 |   port: 8001
12 | 
13 | routers:
14 | - protocol: http
15 |   dtab: |
16 |     /svc => /#/io.l5d.k8s/foo/http;
17 |   servers:
18 |   - port: 4140
19 | 


--------------------------------------------------------------------------------
/linkerd/examples/loadbalancer.yaml:
--------------------------------------------------------------------------------
 1 | # A config that demonstrates various load balancer options.
 2 | namers:
 3 | - kind: io.l5d.fs
 4 |   rootDir: linkerd/examples/io.l5d.fs
 5 | 
 6 | routers:
 7 | - protocol: http
 8 |   dtab: |
 9 |     /svc => /#/io.l5d.fs
10 |   servers:
11 |   - port: 4140
12 |     maxConcurrentRequests: 10000
13 |   client:
14 |     loadBalancer:
15 |       kind: p2c
16 |       maxEffort: 10
17 |     hostConnectionPool:
18 |       minSize: 0
19 |       maxSize: 1000
20 |       idleTimeMs: 10000
21 |       maxWaiters: 5000
22 |     failureAccrual:
23 |       kind: io.l5d.successRate
24 |       successRate: 0.9
25 |       requests: 1000
26 |       backoff:
27 |         kind: jittered
28 |         minMs: 5000
29 |         maxMs: 300000
30 | 


--------------------------------------------------------------------------------
/linkerd/examples/marathon-leader.yaml:
--------------------------------------------------------------------------------
 1 | #notest
 2 | # Do service discovery lookups against the marathon app API.  The marathon
 3 | # master itself is discovered by leader election.
 4 | namers:
 5 | - kind:         io.l5d.marathon
 6 |   prefix:       /io.l5d.marathon
 7 |   # Discover the marathon master by leader election
 8 |   dst:          /$/io.buoyant.namer.zk.leader/localhost:2181/marathon/leader
 9 |   uriPrefix:    /marathon
10 |   ttlMs:        300
11 | 
12 | routers:
13 | - protocol: http
14 |   identifier:
15 |     kind: io.l5d.methodAndHost
16 |     httpUriInDst: true
17 |   dtab: |
18 |     /marathonId => /#/io.l5d.marathon;
19 |     /host       => /$/io.buoyant.http.domainToPathPfx/marathonId;
20 |     /svc/1.1/* => /host;
21 |   servers:
22 |   - port: 4140
23 |     ip: 0.0.0.0
24 | 


--------------------------------------------------------------------------------
/linkerd/examples/marathon.yaml:
--------------------------------------------------------------------------------
 1 | # Do service discovery lookups against the marathon app API.
 2 | namers:
 3 | - kind:           io.l5d.marathon
 4 |   prefix:         /io.l5d.marathon
 5 |   # The host and port of the marathon master are statically configured here.
 6 |   host:           localhost
 7 |   port:           80
 8 |   uriPrefix:      /marathon
 9 |   ttlMs:          300
10 |   useHealthCheck: false
11 | 
12 | routers:
13 | - protocol: http
14 |   identifier:
15 |     kind: io.l5d.methodAndHost
16 |     httpUriInDst: true
17 |   dtab: |
18 |     /marathonId => /#/io.l5d.marathon;
19 |     /host       => /$/io.buoyant.http.domainToPathPfx/marathonId;
20 |     /svc/1.1/* => /host;
21 |   servers:
22 |   - port: 4140
23 |     ip: 0.0.0.0
24 | 


--------------------------------------------------------------------------------
/linkerd/examples/mutualTls.yaml:
--------------------------------------------------------------------------------
 1 | # A router that receives encrypted traffic with TLS and requires client auth.
 2 | namers:
 3 | - kind: io.l5d.fs
 4 |   rootDir: linkerd/examples/io.l5d.fs
 5 | 
 6 | routers:
 7 | - protocol: http
 8 |   dtab: |
 9 |     /svc => /#/io.l5d.fs
10 |   client:
11 |     tls:
12 |       commonName: foo
13 |       trustCertsBundle: /foo/cacert.pem
14 |       clientAuth:
15 |         certPath: /foo/clientCert.pem
16 |         keyPath: /foo/clientKey.pem
17 |         intermediateCertsPath: /foo/intermediateCa.pem
18 |   servers:
19 |   - port: 4140
20 |     # Expect the incoming connection to be encrypted.
21 |     tls:
22 |       certPath: /foo/cert.pem
23 |       keyPath: /foo/key.pem
24 |       # clients must provide a valid certificate
25 |       requireClientAuth: true
26 |       # the authority used to validate client certificates
27 |       caCertPath: /foo/cacert.pem
28 | 


--------------------------------------------------------------------------------
/linkerd/examples/namerd-http.yaml:
--------------------------------------------------------------------------------
 1 | # Use the experimental namerd HTTP API for name resolution.
 2 | routers:
 3 | - protocol: http
 4 |   interpreter:
 5 |     kind: io.l5d.namerd.http
 6 |     experimental: true
 7 |     dst: /$/inet/localhost/4180
 8 |     namespace: default
 9 |   servers:
10 |   - port: 4140
11 |     ip: 0.0.0.0
12 | 


--------------------------------------------------------------------------------
/linkerd/examples/namerd-mesh.yaml:
--------------------------------------------------------------------------------
 1 | # Use the namerd gRPC API for name resolution.
 2 | routers:
 3 | - protocol: http
 4 |   interpreter:
 5 |     kind: io.l5d.mesh
 6 |     dst: /$/inet/127.1/4321
 7 |     root: /default
 8 |   servers:
 9 |   - port: 4140
10 |     ip: 0.0.0.0
11 | 


--------------------------------------------------------------------------------
/linkerd/examples/namerd.yaml:
--------------------------------------------------------------------------------
 1 | # Use namerd for name resolution.
 2 | routers:
 3 | - protocol: http
 4 |   label: named-thrift
 5 |   interpreter:
 6 |     kind: io.l5d.namerd
 7 |     dst: /$/inet/localhost/4100
 8 |     namespace: default
 9 |   servers:
10 |   - port: 4140
11 |     ip: 0.0.0.0
12 | - protocol: http
13 |   label: named-http
14 |   interpreter:
15 |     kind: io.l5d.namerd.http
16 |     experimental: true
17 |     dst: /$/inet/localhost/4180
18 |     namespace: default
19 |   servers:
20 |   - port: 4141
21 |     ip: 0.0.0.0
22 | - protocol: http
23 |   label: named-grpc
24 |   interpreter:
25 |     kind: io.l5d.mesh
26 |     dst: /$/inet/localhost/4321
27 |     root: /default
28 |   servers:
29 |   - port: 4142
30 |     ip: 0.0.0.0
31 | 


--------------------------------------------------------------------------------
/linkerd/examples/prometheus.yaml:
--------------------------------------------------------------------------------
 1 | namers:
 2 | - kind: io.l5d.fs
 3 |   rootDir: linkerd/examples/io.l5d.fs
 4 | 
 5 | routers:
 6 | - protocol: http
 7 |   dtab: /svc => /#/io.l5d.fs;
 8 |   servers:
 9 |   - port: 4140
10 | 
11 | telemetry:
12 | - kind: io.l5d.prometheus
13 | 


--------------------------------------------------------------------------------
/linkerd/examples/proxy.yaml:
--------------------------------------------------------------------------------
 1 | namers: []
 2 | 
 3 | # Simply proxies requests according to the hostname.  If a port is specified
 4 | # in the hostname, that port is used.  Otherwise, port 80 is used by default.
 5 | # If port 443 is specified, linkerd will speak https to the destination.
 6 | #
 7 | # This dtab can be a useful fallback if the specified service isn't found in
 8 | # service discovery.
 9 | routers:
10 | - protocol: http
11 |   dtab: |
12 |     /ph => /$/io.buoyant.rinet ;
13 |     /svc => /ph/80 ;
14 |     /svc => /$/io.buoyant.porthostPfx/ph ;
15 |   servers:
16 |   - port: 4140
17 |   client:
18 |     kind: io.l5d.static
19 |     configs:
20 |     - prefix: /$/io.buoyant.rinet/443/{hostname}
21 |       tls:
22 |         commonName: "{hostname}"
23 | 


--------------------------------------------------------------------------------
/linkerd/examples/recent-requests.yaml:
--------------------------------------------------------------------------------
 1 | namers:
 2 | - kind: io.l5d.fs
 3 |   rootDir: linkerd/examples/io.l5d.fs
 4 | 
 5 | routers:
 6 | - protocol: http
 7 |   dtab: /svc/* => /$/inet/localhost/8888
 8 |   servers:
 9 |   - port: 4140
10 | 
11 | telemetry:
12 | - kind: io.l5d.recentRequests
13 |   sampleRate: 1.0
14 | 


--------------------------------------------------------------------------------
/linkerd/examples/rewriting.yaml:
--------------------------------------------------------------------------------
 1 | # An example of how to use the rewriting namer to reorder path segments.  This
 2 | # resolves names like /http/foo/api to /#/io.l5d.fs/foo.
 3 | namers:
 4 | - kind: io.l5d.fs
 5 |   rootDir: linkerd/examples/io.l5d.fs
 6 | - kind: io.l5d.rewrite
 7 |   prefix: /apiToSrv
 8 |   pattern: "/{service}/api"
 9 |   name: "/srv/{service}"
10 | 
11 | routers:
12 | - protocol: http
13 |   identifier:
14 |     kind: io.l5d.path
15 |     segments: 2
16 |   dtab: |
17 |     /srv => /#/io.l5d.fs ;
18 |     /svc => /#/apiToSrv ;
19 |   servers:
20 |   - port: 4140
21 | 


--------------------------------------------------------------------------------
/linkerd/examples/serversets.yaml:
--------------------------------------------------------------------------------
 1 | # Do service discovery lookups against the zookeeper serversets API.  This
 2 | # config will also announce its address to zookeeper serversets.
 3 | namers:
 4 | - kind: io.l5d.serversets
 5 |   zkAddrs:
 6 |     - host: 127.0.0.1
 7 |       port: 2181
 8 | 
 9 | routers:
10 | - protocol: http
11 |   announcers:
12 |   - kind: io.l5d.serversets
13 |     zkAddrs:
14 |     - host: 127.0.0.1
15 |       port: 2181
16 |     pathPrefix: /discovery/prod
17 |   dtab: |
18 |     /svc => /#/io.l5d.serversets;
19 |     /host/www.example.com => /#/io.l5d.serversets/discovery/prod/www/example:https;
20 |     /host/www.example2.com => /#/io.l5d.serversets/discovery/prod/www/example2;
21 |     /svc/1.1 => /$/io.buoyant.http.anyMethodPfx/host;
22 |   client:
23 |     kind: io.l5d.static
24 |     configs:
25 |     - prefix: "/#/io.l5d.serversets/discovery/prod/{role}/{service}:https"
26 |       tls:
27 |         commonName: "{role}.{service}.com"
28 |   servers:
29 |   - port: 4140
30 |     ip: 0.0.0.0
31 |     announce:
32 |     - /#/io.l5d.serversets/foobar
33 | 


--------------------------------------------------------------------------------
/linkerd/examples/service-options.yaml:
--------------------------------------------------------------------------------
 1 | # A config that demonstrates basic service options.
 2 | routers:
 3 | - protocol: http
 4 |   label: foobar
 5 |   dtab: |
 6 |     /svc/* => /$/inet/localhost/8080
 7 |   service:
 8 |     kind: io.l5d.static
 9 |     configs:
10 |     - prefix: /svc # default for all services
11 |       totalTimeoutMs: 500
12 |     - prefix: /svc/foo
13 |       totalTimeoutMs: 1000 # overrides the default from above
14 |     - prefix: /svc/bar
15 |       # applies only to the /svc/bar service
16 |       retries:
17 |         budget:
18 |           minRetriesPerSec: 5
19 |           percentCanRetry: 0.5
20 |           ttlSecs: 15
21 |         backoff:
22 |           kind: jittered
23 |           minMs: 10
24 |           maxMs: 10000
25 |   servers:
26 |   - port: 4140
27 | 


--------------------------------------------------------------------------------
/linkerd/examples/socket-options.yaml:
--------------------------------------------------------------------------------
 1 | namers:
 2 | - kind: io.l5d.fs
 3 |   rootDir: linkerd/examples/io.l5d.fs
 4 | routers:
 5 | - protocol: http
 6 |   dtab: |
 7 |     /svc => /#/io.l5d.fs ;
 8 |   servers:
 9 |   - port: 4140
10 |     socketOptions:
11 |       noDelay: true
12 |       reuseAddr: true
13 |       reusePort: true
14 |       readTimeoutMs: 61000
15 |       writeTimeoutMs: 61000
16 |       keepAlive: true
17 |       backlog: 128
18 | 


--------------------------------------------------------------------------------
/linkerd/examples/static_namer.yaml:
--------------------------------------------------------------------------------
1 | # Routes all requests to localhost:8080
2 | routers:
3 | - protocol: http
4 |   dtab: |
5 |     /svc/* => /$/inet/localhost/8080;
6 |   servers:
7 |   - port: 4140
8 |     ip: 0.0.0.0
9 | 


--------------------------------------------------------------------------------
/linkerd/examples/statsd.yaml:
--------------------------------------------------------------------------------
 1 | # A fairly minimal linkerd configuration with statsd exporting.
 2 | 
 3 | admin:
 4 |   port: 9990
 5 | 
 6 | telemetry:
 7 | - kind: io.l5d.statsd
 8 |   experimental: true
 9 |   prefix: linkerd
10 |   hostname: 127.0.0.1
11 |   port: 8125
12 |   gaugeIntervalMs: 10000
13 |   sampleRate: 1.0 # for testing only, setting this to 1.0 will increase linkerd latency
14 | 
15 | # An example service discovery backend that uses the filesystem to resolve endpoints.
16 | namers:
17 | - kind: io.l5d.fs
18 |   rootDir: linkerd/examples/io.l5d.fs
19 | 
20 | routers:
21 | - protocol: http
22 |   dtab: /svc => /#/io.l5d.fs
23 |   servers:
24 |   - port: 4140
25 |     ip: 0.0.0.0
26 | 


--------------------------------------------------------------------------------
/linkerd/examples/thrift.yaml:
--------------------------------------------------------------------------------
 1 | # A simplistic thrift-routing linkerd configuration.
 2 | 
 3 | # An example service discovery that backend uses the filesystem to resolve endpoints.
 4 | namers:
 5 | - kind: io.l5d.fs
 6 |   rootDir: linkerd/examples/io.l5d.fs
 7 | 
 8 | # A simple thrift router that looks up each thrift method in io.l5d.fs.
 9 | routers:
10 | - protocol: thrift
11 |   thriftProtocol: binary
12 |   thriftMethodInDst: true
13 |   dtab: |
14 |     /svc => /#/io.l5d.fs/thrift;
15 |   servers:
16 |   - port: 4114
17 |     thriftFramed: true
18 |   client:
19 |     thriftFramed: true
20 |     attemptTTwitterUpgrade: true
21 | 


--------------------------------------------------------------------------------
/linkerd/examples/thriftmux.yaml:
--------------------------------------------------------------------------------
 1 | # A simplistic thriftmux-routing linkerd configuration.
 2 | 
 3 | # An example service discovery that backend uses the filesystem to resolve endpoints.
 4 | namers:
 5 | - kind: io.l5d.fs
 6 |   rootDir: linkerd/examples/io.l5d.fs
 7 | 
 8 | # A simple thriftmux router that looks up each thriftmux method in io.l5d.fs.
 9 | routers:
10 | - protocol: thriftmux
11 |   thriftProtocol: binary
12 |   thriftMethodInDst: true
13 |   experimental: true
14 |   dtab: |
15 |     /svc => /#/io.l5d.fs/thrift;
16 |   servers:
17 |   - port: 4400
18 |     thriftFramed: true
19 |   client:
20 |     thriftFramed: true
21 |     attemptTTwitterUpgrade: true
22 | 


--------------------------------------------------------------------------------
/linkerd/examples/tls.yaml:
--------------------------------------------------------------------------------
 1 | # A router that sends and receives encrypted traffic with TLS.
 2 | namers:
 3 | - kind: io.l5d.fs
 4 |   rootDir: linkerd/examples/io.l5d.fs
 5 | 
 6 | routers:
 7 | - protocol: http
 8 |   dtab: |
 9 |     /svc => /#/io.l5d.fs
10 |   client:
11 |     # Establish encrypted outgoing connections.
12 |     kind: io.l5d.static
13 |     configs:
14 |     - prefix: "/#/io.l5d.fs/{service}"
15 |       tls:
16 |         trustCertsBundle: /foo/caCert.pem
17 |         commonName: "{service}"
18 |   servers:
19 |   - port: 4140
20 |     # Expect the incoming connection to be encrypted.
21 |     tls:
22 |       certPath: /foo/cert.pem
23 |       keyPath: /foo/key.pem
24 |       intermediateCertsPath: /foo/ca-chain.pem
25 | 


--------------------------------------------------------------------------------
/linkerd/examples/tracelog.yaml:
--------------------------------------------------------------------------------
 1 | # Log trace data to the console.
 2 | namers:
 3 | - kind: io.l5d.fs
 4 |   rootDir: linkerd/examples/io.l5d.fs
 5 | 
 6 | routers:
 7 | - protocol: http
 8 |   dtab: |
 9 |     /svc => /#/io.l5d.fs
10 |   servers:
11 |   - port: 4140
12 | 
13 | telemetry:
14 | - kind: io.l5d.tracelog
15 |   sampleRate: 0.2
16 |   level: INFO
17 | 


--------------------------------------------------------------------------------
/linkerd/examples/zipkin.yaml:
--------------------------------------------------------------------------------
 1 | # Send distributed trace data to Zipkin
 2 | namers:
 3 | - kind: io.l5d.fs
 4 |   rootDir: linkerd/examples/io.l5d.fs
 5 | 
 6 | routers:
 7 | - protocol: http
 8 |   dtab: |
 9 |     /svc => /#/io.l5d.fs
10 |   servers:
11 |   - port: 4140
12 | 
13 | telemetry:
14 | - kind: io.l5d.zipkin
15 |   host: localhost
16 |   port: 9410
17 |   sampleRate: 1.0
18 | 


--------------------------------------------------------------------------------
/linkerd/failure-accrual/src/main/resources/META-INF/services/io.buoyant.linkerd.FailureAccrualInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.failureAccrual.ConsecutiveFailuresInitializer
2 | io.buoyant.linkerd.failureAccrual.NoneInitializer
3 | io.buoyant.linkerd.failureAccrual.SuccessRateInitializer
4 | io.buoyant.linkerd.failureAccrual.SuccessRateWindowedInitializer
5 | 


--------------------------------------------------------------------------------
/linkerd/failure-accrual/src/main/scala/io/buoyant/linkerd/failureAccrual/ConsecutiveFailuresInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.failureAccrual
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.liveness.FailureAccrualPolicy
 5 | import io.buoyant.linkerd.{FailureAccrualConfig, FailureAccrualInitializer}
 6 | 
 7 | class ConsecutiveFailuresInitializer extends FailureAccrualInitializer {
 8 |   val configClass = classOf[ConsecutiveFailuresConfig]
 9 |   override def configId = "io.l5d.consecutiveFailures"
10 | }
11 | 
12 | object ConsecutiveFailuresInitializer extends ConsecutiveFailuresInitializer
13 | 
14 | case class ConsecutiveFailuresConfig(failures: Int) extends FailureAccrualConfig {
15 |   @JsonIgnore
16 |   override def policy =
17 |     () => FailureAccrualPolicy.consecutiveFailures(failures, backoffOrDefault)
18 | }
19 | 


--------------------------------------------------------------------------------
/linkerd/failure-accrual/src/main/scala/io/buoyant/linkerd/failureAccrual/NoneInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.failureAccrual
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.liveness.FailureAccrualPolicy
 5 | import com.twitter.util.Duration
 6 | import io.buoyant.linkerd.{FailureAccrualConfig, FailureAccrualInitializer}
 7 | 
 8 | class NoneInitializer extends FailureAccrualInitializer {
 9 |   val configClass = classOf[NoneConfig]
10 |   override def configId = "none"
11 | }
12 | 
13 | object NoneInitializer extends NoneInitializer
14 | 
15 | class NoneConfig extends FailureAccrualConfig {
16 |   @JsonIgnore
17 |   override def policy = () => NonePolicy
18 | }
19 | 
20 | object NonePolicy extends FailureAccrualPolicy {
21 |   override def recordSuccess(): Unit = {}
22 |   override def markDeadOnFailure(): Option[Duration] = None
23 |   override def revived(): Unit = {}
24 | 
25 |   override def name: String = "NonePolicy"
26 | 
27 |   override def show(): String = ""
28 | }
29 | 


--------------------------------------------------------------------------------
/linkerd/failure-accrual/src/main/scala/io/buoyant/linkerd/failureAccrual/SuccessRateInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.failureAccrual
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.liveness.FailureAccrualPolicy
 5 | import io.buoyant.linkerd.{FailureAccrualConfig, FailureAccrualInitializer}
 6 | 
 7 | class SuccessRateInitializer extends FailureAccrualInitializer {
 8 |   val configClass = classOf[SuccessRateConfig]
 9 |   override def configId = "io.l5d.successRate"
10 | }
11 | 
12 | object SuccessRateInitializer extends SuccessRateInitializer
13 | 
14 | case class SuccessRateConfig(successRate: Double, requests: Int) extends FailureAccrualConfig {
15 |   @JsonIgnore
16 |   override def policy =
17 |     () => FailureAccrualPolicy.successRate(successRate, requests, backoffOrDefault)
18 | }
19 | 


--------------------------------------------------------------------------------
/linkerd/failure-accrual/src/main/scala/io/buoyant/linkerd/failureAccrual/SuccessRateWindowedInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.failureAccrual
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.conversions.DurationOps._
 5 | import com.twitter.finagle.liveness.FailureAccrualPolicy
 6 | import io.buoyant.linkerd.{FailureAccrualConfig, FailureAccrualInitializer}
 7 | 
 8 | class SuccessRateWindowedInitializer extends FailureAccrualInitializer {
 9 |   val configClass = classOf[SuccessRateWindowedConfig]
10 |   override def configId = "io.l5d.successRateWindowed"
11 | }
12 | 
13 | object SuccessRateWindowedInitializer extends SuccessRateWindowedInitializer
14 | 
15 | case class SuccessRateWindowedConfig(
16 |   successRate: Double,
17 |   window: Int
18 | ) extends FailureAccrualConfig {
19 |   @JsonIgnore
20 |   override def policy =
21 |     () =>
22 |       FailureAccrualPolicy.successRateWithinDuration(successRate, window.seconds, backoffOrDefault)
23 | }
24 | 


--------------------------------------------------------------------------------
/linkerd/failure-accrual/src/test/scala/io/buoyant/linkerd/failureAccrual/NoneTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.failureAccrual
 2 | 
 3 | import com.twitter.finagle.liveness.FailureAccrualPolicy
 4 | import com.twitter.finagle.util.LoadService
 5 | import io.buoyant.linkerd.FailureAccrualInitializer
 6 | import io.buoyant.test.FunSuite
 7 | 
 8 | class NoneTest extends FunSuite {
 9 |   test("sanity") {
10 |     val config = new NoneConfig
11 |     assert(config.policy().isInstanceOf[FailureAccrualPolicy])
12 |   }
13 | 
14 |   test("service registration") {
15 |     assert(LoadService[FailureAccrualInitializer].exists(_.isInstanceOf[NoneInitializer]))
16 |   }
17 | }
18 | 


--------------------------------------------------------------------------------
/linkerd/failure-accrual/src/test/scala/io/buoyant/linkerd/failureAccrual/SuccessRateTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.failureAccrual
 2 | 
 3 | import com.twitter.finagle.liveness.FailureAccrualPolicy
 4 | import com.twitter.finagle.util.LoadService
 5 | import io.buoyant.linkerd.FailureAccrualInitializer
 6 | import io.buoyant.test.FunSuite
 7 | 
 8 | class SuccessRateTest extends FunSuite {
 9 |   test("sanity") {
10 |     val successRate = 0.6
11 |     val requests = 3
12 |     val config = SuccessRateConfig(successRate, requests)
13 |     assert(config.policy().isInstanceOf[FailureAccrualPolicy])
14 |     assert(config.successRate == successRate)
15 |     assert(config.requests == requests)
16 |   }
17 | 
18 |   test("service registration") {
19 |     assert(LoadService[FailureAccrualInitializer].exists(_.isInstanceOf[SuccessRateInitializer]))
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/linkerd/failure-accrual/src/test/scala/io/buoyant/linkerd/failureAccrual/SuccessRateWindowedTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.failureAccrual
 2 | 
 3 | import com.twitter.finagle.liveness.FailureAccrualPolicy
 4 | import com.twitter.finagle.util.LoadService
 5 | import io.buoyant.linkerd.FailureAccrualInitializer
 6 | import io.buoyant.test.FunSuite
 7 | 
 8 | class SuccessRateWindowedTest extends FunSuite {
 9 |   test("sanity") {
10 |     val successRate = 0.4
11 |     val window = 3
12 |     val config = SuccessRateWindowedConfig(successRate, window)
13 |     assert(config.policy().isInstanceOf[FailureAccrualPolicy])
14 |     assert(config.successRate == successRate)
15 |     assert(config.window == window)
16 |   }
17 | 
18 |   test("service registration") {
19 |     assert(LoadService[FailureAccrualInitializer].exists(_.isInstanceOf[SuccessRateWindowedInitializer]))
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/linkerd/main/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=WARN, stderr
2 | log4j.appender.stderr=org.apache.log4j.AsyncAppender
3 | log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
4 | log4j.appender.stderr.layout.ConversionPattern=%p %d{MMdd HH:mm:ss.SSS z} %t: %m%n
5 | log4j.appender.async=org.apache.log4j.AsyncAppender
6 | log4j.appender.async.appenders=console
7 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/resources/META-INF/services/io.buoyant.linkerd.IdentifierInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.h2.HeaderTokenIdentifierInitializer
2 | io.buoyant.linkerd.protocol.h2.HeaderPathIdentifierInitializer
3 | io.buoyant.linkerd.protocol.h2.IngressIdentifierInitializer
4 | io.buoyant.linkerd.protocol.h2.istio.IstioIdentifierInitializer
5 | io.buoyant.linkerd.protocol.h2.istio.IstioIngressIdentifierInitializer
6 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/resources/META-INF/services/io.buoyant.linkerd.ProtocolInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.H2Initializer
2 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/resources/META-INF/services/io.buoyant.linkerd.RequestAuthorizerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.h2.istio.IstioRequestAuthorizerInitializer
2 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/resources/META-INF/services/io.buoyant.linkerd.ResponseClassifierInitializer:
--------------------------------------------------------------------------------
 1 | io.buoyant.linkerd.protocol.h2.NonRetryable5XXInitializer
 2 | io.buoyant.linkerd.protocol.h2.RetryableAll5XXInitializer
 3 | io.buoyant.linkerd.protocol.h2.RetryableIdempotent5XXInitializer
 4 | io.buoyant.linkerd.protocol.h2.RetryableRead5XXInitializer
 5 | io.buoyant.linkerd.protocol.h2.AllSuccessfulInitializer
 6 | io.buoyant.linkerd.protocol.h2.grpc.AlwaysRetryableInitializer
 7 | io.buoyant.linkerd.protocol.h2.grpc.DefaultInitializer
 8 | io.buoyant.linkerd.protocol.h2.grpc.CompliantInitializer
 9 | io.buoyant.linkerd.protocol.h2.grpc.NeverRetryableInitializer
10 | io.buoyant.linkerd.protocol.h2.grpc.RetryableStatusCodesInitializer
11 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/resources/META-INF/services/io.buoyant.linkerd.TracePropagatorInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.h2.LinkerdTracePropagatorInitializer
2 | io.buoyant.linkerd.protocol.h2.ZipkinTracePropagatorInitializer
3 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/h2/ClientConfig.scala:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/linkerd/linkerd/ea82499d386e44e8958be58e0386f593e639645b/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/h2/ClientConfig.scala


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/h2/H2ClassifierConfig.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol.h2
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.buoyant.h2.service.H2Classifier
 5 | import io.buoyant.config.PolymorphicConfig
 6 | 
 7 | abstract class H2ClassifierConfig extends PolymorphicConfig {
 8 |   @JsonIgnore
 9 |   def mk: H2Classifier
10 | }
11 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/h2/istio/H2IstioRequest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol.h2.istio
 2 | 
 3 | import com.twitter.finagle.Path
 4 | import com.twitter.finagle.buoyant.h2.Request
 5 | import io.buoyant.k8s.istio.IstioRequest
 6 | 
 7 | object H2IstioRequest {
 8 |   def apply(req: Request, istioPath: Option[Path]): IstioRequest[Request] =
 9 |     new IstioRequest(req.path, req.scheme, req.method.toString, req.authority, req.headers.get, req, istioPath)
10 | }
11 | 
12 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/h2/istio/H2IstioRequestHandler.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol.h2.istio
 2 | 
 3 | import com.twitter.finagle.buoyant.h2.{Headers, Request, Response, Status, Stream}
 4 | import com.twitter.util.Future
 5 | import io.buoyant.k8s.istio.identifiers.IstioProtocolSpecificRequestHandler
 6 | import io.buoyant.linkerd.protocol.h2.ErrorReseter.H2ResponseException
 7 | import istio.proxy.v1.config.HTTPRedirect
 8 | 
 9 | class H2IstioRequestHandler extends IstioProtocolSpecificRequestHandler[Request] {
10 |   def redirectRequest(redir: HTTPRedirect, req: Request): Future[Nothing] = {
11 |     val resp = Response(Status.Found, Stream.empty())
12 |     resp.headers.set(Headers.Path, redir.`uri`.getOrElse(req.path))
13 |     resp.headers.set(Headers.Authority, redir.`authority`.getOrElse(req.authority))
14 |     Future.exception(H2ResponseException(resp))
15 |   }
16 | 
17 |   def rewriteRequest(uri: String, authority: Option[String], req: Request): Unit = {
18 |     req.headers.set(Headers.Path, uri)
19 |     req.headers.set(Headers.Authority, authority.getOrElse(""))
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/main/scala/io/buoyant/linkerd/protocol/h2/istio/H2IstioResponse.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol.h2.istio
 2 | 
 3 | import com.twitter.finagle.buoyant.h2.Response
 4 | import com.twitter.finagle.http.Status
 5 | import com.twitter.util.{Duration, Try}
 6 | import io.buoyant.k8s.istio.IstioResponse
 7 | 
 8 | object H2IstioResponse {
 9 |   def apply(resp: Try[Response], duration: Duration): IstioResponse[Response] = {
10 |     val maybeInt = resp.toOption.map(_.status.code)
11 |     new IstioResponse(maybeInt.getOrElse(Status.InternalServerError.code), duration, resp.toOption)
12 |   }
13 | }
14 | 


--------------------------------------------------------------------------------
/linkerd/protocol/h2/src/test/scala/io/buoyant/linkerd/protocol/h2/istio/H2IstioRequestTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol.h2.istio
 2 | 
 3 | import com.twitter.finagle.buoyant.h2.{Method, Request}
 4 | import org.scalatest.FunSuite
 5 | 
 6 | class H2IstioRequestTest extends FunSuite {
 7 |   test("generates istio request with expected attributes") {
 8 |     val httpRequest = Request("http", Method.Connect, "localhost", "/echo/123", null)
 9 |     val istioRequest = H2IstioRequest(httpRequest, None)
10 | 
11 |     assert(istioRequest.uri == httpRequest.path)
12 |     assert(istioRequest.scheme == "http")
13 |     assert(istioRequest.method == "CONNECT")
14 |     assert(istioRequest.authority == "localhost")
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/resources/META-INF/services/io.buoyant.linkerd.IdentifierInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.http.HeaderIdentifierInitializer
2 | io.buoyant.linkerd.protocol.http.HeaderTokenIdentifierInitializer
3 | io.buoyant.linkerd.protocol.http.MethodAndHostIdentifierInitializer
4 | io.buoyant.linkerd.protocol.http.PathIdentifierInitializer
5 | io.buoyant.linkerd.protocol.http.StaticIdentifierInitializer
6 | io.buoyant.linkerd.protocol.http.IngressIdentifierInitializer
7 | io.buoyant.linkerd.protocol.http.istio.IstioIdentifierInitializer
8 | io.buoyant.linkerd.protocol.http.istio.IstioIngressIdentifierInitializer
9 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/resources/META-INF/services/io.buoyant.linkerd.ProtocolInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.HttpInitializer
2 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/resources/META-INF/services/io.buoyant.linkerd.RequestAuthorizerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.http.istio.IstioRequestAuthorizerInitializer
2 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/resources/META-INF/services/io.buoyant.linkerd.ResponseClassifierInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.http.NonRetryable5XXInitializer
2 | io.buoyant.linkerd.protocol.http.RetryableIdempotent5XXInitializer
3 | io.buoyant.linkerd.protocol.http.RetryableRead5XXInitializer
4 | io.buoyant.linkerd.protocol.http.AllSuccessfulInitializer
5 | io.buoyant.linkerd.protocol.http.RetryableAll5XXInitializer
6 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/resources/META-INF/services/io.buoyant.linkerd.TracePropagatorInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.LinkerdTracePropagatorInitializer
2 | io.buoyant.linkerd.protocol.ZipkinTracePropagatorInitializer
3 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/scala/com/twitter/finagle/buoyant/linkerd/DelayedRelease.scala:
--------------------------------------------------------------------------------
 1 | package com.twitter.finagle
 2 | package buoyant.linkerd
 3 | 
 4 | import com.twitter.finagle.client.StackClient
 5 | import com.twitter.finagle.http.{DelayedReleaseService, Request, Response}
 6 | 
 7 | object DelayedRelease {
 8 | 
 9 |   val module: Stackable[ServiceFactory[Request, Response]] =
10 |     new Stack.Module0[ServiceFactory[Request, Response]] {
11 |       val role = StackClient.Role.prepFactory
12 |       val description = "Prevents an HTTP service from being closed until its response completes"
13 |       def make(next: ServiceFactory[Request, Response]) =
14 |         next.map(new DelayedReleaseService(_))
15 |     }
16 | }
17 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/scala/io/buoyant/linkerd/protocol/HttpIdentifierConfig.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.http.Request
 5 | import com.twitter.finagle.{Dtab, Path, Stack}
 6 | import io.buoyant.config.PolymorphicConfig
 7 | import io.buoyant.router.RoutingFactory.Identifier
 8 | 
 9 | abstract class HttpIdentifierConfig extends PolymorphicConfig {
10 |   @JsonIgnore
11 |   def newIdentifier(
12 |     prefix: Path,
13 |     baseDtab: () => Dtab = () => Dtab.base,
14 |     routerParams: Stack.Params = Stack.Params.empty
15 |   ): Identifier[Request]
16 | }
17 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/scala/io/buoyant/linkerd/protocol/http/istio/HttpIstioRequest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol.http.istio
 2 | 
 3 | import com.twitter.finagle.Path
 4 | import com.twitter.finagle.http.Request
 5 | import io.buoyant.k8s.istio.IstioRequest
 6 | 
 7 | object HttpIstioRequest {
 8 |   def apply(req: Request, istioPath: Option[Path]): IstioRequest[Request] =
 9 |     //TODO: match on request scheme
10 |     IstioRequest(req.path, "", req.method.toString, req.host.getOrElse(""), req.headerMap.get, req, istioPath)
11 | }
12 | 
13 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/scala/io/buoyant/linkerd/protocol/http/istio/HttpIstioRequestHandler.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol.http.istio
 2 | 
 3 | import com.twitter.finagle.http.{Request, Response, Status}
 4 | import com.twitter.util.Future
 5 | import io.buoyant.k8s.istio.identifiers.IstioProtocolSpecificRequestHandler
 6 | import io.buoyant.linkerd.protocol.http.ErrorResponder.HttpResponseException
 7 | import istio.proxy.v1.config.HTTPRedirect
 8 | 
 9 | class HttpIstioRequestHandler extends IstioProtocolSpecificRequestHandler[Request] {
10 |   def redirectRequest(redir: HTTPRedirect, req: Request): Future[Nothing] = {
11 |     val redirect = Response(Status.Found)
12 |     redirect.location = redir.`uri`.getOrElse(req.uri)
13 |     redirect.host = redir.`authority`.orElse(req.host).getOrElse("")
14 |     Future.exception(HttpResponseException(redirect))
15 |   }
16 | 
17 |   def rewriteRequest(uri: String, authority: Option[String], req: Request): Unit = {
18 |     req.uri = uri
19 |     req.host = authority.getOrElse("")
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/linkerd/protocol/http/src/main/scala/io/buoyant/linkerd/protocol/http/istio/HttpIstioResponse.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd.protocol.http.istio
 2 | 
 3 | import com.twitter.finagle.http.{Response, Status}
 4 | import com.twitter.util.{Duration, Try}
 5 | import io.buoyant.k8s.istio.IstioResponse
 6 | 
 7 | object HttpIstioResponse {
 8 |   def apply(resp: Try[Response], duration: Duration): IstioResponse[Response] = {
 9 |     val status = resp.toOption.map(_.status).getOrElse(Status.InternalServerError)
10 |     new IstioResponse(status.code, duration, resp.toOption)
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/linkerd/protocol/mux/src/main/resources/META-INF/services/io.buoyant.linkerd.ProtocolInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.MuxInitializer
2 | 


--------------------------------------------------------------------------------
/linkerd/protocol/mux/src/main/scala/io/buoyant/linkerd/protocol/MuxInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.linkerd
 2 | package protocol
 3 | 
 4 | import com.fasterxml.jackson.annotation.JsonIgnore
 5 | import com.twitter.finagle.Path
 6 | import io.buoyant.config.Parser
 7 | import io.buoyant.router.{Mux, RoutingFactory}
 8 | 
 9 | class MuxInitializer extends ProtocolInitializer.Simple {
10 |   val name = "mux"
11 | 
12 |   protected type Req = com.twitter.finagle.mux.Request
13 |   protected type Rsp = com.twitter.finagle.mux.Response
14 | 
15 |   protected val defaultRouter = Mux.router
16 | 
17 |   protected val defaultServer = Mux.server
18 | 
19 |   override def defaultServerPort: Int = 4141
20 | 
21 |   val configClass = classOf[MuxConfig]
22 | }
23 | 
24 | object MuxInitializer extends MuxInitializer
25 | 
26 | class MuxConfig extends RouterConfig {
27 | 
28 |   var servers: Seq[ServerConfig] = Nil
29 |   var service: Option[Svc] = None
30 |   var client: Option[Client] = None
31 | 
32 |   @JsonIgnore
33 |   override def protocol = MuxInitializer
34 | }
35 | 


--------------------------------------------------------------------------------
/linkerd/protocol/thrift/src/main/resources/META-INF/services/io.buoyant.config.ConfigDeserializer:
--------------------------------------------------------------------------------
1 | io.buoyant.config.types.ThriftProtocolDeserializer
2 | 


--------------------------------------------------------------------------------
/linkerd/protocol/thrift/src/main/resources/META-INF/services/io.buoyant.config.ConfigSerializer:
--------------------------------------------------------------------------------
1 | io.buoyant.config.types.ThriftProtocolSerializer
2 | 


--------------------------------------------------------------------------------
/linkerd/protocol/thrift/src/main/resources/META-INF/services/io.buoyant.linkerd.ProtocolInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.ThriftInitializer
2 | 


--------------------------------------------------------------------------------
/linkerd/protocol/thrift/src/main/scala/com/twitter/finagle/buoyant/linkerd/ThriftTraceInitializer.scala:
--------------------------------------------------------------------------------
 1 | package com.twitter.finagle.buoyant.linkerd
 2 | 
 3 | import com.twitter.finagle._
 4 | import com.twitter.finagle.tracing.{Trace, TraceInitializerFilter, Tracer}
 5 | 
 6 | object ThriftTraceInitializer {
 7 |   val role = TraceInitializerFilter.role
 8 | 
 9 |   def serverModule[Req, Rep]: Stackable[ServiceFactory[Req, Rep]] =
10 |     new Stack.Module1[param.Tracer, ServiceFactory[Req, Rep]] {
11 |       val role = ThriftTraceInitializer.role
12 |       val description = "Ensure that there is a trace id set"
13 | 
14 |       def make(_tracer: param.Tracer, next: ServiceFactory[Req, Rep]) = {
15 |         val param.Tracer(tracer) = _tracer
16 |         new ServerFilter(tracer) andThen next
17 |       }
18 |     }
19 | 
20 |   class ServerFilter[Req, Rep](tracer: Tracer)
21 |     extends SimpleFilter[Req, Rep] {
22 | 
23 |     def apply(req: Req, service: Service[Req, Rep]) = {
24 |       if (!Trace.hasId)
25 |         Trace.letTracerAndNextId(tracer) {
26 |           service(req)
27 |         }
28 |       else service(req)
29 |     }
30 |   }
31 | }
32 | 


--------------------------------------------------------------------------------
/linkerd/protocol/thriftmux/src/main/resources/META-INF/services/io.buoyant.linkerd.ProtocolInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.protocol.ThriftMuxInitializer
2 | 


--------------------------------------------------------------------------------
/linkerd/telemeter/usage/src/main/resources/META-INF/services/io.buoyant.telemetry.TelemeterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.linkerd.telemeter.UsageDataTelemeterInitializer
2 | 


--------------------------------------------------------------------------------
/mesh/README.md:
--------------------------------------------------------------------------------
 1 | # io.linkerd.mesh #
 2 | 
 3 | A set of gRPC APIs that can be used to control Linkerd.
 4 | 
 5 | The mesh consists of client-side plugin interfaces (initially, just
 6 | NameInterpreter) as well as server-side service implementations
 7 | (initially, in Namerd's 'io.l5d.mesh' iface).
 8 | 
 9 | **Status**: Experimental; the API will break in an upcoming release.
10 | 
11 | ## TODO ##
12 | 
13 | - [] needs automated tests
14 | - [] io.l5d.mesh interpreter is definitely not resilient to errors
15 | - [] determine if additional observation caching is necessary
16 | 
17 | ## gRPC services ##
18 | 
19 | - `io.linkerd.mesh.Codec` -- Supports parsing/formatting for thin clients.
20 | - `io.linkerd.mesh.Delegator` -- Supports name tree diagnostics.
21 | - `io.linkerd.mesh.Interpreter` -- Supports name tree binding.
22 | - `io.linkerd.mesh.Resolver` -- Supports lookup of address sets (essentially, service discovery).
23 | 
24 | 


--------------------------------------------------------------------------------
/namer/consul/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.consul.ConsulInitializer
2 | 


--------------------------------------------------------------------------------
/namer/consul/src/main/scala/io/buoyant/namer/consul/package.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.Path
 4 | import com.twitter.logging.Logger
 5 | import com.twitter.util.{Activity, Updatable, Var}
 6 | 
 7 | package object consul {
 8 |   private[consul]type VarUp[T] = Var[T] with Updatable[T]
 9 |   private[consul]type ActUp[T] = VarUp[Activity.State[T]]
10 |   val log = Logger.get("io.buoyant.namer.consul")
11 | 
12 |   /** path-extracted schema to make consul api calls */
13 |   private[consul] case class PathScheme(
14 |     dc: String,
15 |     service: SvcKey,
16 |     id: Path,
17 |     subpath: Path
18 |   )
19 | 
20 | }
21 | 


--------------------------------------------------------------------------------
/namer/core/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.RewritingNamerInitializer
2 | 


--------------------------------------------------------------------------------
/namer/core/src/main/resources/META-INF/services/io.buoyant.namer.TransformerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.ConstTransformerInitializer
2 | io.buoyant.namer.ReplaceTransformerInitializer
3 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/RewritingNamer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant
 2 | 
 3 | import com.twitter.finagle.{Name, NameTree, Namer, Path}
 4 | import com.twitter.util.{Activity}
 5 | 
 6 | /**
 7 |  * A helper
 8 |  */
 9 | private[buoyant] trait RewritingNamer extends Namer {
10 |   protected[this] def rewrite(orig: Path): Option[Path]
11 | 
12 |   def lookup(path: Path): Activity[NameTree[Name]] =
13 |     Activity.value(path match {
14 |       case path if path.size > 0 =>
15 |         rewrite(path) match {
16 |           case Some(path) => NameTree.Leaf(Name.Path(path))
17 |           case None => NameTree.Neg
18 |         }
19 |       case _ => NameTree.Neg
20 |     })
21 | }
22 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/ConstTransformer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.Name.Bound
 4 | import com.twitter.finagle.naming.NameInterpreter
 5 | import com.twitter.finagle.{Dtab, Name, NameTree, Path}
 6 | import com.twitter.util.Activity
 7 | 
 8 | /** Bind the given path and use that instead of the tree. */
 9 | class ConstTransformer(prefix: Path, path: Path) extends NameTreeTransformer {
10 | 
11 |   private[this] lazy val bound = NameInterpreter.global.bind(Dtab.empty, path).map { tree =>
12 |     tree.map { b =>
13 |       Name.Bound(b.addr, prefix ++ path, b.path)
14 |     }
15 |   }
16 | 
17 |   override protected def transform(tree: NameTree[Bound]): Activity[NameTree[Bound]] =
18 |     bound
19 | }
20 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/ConstTransformerInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.{Path, Stack}
 5 | 
 6 | class ConstTransformerInitializer extends TransformerInitializer {
 7 |   val configClass = classOf[ConstTransformerConfig]
 8 |   override val configId = "io.l5d.const"
 9 | }
10 | 
11 | object ConstTransformerInitializer extends ConstTransformerInitializer
12 | 
13 | case class ConstTransformerConfig(path: Path) extends TransformerConfig {
14 | 
15 |   @JsonIgnore
16 |   val defaultPrefix = Path.read("/io.l5d.const")
17 | 
18 |   override def mk(params: Stack.Params): NameTreeTransformer = new ConstTransformer(prefix, path)
19 | }
20 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/Delegator.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.{Dentry, Dtab, Name, NameTree, Path}
 4 | import com.twitter.util.{Activity, Future}
 5 | 
 6 | trait Delegator {
 7 | 
 8 |   def delegate(
 9 |     dtab: Dtab,
10 |     tree: NameTree[Name.Path]
11 |   ): Future[DelegateTree[Name.Bound]]
12 | 
13 |   final def delegate(
14 |     dtab: Dtab,
15 |     path: Path
16 |   ): Future[DelegateTree[Name.Bound]] =
17 |     delegate(dtab, NameTree.Leaf(Name.Path(path)))
18 | 
19 |   def dtab: Activity[Dtab]
20 | }
21 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/EnumeratingNamer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.namer
2 | 
3 | import com.twitter.finagle.{Name, NameTree, Path, Namer}
4 | import com.twitter.util.{Activity, Future}
5 | 
6 | trait EnumeratingNamer extends Namer {
7 |   def getAllNames: Activity[Set[Path]]
8 | }
9 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/JNamer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.namer
2 | 
3 | import com.twitter.finagle.Namer
4 | 
5 | /** For better java compatibility */
6 | abstract class JNamer extends Namer
7 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/Metadata.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.addr.WeightedAddress
 4 | 
 5 | object Metadata {
 6 |   val authority = "authority" // HTTP/1.1 Host or HTTP/2.0 :authority
 7 |   val nodeName = "nodeName"
 8 |   val endpointWeight = WeightedAddress.weightKey
 9 | }
10 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/Param.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.{Stack, Namer, Path}
 4 | 
 5 | object Param {
 6 |   case class Namers(namers: Seq[(Path, Namer)])
 7 |   implicit object Namers extends Stack.Param[Namers] {
 8 |     val default = Namers(Nil)
 9 |   }
10 | }
11 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/Paths.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.Path
 4 | import com.twitter.io.Buf
 5 | 
 6 | object Paths {
 7 |   val ConfiguredNamerBuf = Buf.Utf8("#")
 8 |   val ConfiguredNamerPrefix = Path(ConfiguredNamerBuf)
 9 |   val LoadedNamerBuf = Buf.Utf8("
quot;)
10 |   val LoadedNamerPrefix = Path(LoadedNamerBuf)
11 |   val NotHashOrDollar: Buf => Boolean =
12 |     (b: Buf) => !(b == ConfiguredNamerBuf || b == LoadedNamerBuf)
13 |   val TransformerPrefix = Path.Utf8("%")
14 | 
15 |   def stripTransformerPrefix(p: Path): Path =
16 |     if (p.startsWith(TransformerPrefix))
17 |       Path(p.elems.dropWhile(NotHashOrDollar): _*)
18 |     else
19 |       p
20 | }
21 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/ReplaceTransformerInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.{Path, Stack}
 5 | 
 6 | class ReplaceTransformerInitializer extends TransformerInitializer {
 7 |   val configClass = classOf[ReplaceTransformerConfig]
 8 |   override val configId = "io.l5d.replace"
 9 | }
10 | 
11 | case class ReplaceTransformerConfig(path: Path) extends TransformerConfig {
12 | 
13 |   @JsonIgnore
14 |   val defaultPrefix = Path.read("/io.l5d.replace")
15 | 
16 |   @JsonIgnore
17 |   override def mk(params: Stack.Params): NameTreeTransformer = new ReplaceTransformer(prefix, path)
18 | }
19 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/RewritingNamer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.{Name, NameTree, Namer, Path}
 4 | import com.twitter.finagle.buoyant.PathMatcher
 5 | import com.twitter.util.Activity
 6 | 
 7 | class RewritingNamer(matcher: PathMatcher, pattern: String) extends Namer {
 8 |   override def lookup(path: Path): Activity[NameTree[Name]] = matcher.substitutePath(path, pattern) match {
 9 |     case Some(result) => Activity.value(NameTree.Leaf(Name(result)))
10 |     case None => Activity.value(NameTree.Neg)
11 |   }
12 | }
13 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/RewritingNamerInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.{Namer, Path}
 5 | import com.twitter.finagle.buoyant.PathMatcher
 6 | import com.twitter.finagle.Stack.Params
 7 | 
 8 | class RewritingNamerInitializer extends NamerInitializer {
 9 |   override val configId = "io.l5d.rewrite"
10 |   val configClass = classOf[RewritingNamerConfig]
11 | }
12 | 
13 | case class RewritingNamerConfig(
14 |   pattern: String,
15 |   name: String
16 | ) extends NamerConfig {
17 |   assert(pattern != null)
18 |   assert(name != null)
19 | 
20 |   @JsonIgnore
21 |   override def defaultPrefix: Path =
22 |     throw new IllegalArgumentException("The 'prefix' property is required for the io.l5d.rewrite namer.")
23 | 
24 |   @JsonIgnore override protected def newNamer(params: Params): Namer = new RewritingNamer(PathMatcher(pattern), name)
25 | }
26 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/TransformerConfig.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.fasterxml.jackson.annotation.{JsonIgnore, JsonProperty}
 4 | import com.twitter.finagle.{Path, Stack}
 5 | import io.buoyant.config.{ConfigInitializer, PolymorphicConfig}
 6 | 
 7 | abstract class TransformerConfig extends PolymorphicConfig {
 8 | 
 9 |   def defaultPrefix: Path
10 | 
11 |   @JsonProperty("prefix")
12 |   var _prefix: Option[Path] = None
13 | 
14 |   @JsonIgnore
15 |   def prefix = Paths.TransformerPrefix ++ _prefix.getOrElse(defaultPrefix)
16 | 
17 |   @JsonIgnore
18 |   def mk(params: Stack.Params): NameTreeTransformer
19 | }
20 | 
21 | trait TransformerInitializer extends ConfigInitializer
22 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/namer/package.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant
 2 | 
 3 | import com.twitter.util.{Activity, Future, Var}
 4 | 
 5 | package object namer {
 6 |   implicit class RichActivity[T](val activity: Activity[T]) extends AnyVal {
 7 |     /** A Future representing the first non-pending value of this Activity */
 8 |     def toFuture: Future[T] = activity.values.toFuture.flatMap(Future.const)
 9 | 
10 |     def dedup: Activity[T] = Activity(Var.async[Activity.State[T]](Activity.Pending) { up =>
11 |       activity.states.dedup.respond(up.update)
12 |     })
13 |   }
14 | }
15 | 


--------------------------------------------------------------------------------
/namer/core/src/main/scala/io/buoyant/rinet.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant
 2 | 
 3 | import com.twitter.finagle._
 4 | import com.twitter.util.Activity
 5 | 
 6 | /**
 7 |  * An alternate form of the inet namer that expects port before host.
 8 |  *
 9 |  *   /$/io.buoyant.rinet/<port>/<host>
10 |  *
11 |  * is equivalent to
12 |  *
13 |  *   /$/inet/<host>/<port>
14 |  */
15 | class rinet extends Namer {
16 |   override def lookup(path: Path): Activity[NameTree[Name]] = path.take(2) match {
17 |     case Path.Utf8(port, host) =>
18 |       Activity.value(NameTree.Leaf(
19 |         Resolver.eval(s"inet!$host:$port") match {
20 |           case bound: Name.Bound => Name.Bound(bound.addr, rinet.prefix ++ Path.read(s"/$port/$host"), path.drop(2))
21 |           case name => name
22 |         }
23 |       ))
24 |     case _ =>
25 |       Activity.value(NameTree.Neg)
26 |   }
27 | }
28 | 
29 | object rinet {
30 |   val prefix = Path.read("/$/io.buoyant.rinet")
31 | }
32 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/RinetTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant
 2 | 
 3 | import com.twitter.finagle._
 4 | import com.twitter.util.Future
 5 | import io.buoyant.namer.RichActivity
 6 | import io.buoyant.test.FunSuite
 7 | 
 8 | class RinetTest extends FunSuite {
 9 | 
10 |   test("rinet binds") {
11 |     val path = Path.read("/$/io.buoyant.rinet/12345/localhost/residual")
12 |     val tree = await(Namer.global.bind(NameTree.Leaf(path)).toFuture)
13 |     val NameTree.Leaf(bound) = tree
14 |     assert(bound.id == Path.read("/$/io.buoyant.rinet/12345/localhost"))
15 |     assert(bound.path == Path.read("/residual"))
16 |     val addr = await(bound.addr.changes.filter(_ != Addr.Pending).toFuture())
17 |     val Addr.Bound(addresses, _) = addr
18 |     assert(addresses == Set(Address("localhost", 12345)))
19 |   }
20 | }
21 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/namer/InterpreterInitializerTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.naming.NameInterpreter
 4 | import com.twitter.finagle.{Dtab, NameTree, Path, Stack}
 5 | import io.buoyant.config.Parser
 6 | import org.scalatest.FunSuite
 7 | 
 8 | class InterpreterInitializerTest extends FunSuite {
 9 | 
10 |   def parse(config: String): NameInterpreter = {
11 |     val mapper = Parser.objectMapper(config, Iterable(Seq(TestInterpreterInitializer)))
12 |     val interpCfg = mapper.readValue[InterpreterConfig](config)
13 |     interpCfg.interpreter(Stack.Params.empty)
14 |   }
15 | 
16 |   test("parse and initialize") {
17 |     val yaml =
18 |       s"""kind: test
19 |          |alwaysFail: true
20 |          |""".stripMargin
21 | 
22 |     val interpreter = parse(yaml)
23 |     val activity = interpreter.bind(Dtab.read("/foo => /bar"), Path.read("/foo"))
24 |     assert(activity.sample == NameTree.Neg) // since alwaysFail is true
25 |   }
26 | }
27 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/namer/NamerTestUtil.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle.{Name, NameTree, Namer, Path}
 4 | import com.twitter.util.{Await, Future}
 5 | import org.scalatest.FunSuite
 6 | 
 7 | trait NamerTestUtil { self: FunSuite =>
 8 | 
 9 |   protected def lookup(namer: Namer, p: Path): NameTree[Name] =
10 |     Await.result(namer.lookup(p).toFuture)
11 | 
12 |   protected def lookupBound(namer: Namer, p: Path): Seq[Name.Bound] =
13 |     lookup(namer, p).eval.toSeq.flatten.collect {
14 |       case bound: Name.Bound => bound
15 |     }
16 | 
17 |   protected def assertBoundIdAutobinds(namer: Namer, path: Path, prefix: Path): Unit = {
18 |     assert(path.startsWith(prefix))
19 |     for (bound <- lookupBound(namer, path.drop(prefix.size))) {
20 |       val idPath = bound.id.asInstanceOf[Path]
21 |       assert(path.startsWith(prefix))
22 |       val NameTree.Leaf(rebound: Name.Bound) = lookup(namer, idPath.drop(prefix.size))
23 |       assert(rebound.id == bound.id)
24 |     }
25 |   }
26 | }
27 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/namer/TestInterpreter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.twitter.finagle._
 4 | import com.twitter.finagle.naming.NameInterpreter
 5 | import com.twitter.util.Activity
 6 | 
 7 | class TestInterpreterInitializer extends InterpreterInitializer {
 8 |   val configClass = classOf[TestInterpreterConfig]
 9 |   override val configId = TestInterpreterConfig.kind
10 | }
11 | 
12 | object TestInterpreterInitializer extends TestInterpreterInitializer
13 | 
14 | case class TestInterpreterConfig(alwaysFail: Option[Boolean]) extends InterpreterConfig {
15 |   def newInterpreter(params: Stack.Params): NameInterpreter = {
16 |     TestInterpreter(alwaysFail getOrElse false)
17 |   }
18 | }
19 | 
20 | object TestInterpreterConfig {
21 |   def kind = "test"
22 | }
23 | 
24 | case class TestInterpreter(alwaysFail: Boolean) extends NameInterpreter {
25 |   override def bind(dtab: Dtab, path: Path): Activity[NameTree[Name.Bound]] =
26 |     if (alwaysFail)
27 |       Activity.value(NameTree.Neg)
28 |     else
29 |       Activity.pending
30 | }
31 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/namer/TestTransformer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.Name.Bound
 5 | import com.twitter.finagle.{NameTree, Path, Stack}
 6 | import com.twitter.util.Activity
 7 | 
 8 | class TestTransformer extends NameTreeTransformer {
 9 |   override protected def transform(tree: NameTree[Bound]): Activity[NameTree[Bound]] =
10 |     Activity.value(NameTree.Empty)
11 | }
12 | 
13 | object TestTransformerInitializer extends TransformerInitializer {
14 |   val configClass = classOf[TestTransformerConfig]
15 |   override val configId = "io.l5d.empty"
16 | }
17 | 
18 | class TestTransformerConfig extends TransformerConfig {
19 | 
20 |   @JsonIgnore
21 |   val defaultPrefix = Path.read("/io.l5d.empty")
22 | 
23 |   @JsonIgnore
24 |   override def mk(params: Stack.Params): NameTreeTransformer = new TestTransformer
25 | }
26 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/namer/booNamer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.namer
2 | 
3 | import com.twitter.finagle.Path
4 | 
5 | class booNamer extends TestNamerConfig {
6 |   override def defaultPrefix = Path.read("/boo")
7 | }
8 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/namer/booNamerInitializer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.namer
2 | 
3 | object booNamerInitializer extends NamerInitializer {
4 |   override def configClass = classOf[booNamer]
5 | }
6 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/namer/booUrnsNamer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.namer
2 | 
3 | import com.twitter.finagle.Path
4 | 
5 | class booUrnsNamer extends TestNamerConfig {
6 |   override def defaultPrefix = Path.read("/boo/urns")
7 | }
8 | 


--------------------------------------------------------------------------------
/namer/core/src/test/scala/io/buoyant/namer/booUrnsNamerInitializer.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.namer
2 | 
3 | object booUrnsNamerInitializer extends NamerInitializer {
4 |   override def configClass = classOf[booUrnsNamer]
5 | }
6 | 


--------------------------------------------------------------------------------
/namer/curator/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.curator.CuratorInitializer
2 | 


--------------------------------------------------------------------------------
/namer/dnssrv/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.dnssrv.DnsSrvNamerInitializer


--------------------------------------------------------------------------------
/namer/fs/src/main/resources/META-INF/services/io.buoyant.config.ConfigSerializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.fs.UpRegSerializer
2 | 


--------------------------------------------------------------------------------
/namer/fs/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.fs.FsInitializer
2 | 


--------------------------------------------------------------------------------
/namer/fs/src/main/scala/io/buoyant/namer/fs/FsInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer.fs
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.{Path, Stack}
 5 | import io.buoyant.config.types.Directory
 6 | import io.buoyant.namer.{NamerConfig, NamerInitializer}
 7 | 
 8 | class FsInitializer extends NamerInitializer {
 9 |   val configClass = classOf[FsConfig]
10 |   override def configId = "io.l5d.fs"
11 | }
12 | 
13 | object FsInitializer extends FsInitializer
14 | 
15 | case class FsConfig(rootDir: Directory) extends NamerConfig {
16 |   @JsonIgnore
17 |   override def defaultPrefix: Path = Path.read("/io.l5d.fs")
18 | 
19 |   /**
20 |    * Construct a namer.
21 |    */
22 |   @JsonIgnore
23 |   def newNamer(params: Stack.Params) = new WatchingNamer(rootDir.path, prefix)
24 | }
25 | 


--------------------------------------------------------------------------------
/namer/fs/src/main/scala/io/buoyant/namer/fs/UpRegSerializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer.fs
 2 | 
 3 | import com.fasterxml.jackson.core.JsonGenerator
 4 | import com.fasterxml.jackson.databind.SerializerProvider
 5 | import com.twitter.io.Buf
 6 | import com.twitter.util.Activity
 7 | import io.buoyant.config.ConfigSerializer
 8 | 
 9 | class UpRegSerializer extends ConfigSerializer[Watcher.File.UpReg] {
10 | 
11 |   override def serialize(
12 |     value: Watcher.File.UpReg,
13 |     gen: JsonGenerator,
14 |     provider: SerializerProvider
15 |   ): Unit = {
16 |     value.buf.sample() match {
17 |       case Activity.Ok(Buf.Utf8(s)) => gen.writeString(s)
18 |       case Activity.Pending => gen.writeString("pending")
19 |       case Activity.Failed(e) => gen.writeString("error: " + e.getMessage)
20 |     }
21 |   }
22 | }
23 | 


--------------------------------------------------------------------------------
/namer/fs/src/main/scala/io/buoyant/namer/fs/WatchState.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer.fs
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.util.Time
 5 | import java.nio.file.{Path, WatchEvent}
 6 | 
 7 | class WatchState {
 8 |   @JsonIgnore
 9 |   def recordEvent(ev: WatchEvent[_]): Unit = synchronized {
10 |     lastEventKind = Some(ev.kind().name())
11 |     ev.context() match {
12 |       case p: Path => lastEventName = Some(p.toString)
13 |       case _ =>
14 |     }
15 |     lastEventAt = Some(Time.now.toString)
16 |   }
17 | 
18 |   // These fields exist to be serialized.
19 |   protected var lastEventKind: Option[String] = None
20 |   protected var lastEventName: Option[String] = None
21 |   protected var lastEventAt: Option[String] = None
22 | }
23 | 


--------------------------------------------------------------------------------
/namer/istio/src/main/resources/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.k8s.istio.IstioInitializer
2 | 


--------------------------------------------------------------------------------
/namer/k8s/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.k8s.K8sExternalInitializer
2 | io.buoyant.namer.k8s.K8sInitializer
3 | io.buoyant.namer.k8s.K8sNamespacedInitializer
4 | 


--------------------------------------------------------------------------------
/namer/marathon/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.marathon.MarathonInitializer
2 | 


--------------------------------------------------------------------------------
/namer/marathon/src/main/scala/io/buoyant/namer/marathon/BasicAuthenticatorFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer.marathon
 2 | 
 3 | import com.twitter.finagle.{http, SimpleFilter, Service}
 4 | import com.twitter.util.Future
 5 | import io.buoyant.marathon.v2.Api
 6 | 
 7 | class BasicAuthenticatorFilter(http_auth_token: String) extends SimpleFilter[http.Request, http.Response] {
 8 | 
 9 |   def apply(req: http.Request, svc: Service[http.Request, http.Response]): Future[http.Response] = {
10 |     req.headerMap.set("Authorization", s"Basic $http_auth_token")
11 |     svc(req)
12 |   }
13 | }


--------------------------------------------------------------------------------
/namer/rancher/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.rancher.RancherInitializer
2 | 


--------------------------------------------------------------------------------
/namer/serversets/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.serversets.ServersetsInitializer
2 | 


--------------------------------------------------------------------------------
/namer/serversets/src/main/scala/com/twitter/finagle/serversets2/BouyantZkResolver.scala:
--------------------------------------------------------------------------------
 1 | package com.twitter.finagle.serverset2
 2 | 
 3 | import com.twitter.finagle.{Addr, Path, Resolver}
 4 | import com.twitter.finagle.serverset2.naming.ServersetPath
 5 | import com.twitter.util.Var
 6 | 
 7 | trait BouyantZkResolver {
 8 |   protected[this] def addrOf(
 9 |     zkHosts: String,
10 |     zkPath: String,
11 |     endpoint: Option[String],
12 |     shardId: Option[Int]
13 |   ): Var[Addr]
14 | 
15 |   def resolve(path: Path): Var[Addr] = ServersetPath.of(path) match {
16 |     case Some(ServersetPath(zkHosts, zkPath, endpoint, shardId)) =>
17 |       addrOf(zkHosts, zkPath.show, endpoint, shardId)
18 |     case _ =>
19 |       Var.value(Addr.Neg)
20 |   }
21 | }
22 | 
23 | class BouyantZkResolverImpl(zk2: Zk2Resolver) extends BouyantZkResolver {
24 |   def this() = this(Resolver.get(classOf[Zk2Resolver]).get)
25 | 
26 |   protected[this] def addrOf(
27 |     zkHosts: String,
28 |     zkPath: String,
29 |     endpoint: Option[String],
30 |     shardId: Option[Int]
31 |   ): Var[Addr] =
32 |     zk2.addrOf(zkHosts, zkPath, endpoint, shardId)
33 | }
34 | 


--------------------------------------------------------------------------------
/namer/serversets/src/main/scala/io/buoyant/namer/serversets/ServersetsInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer.serversets
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.{Stack, Path}
 5 | import io.buoyant.config.types.{HostAndPort, Port}
 6 | import io.buoyant.namer.{NamerConfig, NamerInitializer}
 7 | 
 8 | class ServersetsInitializer extends NamerInitializer {
 9 |   val configClass = classOf[ServersetsConfig]
10 |   override def configId = "io.l5d.serversets"
11 | }
12 | 
13 | object ServersetsInitializer extends ServersetsInitializer
14 | 
15 | case class ServersetsConfig(zkAddrs: Seq[HostAndPort]) extends NamerConfig {
16 |   @JsonIgnore
17 |   override def defaultPrefix: Path = Path.read("/io.l5d.serversets")
18 | 
19 |   @JsonIgnore
20 |   val connectString = zkAddrs.map(_.toString(defaultPort = Port(2181))).mkString(",")
21 | 
22 |   /**
23 |    * Construct a namer.
24 |    */
25 |   def newNamer(params: Stack.Params) = new ServersetNamer(connectString, prefix)
26 | }
27 | 


--------------------------------------------------------------------------------
/namer/zk-leader/src/main/resources/META-INF/services/io.buoyant.namer.NamerInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namer.zk.ZkLeaderNamerInitializer
2 | 


--------------------------------------------------------------------------------
/namer/zk-leader/src/main/scala/io/buoyant/namer/zk/ZkLeaderNamerInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer.zk
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.Stack.Params
 5 | import com.twitter.finagle.{Namer, Path}
 6 | import io.buoyant.config.types.HostAndPort
 7 | import io.buoyant.namer.{NamerConfig, NamerInitializer}
 8 | 
 9 | class ZkLeaderNamerInitializer extends NamerInitializer {
10 |   override def configClass = classOf[ZkLeaderNamerConfig]
11 |   override def configId: String = "io.l5d.zkLeader"
12 | }
13 | 
14 | case class ZkLeaderNamerConfig(zkAddrs: Seq[HostAndPort]) extends NamerConfig {
15 |   @JsonIgnore
16 |   override def defaultPrefix: Path = Path.Utf8("io.l5d.zkLeader")
17 | 
18 |   @JsonIgnore
19 |   override def newNamer(params: Params): Namer = new ZkLeaderNamer(prefix, zkAddrs)
20 | }
21 | 


--------------------------------------------------------------------------------
/namer/zk-leader/src/test/scala/io/buoyant/namer/zk/ZkLeaderTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namer.zk
 2 | 
 3 | import com.twitter.finagle.{Path, Stack}
 4 | import com.twitter.finagle.util.LoadService
 5 | import io.buoyant.config.types.{HostAndPort, Port}
 6 | import io.buoyant.namer.NamerInitializer
 7 | import org.scalatest.FunSuite
 8 | 
 9 | class ZkLeaderTest extends FunSuite {
10 | 
11 |   test("sanity") {
12 |     // ensure it doesn't totally blowup
13 |     val _ = ZkLeaderNamerConfig(Seq(HostAndPort(Some("localhost"), Some(Port(1234)))))
14 |       .newNamer(Stack.Params.empty)
15 |   }
16 | 
17 |   test("service registration") {
18 |     assert(LoadService[NamerInitializer]().exists(_.isInstanceOf[ZkLeaderNamerInitializer]))
19 |   }
20 | 
21 |   test("parse zk hosts") {
22 |     val namer = new leader()
23 |       .zkLeaderNamer(Path.read("/1.2.3.4:8000::5.6.7.8:8001/path/to/group"))
24 |     assert(namer.zkAddrs ==
25 |       Seq(
26 |         HostAndPort(Some("1.2.3.4"), Some(Port(8000))),
27 |         HostAndPort(Some("5.6.7.8"), Some(Port(8001)))
28 |       ))
29 |   }
30 | }
31 | 


--------------------------------------------------------------------------------
/namerd/core/src/main/scala/io/buoyant/namerd/DtabStoreInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd
 2 | 
 3 | import com.fasterxml.jackson.annotation.{JsonIgnore, JsonProperty}
 4 | import com.twitter.finagle.Stack
 5 | import io.buoyant.config.{ConfigInitializer, PolymorphicConfig}
 6 | 
 7 | abstract class DtabStoreInitializer extends ConfigInitializer
 8 | 
 9 | abstract class DtabStoreConfig extends PolymorphicConfig {
10 |   /** This property must be set to true in order to use this dtab store if it is experimental */
11 |   @JsonProperty("experimental")
12 |   var _experimentalEnabled: Option[Boolean] = None
13 | 
14 |   /**
15 |    * Indicates whether this is an experimental dtab store.  Experimental dtab stores must have the
16 |    * `experimental` property set to true to be used
17 |    */
18 |   @JsonIgnore
19 |   def experimentalRequired: Boolean = false
20 | 
21 |   /** If this dtab store is experimental but has not set the `experimental` property. */
22 |   @JsonIgnore
23 |   def disabled = experimentalRequired && !_experimentalEnabled.contains(true)
24 | 
25 |   @JsonIgnore
26 |   def mkDtabStore(params: Stack.Params): DtabStore
27 | }
28 | 


--------------------------------------------------------------------------------
/namerd/core/src/main/scala/io/buoyant/namerd/Namerd.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd
 2 | 
 3 | import com.twitter.finagle.{Dtab, Path, Namer, ListeningServer}
 4 | import com.twitter.util.Activity
 5 | import io.buoyant.admin.Admin
 6 | import io.buoyant.telemetry.Telemeter
 7 | 
 8 | private[namerd] case class Namerd(
 9 |   interfaces: Seq[Servable],
10 |   dtabStore: DtabStore,
11 |   namers: Map[Path, Namer],
12 |   admin: Admin,
13 |   telemeters: Seq[Telemeter]
14 | ) {
15 | 
16 |   def extractDtab(ns: Ns): Activity[Dtab] = dtabStore.observe(ns).map {
17 |     case Some(dtab) => dtab.dtab
18 |     case None => Dtab.empty
19 |   }
20 | }
21 | 
22 | trait Servable {
23 |   def kind: String
24 |   def serve(): ListeningServer
25 | }
26 | 


--------------------------------------------------------------------------------
/namerd/core/src/main/scala/io/buoyant/namerd/package.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant
2 | 
3 | package object namerd {
4 |   type Ns = String
5 | }
6 | 


--------------------------------------------------------------------------------
/namerd/core/src/test/scala/io/buoyant/namerd/NullDtabStore.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd
 2 | 
 3 | import com.twitter.finagle.Dtab
 4 | import com.twitter.util.{Activity, Future}
 5 | import io.buoyant.namerd.DtabStore.Version
 6 | 
 7 | object NullDtabStore extends DtabStore {
 8 |   override def list(): Activity[Set[Ns]] = Activity.pending
 9 |   override def update(ns: Ns, dtab: Dtab, version: Version): Future[Unit] = Future.never
10 |   override def put(ns: Ns, dtab: Dtab): Future[Unit] = Future.never
11 |   override def observe(ns: Ns): Activity[Option[VersionedDtab]] = Activity.pending
12 |   override def delete(ns: Ns): Future[Unit] = Future.never
13 |   override def create(ns: Ns, dtab: Dtab): Future[Unit] = Future.never
14 | }
15 | 


--------------------------------------------------------------------------------
/namerd/core/src/test/scala/io/buoyant/namerd/TestNamerInterface.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd
 2 | 
 3 | import com.twitter.finagle.stats.StatsReceiver
 4 | import com.twitter.finagle.{Path, Namer, NullServer}
 5 | import com.twitter.finagle.naming.NameInterpreter
 6 | import java.net.InetSocketAddress
 7 | 
 8 | class TestInterpreterInterfaceConfig extends InterpreterInterfaceConfig {
 9 |   val defaultAddr: InetSocketAddress = new InetSocketAddress(0)
10 | 
11 |   def mk(
12 |     interpreters: Ns => NameInterpreter,
13 |     namers: Map[Path, Namer],
14 |     store: DtabStore,
15 |     stats: StatsReceiver
16 |   ): Servable =
17 |     TestNamerInterfaceServable
18 | }
19 | 
20 | object TestNamerInterfaceServable extends Servable {
21 |   def kind = "test"
22 |   def serve() = NullServer
23 | }
24 | 
25 | case class TestNamerInterface(namers: Ns => NameInterpreter)
26 | 
27 | class TestNamerInterfaceInitializer extends InterfaceInitializer {
28 |   override def configId = "test"
29 |   override def configClass = classOf[TestInterpreterInterfaceConfig]
30 | }
31 | 
32 | object TestNamerInterfaceInitializer extends TestNamerInterfaceInitializer
33 | 


--------------------------------------------------------------------------------
/namerd/examples/all.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   port: 9991
 3 | 
 4 | storage:
 5 |   kind: io.l5d.inMemory
 6 |   namespaces:
 7 |     default: /svc => /#/io.l5d.fs;
 8 | 
 9 | namers:
10 |   - kind: io.l5d.fs
11 |     rootDir: namerd/examples/disco
12 | 
13 | interfaces:
14 |   - kind: io.l5d.httpController
15 |   - kind: io.l5d.mesh
16 |   - kind: io.l5d.thriftNameInterpreter
17 | 


--------------------------------------------------------------------------------
/namerd/examples/basic.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   port: 9991
 3 | storage:
 4 |   kind: io.l5d.inMemory
 5 |   namespaces:
 6 |     default: |
 7 |       /svc => /#/io.l5d.fs;
 8 | namers:
 9 | - kind: io.l5d.fs
10 |   rootDir: namerd/examples/disco
11 | interfaces:
12 | - kind: io.l5d.thriftNameInterpreter
13 | - kind: io.l5d.httpController
14 | telemetry:
15 | - kind: io.l5d.prometheus
16 | - kind: io.l5d.influxdb
17 | 


--------------------------------------------------------------------------------
/namerd/examples/certs/namerd-cacert.pem:
--------------------------------------------------------------------------------
 1 | -----BEGIN CERTIFICATE-----
 2 | MIICujCCAaICCQDBBDBp58kubDANBgkqhkiG9w0BAQsFADAfMQswCQYDVQQGEwJV
 3 | UzEQMA4GA1UEAwwHVGVzdCBDQTAeFw0xNjA5MjgxNzEyMDFaFw0xNjEwMjgxNzEy
 4 | MDFaMB8xCzAJBgNVBAYTAlVTMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG
 5 | 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA70oRir+Kb/vGppIesZwL6arlSfVmMLT7TwY1
 6 | iHOOcReZ2d8x1F8IvZmWPERh3aenjtTeef0hpfg5zp7MDJklxjP3N7ZqBKVBLOWO
 7 | dr+GKg94tIBjQrFQCwQUEVsso9TRBHkZ5eeVYKQMC3wl1bY8ZbGVY86C8/b0ZI/v
 8 | 0OvC5FEUfU8FPLEbrzsZ2SCpTfLpQBAmWJN9KJH7azki34ObbbdF0HONN31C/KYJ
 9 | mtFJBuPiggEYv1fF4ve6T1VwTgaMRXKgGZmZ1uhxCUXgKxyBQG1HYkWh8p3pKpAA
10 | SSHjiN66rdz7DD3gQhxp24BdizGNRLmldG7px8ijBtyh+OqmUQIDAQABMA0GCSqG
11 | SIb3DQEBCwUAA4IBAQCpEsrcaadpKBYlMYCRYl7942ahYcVYD4OliZXopctvvEZ0
12 | giHkGMG4spkUhvE27ETXGqWx81KoCgxdrNLIBHpytbVHWK/hMsK3sViTLICurmqo
13 | Ghn40HHMHdU/CtVXU65YvF7OpaGVMscKQ88f0ZMUZtSkoCHbIMB3VswalS8qYSfO
14 | 1bW3dAmx72VQVdXkLzA94M0x6xot+E/EyTJ4Gyta1lA8lvRoKdP3qDiPhofFpdPG
15 | WzIqazXyx2BTzQFot07DhTzun/e+k5tO4c8Zm126UND+u0mLoyCKCcqDUBlpBWFc
16 | 6x2iJ1Iz89jXaRg6b6fKOa+MlEO7H80uaBdabixj
17 | -----END CERTIFICATE-----
18 | 


--------------------------------------------------------------------------------
/namerd/examples/consul-storage.yaml:
--------------------------------------------------------------------------------
1 | admin:
2 |   ip: 0.0.0.0
3 |   port: 9991
4 | interfaces:
5 |   - kind: io.l5d.httpController
6 | storage:
7 |   kind: io.l5d.consul
8 | 


--------------------------------------------------------------------------------
/namerd/examples/consul.yaml:
--------------------------------------------------------------------------------
 1 | namers:
 2 | - kind: io.l5d.consul
 3 |   useHealthCheck: true
 4 | admin:
 5 |   port: 9991
 6 | storage:
 7 |   kind: io.l5d.inMemory
 8 |   namespaces:
 9 |     default: ""
10 | interfaces:
11 | - kind: io.l5d.thriftNameInterpreter
12 | - kind: io.l5d.httpController
13 | 


--------------------------------------------------------------------------------
/namerd/examples/destination.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   port: 9991
 3 | storage:
 4 |   kind: io.l5d.k8s
 5 |   host: localhost
 6 |   port: 8001
 7 | namers:
 8 | - kind: io.l5d.k8s
 9 |   host: localhost
10 |   port: 8001
11 | interfaces:
12 |   - kind: io.l5d.destination
13 |     namespace: internal
14 |   - kind: io.l5d.httpController
15 | 
16 | 
17 | 


--------------------------------------------------------------------------------
/namerd/examples/disco/default:
--------------------------------------------------------------------------------
1 | 127.1 9990
2 | 127.2 9990
3 | 


--------------------------------------------------------------------------------
/namerd/examples/etcd.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   port: 9991
 3 | storage:
 4 |   kind: io.l5d.etcd
 5 |   pathPrefix: /dtabs
 6 | namers: []
 7 | interfaces:
 8 | - kind: io.l5d.thriftNameInterpreter
 9 | - kind: io.l5d.httpController
10 | 


--------------------------------------------------------------------------------
/namerd/examples/k8s-mesh.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   port: 9990
 3 | namers:
 4 | - kind: io.l5d.k8s
 5 |   host: localhost
 6 |   port: 8001
 7 |   prefix: /ds
 8 |   transformers:
 9 |   - kind: io.l5d.k8s.daemonset
10 |     namespace: default
11 |     port: incoming
12 |     service: l5d
13 | - kind: io.l5d.k8s
14 |   host: localhost
15 |   port: 8001
16 | 
17 | storage:
18 |   kind: io.l5d.inMemory
19 |   namespaces:
20 |     incoming: |
21 |      /svc => /#/io.l5d.k8s/default/http ;
22 |     outgoing: |
23 |      /svc => /#/ds/default/http ;
24 | 
25 | interfaces:
26 | - kind: io.l5d.thriftNameInterpreter
27 |   ip: 0.0.0.0
28 |   port: 4100
29 | - kind: io.l5d.httpController
30 |   ip: 0.0.0.0
31 |   port: 4180
32 | 


--------------------------------------------------------------------------------
/namerd/examples/k8s.yaml:
--------------------------------------------------------------------------------
 1 | # This file assumes you are running through `kubectl proxy` on localhost:8001.
 2 | storage:
 3 |   kind: io.l5d.k8s
 4 |   host: localhost
 5 |   port: 8001 # Running through kubectl proxy
 6 | interfaces:
 7 | - kind: io.l5d.thriftNameInterpreter
 8 | - kind: io.l5d.httpController
 9 | namers:
10 | - kind: io.l5d.fs
11 |   rootDir: namerd/examples/disco
12 | 


--------------------------------------------------------------------------------
/namerd/examples/k8s/3rdparty.yaml:
--------------------------------------------------------------------------------
 1 | kind: CustomResourceDefinition
 2 | apiVersion: apiextensions.k8s.io/v1beta1
 3 | metadata:
 4 |   name: dtabs.l5d.io
 5 | spec:
 6 |   scope: Namespaced
 7 |   group: l5d.io
 8 |   version: v1alpha1
 9 |   names:
10 |     kind: DTab
11 |     plural: dtabs
12 |     singular: dtab


--------------------------------------------------------------------------------
/namerd/examples/mesh.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   port: 9991
 3 | 
 4 | storage:
 5 |   kind: io.l5d.inMemory
 6 |   namespaces:
 7 |     default: /grpc => /#/io.l5d.fs;
 8 | 
 9 | namers:
10 |   - kind: io.l5d.fs
11 |     rootDir: namerd/examples/disco
12 | 
13 | interfaces:
14 |   - kind: io.l5d.httpController
15 |   - kind: io.l5d.mesh
16 |     port: 4321
17 | 


--------------------------------------------------------------------------------
/namerd/examples/minimal.yaml:
--------------------------------------------------------------------------------
1 | # example config demonstrating the minimal set of namerd config keys required
2 | storage:
3 |   kind: io.l5d.inMemory
4 | interfaces:
5 | - kind: io.l5d.httpController
6 | 


--------------------------------------------------------------------------------
/namerd/examples/src/test/scala/io/buoyant/namerd/examples/ExamplesTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.examples
 2 | 
 3 | import io.buoyant.namerd.NamerdConfig
 4 | import java.io.{File, FilenameFilter}
 5 | import org.scalatest.FunSuite
 6 | import scala.io.Source
 7 | 
 8 | class ExamplesTest extends FunSuite {
 9 | 
10 |   val examplesDir = new File("namerd/examples")
11 |   val files = examplesDir.listFiles(new FilenameFilter {
12 |     override def accept(dir: File, name: String): Boolean = name.endsWith(".yaml")
13 |   })
14 | 
15 |   for (file <- files) {
16 |     test(file.getName) {
17 |       val source = Source.fromFile(file)
18 |       try {
19 |         val lines = source.getLines().toSeq
20 |         val firstLine = lines.headOption
21 |         if (!firstLine.contains("#notest")) {
22 |           val config = lines.mkString("\n")
23 |           val _ = NamerdConfig.loadNamerd(config)
24 |         }
25 |       } finally {
26 |         source.close()
27 |       }
28 |     }
29 |   }
30 | }
31 | 
32 | 


--------------------------------------------------------------------------------
/namerd/examples/static.yaml:
--------------------------------------------------------------------------------
 1 | admin:
 2 |   port: 9991
 3 | storage:
 4 |   kind: io.l5d.inMemory
 5 |   namespaces:
 6 |     default: |
 7 |       /svc/* => /$/inet/localhost/8080
 8 | namers: []
 9 | interfaces:
10 | - kind: io.l5d.thriftNameInterpreter
11 | - kind: io.l5d.httpController
12 | 


--------------------------------------------------------------------------------
/namerd/examples/zk.yaml:
--------------------------------------------------------------------------------
 1 | storage:
 2 |   kind: io.l5d.zk
 3 |   pathPrefix: /dtabs
 4 |   zkAddrs:
 5 |   - host: localhost
 6 |     port: 2181
 7 |   authInfo:
 8 |     scheme: digest
 9 |     auth: user_123:password_123
10 |   acls:
11 |   - scheme: auth
12 |     id: ""
13 |     perms: crwda 
14 | interfaces:
15 | - kind: io.l5d.thriftNameInterpreter
16 | - kind: io.l5d.httpController
17 | namers:
18 | - kind: io.l5d.fs
19 |   rootDir: namerd/examples/disco
20 | 


--------------------------------------------------------------------------------
/namerd/iface/control-http/src/main/resources/META-INF/services/io.buoyant.namerd.InterfaceInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.iface.HttpControlServiceInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/iface/destination/src/main/protobuf/net.proto:
--------------------------------------------------------------------------------
 1 | //This file is added using pull-destination-proto.sh. DO NOT EDIT!
 2 | syntax = "proto3";
 3 | 
 4 | package io.linkerd.proxy.net;
 5 | 
 6 | option go_package = "github.com/linkerd/linkerd2-proxy-api/go/net";
 7 | 
 8 | message IPAddress {
 9 |   oneof ip {
10 |     fixed32 ipv4 = 1;
11 |     IPv6 ipv6 = 2;
12 |   }
13 | }
14 | 
15 | message IPv6 {
16 |   fixed64 first = 1; // hextets 1-4
17 |   fixed64 last = 2; // hextets 5-8
18 | }
19 | 
20 | message TcpAddress {
21 |   IPAddress ip = 1;
22 |   uint32 port = 2;
23 | }


--------------------------------------------------------------------------------
/namerd/iface/destination/src/main/resources/META-INF/services/io.buoyant.namerd.InterfaceInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.iface.DestinationIfaceInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/iface/destination/src/main/resources/pull-destination-proto.sh:
--------------------------------------------------------------------------------
 1 | #!/usr/bin/env bash
 2 | cd ../protobuf || exit
 3 | LATEST_API_RELEASE=v0.1.1
 4 | BASE_PROTO_URL=https://raw.githubusercontent.com/linkerd/linkerd2-proxy-api/$LATEST_API_RELEASE/proto
 5 | PROTOFILES="destination.proto net.proto"
 6 | 
 7 | 
 8 | for proto_file in $PROTOFILES; do
 9 |   echo "Copying $proto_file from linkerd2 repo"
10 |   printf "//This file is added using pull-destination-proto.sh. DO NOT EDIT!\\n%s" "$(curl $BASE_PROTO_URL/"$proto_file")" > "$proto_file"
11 | done
12 | 
13 | 


--------------------------------------------------------------------------------
/namerd/iface/interpreter-thrift/src/main/resources/META-INF/services/io.buoyant.config.ConfigSerializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.iface.AddrReqSerializer
2 | io.buoyant.namerd.iface.AddrSerializer
3 | io.buoyant.namerd.iface.BindReqSerializer
4 | io.buoyant.namerd.iface.BoundSerializer
5 | 


--------------------------------------------------------------------------------
/namerd/iface/interpreter-thrift/src/main/resources/META-INF/services/io.buoyant.namerd.InterfaceInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.iface.ThriftInterpreterInterfaceInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/iface/interpreter-thrift/src/main/scala/io/buoyant/namerd/iface/AddrReqSerializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.iface
 2 | 
 3 | import com.fasterxml.jackson.core.JsonGenerator
 4 | import com.fasterxml.jackson.databind.SerializerProvider
 5 | import io.buoyant.config.ConfigSerializer
 6 | import io.buoyant.namerd.iface.{thriftscala => thrift}
 7 | 
 8 | class AddrReqSerializer extends ConfigSerializer[thrift.AddrReq] {
 9 |   import ByteBufferSerializers._
10 | 
11 |   override def serialize(
12 |     value: thrift.AddrReq,
13 |     gen: JsonGenerator,
14 |     provider: SerializerProvider
15 |   ): Unit = {
16 |     gen.writeStartObject()
17 |     gen.writeStringField("name", path(value.name.name))
18 |     gen.writeStringField("stamp", stamp(value.name.stamp))
19 |     gen.writeStringField("namespace", value.name.ns)
20 |     gen.writeStringField("clientId", path(value.clientId))
21 |     gen.writeEndObject()
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/namerd/iface/interpreter-thrift/src/main/scala/io/buoyant/namerd/iface/BindReqSerializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.iface
 2 | 
 3 | import com.fasterxml.jackson.core.JsonGenerator
 4 | import com.fasterxml.jackson.databind.SerializerProvider
 5 | import io.buoyant.config.ConfigSerializer
 6 | import io.buoyant.namerd.iface.{thriftscala => thrift}
 7 | 
 8 | class BindReqSerializer extends ConfigSerializer[thrift.BindReq] {
 9 |   import ByteBufferSerializers._
10 | 
11 |   override def serialize(
12 |     value: thrift.BindReq,
13 |     gen: JsonGenerator,
14 |     provider: SerializerProvider
15 |   ): Unit = {
16 |     gen.writeStartObject()
17 |     gen.writeStringField("name", path(value.name.name))
18 |     gen.writeStringField("dtab", value.dtab)
19 |     gen.writeStringField("stamp", stamp(value.name.stamp))
20 |     gen.writeStringField("namespace", value.name.ns)
21 |     gen.writeStringField("clientId", path(value.clientId))
22 |     gen.writeEndObject()
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/namerd/iface/interpreter-thrift/src/main/scala/io/buoyant/namerd/iface/ByteBufferSerializers.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.iface
 2 | 
 3 | import com.twitter.io.Buf
 4 | import java.nio.ByteBuffer
 5 | 
 6 | object ByteBufferSerializers {
 7 | 
 8 |   def utf8(bb: ByteBuffer): String =
 9 |     Buf.Utf8.unapply(Buf.ByteBuffer.Shared(bb)).get
10 | 
11 |   def path(path: Seq[ByteBuffer]): String =
12 |     path.map(utf8).mkString("/", "/", "")
13 | 
14 |   def stamp(bb: ByteBuffer): String = {
15 |     if (bb.remaining() >= 8) bb.duplicate().getLong.toString else ""
16 |   }
17 | 
18 |   def ipv4(bb: ByteBuffer): String = {
19 |     val dup = bb.duplicate()
20 |     if (dup.remaining() >= 4)
21 |       s"${dup.get()}.${dup.get()}.${dup.get()}.${dup.get()}"
22 |     else ""
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/namerd/iface/interpreter-thrift/src/main/scala/io/buoyant/namerd/iface/PollState.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.iface
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.util.{Return, Throw, Time, Try}
 5 | 
 6 | class PollState[Req, Rep] {
 7 | 
 8 |   @JsonIgnore
 9 |   def recordApiCall(req: Req): Unit = synchronized {
10 |     request = Some(req)
11 |     lastRequestAt = Some(Time.now.toString)
12 |   }
13 | 
14 |   @JsonIgnore
15 |   def recordResponse(rep: Try[Rep]): Unit = synchronized {
16 |     lastResponseAt = Some(Time.now.toString)
17 |     rep match {
18 |       case Return(r) =>
19 |         response = Some(r)
20 |         error = None
21 |       case Throw(e) =>
22 |         error = Some(e.getMessage)
23 |         response = None
24 |     }
25 |   }
26 | 
27 |   // These fields exist to be serialized.
28 |   protected var request: Option[Req] = None
29 |   protected var lastRequestAt: Option[String] = None
30 |   protected var response: Option[Rep] = None
31 |   protected var lastResponseAt: Option[String] = None
32 |   protected var error: Option[String] = None
33 | }
34 | 


--------------------------------------------------------------------------------
/namerd/iface/mesh/src/main/resources/META-INF/services/io.buoyant.namerd.InterfaceInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.iface.MeshIfaceInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/iface/mesh/src/main/scala/io/buoyant/namerd/iface/mesh/Errors.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.iface.mesh
 2 | 
 3 | import com.twitter.finagle.Path
 4 | import io.buoyant.grpc.runtime.GrpcStatus
 5 | 
 6 | object Errors {
 7 |   val NoRoot = GrpcStatus.InvalidArgument("No namespace specified")
 8 |   val RootNotFound = GrpcStatus.NotFound("Root not found")
 9 |   val NoName = GrpcStatus.NotFound("No name given")
10 |   def InvalidRoot(p: Path) =
11 |     GrpcStatus.InvalidArgument(s"Invalid root: `${p.show}` must have exactly one segment")
12 | }
13 | 


--------------------------------------------------------------------------------
/namerd/iface/mesh/src/test/scala/io/buoyant/namerd/iface/mesh/DelegatorServiceTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.iface.mesh
 2 | 
 3 | import com.google.protobuf.CodedOutputStream
 4 | import com.twitter.finagle._
 5 | import io.buoyant.namer.DelegateTree
 6 | import io.buoyant.test.FunSuite
 7 | import io.linkerd.mesh.DelegateTreeRsp
 8 | import java.io.ByteArrayOutputStream
 9 | 
10 | class DelegatorServiceTest extends FunSuite {
11 |   test("Delegator service responding with DelegateTree Exception shouldn't throw a null pointer exception"){
12 |     val out = CodedOutputStream.newInstance(new ByteArrayOutputStream())
13 |     DelegateTreeRsp.codec.encode(DelegatorService.toDelegateTreeRsp(DelegateTree.Exception(Path.read("/svc"), Dentry.nop, new Throwable)), out)
14 |     assert(out.getTotalBytesWritten > 0)
15 |   }
16 | }
17 | 


--------------------------------------------------------------------------------
/namerd/main/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=WARN, stderr
2 | log4j.appender.stderr=org.apache.log4j.AsyncAppender
3 | log4j.appender.stderr.layout=org.apache.log4j.PatternLayout
4 | log4j.appender.stderr.layout.ConversionPattern=%p %d{MMdd HH:mm:ss.SSS z} %t: %m%n
5 | log4j.appender.async=org.apache.log4j.AsyncAppender
6 | log4j.appender.async.appenders=console
7 | 


--------------------------------------------------------------------------------
/namerd/storage/consul/src/main/resources/META-INF/services/io.buoyant.namerd.DtabStoreInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.storage.consul.ConsulDtabStoreInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/storage/etcd/src/main/resources/META-INF/services/io.buoyant.namerd.DtabStoreInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.storage.etcd.EtcdDtabStoreInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/storage/in-memory/src/main/resources/META-INF/services/io.buoyant.namerd.DtabStoreInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.storage.InMemoryDtabStoreInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/storage/in-memory/src/main/scala/io/buoyant/namerd/storage/InMemoryDtabStoreInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.storage
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.Dtab
 5 | import com.twitter.finagle.Stack
 6 | import io.buoyant.namerd.{DtabStore, DtabStoreConfig, DtabStoreInitializer}
 7 | 
 8 | class InMemoryDtabStoreInitializer extends DtabStoreInitializer {
 9 |   override def configClass = classOf[InMemoryConfig]
10 |   override def configId = "io.l5d.inMemory"
11 | }
12 | 
13 | case class InMemoryConfig(namespaces: Option[Map[String, Dtab]]) extends DtabStoreConfig {
14 |   @JsonIgnore
15 |   override def mkDtabStore(params: Stack.Params): DtabStore = new InMemoryDtabStore(namespaces.getOrElse(Map.empty))
16 | }
17 | 


--------------------------------------------------------------------------------
/namerd/storage/k8s/src/main/resources/META-INF/services/io.buoyant.k8s.SerializationModule:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.storage.kubernetes.DtabSerializationModule
2 | 


--------------------------------------------------------------------------------
/namerd/storage/k8s/src/main/resources/META-INF/services/io.buoyant.namerd.DtabStoreInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.storage.K8sDtabStoreInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/storage/k8s/src/main/scala/io/buoyant/namerd/storage/K8sDtabStoreInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.storage
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.Stack
 5 | import io.buoyant.config.types.Port
 6 | import io.buoyant.k8s.ClientConfig
 7 | import io.buoyant.namerd.{DtabStore, DtabStoreConfig, DtabStoreInitializer}
 8 | 
 9 | case class K8sConfig(
10 |   host: Option[String],
11 |   port: Option[Port],
12 |   namespace: Option[String]
13 | ) extends DtabStoreConfig with ClientConfig {
14 | 
15 |   @JsonIgnore
16 |   def portNum = port.map(_.port)
17 | 
18 |   @JsonIgnore
19 |   override def mkDtabStore(params: Stack.Params): DtabStore = {
20 |     val client = mkClient(params)
21 | 
22 |     new K8sDtabStore(client, dst, namespace.getOrElse(DefaultNamespace))
23 |   }
24 | }
25 | 
26 | class K8sDtabStoreInitializer extends DtabStoreInitializer {
27 |   override def configClass = classOf[K8sConfig]
28 |   override def configId = "io.l5d.k8s"
29 | }
30 | 
31 | object K8sDtabStoreInitializer extends K8sDtabStoreInitializer
32 | 


--------------------------------------------------------------------------------
/namerd/storage/k8s/src/main/scala/io/buoyant/namerd/storage/kubernetes/Dtab.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.storage.kubernetes
 2 | 
 3 | import com.twitter.finagle.Dentry
 4 | import io.buoyant.k8s.{KubeObject, ObjectMeta}
 5 | 
 6 | /**
 7 |  * This is the Dtab JSON format stored in the k8s thirdparty API. It should
 8 |  * largely mirror the JSON format returned from namerd HTTP APIs.
 9 |  */
10 | case class Dtab(
11 |   dentries: Seq[Dentry],
12 |   kind: Option[String] = Some("DTab"),
13 |   metadata: Option[ObjectMeta] = None,
14 |   apiVersion: Option[String] = None
15 | ) extends KubeObject
16 | 


--------------------------------------------------------------------------------
/namerd/storage/k8s/src/main/scala/io/buoyant/namerd/storage/kubernetes/DtabDescriptor.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.storage.kubernetes
 2 | 
 3 | import com.twitter.finagle.{Dtab => FDtab}
 4 | import io.buoyant.k8s._
 5 | 
 6 | object DtabDescriptor extends ObjectDescriptor[Dtab, DtabWatch] {
 7 |   def listName = "dtabs"
 8 |   def toWatch(d: Dtab) = DtabModified(d)
 9 | }
10 | 
11 | 


--------------------------------------------------------------------------------
/namerd/storage/k8s/src/main/scala/io/buoyant/namerd/storage/kubernetes/DtabList.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.storage.kubernetes
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonProperty
 4 | import io.buoyant.k8s.{KubeList, ObjectMeta}
 5 | 
 6 | case class DtabList(
 7 |   @JsonProperty("items") items: Seq[Dtab],
 8 |   kind: Option[String] = None,
 9 |   metadata: Option[ObjectMeta] = None,
10 |   apiVersion: Option[String] = None
11 | ) extends KubeList[Dtab]
12 | 


--------------------------------------------------------------------------------
/namerd/storage/k8s/src/main/scala/io/buoyant/namerd/storage/kubernetes/DtabSerializationModule.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.namerd.storage.kubernetes
2 | 
3 | import io.buoyant.k8s.SerializationModule
4 | import io.buoyant.namerd.DtabCodec
5 | 
6 | class DtabSerializationModule extends SerializationModule {
7 |   def module = DtabCodec.module
8 | }
9 | 


--------------------------------------------------------------------------------
/namerd/storage/k8s/src/test/scala/io/buoyant/namerd/storage/K8sConfigTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.storage
 2 | 
 3 | import io.buoyant.config.Parser
 4 | import io.buoyant.config.types.Port
 5 | import io.buoyant.namerd.DtabStoreConfig
 6 | import io.buoyant.test.FunSuite
 7 | import org.scalatest.OptionValues
 8 | 
 9 | class K8sConfigTest extends FunSuite with OptionValues {
10 |   test("parse config") {
11 |     val yaml =
12 |       """
13 |       |kind: io.l5d.k8s
14 |       |host: localhost
15 |       |port: 8001
16 |       |namespace: default
17 |     """.stripMargin
18 | 
19 |     val mapper = Parser.objectMapper(yaml, Iterable(Seq(K8sDtabStoreInitializer)))
20 |     val k8s = mapper.readValue[DtabStoreConfig](yaml).asInstanceOf[K8sConfig]
21 |     assert(k8s.host.value == "localhost")
22 |     assert(k8s.port.value == Port(8001))
23 |     assert(k8s.namespace.value == "default")
24 |   }
25 | }
26 | 


--------------------------------------------------------------------------------
/namerd/storage/zk/src/main/resources/META-INF/services/io.buoyant.namerd.DtabStoreInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.namerd.storage.ZkDtabStoreInitializer
2 | 


--------------------------------------------------------------------------------
/namerd/storage/zk/src/test/scala/io/buoyant/namerd/storage/AclTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.namerd.storage
 2 | 
 3 | import io.buoyant.test.Exceptions
 4 | import org.scalatest.FunSuite
 5 | 
 6 | class AclTest extends FunSuite with Exceptions {
 7 | 
 8 |   test("unrecognized perm") {
 9 |     assertThrows[IllegalArgumentException](Acl("scheme", "id", "crwdaz"))
10 |   }
11 | 
12 |   test("duplicate perm") {
13 |     assertThrows[IllegalArgumentException](Acl("scheme", "id", "cc"))
14 |   }
15 | }
16 | 


--------------------------------------------------------------------------------
/project/Finagle.scala:
--------------------------------------------------------------------------------
 1 | import pl.project13.scala.sbt.JmhPlugin
 2 | import sbt.Keys.publishArtifact
 3 | import sbt._
 4 | 
 5 | /** Finagle protocol extensions. */
 6 | object Finagle extends Base {
 7 | 
 8 |   val buoyantCore = projectDir("finagle/buoyant")
 9 |     .withTwitterLibs(Deps.finagle("netty4"))
10 |     .withTests()
11 | 
12 |   val h2 = projectDir("finagle/h2")
13 |     .dependsOn(buoyantCore)
14 |     .withLibs(
15 |       Deps.netty4("codec-http2"), Deps.netty4("handler"), Deps.boringssl
16 |     )
17 |     .withTests()
18 |     .withE2e()
19 | 
20 |   val benchmark = projectDir("finagle/benchmark")
21 |     .dependsOn(h2, buoyantCore, testUtil)
22 |     .enablePlugins(JmhPlugin)
23 |     .settings(publishArtifact := false)
24 |     .withTwitterLib(Deps.twitterUtil("benchmark"))
25 | 
26 |   val all = aggregateDir("finagle", buoyantCore, h2, benchmark)
27 | }
28 | 


--------------------------------------------------------------------------------
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version=0.13.16
2 | 


--------------------------------------------------------------------------------
/protoc:
--------------------------------------------------------------------------------
 1 | #!/bin/bash
 2 | 
 3 | set -e
 4 | 
 5 | if [ "$(uname -s)" = "Darwin" ]; then
 6 |   os=osx
 7 | else
 8 |   os=linux
 9 | fi
10 | arch=$(uname -m)
11 | 
12 | protocbin=.protoc
13 | protocversion=3.0.0
14 | protocurl="https://github.com/google/protobuf/releases/download/v${protocversion}/protoc-${protocversion}-${os}-${arch}.zip"
15 | 
16 | if [ ! -f "$protocbin" ]; then
17 |   tmp=$(mktemp -d -t protoc.XXX)
18 |   pushd "$tmp" > /dev/null
19 |   curl -L --silent --fail -o "$protocbin.zip" "$protocurl"
20 |   jar xf "$protocbin.zip"
21 |   chmod +x bin/protoc
22 |   popd > /dev/null
23 |   mv "$tmp/bin/protoc" "$protocbin"
24 |   rm -rf "$tmp"
25 | fi
26 | 
27 | ./$protocbin "$@"
28 | 


--------------------------------------------------------------------------------
/router/base-http/src/main/scala/io/buoyant/router/http/HeadersLike.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router.http
 2 | 
 3 | /**
 4 |  * Type class for HTTP headers object
 5 |  * @tparam H Headers object type
 6 |  */
 7 | trait HeadersLike[H] {
 8 |   def toSeq(headers: H): Seq[(String, String)]
 9 |   def contains(headers: H, k: String): Boolean
10 |   def get(headers: H, k: String): Option[String]
11 |   def getAll(headers: H, k: String): Seq[String]
12 |   def add(headers: H, k: String, v: String): Unit
13 |   def set(headers: H, k: String, v: String): Unit
14 |   def remove(headers: H, key: String): Seq[String]
15 | }
16 | 


--------------------------------------------------------------------------------
/router/base-http/src/main/scala/io/buoyant/router/http/RequestLike.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router.http
 2 | 
 3 | /**
 4 |  * Type class for HTTP 1.1/2 requests
 5 |  * @tparam R Request type
 6 |  * @tparam H Headers object type
 7 |  */
 8 | abstract class RequestLike[R, H: HeadersLike] {
 9 |   def headers(request: R): H
10 | }
11 | 


--------------------------------------------------------------------------------
/router/core/src/main/scala/com/twitter/finagle/buoyant/EncodeResidual.scala:
--------------------------------------------------------------------------------
 1 | package com.twitter.finagle.buoyant
 2 | 
 3 | import com.twitter.finagle._
 4 | 
 5 | object EncodeResidual {
 6 |   val role = Stack.Role("EncodeResidual")
 7 |   val description = "Supports rewriting of downstream requests"
 8 | 
 9 |   trait Module[Req, Rsp] extends Stack.Module1[Dst.Bound, ServiceFactory[Req, Rsp]] {
10 |     val role = EncodeResidual.role
11 |     val description = EncodeResidual.description
12 | 
13 |     final def make(dst: Dst.Bound, next: ServiceFactory[Req, Rsp]) =
14 |       mkFilter(dst).andThen(next)
15 | 
16 |     def mkFilter(dst: Dst.Bound): Filter[Req, Rsp, Req, Rsp]
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/router/core/src/main/scala/com/twitter/finagle/buoyant/package.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant
2 | 
3 | /**
4 |  * The [[io.buoyant.router]] and [[com.twitter.finagle.buoyant]]
5 |  * packages provide a library for building RPC routers with Finagle.
6 |  */
7 | package object router
8 | 


--------------------------------------------------------------------------------
/router/core/src/main/scala/com/twitter/finagle/naming/buoyant/RichNoBrokersAvailableException.scala:
--------------------------------------------------------------------------------
 1 | package com.twitter.finagle.naming.buoyant
 2 | 
 3 | import com.twitter.finagle._
 4 | import com.twitter.finagle.buoyant.Dst
 5 | import com.twitter.util.Future
 6 | 
 7 | class RichNoBrokersAvailableException(
 8 |   path: Dst.Path,
 9 |   dtab: Option[Dtab]
10 | ) extends RequestException {
11 | 
12 |   private[this] def formatDtab(d: Dtab): String =
13 |     d.map { dentry =>
14 |       s"  ${dentry.prefix.show} => ${dentry.dst.show}"
15 |     }.mkString("\n")
16 | 
17 |   override def exceptionMessage(): String =
18 |     s"""Unable to route request!
19 | 
20 | service name: ${path.path.show}
21 | dtab:
22 | ${formatDtab(dtab.getOrElse(Dtab.empty))}
23 | base dtab:
24 | ${formatDtab(path.baseDtab)}
25 | override dtab:
26 | ${formatDtab(path.localDtab)}
27 | """.stripMargin
28 | }
29 | 
30 | object RichNoBrokersAvailableException {
31 | 
32 |   def apply(path: Dst.Path): Future[Nothing] =
33 |     Future.exception(new RichNoBrokersAvailableException(path, None))
34 | }
35 | 


--------------------------------------------------------------------------------
/router/core/src/main/scala/io/buoyant/router/Originator.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router
 2 | 
 3 | import com.twitter.finagle.Stack
 4 | 
 5 | /**
 6 |  * Originator.Param is a boolean stack param that is used to configure a
 7 |  * [[io.buoyant.router.Router Router]]. If the param is set to true, it
 8 |  * indicates that the router is the first hop in a linker-to-linker request,
 9 |  * and the router's stats are updated to reflect that.
10 |  *
11 |  * @see com.twitter.finagle.Stack.Param
12 |  */
13 | object Originator {
14 |   case class Param(originator: Boolean) {
15 |     def mk(): (Param, Stack.Param[Param]) =
16 |       (this, Param.param)
17 |   }
18 | 
19 |   object Param {
20 |     implicit val param: Stack.Param[Param] =
21 |       Stack.Param(Param(false))
22 |   }
23 | }
24 | 


--------------------------------------------------------------------------------
/router/core/src/main/scala/io/buoyant/router/PerDstPathFilter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router
 2 | 
 3 | import com.twitter.finagle.{Path, Filter, Service, SimpleFilter}
 4 | import com.twitter.finagle.buoyant.Dst
 5 | import com.twitter.finagle.service.StatsFilter
 6 | import com.twitter.util.{Future, Memoize}
 7 | import io.buoyant.router.context.DstPathCtx
 8 | 
 9 | class PerDstPathFilter[Req, Rsp](mk: Path => Filter[Req, Rsp, Req, Rsp])
10 |   extends SimpleFilter[Req, Rsp] {
11 | 
12 |   private[this] val getFilter = Memoize(mk)
13 | 
14 |   def apply(req: Req, service: Service[Req, Rsp]): Future[Rsp] =
15 |     DstPathCtx.current match {
16 |       case None | Some(Dst.Path(Path.empty, _, _)) =>
17 |         service(req)
18 | 
19 |       case Some(Dst.Path(path, _, _)) =>
20 |         val filter = getFilter(path)
21 |         filter(req, service)
22 |     }
23 | }
24 | 


--------------------------------------------------------------------------------
/router/core/src/main/scala/io/buoyant/router/RouterLabel.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router
 2 | 
 3 | import com.twitter.finagle.Stack
 4 | 
 5 | /**
 6 |  * RouterLabel.Param is a string stack param containing the router's label.
 7 |  *
 8 |  * @see com.twitter.finagle.Stack.Param
 9 |  */
10 | object RouterLabel {
11 |   case class Param(label: String) {
12 |     def mk(): (Param, Stack.Param[Param]) =
13 |       (this, Param.param)
14 |   }
15 | 
16 |   object Param {
17 |     implicit val param: Stack.Param[Param] =
18 |       Stack.Param(Param(""))
19 |   }
20 | }
21 | 


--------------------------------------------------------------------------------
/router/core/src/main/scala/io/buoyant/router/context/dst.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.router.context
2 | 
3 | import com.twitter.finagle.buoyant.Dst
4 | 
5 | object DstPathCtx extends LocalKey[Dst.Path]("Dst.Path")
6 | 
7 | object DstBoundCtx extends LocalKey[Dst.Bound]("Dst.Bound")
8 | 


--------------------------------------------------------------------------------
/router/core/src/main/scala/io/buoyant/router/context/responseClassifier.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router.context
 2 | 
 3 | import com.twitter.finagle.param
 4 | 
 5 | /**
 6 |  * We set the ResponseClassifier from the path stack into a local context
 7 |  * so that when the request enters the client stack, it can use the path stack's
 8 |  * response classifier for reporting stats
 9 |  */
10 | object ResponseClassifierCtx extends LocalKey[param.ResponseClassifier]("ResponseClassifier")
11 | 


--------------------------------------------------------------------------------
/router/h2/src/main/scala/io/buoyant/router/context/h2/H2ClassifierCtx.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router.context.h2
 2 | 
 3 | import com.twitter.finagle.buoyant.h2.param
 4 | import io.buoyant.router.context.LocalKey
 5 | 
 6 | /**
 7 |  * We set the H2Classifier from the path stack into a local context
 8 |  * so that when the request enters the client stack, it can use the path stack's
 9 |  * stream classifier for reporting stats.
10 |  *
11 |  * This is based directly on `ResponseClassifierCtx` in the H1 protocol
12 |  */
13 | object H2ClassifierCtx extends LocalKey[param.H2Classifier]("H2Classifier")
14 | 


--------------------------------------------------------------------------------
/router/h2/src/main/scala/io/buoyant/router/h2/DupRequest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router.h2
 2 | 
 3 | import com.twitter.finagle.{Service, ServiceFactory, SimpleFilter, Stack, Stackable}
 4 | import com.twitter.finagle.buoyant.h2.{Request, Response}
 5 | 
 6 | object DupRequest {
 7 |   val role = Stack.Role("DupRequest")
 8 | 
 9 |   object filter extends SimpleFilter[Request, Response] {
10 |     def apply(req: Request, service: Service[Request, Response]) = service(req.dup())
11 |   }
12 | 
13 |   val module: Stackable[ServiceFactory[Request, Response]] =
14 |     new Stack.Module0[ServiceFactory[Request, Response]] {
15 |       val role = DupRequest.role
16 |       val description = "Provides the rest of the subsequent stack with a duplicate request"
17 |       def make(next: ServiceFactory[Request, Response]) = filter.andThen(next)
18 |     }
19 | }
20 | 


--------------------------------------------------------------------------------
/router/h2/src/test/scala/io/buoyant/router/H2Test.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router
 2 | 
 3 | import com.twitter.finagle.Stack
 4 | import io.buoyant.router.h2.{LocalClassifierStreamStatsFilter, PerDstPathStreamStatsFilter}
 5 | import io.buoyant.test.FunSuite
 6 | 
 7 | class H2Test extends FunSuite {
 8 | 
 9 |   def get[T](stk: Stack[T], role: Stack.Role): Option[Stack[T]] = {
10 |     var found: Option[Stack[T]] = None
11 |     stk.foreach { s =>
12 |       if (s.head.role == role) found = Some(s)
13 |     }
14 |     found
15 |   }
16 | 
17 |   test("client stack contains classified stream filter") {
18 |     val statsModule = get(H2.router.client.stack, LocalClassifierStreamStatsFilter.role).get
19 |     assert(statsModule.head.description == LocalClassifierStreamStatsFilter.description)
20 | 
21 |     val perDstStats = get(H2.router.client.stack, PerDstPathStreamStatsFilter.module.role).get
22 |     assert(perDstStats.head.description == "perdstpathstatsfilter, using H2 stream classification")
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/router/h2/src/test/scala/io/buoyant/router/h2/DupRequestTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router.h2
 2 | 
 3 | import com.twitter.finagle.Service
 4 | import com.twitter.finagle.buoyant.h2._
 5 | import com.twitter.util.Future
 6 | import io.buoyant.test.Awaits
 7 | import org.scalatest.FunSuite
 8 | 
 9 | class DupRequestTest extends FunSuite with Awaits {
10 | 
11 |   test("changes in service don't impact original") {
12 |     val service = DupRequest.filter.andThen(Service.mk[Request, Response] { req =>
13 |       req.headers.set("badness", "true")
14 |       Future.value(Response(Status.Ok, Stream.empty()))
15 |     })
16 | 
17 |     val req = Request("http", Method.Get, "hihost", "/", Stream.empty())
18 |     await(service(req))
19 |     assert(!req.headers.contains("badness"))
20 |   }
21 | }
22 | 


--------------------------------------------------------------------------------
/router/http/src/main/scala/io/buoyant/http/status.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.http
 2 | 
 3 | import com.twitter.finagle.{Path, Service, ServiceNamer}
 4 | import com.twitter.finagle.http._
 5 | import com.twitter.util.{Future, Try}
 6 | 
 7 | /**
 8 |  * A service namer that accepts names in the form:
 9 |  *
10 |  *   /400/resource/name
11 |  *
12 |  * and binds the name to an Http service that always responds with the
13 |  * given status code (i.e. 400).
14 |  */
15 | class status extends ServiceNamer[Request, Response] {
16 | 
17 |   private[this] object Code {
18 |     def unapply(s: String): Option[Status] =
19 |       Try(s.toInt).toOption.filter { s => 100 <= s && s < 600 }.map(Status.fromCode(_))
20 |   }
21 | 
22 |   def lookupService(path: Path): Option[Service[Request, Response]] = path.take(1) match {
23 |     case Path.Utf8(Code(status)) => Some(Service.const(Future.value(Response(status))))
24 |     case _ => None
25 |   }
26 | }
27 | 


--------------------------------------------------------------------------------
/router/http/src/main/scala/io/buoyant/router/http/StaticIdentifier.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router.http
 2 | 
 3 | import com.twitter.finagle.buoyant.Dst
 4 | import com.twitter.finagle.{Dtab, Path}
 5 | import com.twitter.finagle.http.Request
 6 | import com.twitter.util.Future
 7 | import io.buoyant.router.RoutingFactory
 8 | import io.buoyant.router.RoutingFactory.{IdentifiedRequest, RequestIdentification}
 9 | 
10 | class StaticIdentifier(
11 |   path: Path,
12 |   baseDtab: () => Dtab = () => Dtab.base
13 | ) extends RoutingFactory.Identifier[Request] {
14 | 
15 |   def apply(req: Request): Future[RequestIdentification[Request]] = {
16 |     val dst = Dst.Path(path, baseDtab(), Dtab.local)
17 |     Future.value(new IdentifiedRequest(dst, req))
18 |   }
19 | }
20 | 


--------------------------------------------------------------------------------
/router/http/src/test/scala/io/buoyant/http/StatusTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.http
 2 | 
 3 | import com.twitter.finagle.{Status => _, _}
 4 | import com.twitter.finagle.http._
 5 | import io.buoyant.test.FunSuite
 6 | 
 7 | class StatusTest extends FunSuite {
 8 | 
 9 |   def lookup(path: Path) =
10 |     await(Namer.global.lookup(path).values.toFuture).get
11 | 
12 |   test("status") {
13 |     val client = Http.newService("/$/io.buoyant.http.status/401/foo/bar.a.b/bah")
14 |     val rsp = await(client(Request()))
15 |     assert(rsp.status == Status.Unauthorized)
16 |   }
17 | 
18 |   test("status: invalid") {
19 |     val path = Path.read("/$/io.buoyant.http.status/foo/bar.a.b/bah")
20 |     assert(lookup(path) == NameTree.Neg)
21 |   }
22 | 
23 |   test("status: no code") {
24 |     val path = Path.read("/$/io.buoyant.http.status")
25 |     assert(lookup(path) == NameTree.Neg)
26 |   }
27 | 
28 | }
29 | 


--------------------------------------------------------------------------------
/router/mux/src/main/scala/io/buoyant/router/MuxEncodeResidual.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router
 2 | 
 3 | import com.twitter.finagle.{Path, Service, ServiceFactory, SimpleFilter, Stack}
 4 | import com.twitter.finagle.buoyant.{Dst, EncodeResidual}
 5 | import com.twitter.finagle.mux.{Request, Response}
 6 | import com.twitter.util._
 7 | 
 8 | object MuxEncodeResidual extends Stack.Module1[Dst.Bound, ServiceFactory[Request, Response]] {
 9 |   val role = EncodeResidual.role
10 |   val description = EncodeResidual.description
11 |   def make(bound: Dst.Bound, factory: ServiceFactory[Request, Response]) =
12 |     new ResidualFilter(bound.path) andThen factory
13 | 
14 |   class ResidualFilter(path: Path) extends SimpleFilter[Request, Response] {
15 |     def apply(req: Request, service: Service[Request, Response]) =
16 |       service(Request(path, req.body))
17 |   }
18 | }
19 | 


--------------------------------------------------------------------------------
/router/thrift-idl/src/main/thrift/ping.thrift:
--------------------------------------------------------------------------------
1 | #@namespace scala io.buoyant.router.thriftscala
2 | 
3 | service PingService {
4 |   string ping(
5 |     1: string msg
6 |   )
7 | }
8 | 


--------------------------------------------------------------------------------
/router/thrift/src/main/scala/io/buoyant/router/thrift/Dest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.router.thrift
 2 | 
 3 | import com.twitter.finagle.Path
 4 | import com.twitter.util.Local
 5 | 
 6 | /** A thread local context for storing the destination of the current request. */
 7 | object Dest {
 8 |   private val l = new Local[Path]
 9 | 
10 |   def local: Path = l().getOrElse(Path.empty)
11 | 
12 |   def local_=(path: Path): Unit = l() = path
13 | }
14 | 


--------------------------------------------------------------------------------
/telemetry/core/src/test/resources/META-INF/services/io.buoyant.telemetry.TelemeterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.telemetry.TestTelemeterInitializer
2 | 


--------------------------------------------------------------------------------
/telemetry/influxdb/src/main/resources/META-INF/services/io.buoyant.telemetry.TelemeterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.telemetry.influxdb.InfluxDbTelemeterInitializer
2 | 


--------------------------------------------------------------------------------
/telemetry/influxdb/src/main/scala/io/buoyant/telemetry/influxdb/InfluxDbTelemeterInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.telemetry.influxdb
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.Stack
 5 | import io.buoyant.telemetry.{MetricsTree, Telemeter, TelemeterConfig, TelemeterInitializer}
 6 | 
 7 | class InfluxDbTelemeterInitializer extends TelemeterInitializer {
 8 |   type Config = InfluxDbConfig
 9 |   val configClass = classOf[InfluxDbConfig]
10 |   override val configId = "io.l5d.influxdb"
11 | }
12 | 
13 | object InfluxDbTelemeterInitializer extends InfluxDbTelemeterInitializer
14 | 
15 | class InfluxDbConfig extends TelemeterConfig {
16 |   @JsonIgnore def mk(params: Stack.Params): Telemeter = new InfluxDbTelemeter(params[MetricsTree])
17 | }
18 | 


--------------------------------------------------------------------------------
/telemetry/influxdb/src/test/scala/io/buoyant/telemetry/influxdb/InfluxDbTelemeterInitializerTest.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.telemetry.influxdb
 2 | 
 3 | import com.twitter.finagle.Stack
 4 | import com.twitter.finagle.util.LoadService
 5 | import io.buoyant.config.Parser
 6 | import io.buoyant.telemetry.{TelemeterConfig, TelemeterInitializer}
 7 | import io.buoyant.test.FunSuite
 8 | 
 9 | class InfluxDbTelemeterInitializerTest extends FunSuite {
10 | 
11 |   test("io.l5d.influxdb telemeter loads") {
12 |     val yaml =
13 |       """|kind: io.l5d.influxdb
14 |          |""".stripMargin
15 | 
16 |     val config = Parser.objectMapper(yaml, Seq(LoadService[TelemeterInitializer]))
17 |       .readValue[TelemeterConfig](yaml)
18 | 
19 |     val telemeter = config.mk(Stack.Params.empty)
20 |     assert(telemeter.isInstanceOf[InfluxDbTelemeter])
21 |     assert(telemeter.stats.isNull)
22 |     assert(telemeter.tracer.isNull)
23 |   }
24 | }
25 | 


--------------------------------------------------------------------------------
/telemetry/prometheus/src/main/resources/META-INF/services/io.buoyant.telemetry.TelemeterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.telemetry.prometheus.PrometheusTelemeterInitializer
2 | 


--------------------------------------------------------------------------------
/telemetry/prometheus/src/main/scala/io/buoyant/telemetry/prometheus/PrometheusTelemeterInitializer.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.telemetry.prometheus
 2 | 
 3 | import com.fasterxml.jackson.annotation.JsonIgnore
 4 | import com.twitter.finagle.Stack
 5 | import io.buoyant.telemetry.{MetricsTree, Telemeter, TelemeterConfig, TelemeterInitializer}
 6 | 
 7 | class PrometheusTelemeterInitializer extends TelemeterInitializer {
 8 |   type Config = PrometheusConfig
 9 |   val configClass = classOf[PrometheusConfig]
10 |   override val configId = "io.l5d.prometheus"
11 | }
12 | 
13 | object PrometheusTelemeterInitializer extends PrometheusTelemeterInitializer
14 | 
15 | class PrometheusConfig(path: Option[String], prefix: Option[String]) extends TelemeterConfig {
16 |   @JsonIgnore def mk(params: Stack.Params): Telemeter =
17 |     new PrometheusTelemeter(
18 |       params[MetricsTree],
19 |       path.getOrElse("/admin/metrics/prometheus"),
20 |       prefix.getOrElse("")
21 |     )
22 | }
23 | 


--------------------------------------------------------------------------------
/telemetry/recent-requests/src/main/resources/META-INF/services/io.buoyant.telemetry.TelemeterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.telemetry.recentRequests.RecentRequestsInitializer
2 | 


--------------------------------------------------------------------------------
/telemetry/recent-requests/src/main/scala/io/buoyant/telemetry/recentRequests/RecentRequestsTelemeter.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.telemetry.recentRequests
 2 | 
 3 | import com.twitter.finagle.stats.NullStatsReceiver
 4 | import io.buoyant.admin.Admin.{Handler, NavItem, WithHandlers, WithNavItems}
 5 | import io.buoyant.telemetry.Telemeter
 6 | 
 7 | class RecentRequestsTelemeter(sampleRate: Double, capacity: Int) extends Telemeter with WithHandlers with WithNavItems {
 8 |   val stats = NullStatsReceiver
 9 |   val tracer = new RecentRequetsTracer(sampleRate, capacity)
10 |   def run() = Telemeter.nopRun
11 | 
12 |   private[this] val handler = new RecentRequestsAdminHandler(tracer)
13 | 
14 |   override def adminHandlers: Seq[Handler] = Seq(Handler("/requests", handler))
15 | 
16 |   override def navItems: Seq[NavItem] = Seq(NavItem("requests", "requests"))
17 | }
18 | 


--------------------------------------------------------------------------------
/telemetry/statsd/src/main/resources/META-INF/services/io.buoyant.telemetry.TelemeterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.telemetry.StatsDInitializer
2 | 


--------------------------------------------------------------------------------
/telemetry/tracelog/src/main/resources/META-INF/services/io.buoyant.telemetry.TelemeterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.telemetry.TracelogInitializer
2 | 


--------------------------------------------------------------------------------
/telemetry/zipkin/src/main/resources/META-INF/services/io.buoyant.telemetry.TelemeterInitializer:
--------------------------------------------------------------------------------
1 | io.buoyant.telemetry.ZipkinInitializer
2 | 


--------------------------------------------------------------------------------
/test-util/src/main/scala/io/buoyant/test/BudgetedRetries.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.test
 2 | 
 3 | import org.scalatest.{Canceled, Failed, Outcome, Retries}
 4 | 
 5 | /**
 6 |  * Mixin trait for tests to support a retry budget.
 7 |  */
 8 | trait BudgetedRetries extends FunSuite with Retries {
 9 | 
10 |   /**
11 |    * The number of retries permitted before a test is failed.
12 |    *
13 |    * Tests that mix in `BudgetedRetries`
14 |    */
15 |   def retries = 4
16 | 
17 |   override def withFixture(test: NoArgTest) =
18 |     if (isRetryable(test)) withRetries(test, retries)
19 |     else super.withFixture(test)
20 | 
21 |   private[this] def withRetries(test: NoArgTest, remaining: Int): Outcome =
22 |     super.withFixture(test) match {
23 |       case Failed(_) | Canceled(_) if remaining == 1 => super.withFixture(test)
24 |       case Failed(_) | Canceled(_) => withRetries(test, remaining - 1)
25 |       case other => other
26 |     }
27 | }
28 | 


--------------------------------------------------------------------------------
/test-util/src/main/scala/io/buoyant/test/Exceptions.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.test
 2 | 
 3 | import org.scalatest.Assertions
 4 | 
 5 | trait Exceptions extends Assertions {
 6 | 
 7 |   // assertThrows is like intercept, but discards the intercepted exception.
 8 |   def assertThrows[T <: AnyRef: Manifest](f: => Any): Unit = {
 9 |     val _ = intercept[T](f)
10 |   }
11 | }
12 | 


--------------------------------------------------------------------------------
/test-util/src/main/scala/io/buoyant/test/FunSuite.scala:
--------------------------------------------------------------------------------
1 | package io.buoyant.test
2 | 
3 | trait FunSuite extends org.scalatest.FunSuite
4 |   with Awaits
5 |   with Exceptions
6 |   with Logging
7 |   with Json
8 | 


--------------------------------------------------------------------------------
/test-util/src/main/scala/io/buoyant/test/Logging.scala:
--------------------------------------------------------------------------------
 1 | package io.buoyant.test
 2 | 
 3 | import com.twitter.logging._
 4 | import com.twitter.util.{Await, Duration, Future, Time, TimeoutException}
 5 | 
 6 | trait Logging { _: org.scalatest.FunSuite =>
 7 | 
 8 |   val log = Logger.get(getClass.getName)
 9 | 
10 |   def setLogLevel(level: Level): Unit =
11 |     Logger.configure(List(LoggerFactory(
12 |       node = "",
13 |       level = Some(level),
14 |       handlers = List(ConsoleHandler())
15 |     )))
16 | 
17 | }
18 | 


--------------------------------------------------------------------------------