1
#pragma once
2

            
3
#include "envoy/common/pure.h"
4
#include "envoy/config/tap/v3/common.pb.h"
5
#include "envoy/data/tap/v3/wrapper.pb.h"
6
#include "envoy/extensions/filters/http/tap/v3/tap.pb.h"
7
#include "envoy/http/header_map.h"
8

            
9
#include "source/extensions/common/matcher/matcher.h"
10

            
11
#include "absl/strings/string_view.h"
12

            
13
namespace Envoy {
14
namespace Extensions {
15
namespace Common {
16
namespace Tap {
17

            
18
using Matcher = Envoy::Extensions::Common::Matcher::Matcher;
19

            
20
using TraceWrapperPtr = std::unique_ptr<envoy::data::tap::v3::TraceWrapper>;
21
124
inline TraceWrapperPtr makeTraceWrapper() {
22
124
  return std::make_unique<envoy::data::tap::v3::TraceWrapper>();
23
124
}
24

            
25
/**
26
 * A handle for a per-tap sink. This allows submitting either a single buffered trace, or a series
27
 * of trace segments that the sink can aggregate in whatever way it chooses.
28
 */
29
class PerTapSinkHandle {
30
public:
31
59
  virtual ~PerTapSinkHandle() = default;
32

            
33
  /**
34
   * Send a trace wrapper to the sink. This may be a fully buffered trace or a segment of a larger
35
   * trace depending on the contents of the wrapper.
36
   * @param trace supplies the trace to send.
37
   * @param format supplies the output format to use.
38
   */
39
  virtual void submitTrace(TraceWrapperPtr&& trace,
40
                           envoy::config::tap::v3::OutputSink::Format format) PURE;
41
};
42

            
43
using PerTapSinkHandlePtr = std::unique_ptr<PerTapSinkHandle>;
44

            
45
/**
46
 * Wraps potentially multiple PerTapSinkHandle instances and any common pre-submit functionality.
47
 * Each active tap will have a reference to one of these, which in turn may have references to
48
 * one or more PerTapSinkHandle.
49
 */
50
class PerTapSinkHandleManager {
51
public:
52
70
  virtual ~PerTapSinkHandleManager() = default;
53

            
54
  /**
55
   * Submit a buffered or streamed trace segment to all managed per-tap sink handles.
56
   */
57
  virtual void submitTrace(TraceWrapperPtr&& trace) PURE;
58
};
59

            
60
using PerTapSinkHandleManagerPtr = std::unique_ptr<PerTapSinkHandleManager>;
61

            
62
/**
63
 * Sink for sending tap messages.
64
 */
65
class Sink {
66
public:
67
43
  virtual ~Sink() = default;
68

            
69
  /**
70
   * Create a per tap sink handle for use in submitting either buffered traces or trace segments.
71
   * @param trace_id supplies a locally unique trace ID. Some sinks use this for output generation.
72
   * @param type     Indicates the type of Sink specified in request body
73
   */
74
  virtual PerTapSinkHandlePtr
75
  createPerTapSinkHandle(uint64_t trace_id,
76
                         envoy::config::tap::v3::OutputSink::OutputSinkTypeCase type) PURE;
77
};
78

            
79
using SinkPtr = std::unique_ptr<Sink>;
80

            
81
/**
82
 * Abstract tap sink factory. Produces a factory that can instantiate SinkPtr objects
83
 */
84
class TapSinkFactory : public Config::TypedFactory {
85
public:
86
4
  ~TapSinkFactory() override = default;
87
4
  std::string category() const override { return "envoy.tap.sinks"; }
88

            
89
  /**
90
   * Create a Sink that can be used for writing out data produced by the tap filter.
91
   * @param config supplies the protobuf configuration for the sink factory
92
   * @param  http_context supplies HTTP context
93
   */
94
  virtual SinkPtr createSinkPtr(const Protobuf::Message& config,
95
                                Server::Configuration::GenericFactoryContext& http_context) PURE;
96
};
97

            
98
using TapSinkFactoryPtr = std::unique_ptr<TapSinkFactory>;
99

            
100
/**
101
 * Generic configuration for a tap extension (filter, transport socket, etc.).
102
 */
103
class ExtensionConfig {
104
public:
105
42
  virtual ~ExtensionConfig() = default;
106

            
107
  /**
108
   * @return the ID to use for admin extension configuration tracking (if applicable).
109
   */
110
  virtual const absl::string_view adminId() PURE;
111

            
112
  /**
113
   * Clear any active tap configuration.
114
   */
115
  virtual void clearTapConfig() PURE;
116

            
117
  /**
118
   * Install a new tap configuration.
119
   * @param proto_config supplies the generic tap config to install. Not all configuration fields
120
   *        may be applicable to an extension (e.g. HTTP fields). The extension is free to fail
121
   *        the configuration load via exception if it wishes.
122
   * @param admin_streamer supplies the singleton admin sink to use for output if the configuration
123
   *        specifies that output type. May not be used if the configuration does not specify
124
   *        admin output. May be nullptr if admin is not used to supply the config.
125
   */
126
  virtual void newTapConfig(const envoy::config::tap::v3::TapConfig& proto_config,
127
                            Sink* admin_streamer) PURE;
128
};
129

            
130
/**
131
 * Abstract tap configuration base class.
132
 */
133
class TapConfig {
134
public:
135
57
  virtual ~TapConfig() = default;
136

            
137
  /**
138
   * Return a per-tap sink handle manager for use by a tap session.
139
   * @param trace_id supplies a locally unique trace ID. Some sinks use this for output generation.
140
   */
141
  virtual PerTapSinkHandleManagerPtr createPerTapSinkHandleManager(uint64_t trace_id) PURE;
142

            
143
  /**
144
   * Return the maximum received bytes that can be buffered in memory. Streaming taps are still
145
   * subject to this limit depending on match status.
146
   */
147
  virtual uint32_t maxBufferedRxBytes() const PURE;
148

            
149
  /**
150
   * Return the maximum transmitted bytes that can be buffered in memory. Streaming taps are still
151
   * subject to this limit depending on match status.
152
   */
153
  virtual uint32_t maxBufferedTxBytes() const PURE;
154

            
155
  /**
156
   * Return the minimum transmitted bytes that can be buffered in memory. Streaming taps are still
157
   * subject to this limit depending on match status.
158
   */
159
  virtual uint32_t minStreamedSentBytes() const PURE;
160

            
161
  /**
162
   * Return a new match status vector that is correctly sized for the number of matchers that are in
163
   * the configuration.
164
   */
165
  virtual Matcher::MatchStatusVector createMatchStatusVector() const PURE;
166

            
167
  /**
168
   * Return the root matcher for use in updating a match status vector.
169
   */
170
  virtual const Matcher& rootMatcher() const PURE;
171

            
172
  /**
173
   * Non-const version of rootMatcher method.
174
   */
175
436
  Matcher& rootMatcher() {
176
436
    return const_cast<Matcher&>(static_cast<const TapConfig&>(*this).rootMatcher());
177
436
  }
178

            
179
  /**
180
   * Return whether the tap session should run in streaming or buffering mode.
181
   */
182
  virtual bool streaming() const PURE;
183
};
184

            
185
using TapConfigSharedPtr = std::shared_ptr<TapConfig>;
186

            
187
/**
188
 * Abstract tap configuration factory. Given a new generic tap configuration, produces an
189
 * extension specific tap configuration.
190
 */
191
class TapConfigFactory {
192
public:
193
36
  virtual ~TapConfigFactory() = default;
194

            
195
  /**
196
   * @return a new configuration given a raw tap service config proto. See
197
   * ExtensionConfig::newTapConfig() for param info.
198
   */
199
  virtual TapConfigSharedPtr
200
  createConfigFromProto(const envoy::config::tap::v3::TapConfig& proto_config,
201
                        Sink* admin_streamer) PURE;
202
};
203

            
204
using TapConfigFactoryPtr = std::unique_ptr<TapConfigFactory>;
205

            
206
} // namespace Tap
207
} // namespace Common
208
} // namespace Extensions
209
} // namespace Envoy