sozu-command-lib 0.15.19

configuration library to command a sozu instance
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
syntax = "proto2";
package command;

// A message received by Sōzu to change its state or query information
message Request {
  oneof request_type {
    // This message tells Sōzu to dump the current proxy state (backends,
    // front domains, certificates, etc) as a list of JSON-serialized Requests,
    // separated by a 0 byte, to a file. This file can be used later
    // to bootstrap the proxy. This message is not forwarded to workers.
    // If the specified path is relative, it will be calculated relative to the current
    // working directory of the proxy.
    string save_state = 1;
    // load a state file, given its path
    string load_state = 2;
    // list the workers and their status
    ListWorkers list_workers = 4;
    // list the frontends, filtered by protocol and/or domain
    FrontendFilters list_frontends = 5;
    // list all listeners
    ListListeners list_listeners = 6;
    // launch a new worker, giving its tag
    string launch_worker = 7;
    // upgrade the main process
    UpgradeMain upgrade_main = 8;
    // upgrade an existing worker, giving its id
    uint32 upgrade_worker = 9;
    // subscribe to proxy events
    SubscribeEvents subscribe_events = 10;
    // reload the configuration from the config file, or a new file
    // CHECK: this used to be an option. None => use the config file, Some(string) => path_to_file
    // make sure it works using "" and "path_to_file"
    string reload_configuration = 11;
    // give status of main process and all workers
    Status status = 12;
    // add a cluster
    Cluster add_cluster = 13;
    // remove a cluster giving its id
    string remove_cluster = 14;
    // add an HTTP frontend
    RequestHttpFrontend add_http_frontend = 15;
    // remove an HTTP frontend
    RequestHttpFrontend remove_http_frontend = 16;
    // add an HTTPS frontend
    RequestHttpFrontend add_https_frontend = 17;
    // remove an HTTPS frontend
    RequestHttpFrontend remove_https_frontend = 18;
    // add a certificate
    AddCertificate add_certificate = 19;
    // replace a certificate
    ReplaceCertificate replace_certificate = 20;
    // remove a certificate
    RemoveCertificate remove_certificate = 21;
    // add a TCP frontend
    RequestTcpFrontend add_tcp_frontend = 22;
    // remove a TCP frontend
    RequestTcpFrontend remove_tcp_frontend = 23;
    // add a backend
    AddBackend add_backend = 24;
    // remove a backend
    RemoveBackend remove_backend = 25;
    // add an HTTP listener
    HttpListenerConfig add_http_listener = 26;
    // add an HTTPS listener
    HttpsListenerConfig add_https_listener = 27;
    // add a TCP listener
    TcpListenerConfig add_tcp_listener = 28;
    // remove a listener
    RemoveListener remove_listener = 29;
    // activate a listener
    ActivateListener activate_listener = 30;
    // deactivate a listener
    DeactivateListener deactivate_listener = 31;
    // query a cluster by id
    string query_cluster_by_id = 35;
    // query clusters with a hostname and optional path
    QueryClusterByDomain query_clusters_by_domain = 36;
    // query clusters hashes
    QueryClustersHashes query_clusters_hashes = 37;
    // query metrics
    QueryMetricsOptions query_metrics = 38;
    // soft stop
    SoftStop soft_stop = 39;
    // hard stop
    HardStop hard_stop = 40;
    // enable, disable or clear the metrics 
    MetricsConfiguration configure_metrics = 41;
    // Change the logging level
    string Logging = 42;
    // Return the listen sockets
    ReturnListenSockets return_listen_sockets = 43;
    // Get certificates from the state (rather than from the workers)
    QueryCertificatesFilters query_certificates_from_the_state = 44;
    // Get certificates from the workers (rather than from the state)
    QueryCertificatesFilters query_certificates_from_workers = 45;
    // query the state about how many requests of each type has been received
    // since startup
    CountRequests count_requests = 46;
  }
}

message ListWorkers {}
message ListListeners {}
message UpgradeMain {}
message SubscribeEvents {}
message Status {}
message QueryClustersHashes {}
message SoftStop {}
message HardStop {}
message ReturnListenSockets {}
message CountRequests {}

// details of an HTTP listener
message HttpListenerConfig {
    required string address = 1;
    optional string public_address = 2;
    required string answer_404 = 3;
    required string answer_503 = 4;
    required bool expect_proxy = 5 [default = false];
    required string sticky_name = 6;
    // client inactive time, in seconds
    required uint32 front_timeout = 7 [default = 60];
    // backend server inactive time, in seconds
    required uint32 back_timeout = 8 [default = 30];
    // time to connect to the backend, in seconds
    required uint32 connect_timeout = 9 [default = 3];
    // max time to send a complete request, in seconds
    required uint32 request_timeout = 10 [default = 10];
    // wether the listener is actively listening on its socket
    required bool active = 11 [default = false];
}

