-
Notifications
You must be signed in to change notification settings - Fork 42
/
Copy pathapi-manifest.toml
573 lines (515 loc) · 19.6 KB
/
api-manifest.toml
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
# Describes all the Dropshot/OpenAPI/Progenitor APIs in the system
#
# See README.adoc in this package for details.
#
# TODO It would be nice to collect a bunch of this information from the same
# sources that drive the actual build process (e.g., package-manifest.toml).
# For non-Omicron components, the deployment units (zone images and tarballs
# that get unpacked into the switch zone or global zone) come from buildomat
# jobs on other repositories. In at least some components those come from those
# components' package-manifest.toml files, which we probably have available, so
# we could still incorporate that information.
#
# TODO The following items from package-manifest.toml are currently ignored
# because they are assumed not to contain servers or clients that we care about:
#
# - faux_mgs
# - crucible_dtrace
# - mg-ddm
#
# The following were at one point included here, but do not appear to contain
# Progenitor clients or APIs, so they're left out to avoid needing to create and
# process clones of these repos:
#
# - pumpkind
# - thundermuffin
#
# If we do wind up processing package-manifest.toml, we may want to maintain an
# explicit list of items that we ignore so that we can fail when something is
# neither included nor ignored so that we can be sure we're not missing
# anything.
#
# TODO The metadata here overlaps with metadata hardcoded in `openapi-manager`.
################################################################################
# Ignored non-client packages
#
# These are packages that may be flagged as clients because they directly depend
# on Progenitor, but which are not really clients.
#
# These are cases that cannot be easily handled by the evaluation rules later in
# this file because they need to be processed earlier.
################################################################################
ignored_non_clients = [
# omicron-common depends on progenitor so that it can define some generic
# error handling and a generic macro for defining clients. omicron-common
# itself is not a progenitor-based client.
"omicron-common",
# propolis-mock-server uses Progenitor to generate types that are
# compatible with the real Propolis server. It doesn't actually use the
# client and we don't really care about it for these purposes anyway.
"propolis-mock-server",
]
################################################################################
# Deployment Units
#
# A deployment unit is a set of Rust packages that are always deployed together.
# This is particularly relevant for upgrade because we'll want to construct a
# DAG describing the order in which we update components. It's possible that we
# could have a DAG among the Rust packages that get deployed but there may
# still be cycles within the deployment unit dependency graph.
################################################################################
# The host OS includes Sled Agent, Propolis, and all the components that get
# bundled into the switch zone.
[[deployment_units]]
label = "Host OS"
packages = [
"omicron-sled-agent",
"propolis-server",
# switch zone
"ddmd",
"dpd",
"lldpd",
"mgd",
"omicron-gateway",
"tfportd",
"wicketd",
]
# Installinator gets packaged into its own host OS image.
[[deployment_units]]
label = "Installinator"
packages = [ "installinator" ]
# The rest of these get bundled by standard control plane zone images.
[[deployment_units]]
label = "Crucible"
packages = [ "crucible-agent", "crucible-downstairs" ]
[[deployment_units]]
label = "Crucible Pantry"
packages = [ "crucible-pantry" ]
[[deployment_units]]
label = "Cockroach"
packages = [ "omicron-cockroach-admin" ]
# These are really three distinct deployment units, but they behave the same for
# our purposes, and the tooling doesn't support multiple deployment units
# that each expose a particular service.
[[deployment_units]]
label = "Clickhouse (single-node) / Clickhouse Server (multi-node) / Clickhouse Keeper (multi-node)"
packages = [ "omicron-clickhouse-admin" ]
[[deployment_units]]
label = "DNS Server"
packages = [ "dns-server" ]
[[deployment_units]]
label = "Nexus"
packages = [ "omicron-nexus" ]
[[deployment_units]]
label = "Oximeter"
packages = [ "oximeter-collector" ]
################################################################################
# APIs
#
# Each API includes:
#
# `client_package_name`: the name of the Rust package that's a
# Progenitor-based client for this API. This is used as a primary key for the
# API.
#
# `label`: a human-readable name for this API
#
# `server_package_name`: the package that contains the Dropshot API definition.
#
# `versioned_how`: one of:
#
# "server": this component uses server-side versioning only, meaning that the
# update system can ensure that servers are always updated before
# clients.
#
# "client": this component uses client-side versioning, meaning that the
# update system cannot ensure that servers are always updated
# before clients, so clients need to deal with multiple different
# server versions.
#
# You must also specify `versioned_how_reason` if you use "client".
#
# "unknown": this has not been determined. This will break tests. But the
# tooling supports this value so that during development you can
# relax these constraints.
#
# [`versioned_how_reason`]: free text string explaining why `versioned_how` must
# be "client" for this API. This is printed in documentation and command output
# and serves as documentation for developers to understand why we made this
# choice. This should be present only if `versioned_how = "client"`.
#
# [`notes`]: optional free-form human-readable summary documentation about this
# API
################################################################################
[[apis]]
client_package_name = "bootstrap-agent-client"
label = "Bootstrap Agent"
server_package_name = "bootstrap-agent-api"
versioned_how = "client"
versioned_how_reason = "depends on itself (i.e., instances call each other)"
[[apis]]
client_package_name = "clickhouse-admin-keeper-client"
label = "Clickhouse Cluster Admin for Keepers"
server_package_name = "clickhouse-admin-api"
versioned_how = "server"
notes = """
This is the server running inside multi-node Clickhouse keeper zones that's \
responsible for local configuration and monitoring.
"""
[[apis]]
client_package_name = "clickhouse-admin-server-client"
label = "Clickhouse Cluster Admin for Servers"
server_package_name = "clickhouse-admin-api"
versioned_how = "server"
notes = """
This is the server running inside multi-node Clickhouse server zones that's \
responsible for local configuration and monitoring.
"""
[[apis]]
client_package_name = "clickhouse-admin-single-client"
label = "Clickhouse Single-Node Cluster Admin"
server_package_name = "clickhouse-admin-api"
versioned_how = "server"
notes = """
This is the server running inside single-node Clickhouse server zones that's \
responsible for local configuration and monitoring.
"""
[[apis]]
client_package_name = "cockroach-admin-client"
label = "CockroachDB Cluster Admin"
server_package_name = "cockroach-admin-api"
versioned_how = "server"
notes = """
This is the server running inside CockroachDB zones that performs \
configuration and monitoring that requires the `cockroach` CLI.
"""
[[apis]]
client_package_name = "crucible-agent-client"
label = "Crucible Agent"
server_package_name = "crucible-agent"
versioned_how = "server"
[[apis]]
client_package_name = "repair-client"
label = "Crucible Repair"
server_package_name = "crucible-downstairs"
versioned_how = "client"
versioned_how_reason = "depends on itself (i.e., instances call each other)"
notes = """
The repair service offered by a crucible-downstairs supports both repairing \
one downstairs from another, and making a clone of a read-only downstairs \
when creating a new region in the crucible agent.
"""
[[apis]]
client_package_name = "crucible-pantry-client"
label = "Crucible Pantry"
server_package_name = "crucible-pantry"
versioned_how = "server"
[[apis]]
client_package_name = "ddm-admin-client"
label = "Maghemite DDM Admin"
server_package_name = "ddmd"
versioned_how = "server"
notes = """
The `ddmd` server runs in each sled GZ and each switch zone. These daemons \
provide an interface for advertising network prefixes, and observing what \
prefixes have been received from other DDM daemons in the rack. Sled agent \
uses this interface to announce bootstrap and underlay network prefixes, as \
well as learn about routes to other sleds and services in the rack. This \
interface is required in early-networking before a rack is fully up with Nexus \
running. Nexus does not consume this interface today, but will for \
observability APIs in the future.
"""
[[apis]]
client_package_name = "dns-service-client"
label = "DNS Server"
server_package_name = "dns-server-api"
versioned_how = "server"
[[apis]]
client_package_name = "dpd-client"
label = "Dendrite DPD"
server_package_name = "dpd"
# TODO We might need to pick this apart more carefully. DPD invokes and is
# invoked by several different services. It's possible that some of them can
# treat it as server-managed.
versioned_how = "client"
versioned_how_reason = "Sled Agent calling DPD creates a circular dependency"
notes = """
Dendrite's data plane daemon (`dpd`) is the interface to configure and manage \
the rack switches. It's consumed by sled-agent to get the rack off the \
ground. The dpd API is also used by nexus as operators make changes to the \
rack external network configuration, these changes are synchronized by nexus \
to `dpd`. The `dpd` API is a auto-generated from it's OpenAPI specification \
and exists as a client library within omicron. This is because the Dendrite \
repo is not currently open source.
"""
[[apis]]
client_package_name = "ereporter-client"
label = "Ereporter"
server_package_name = "ereporter-api"
versioned_how = "server"
notes = """
Implemented by sled-agents and by MGS, and consumed by Nexus to collect \
ereports.
The sled-agent and MGS APIs are server-versioned, so this can be as well.
"""
[[apis]]
client_package_name = "lldpd-client"
label = "LLDP daemon"
server_package_name = "lldpd"
versioned_how = "server"
notes = "The LLDP daemon runs in the switch zone and is deployed next to dpd."
[[apis]]
client_package_name = "gateway-client"
label = "Management Gateway Service"
server_package_name = "gateway-api"
versioned_how = "server"
notes = "Wicketd is deployed in a unit with MGS so we can ignore that one."
[[apis]]
client_package_name = "installinator-client"
label = "Wicketd Installinator"
server_package_name = "installinator-api"
# The installinator-client is used only by Installinator. This is part of the
# recovery OS image. Today, this is not really "shipped" in the traditional
# sense. The only way it gets used today is by an operator uploading it to
# Wicket and then performing a MUPdate. In this sense, we do not control the
# client, so we mark this client-managed -- it's up to the operator to make sure
# they're using a TUF repo whose recovery image contains an Installinator that's
# compatible with the API served by Wicket on the deployed system. In practice,
# we're almost certainly just going to avoid changing this API.
versioned_how = "client"
versioned_how_reason = "client is provided implicitly by the operator"
[[apis]]
client_package_name = "mg-admin-client"
label = "Maghemite MG Admin"
server_package_name = "mgd"
versioned_how = "server"
notes = """
The `mgd` daemon runs in each switch zone. This daemon is responsible for all \
external route management for a switch. It provides interfaces for static \
route management, BGP configuration and BFD configuration. This interface is \
consumed by both nexus and sled agent, since we need external connectivity to \
bring the rack up.
"""
[[apis]]
client_package_name = "nexus-client"
label = "Nexus Internal API"
server_package_name = "nexus-internal-api"
# nexus-client has to be client-versioned today because it's got a cyclic
# dependency with sled-agent-client, which is server-versioned.
versioned_how = "client"
versioned_how_reason = "Circular dependencies between Nexus and other services"
[[apis]]
client_package_name = "oxide-client"
label = "External API"
server_package_name = "nexus-external-api"
# The versioning strategy for the external API is outside the scope of this
# tool. It doesn't matter what we put here.
versioned_how = "server"
notes = "Special case, since we don't fully control all clients"
[[apis]]
client_package_name = "oximeter-client"
label = "Oximeter"
server_package_name = "oximeter-api"
versioned_how = "server"
notes = """
Shared types for this interface are in `omicron-common`. The producer makes \
requests to Nexus, and receives them from `oximeter-collector`. \
`oximeter-collector` makes requests to Nexus and the producer, and receives \
them from Nexus (for periodic renewals). Nexus receives requests from both, \
and makes the periodic renewal requests to `oximeter-collector`.
"""
[[apis]]
client_package_name = "propolis-client"
label = "Propolis"
server_package_name = "propolis-server"
versioned_how = "server"
notes = """
Sled Agent is deployed in a unit with Propolis so we can ignore that one.
"""
[[apis]]
client_package_name = "sled-agent-client"
label = "Sled Agent"
server_package_name = "sled-agent-api"
versioned_how = "server"
[[apis]]
client_package_name = "repo-depot-client"
label = "Repo Depot API"
server_package_name = "repo-depot-api"
versioned_how = "client"
versioned_how_reason = "depends on itself (i.e., instances call each other)"
[[apis]]
client_package_name = "wicketd-client"
label = "Wicketd"
server_package_name = "wicketd-api"
versioned_how = "server"
notes = """
wicketd-client is only used by wicket, which is deployed in a unit with wicketd.
"""
[[apis]]
client_package_name = "crucible-control-client"
label = "Crucible Control (for testing only)"
server_package_name = "crucible"
versioned_how = "server"
notes = """
Exposed by Crucible upstairs for debugging via the `cmon` debugging tool.
"""
[[apis]]
client_package_name = "dsc-client"
label = "Downstairs Controller (debugging only)"
server_package_name = "dsc"
versioned_how = "server"
dev_only = true
notes = """
`dsc` is a control program for spinning up and controlling instances of Crucible
downstairs for testing. You can use the same program to control a running `dsc`
instance. It's also used by `crutest` for testing.
"""
################################################################################
# Dependency filter rules
#
# These rules are used to postprocess the API dependencies that are inferred
# from the Cargo dependencies. Each rule has properties:
#
# * `ancestor`: a Rust package name
# * `client`: the name of a Rust package that's a Progenitor-based API client
# * `evaluation`: a developer-maintained flag for this dependency
# * `note`: a human-readable explanation for the evaluation
#
# This tool works by assembling a list of _possible_ API dependencies based on
# Cargo package dependencies and then applying these rules to filter some out.
# A rule matches a possible API dependency on `client` if the Cargo package
# dependency path goes through `ancestor`. For example: omicron-sled-agent
# depends on omicron-common, which depends on mg-admin-client. This causes the
# tool to initially think that omicron-sled-agent uses the MGD Admin API. A
# rule with `client = mg-admin-client` and `ancestor = omicron-common` would
# filter this out.
#
# See the README for more details, including what the different evaluations mean.
################################################################################
#
# There are no DAG dependencies yet because we've only started evaluating which
# edges should be in that graph.
#
#
# Non-DAG dependencies. See above for details.
#
[[dependency_filter_rules]]
ancestor = "oximeter-producer"
client = "nexus-client"
evaluation = "non-dag"
note = """
All Oximeter producers are Nexus clients. This is a good candidate for a
non-DAG dependency because the API is small and stable and the reverse
directions are often not.
"""
#
# "Not-deployed" dependencies. See above for details.
#
# TODO All things being equal, it would be better to separate these programs
# into their own packages that are separate from the package that *is* deployed.
# Then we wouldn't need these rules. As it is, these rules rely on manual
# vetting that the dependency _is_ only in the dev/test program. If things ever
# changed (e.g., if one of these grew a real dependency on the same API), we'd
# miss it in this tooling.
#
[[dependency_filter_rules]]
ancestor = "oximeter-collector"
client = "oximeter-client"
evaluation = "not-deployed"
note = """
Oximeter provides a standalone collector that is not used in deployed systems.
"""
[[dependency_filter_rules]]
ancestor = "wicketd"
client = "wicketd-client"
evaluation = "not-deployed"
note = """
Wicketd provides a function to refresh the server's config. This could probably
move into the client package instead.
"""
[[dependency_filter_rules]]
ancestor = "dns-server"
client = "dns-service-client"
evaluation = "not-deployed"
note = """
DNS server depends on itself only to provide TransientServer, which is not a
deployed component.
"""
[[dependency_filter_rules]]
ancestor = "omicron-sled-agent"
client = "sled-agent-client"
evaluation = "not-deployed"
note = """
Sled Agent uses a Sled Agent client in two ways: RSS, which we don't care about
for the purpose of upgrade, and in the `zone-bundle` binary, which is not
deployed.
"""
#
# "Bogus" dependencies. See above for details.
#
# In most of these cases, some crate is using a client crate for its types, not
# its client. In these cases, if the component has a real dependency on that
# other API, then it will need some other dependency on the client and that will
# show up as a non-bogus dependency.
#
# TODO It would be nice to remove the need for all of these to avoid accidental
# future false negatives.
#
[[dependency_filter_rules]]
ancestor = "omicron-common"
client = "mg-admin-client"
evaluation = "bogus"
note = """
omicron_common depends on mg-admin-client solely to impl some `From`
conversions. That makes it look like just about everything depends on
mg-admin-client, which isn't true. It'd be nice to remove this. Most clients
put those conversions into the client rather than omicron_common.
"""
[[dependency_filter_rules]]
ancestor = "nexus-types"
client = "gateway-client"
evaluation = "bogus"
note = """
nexus-types depends on gateway-client for defining some types.
"""
[[dependency_filter_rules]]
ancestor = "internal-dns"
client = "dns-service-client"
evaluation = "bogus"
note = """
Past versions of internal-dns (which does not exist any more) depended on
dns-service-client for defining some types. We can remove this when other repos
that depend on Omicron have updated past the removal of the "internal-dns"
package.
"""
[[dependency_filter_rules]]
ancestor = "nexus-types"
client = "dns-service-client"
evaluation = "bogus"
note = """
Past versions of nexus-types that are still referenced in the dependency tree
depended on dns-service-client for defining some types.
"""
[[dependency_filter_rules]]
ancestor = "nexus-types"
client = "sled-agent-client"
evaluation = "bogus"
note = """
Past versions of nexus-types that are still referenced in the dependency tree
depended on sled-agent-client for defining some types.
"""
[[dependency_filter_rules]]
ancestor = "sled-agent-types"
client = "propolis-client"
evaluation = "bogus"
note = """
sled-agent-types uses propolis-client for types only.
"""
[[dependency_filter_rules]]
ancestor = "omicron-sled-agent"
client = "crucible-agent-client"
evaluation = "bogus"
note = """
Sled Agent uses the Crucible Agent client types only, and only in the simulated
sled agent.
"""