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
[]
= "dynamic-config-server"
= "An HTTP configuration server for dynamic-config: one document per application and profile, served under per-caller authorisation."
= true
= true
# Above the workspace floor of 1.71, and the only crate here that is: axum
# 0.8 declares 1.80 and this crate is a server, so there is no version of it
# that does not carry a web framework. Measured, not declared — `cargo +1.79
# check -p dynamic-config-server` fails inside axum-core. The library's floor
# is untouched: nothing depends on this crate.
= "1.80"
= true
= true
= true
= "https://docs.rs/dynamic-config-server"
= true
= ["config", "web-programming::http-server"]
= ["config", "server", "http", "hot-reload", "microservices"]
= true
# The README carries a dependency snippet as well as an install line, because
# the router *is* the API: a service already running axum mounts it rather
# than running the binary. That puts this crate in the roster the two version
# gates walk (`scripts/sync-readme-versions.sh` and
# `doc_surface::the_readmes_agree_on_one_version`), which is where a published
# crate belongs. `dynamic-config-store-core` stays out of it: nothing depends
# on that crate directly, so it has no snippet to keep honest.
[]
# The engine. `watch` for the file watcher (the server never polls), `tokio`
# for `off_thread`, so the diagnostic endpoints re-read sources on the
# blocking pool rather than on a request worker, and `telemetry` for
# `/metrics` — the library's own rendering of the same `ConfigStatus`
# `/status` returns, rather than a second set of numbers kept here. It pulls
# nothing in: an exposition format is a wire encoding, not a crate.
= { = true, = [
"json",
"toml",
"yaml",
"watch",
"async",
"tokio",
"telemetry",
] }
# Default features off: `axum::serve` needs `tokio` and `http1`, JSON
# responses need `json`, and the rest — multipart, ws, form, tracing — is
# surface this server does not expose and would not want in its CVE feed.
= { = "0.8", = false, = [
"http1",
"json",
"tokio",
] }
= { = "1.47", = false, = [
"rt-multi-thread",
"macros",
"net",
"signal",
"time",
] }
# The one trait `Sse` needs — `Stream` — from the crate that defines it.
# Already in the graph beneath axum, which is what makes this a name for
# something that is there rather than a new dependency: no proc macro, no
# executor, no runtime, and nothing to configure.
= { = "0.3.31", = false, = [
"std",
] }
= { = "1.0.221", = ["derive"] }
= "1.0.127"
# --- TLS, behind the `tls` feature ---------------------------------------
#
# Off by default, and that is the honest half of the decision this crate used
# to record as "no TLS at all": a deployment that already has a terminator in
# front keeps exactly the dependency graph it has today, and the ones that
# terminate here opt in. `--features tls` is the switch; a `[server.tls]`
# block in a build without it is a refusal, not a silently ignored key.
#
# `ring` rather than rustls's default `aws-lc-rs`, and no OpenSSL anywhere:
# aws-lc-rs vendors AWS-LC, which is a large C library built with cmake (and
# NASM on Windows), while `ring` is a small amount of C and assembly built
# with `cc` — and, more to the point, `ring` and rustls 0.23 are *already* in
# this workspace's graph through async-nats and the AWS SDK. The feature
# therefore adds no crate to the lockfile that a `--all-features` build did
# not already contain, which is a different and much better trade than the
# one this crate turned down when it recorded "no second TLS stack".
# `0.23.31`, shared across the workspace, and not a preference. Three
# requirements meet here: `aws-lc-rs` as a feature name does not exist before
# 0.23.2, `aws-smithy-http-client` requires `^0.23.31`, and
# `dynamic-config-python-remote` puts every store and the server in one graph.
# `-Z direct-minimal-versions` pins each direct declaration to its *own*
# floor, so any floor below the union's maximum is a contradiction rather
# than a lower bound.
= { = "0.23.31", = false, = [
"ring",
"std",
"tls12",
], = true }
= { = "0.26.2", = false, = [
"ring",
"tls12",
], = true }
# The accept loop is this crate's own (see `src/serve.rs` for why), so it
# names the two pieces `axum::serve` uses internally rather than a second
# server framework: a hyper HTTP/1 connection, and the adapter that hands a
# `Router` to it. Both are already compiled as part of axum's `tokio`
# feature — naming them here adds no crate. The features are chosen by the
# two Cargo features rather than here, because `server` and `client` are
# different halves of the same crate and neither build should compile the
# other's.
= { = "1.7", = false, = true }
# `0.1.16`: the `service` feature this crate turns on arrived in 0.1.2, and
# `aws-smithy-http-client` — in the same graph whenever the Python remote
# wheel is built — requires `^0.1.16`. Under `-Z direct-minimal-versions`
# every direct declaration is pinned to its *own* floor, so a floor below
# what anything else in the union needs is a contradiction rather than a
# preference.
= { = "0.1.16", = false, = true }
# --- the client half, behind the `client` feature -------------------------
#
# The vocabulary for TLS is `dynamic_config_store_core::tls::TlsConfig`, the
# same data-only type all eight store crates take. A third spelling for "a CA
# to trust and a client certificate to present" would be a defect, so this
# crate takes a dependency rather than an opinion. Published one wave ahead
# of this crate in `release.yml`, so the order already works.
= { = true, = true }
# Reading a bounded response body, and an empty request one. Already beneath
# axum; naming it adds no crate.
= { = "0.1.2", = true }
# `1.11.1`: `async-nats` requires it, and `dynamic-config-python-remote`
# puts that crate and this one in one graph — a floor of `^1.10` here pins
# 1.10.0 under `-Z direct-minimal-versions` and contradicts it.
= { = "1.11.1", = true }
# The platform's trust store, for the case store-core defines as "an empty
# `TlsConfig` is not no-TLS, it is the platform's own roots". Already in this
# workspace's lockfile, and it links no OpenSSL: `openssl-probe` finds the
# usual certificate *paths* and reads them, which is what a program without
# an OpenSSL dependency has to do to find what OpenSSL would have found.
= { = "0.8.1", = true }
[]
= []
# TLS termination and mutual TLS. See `book/src/config-server.md`.
= [
"dep:rustls",
"dep:tokio-rustls",
"dep:hyper",
"hyper/http1",
"hyper/server",
"dep:hyper-util",
"hyper-util/service",
"hyper-util/tokio",
"tokio/sync",
]
# The client half: a `RemoteSource` for this server's document endpoint and
# the task that follows its change stream. In this crate rather than a
# companion so the two halves are tested against each other — including the
# one test that matters most, which kills the server and asserts its clients
# keep serving.
= [
"dep:rustls",
"dep:tokio-rustls",
"dep:rustls-native-certs",
"dep:dynamic-config-store-core",
"dep:http-body-util",
"dep:bytes",
"dep:hyper",
"hyper/http1",
"hyper/client",
"dep:hyper-util",
"hyper-util/tokio",
"tokio/io-util",
]
[]
# Drives the real router without a socket: `ServiceExt::oneshot`.
# `0.5.2`: axum 0.8 itself requires `^0.5.2`, and under
# `-Z direct-minimal-versions` this crate's own `^0.5` would pin 0.5.0 and
# contradict it.
= { = "0.5.2", = ["util"] }
= "0.1.2"
# `3.26`: `gix-odb` requires it, and `dynamic-config-python-remote` puts the
# git store in the same graph as everything else. `-Z direct-minimal-versions`
# pins a bare `3` to 3.0.0, which nothing in that union can build against.
= "3.26"
= { = "1.47", = [
"rt-multi-thread",
"macros",
"time",
# The TLS tests and the example write a request and read a response by
# hand: the interesting part is the handshake, and a client library
# between the assertion and the thing asserted is one more thing to
# explain when it fails.
"io-util",
] }
# Certificates are generated by the test that needs them and by the example,
# never checked in: a repository with a private key in it has a private key
# in it, whatever the README says about the key being a test one. `ring`
# again, for the reason above. Pinned in the lockfile to the last 0.14 that
# declares 1.71, so a `cargo +1.80 test` stays possible; the requirement is a
# caret because nothing here needs a newer one.
= { = "0.14", = false, = [
"crypto",
"pem",
"ring",
] }
# The client half of the handshake test: a real TLS client presenting a real
# certificate to a real socket.
= { = "0.26.2", = false, = [
"ring",
"tls12",
] }
[[]]
= "dynamic-config-server"
= "src/main.rs"
[[]]
= "tls_mutual"
= "examples/tls_mutual.rs"
= ["tls"]
[]
= true
= ["--cfg", "docsrs"]