// details of an HTTPS listener
message HttpsListenerConfig {
    required string address = 1;
    optional string public_address = 2;
    required string answer_404 = 3;
    required string answer_503 = 4;
    required bool expect_proxy = 5 [default = false];
    required string sticky_name = 6;
    // client inactive time, in seconds
    required uint32 front_timeout = 7 [default = 60];
    // backend server inactive time, in seconds
    required uint32 back_timeout = 8 [default = 30];
    // time to connect to the backend, in seconds
    required uint32 connect_timeout = 9 [default = 3];
    // max time to send a complete request, in seconds
    required uint32 request_timeout = 10 [default = 10];
    // wether the listener is actively listening on its socket
    required bool active = 11 [default = false];
    // TLS versions
    repeated TlsVersion versions = 12;
    repeated string cipher_list = 13;
    repeated string cipher_suites = 14;
    repeated string signature_algorithms = 15;
    repeated string groups_list = 16;
    optional string certificate = 17;
    repeated string certificate_chain = 18;
    optional string key = 19;
    // Number of TLS 1.3 tickets to send to a client when establishing a connection.
    // The tickets allow the client to resume a session. This protects the client
    // agains session tracking. Defaults to 4.
    required uint64 send_tls13_tickets = 20;
}

// details of an TCP listener
message TcpListenerConfig {
    required string address = 1;
    optional string public_address = 2;
    required bool expect_proxy = 3 [default = false];
    // client inactive time, in seconds
    required uint32 front_timeout = 4 [default = 60];
    // backend server inactive time, in seconds
    required uint32 back_timeout = 5 [default = 30];
    // time to connect to the backend, in seconds
    required uint32 connect_timeout = 6 [default = 3];
    // wether the listener is actively listening on its socket
    required bool active = 7 [default = false];
}

message ActivateListener {
    required string address = 1;
    required ListenerType proxy = 2;
    required bool from_scm = 3;
}

message DeactivateListener {
    required string address = 1;
    required ListenerType proxy = 2;
    required bool to_scm = 3;
}

message RemoveListener {
    required string address = 1;
    required ListenerType proxy = 2;
}

enum ListenerType {
    HTTP = 0;
    HTTPS = 1;
    TCP = 2;
}

// All listeners, listed
message ListenersList {
    // address -> http listener config
    map<string, HttpListenerConfig> http_listeners = 1;
    // address -> https listener config
    map<string, HttpsListenerConfig> https_listeners = 2;
    // address -> tcp listener config
    map<string, TcpListenerConfig> tcp_listeners = 3;
}

// An HTTP or HTTPS frontend, as order to, or received from, Sōzu
message RequestHttpFrontend {
    optional string cluster_id = 1;
    required string address = 2;
    required string hostname = 3;
    required PathRule path = 4;
    optional string method = 5;
    required RulePosition position = 6 [default = TREE];
    // custom tags to identify the frontend in the access logs
    map<string, string> tags = 7;
}

message RequestTcpFrontend {
    required string cluster_id = 1;
    // the socket address on which to listen for incoming traffic
    required string address = 2;
    // custom tags to identify the frontend in the access logs
    map<string, string> tags = 3;
}

// list the frontends, filtered by protocol and/or domain
message FrontendFilters {
    required bool http = 1;
    required bool https = 2;
    required bool tcp = 3;
    optional string domain = 4;
}

// A filter for the path of incoming requests
message PathRule {
    // The kind of filter used for path rules
    required PathRuleKind kind = 1;
    // the value of the given prefix, regex or equal pathrule
    required string value = 2;
}

// The kind of filter used for path rules
enum PathRuleKind {
    // filters paths that start with a pattern, typically "/api"
    PREFIX = 0;
    // filters paths that match a regex pattern
    REGEX = 1;
    // filters paths that exactly match a pattern, no more, no less
    EQUALS = 2;
}

// TODO: find a proper definition for this
enum RulePosition {
    PRE = 0;
    POST = 1;
    TREE = 2;
}

// Add a new TLS certificate to an HTTPs listener
message AddCertificate {
    required string address = 1;
    required CertificateAndKey certificate = 2;
    // A unix timestamp. Overrides certificate expiration.
    optional int64 expired_at = 3;
}

message RemoveCertificate {
    required string address = 1;
    // a hex-encoded TLS fingerprint to identify the certificate to remove
    required string fingerprint = 2;
}

message ReplaceCertificate {
    required string address = 1;
    required CertificateAndKey new_certificate = 2;
    // a hex-encoded TLS fingerprint to identify the old certificate
    required string old_fingerprint = 3;
    // A unix timestamp. Overrides certificate expiration.
    optional int64 new_expired_at = 4;
}

message CertificateAndKey {
    required string certificate = 1;
    repeated string certificate_chain = 2;
    required string key = 3;
    repeated TlsVersion versions = 4;
    // hostnames linked to the certificate
    repeated string names = 5;
}

// Should be either a domain name or a fingerprint.
// These filter do not compound, use either one but not both.
// If none of them is specified, all certificates will be returned.
message QueryCertificatesFilters {
    // a domain name to filter certificate results
    optional string domain = 1;
    // a hex-encoded fingerprint of the TLS certificate to find
    optional string fingerprint = 2;
}

// domain name and fingerprint of a certificate
message CertificateSummary {
    required string domain = 1;
    // a hex-encoded TLS fingerprint
    required string fingerprint = 2;
}

// Used by workers to reply to some certificate queries
message ListOfCertificatesByAddress {
    repeated CertificatesByAddress certificates = 1;
}

// Summaries of certificates for a given address
message CertificatesByAddress {
    required string address = 1;
    repeated CertificateSummary certificate_summaries = 2;
}

// to reply to several certificate queries
message CertificatesWithFingerprints {
    // a map of fingerprint -> certificate_and_key
    map<string, CertificateAndKey> certs = 1;
}

enum TlsVersion {
    SSL_V2 = 0;
    SSL_V3 = 1;
    TLS_V1_0 = 2;
    TLS_V1_1 = 3;
    TLS_V1_2 = 4;
    TLS_V1_3 = 5;
}

// A cluster is what binds a frontend to backends with routing rules
message Cluster {
    required string cluster_id = 1;
    // wether a connection from a client shall be always redirected to the same backend
    required bool sticky_session = 2;
    required bool https_redirect = 3;
    optional ProxyProtocolConfig proxy_protocol = 4;
    required LoadBalancingAlgorithms load_balancing = 5 [default = ROUND_ROBIN];
    optional string answer_503 = 6;
    optional LoadMetric load_metric = 7;
}

enum LoadBalancingAlgorithms {
    ROUND_ROBIN = 0;
    RANDOM = 1;
    LEAST_LOADED = 2;
    POWER_OF_TWO = 3;
}

enum ProxyProtocolConfig {
    EXPECT_HEADER = 0;
    SEND_HEADER = 1;
    RELAY_HEADER = 2;
}

// how sozu measures which backend is less loaded
enum LoadMetric {
    // number of TCP connections
    CONNECTIONS = 0;
    // number of active HTTP requests
    REQUESTS = 1;
    // time to connect to the backend, weighted by the number of active connections (peak EWMA)
    CONNECTION_TIME = 2;
}

// add a backend
message AddBackend {
    required string cluster_id = 1;
    required string backend_id = 2;
    // the socket address of the backend
    required string address = 3;
    optional string sticky_id = 4;
    optional LoadBalancingParams load_balancing_parameters = 5;
    optional bool backup = 6;
}

// remove an existing backend
message RemoveBackend {
    required string cluster_id = 1;
    required string backend_id = 2;
    // the socket address of the backend
    required string address = 3 ;
}

message LoadBalancingParams {
    required int32 weight = 1;
}

message QueryClusterByDomain {
    required string hostname = 1;
    optional string path = 2;
}

// Options when querying metrics
message QueryMetricsOptions {
    // query a list of available metrics
    required bool list = 1;
    // query metrics for these clusters
    repeated string cluster_ids = 2;
    // query metrics for these backends
    repeated string backend_ids = 3;
    // query only these metrics
    repeated string metric_names = 4;
    // query only worker and main process metrics (no cluster metrics)
    required bool no_clusters = 5;
}

// options to configure metrics collection
enum MetricsConfiguration {
    // enable metrics collection
    ENABLED = 0;
    // disable metrics collection
    DISABLED = 1;
    // wipe the metrics memory
    CLEAR = 2;
}

// Response to a request
message Response {
    // wether the request was a success, a failure, or is processing
    required ResponseStatus status = 1 [default = FAILURE];
    // a success or error message
    required string message = 2;
    // response data, if any
    optional ResponseContent content = 3;
}


// content of a response
message ResponseContent {
    oneof content_type {
        // a list of workers, with ids, pids, statuses
        WorkerInfos workers = 1;
        // aggregated metrics of main process and workers
        AggregatedMetrics metrics = 2;
        // a collection of worker responses to the same request
        WorkerResponses worker_responses = 3;
        // a proxy event
        Event event = 4;
        // a filtered list of frontend
        ListedFrontends frontend_list = 5;
        // all listeners
        ListenersList listeners_list = 6;
        // contains proxy & cluster metrics
        WorkerMetrics worker_metrics = 7;
        // Lists of metrics that are available
        AvailableMetrics available_metrics = 8;
        // a list of cluster informations
        ClusterInformations clusters = 9;
        // collection of hashes of cluster information, 
        ClusterHashes cluster_hashes = 10;
        // a list of certificates summaries, grouped by socket address
        ListOfCertificatesByAddress certificates_by_address = 11;
        // a map of complete certificates using fingerprints as key
        CertificatesWithFingerprints certificates_with_fingerprints = 12;
        // a census of the types of requests received since startup,
        RequestCounts request_counts = 13;
    }
}

// a map of worker_id -> ResponseContent
message WorkerResponses {
    map<string, ResponseContent> map = 1;
}

// lists of frontends present in the state
message ListedFrontends {
    repeated RequestHttpFrontend http_frontends = 1;
    repeated RequestHttpFrontend https_frontends = 2;
    repeated RequestTcpFrontend tcp_frontends = 3;
}

message ClusterInformations {
    repeated ClusterInformation vec = 1;
}

// Information about a given cluster
// Contains types usually used in requests, because they are readily available in protobuf
message ClusterInformation {
    optional Cluster configuration = 1;
    repeated RequestHttpFrontend http_frontends = 2;
    repeated RequestHttpFrontend https_frontends = 3;
    repeated RequestTcpFrontend tcp_frontends = 4;
    repeated AddBackend backends = 5;
}

message Event {
    required EventKind kind = 1;
    optional string cluster_id = 2;
    optional string backend_id = 3;
    optional string address = 4;
}

enum EventKind {
    BACKEND_DOWN = 0;
    BACKEND_UP = 1;
    NO_AVAILABLE_BACKENDS = 2;
    REMOVED_BACKEND_HAS_NO_CONNECTIONS = 3;
}

message ClusterHashes {
    // cluster id -> hash of cluster information
    map<string, uint64> map = 1;
}

enum ResponseStatus {
    OK = 0;
    PROCESSING = 1;
    FAILURE = 2;
}

// A list of worker infos
message WorkerInfos {
    repeated WorkerInfo vec = 1;
}

// Information about a worker with id, pid, runstate
message WorkerInfo {
    required uint32 id = 1;
    required int32 pid = 2;
    required RunState run_state = 3;
}

// Runstate of a worker
enum RunState {
    RUNNING = 0;
    STOPPING = 1;
    STOPPED = 2;
    NOT_ANSWERING = 3;
}

// lists of available metrics in a worker, or in the main process (in which case there are no cluster metrics)
message AvailableMetrics {
    repeated string proxy_metrics = 1;
    repeated string cluster_metrics = 2;
}

// Aggregated metrics of main process & workers
message AggregatedMetrics {
    map<string, FilteredMetrics> main = 1;
    map<string, WorkerMetrics> workers = 2;
}

// All metrics of a worker: proxy and clusters
// Populated by Options so partial results can be sent
message WorkerMetrics {
   // Metrics of the worker process, key -> value
    map<string, FilteredMetrics> proxy = 1;
    // cluster_id -> cluster_metrics
    map<string, ClusterMetrics> clusters = 2;
}

// the metrics of a given cluster, with several backends
message ClusterMetrics {
    // metric name -> metric value
    map<string, FilteredMetrics> cluster = 1;
    // backend_id -> (metric name-> metric value)
    repeated BackendMetrics backends = 2;
}

message BackendMetrics {
    required string backend_id = 1;
    map<string, FilteredMetrics> metrics = 2;
}

message FilteredMetrics {
    oneof inner {
        uint64 gauge = 1;
        int64 count = 2;
        uint64 time = 3;
        Percentiles percentiles = 4;
        FilteredTimeSerie time_serie = 5;
    }
}

message FilteredTimeSerie {
    required uint32 last_second = 1;
    repeated uint32 last_minute = 2;
    repeated uint32 last_hour = 3;
}


message Percentiles {
    required uint64 samples = 1;
    required uint64 p_50 = 2;
    required uint64 p_90 = 3;
    required uint64 p_99 = 4;
    required uint64 p_99_9 = 5;
    required uint64 p_99_99 = 6;
    required uint64 p_99_999 = 7;
    required uint64 p_100 = 8;
}

message RequestCounts {
    map<string, int32> map = 1;
}