1use serde::Deserialize;
4
5use crate::{Diagnostic, DiagnosticCode, PodmanLensResult};
6
7const COVERAGE_CATALOGUE_JSON: &str = include_str!("../catalogue/v1/native-field-coverage.json");
8
9#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
11#[serde(rename_all = "kebab-case")]
12#[non_exhaustive]
13pub enum NativeFieldCoverageClassification {
14 SupportedExact,
16 TargetGated,
18 Manual,
20 ObservationOnly,
22 UnknownIncomplete,
24 RuntimeOnlyDiscarded,
26}
27
28#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
30#[serde(rename_all = "kebab-case")]
31#[non_exhaustive]
32pub enum NativeFieldCoveragePlane {
33 InputObservation,
35 OutputIntent,
37}
38
39impl NativeFieldCoverageClassification {
40 const fn as_str(self) -> &'static str {
41 match self {
42 Self::SupportedExact => "supported-exact",
43 Self::TargetGated => "target-gated",
44 Self::Manual => "manual",
45 Self::ObservationOnly => "observation-only",
46 Self::UnknownIncomplete => "unknown-incomplete",
47 Self::RuntimeOnlyDiscarded => "runtime-only-discarded",
48 }
49 }
50}
51
52struct ExpectedInputEntry {
53 id: &'static str,
54 resource_kind: &'static str,
55 native_path: &'static str,
56 classification: &'static str,
57 decoder: &'static str,
58 planner: &'static str,
59 renderer: &'static str,
60 public_contract: &'static str,
61 finding: &'static str,
62 positive_test: &'static str,
63 negative_test: &'static str,
64}
65
66macro_rules! expected {
67 ($id:literal, $resource_kind:literal, $native_path:literal, $classification:literal, $decoder:literal, $planner:literal, $renderer:literal, $public_contract:literal, $finding:literal, $positive_test:literal, $negative_test:literal) => {
68 ExpectedInputEntry {
69 id: $id,
70 resource_kind: $resource_kind,
71 native_path: $native_path,
72 classification: $classification,
73 decoder: $decoder,
74 planner: $planner,
75 renderer: $renderer,
76 public_contract: $public_contract,
77 finding: $finding,
78 positive_test: $positive_test,
79 negative_test: $negative_test,
80 }
81 };
82}
83
84macro_rules! b4_input {
85 ($id:literal, $resource_kind:literal, $native_path:literal, $decoder:literal, $public_contract:literal) => {
86 expected!(
87 $id,
88 $resource_kind,
89 $native_path,
90 "observation-only",
91 $decoder,
92 "not_applicable",
93 "not_applicable",
94 $public_contract,
95 "PLN0017",
96 "tests::inventory::native_image_volume_and_secret_metadata_are_typed_and_redacted",
97 "tests::inventory::native_image_volume_and_secret_metadata_malformed_fields_fail_closed"
98 )
99 };
100}
101
102macro_rules! runtime_only_input {
103 ($id:literal, $resource_kind:literal, $native_path:literal) => {
104 expected!(
105 $id,
106 $resource_kind,
107 $native_path,
108 "runtime-only-discarded",
109 "inventory::is_known_runtime_only_field",
110 "not_applicable",
111 "not_applicable",
112 "ObservationHeader::unmodelled_fields",
113 "PLN0017",
114 "tests::inventory::known_runtime_projection_fields_do_not_consume_unmodelled_retention",
115 "tests::inventory::known_runtime_projection_fields_do_not_consume_unmodelled_retention"
116 )
117 };
118}
119
120const EXPECTED_INPUT_ENTRIES: &[ExpectedInputEntry] = &[
121 expected!(
122 "PLN-FLD-0001",
123 "container",
124 "$.Id",
125 "supported-exact",
126 "inventory::decode_container",
127 "not_applicable",
128 "not_applicable",
129 "ObservationHeader::identity",
130 "PLN0017",
131 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
132 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
133 ),
134 expected!(
135 "PLN-FLD-0002",
136 "container",
137 "$.Name",
138 "supported-exact",
139 "inventory::decode_container",
140 "not_applicable",
141 "not_applicable",
142 "ObservationHeader::identity",
143 "PLN0017",
144 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
145 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
146 ),
147 expected!(
148 "PLN-FLD-0003",
149 "container",
150 "$.Config.Labels",
151 "observation-only",
152 "inventory::decode_container",
153 "not_applicable",
154 "not_applicable",
155 "ContainerObservation::labels",
156 "PLN0017",
157 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
158 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
159 ),
160 expected!(
161 "PLN-FLD-0004",
162 "container",
163 "$.Config.Env",
164 "observation-only",
165 "inventory::decode_container",
166 "not_applicable",
167 "not_applicable",
168 "ContainerObservation::environment",
169 "PLN0019",
170 "tests::inventory::explicit_environment_inclusion_is_opaque_and_preserves_duplicate_order",
171 "tests::inventory::environment_boundaries_preserve_valid_entries_and_report_every_bad_occurrence"
172 ),
173 expected!(
174 "PLN-FLD-0005",
175 "container",
176 "$.Config.Secrets",
177 "observation-only",
178 "inventory::decode_container_secret_grants",
179 "not_applicable",
180 "not_applicable",
181 "ContainerObservation::secret_grants",
182 "PLN0017",
183 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
184 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
185 ),
186 expected!(
187 "PLN-FLD-0006",
188 "container",
189 "$.Image",
190 "observation-only",
191 "inventory::decode_container",
192 "not_applicable",
193 "not_applicable",
194 "ContainerObservation::local_image_id",
195 "PLN0017",
196 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
197 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
198 ),
199 expected!(
200 "PLN-FLD-0007",
201 "container",
202 "$.ImageName",
203 "observation-only",
204 "inventory::decode_container",
205 "not_applicable",
206 "not_applicable",
207 "ContainerObservation::configured_image",
208 "PLN0017",
209 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
210 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
211 ),
212 expected!(
213 "PLN-FLD-0008",
214 "container",
215 "$.Pod",
216 "observation-only",
217 "inventory::decode_native_reference",
218 "not_applicable",
219 "not_applicable",
220 "ContainerObservation::pod_membership",
221 "PLN0017",
222 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
223 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
224 ),
225 expected!(
226 "PLN-FLD-0009",
227 "container",
228 "$.NetworkSettings.Networks",
229 "observation-only",
230 "inventory::decode_container_networks",
231 "not_applicable",
232 "not_applicable",
233 "ResourceGraph::dependencies",
234 "PLN0017",
235 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
236 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
237 ),
238 expected!(
239 "PLN-FLD-0010",
240 "container",
241 "$.Mounts",
242 "observation-only",
243 "inventory::decode_container_mounts",
244 "not_applicable",
245 "not_applicable",
246 "ContainerObservation::mounts",
247 "PLN0017",
248 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
249 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
250 ),
251 expected!(
252 "PLN-FLD-0011",
253 "container",
254 "$.Dependencies",
255 "observation-only",
256 "inventory::decode_native_dependencies",
257 "not_applicable",
258 "not_applicable",
259 "ContainerObservation::native_dependencies",
260 "PLN0017",
261 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
262 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
263 ),
264 expected!(
265 "PLN-FLD-0012",
266 "container",
267 "$.HostConfig.MemorySwappiness",
268 "target-gated",
269 "inventory::decode_memory_swappiness",
270 "not_applicable",
271 "not_applicable",
272 "ContainerObservation::memory_swappiness",
273 "PLN0022",
274 "tests::inventory::memory_swappiness_normalizes_system_default_and_rejects_invalid_values",
275 "tests::inventory::memory_swappiness_normalizes_system_default_and_rejects_invalid_values"
276 ),
277 expected!(
278 "PLN-FLD-0013",
279 "container",
280 "$.HostConfig.*",
281 "unknown-incomplete",
282 "inventory::unknown_nested_fields",
283 "not_applicable",
284 "not_applicable",
285 "ObservationHeader::unmodelled_fields",
286 "PLN0023",
287 "tests::inventory::host_config_members_not_yet_modeled_are_retained_as_unknown_metadata",
288 "tests::inventory::unknown_fields_are_bounded_per_record_and_across_the_inventory"
289 ),
290 expected!(
291 "PLN-FLD-0014",
292 "container",
293 "$.IsInfra",
294 "observation-only",
295 "inventory::decode_is_infra",
296 "not_applicable",
297 "not_applicable",
298 "ContainerObservation::infra",
299 "PLN0017",
300 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
301 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
302 ),
303 expected!(
304 "PLN-FLD-0015",
305 "pod",
306 "$.Id",
307 "supported-exact",
308 "inventory::decode_pod",
309 "not_applicable",
310 "not_applicable",
311 "ObservationHeader::identity",
312 "PLN0017",
313 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
314 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
315 ),
316 expected!(
317 "PLN-FLD-0016",
318 "pod",
319 "$.Name",
320 "supported-exact",
321 "inventory::decode_pod",
322 "not_applicable",
323 "not_applicable",
324 "ObservationHeader::identity",
325 "PLN0017",
326 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
327 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
328 ),
329 expected!(
330 "PLN-FLD-0017",
331 "pod",
332 "$.Labels",
333 "observation-only",
334 "inventory::decode_pod",
335 "not_applicable",
336 "not_applicable",
337 "PodObservation::labels",
338 "PLN0017",
339 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
340 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
341 ),
342 expected!(
343 "PLN-FLD-0018",
344 "pod",
345 "$.Containers",
346 "observation-only",
347 "inventory::decode_pod_containers",
348 "not_applicable",
349 "not_applicable",
350 "ResourceGraph::dependencies",
351 "PLN0017",
352 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
353 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
354 ),
355 expected!(
356 "PLN-FLD-0019",
357 "pod",
358 "$.Networks",
359 "observation-only",
360 "inventory::decode_pod_networks",
361 "not_applicable",
362 "not_applicable",
363 "ResourceGraph::dependencies",
364 "PLN0017",
365 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
366 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
367 ),
368 expected!(
369 "PLN-FLD-0020",
370 "network",
371 "$.id",
372 "supported-exact",
373 "inventory::decode_network",
374 "not_applicable",
375 "not_applicable",
376 "ObservationHeader::identity",
377 "PLN0017",
378 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
379 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
380 ),
381 expected!(
382 "PLN-FLD-0021",
383 "network",
384 "$.name",
385 "supported-exact",
386 "inventory::decode_network",
387 "not_applicable",
388 "not_applicable",
389 "ObservationHeader::identity",
390 "PLN0017",
391 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
392 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
393 ),
394 expected!(
395 "PLN-FLD-0022",
396 "network",
397 "$.labels",
398 "observation-only",
399 "inventory::decode_network",
400 "not_applicable",
401 "not_applicable",
402 "NetworkObservation::labels",
403 "PLN0017",
404 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
405 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
406 ),
407 expected!(
408 "PLN-FLD-0023",
409 "network",
410 "$.internal",
411 "observation-only",
412 "inventory::decode_network_details",
413 "not_applicable",
414 "not_applicable",
415 "NetworkObservation::internal",
416 "PLN0017",
417 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
418 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
419 ),
420 expected!(
421 "PLN-FLD-0024",
422 "network",
423 "$.options",
424 "observation-only",
425 "inventory::decode_network_details",
426 "not_applicable",
427 "not_applicable",
428 "NetworkObservation::options",
429 "PLN0017",
430 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
431 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
432 ),
433 expected!(
434 "PLN-FLD-0025",
435 "network",
436 "$.subnets",
437 "observation-only",
438 "inventory::decode_network_details",
439 "not_applicable",
440 "not_applicable",
441 "NetworkObservation::subnets",
442 "PLN0017",
443 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
444 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
445 ),
446 expected!(
447 "PLN-FLD-0026",
448 "volume",
449 "$.Name",
450 "supported-exact",
451 "inventory::decode_volume",
452 "not_applicable",
453 "not_applicable",
454 "ObservationHeader::identity",
455 "PLN0017",
456 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
457 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
458 ),
459 expected!(
460 "PLN-FLD-0027",
461 "volume",
462 "$.Labels",
463 "observation-only",
464 "inventory::decode_volume",
465 "not_applicable",
466 "not_applicable",
467 "VolumeObservation::labels",
468 "PLN0017",
469 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
470 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
471 ),
472 expected!(
473 "PLN-FLD-0028",
474 "image",
475 "$.Id",
476 "supported-exact",
477 "inventory::decode_image",
478 "not_applicable",
479 "not_applicable",
480 "ObservationHeader::identity",
481 "PLN0017",
482 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
483 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
484 ),
485 expected!(
486 "PLN-FLD-0029",
487 "image",
488 "$.RepoTags",
489 "observation-only",
490 "inventory::decode_image",
491 "not_applicable",
492 "not_applicable",
493 "ImageObservation::repo_tags",
494 "PLN0017",
495 "tests::inventory::native_image_volume_and_secret_metadata_are_typed_and_redacted",
496 "tests::inventory::native_image_volume_and_secret_metadata_malformed_fields_fail_closed"
497 ),
498 expected!(
499 "PLN-FLD-0030",
500 "image",
501 "$.Labels",
502 "observation-only",
503 "inventory::decode_image",
504 "not_applicable",
505 "not_applicable",
506 "ImageObservation::labels",
507 "PLN0017",
508 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
509 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
510 ),
511 expected!(
512 "PLN-FLD-0031",
513 "image",
514 "$.Config.Env",
515 "observation-only",
516 "inventory::decode_image",
517 "not_applicable",
518 "not_applicable",
519 "ImageObservation::environment",
520 "PLN0019",
521 "tests::inventory::explicit_environment_inclusion_is_opaque_and_preserves_duplicate_order",
522 "tests::inventory::environment_boundaries_preserve_valid_entries_and_report_every_bad_occurrence"
523 ),
524 expected!(
525 "PLN-FLD-0032",
526 "secret",
527 "$.ID",
528 "supported-exact",
529 "inventory::decode_secret",
530 "not_applicable",
531 "not_applicable",
532 "ObservationHeader::identity",
533 "PLN0017",
534 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
535 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
536 ),
537 expected!(
538 "PLN-FLD-0033",
539 "secret",
540 "$.Spec.Name",
541 "supported-exact",
542 "inventory::decode_secret",
543 "not_applicable",
544 "not_applicable",
545 "ObservationHeader::identity",
546 "PLN0017",
547 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
548 "tests::inventory::every_inspect_status_and_shape_failure_retains_a_partial_stable_identity"
549 ),
550 expected!(
551 "PLN-FLD-0034",
552 "secret",
553 "$.Spec.Labels",
554 "observation-only",
555 "inventory::decode_secret",
556 "not_applicable",
557 "not_applicable",
558 "SecretObservation::labels",
559 "PLN0017",
560 "tests::inventory::acquisition_probes_lists_every_kind_then_inspects_canonical_stable_ids",
561 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
562 ),
563 expected!(
564 "PLN-FLD-0035",
565 "secret",
566 "$.Spec.Driver",
567 "observation-only",
568 "inventory::decode_secret",
569 "not_applicable",
570 "not_applicable",
571 "SecretObservation::driver",
572 "PLN0017",
573 "tests::inventory::secret_driver_is_modeled_without_unsupported_metadata",
574 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
575 ),
576 expected!(
577 "PLN-FLD-0036",
578 "secret",
579 "$.SecretData",
580 "manual",
581 "inventory::decode_secret",
582 "not_applicable",
583 "not_applicable",
584 "ObservationHeader::findings",
585 "PLN0018",
586 "tests::inventory::secret_payload_is_discarded_from_metadata_inspection",
587 "tests::inventory::secret_payload_is_discarded_from_metadata_inspection"
588 ),
589 expected!(
590 "PLN-FLD-0037",
591 "secret",
592 "$.Spec.SecretData",
593 "manual",
594 "inventory::decode_secret",
595 "not_applicable",
596 "not_applicable",
597 "ObservationHeader::findings",
598 "PLN0018",
599 "tests::inventory::secret_payload_is_discarded_from_metadata_inspection",
600 "tests::inventory::secret_payload_is_discarded_from_metadata_inspection"
601 ),
602 expected!(
603 "PLN-FLD-0038",
604 "all",
605 "$.<unknown>",
606 "unknown-incomplete",
607 "inventory::unknown_top_level",
608 "not_applicable",
609 "not_applicable",
610 "ObservationHeader::unmodelled_completeness",
611 "PLN0021",
612 "tests::inventory::unknown_fields_are_bounded_per_record_and_across_the_inventory",
613 "tests::input_corpus::malformed_corpus_is_structured_and_bounded_never_panics"
614 ),
615 expected!(
616 "PLN-FLD-0039",
617 "container",
618 "$.Config.Cmd",
619 "observation-only",
620 "inventory::decode_container_configuration",
621 "not_applicable",
622 "not_applicable",
623 "ContainerObservation::command",
624 "PLN0017",
625 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
626 "tests::inventory::malformed_enclosing_config_marks_every_modeled_child_malformed"
627 ),
628 expected!(
629 "PLN-FLD-0040",
630 "container",
631 "$.Config.Entrypoint",
632 "observation-only",
633 "inventory::decode_container_configuration",
634 "not_applicable",
635 "not_applicable",
636 "ContainerObservation::entrypoint",
637 "PLN0017",
638 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
639 "tests::inventory::malformed_enclosing_config_marks_every_modeled_child_malformed"
640 ),
641 expected!(
642 "PLN-FLD-0041",
643 "container",
644 "$.Config.User",
645 "observation-only",
646 "inventory::decode_container_configuration",
647 "not_applicable",
648 "not_applicable",
649 "ContainerObservation::user",
650 "PLN0017",
651 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
652 "tests::inventory::malformed_enclosing_config_marks_every_modeled_child_malformed"
653 ),
654 expected!(
655 "PLN-FLD-0042",
656 "container",
657 "$.Config.WorkingDir",
658 "observation-only",
659 "inventory::decode_container_configuration",
660 "not_applicable",
661 "not_applicable",
662 "ContainerObservation::working_directory",
663 "PLN0017",
664 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
665 "tests::inventory::malformed_enclosing_config_marks_every_modeled_child_malformed"
666 ),
667 expected!(
668 "PLN-FLD-0043",
669 "container",
670 "$.Config.Hostname",
671 "observation-only",
672 "inventory::decode_container_configuration",
673 "not_applicable",
674 "not_applicable",
675 "ContainerObservation::hostname",
676 "PLN0017",
677 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
678 "tests::inventory::malformed_enclosing_config_marks_every_modeled_child_malformed"
679 ),
680 expected!(
681 "PLN-FLD-0046",
682 "container",
683 "$.Mounts.Type",
684 "observation-only",
685 "inventory::decode_container_mounts",
686 "not_applicable",
687 "not_applicable",
688 "ContainerObservation::mounts",
689 "PLN0023",
690 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
691 "tests::inventory::malformed_secret_aliases_and_unsupported_mounts_remain_non_deployable_evidence"
692 ),
693 expected!(
694 "PLN-FLD-0047",
695 "container",
696 "$.Mounts.Name",
697 "observation-only",
698 "inventory::decode_container_mounts",
699 "not_applicable",
700 "not_applicable",
701 "ContainerMountObservation::source",
702 "PLN0017",
703 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
704 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
705 ),
706 expected!(
707 "PLN-FLD-0048",
708 "container",
709 "$.Mounts.Source",
710 "observation-only",
711 "inventory::decode_container_mounts",
712 "not_applicable",
713 "not_applicable",
714 "ContainerMountObservation::source",
715 "PLN0017",
716 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
717 "tests::inventory::malformed_mount_destination_or_local_backing_path_invalidates_the_complete_mount_family"
718 ),
719 expected!(
720 "PLN-FLD-0049",
721 "container",
722 "$.Mounts.Destination",
723 "observation-only",
724 "inventory::decode_container_mounts",
725 "not_applicable",
726 "not_applicable",
727 "ContainerMountObservation::destination",
728 "PLN0017",
729 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
730 "tests::inventory::malformed_mount_destination_or_local_backing_path_invalidates_the_complete_mount_family"
731 ),
732 expected!(
733 "PLN-FLD-0050",
734 "container",
735 "$.Mounts.RW",
736 "observation-only",
737 "inventory::decode_container_mounts",
738 "not_applicable",
739 "not_applicable",
740 "ContainerMountObservation::writable",
741 "PLN0017",
742 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
743 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
744 ),
745 expected!(
746 "PLN-FLD-0051",
747 "container",
748 "$.Mounts.Options",
749 "observation-only",
750 "inventory::decode_container_mounts",
751 "not_applicable",
752 "not_applicable",
753 "ContainerMountObservation::options",
754 "PLN0017",
755 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
756 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
757 ),
758 expected!(
759 "PLN-FLD-0052",
760 "container",
761 "$.Mounts.Propagation",
762 "observation-only",
763 "inventory::decode_container_mounts",
764 "not_applicable",
765 "not_applicable",
766 "ContainerMountObservation::propagation",
767 "PLN0017",
768 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
769 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
770 ),
771 expected!(
772 "PLN-FLD-0053",
773 "container",
774 "$.Mounts.SubPath",
775 "observation-only",
776 "inventory::decode_container_mounts",
777 "not_applicable",
778 "not_applicable",
779 "ContainerMountObservation::subpath",
780 "PLN0017",
781 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
782 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record"
783 ),
784 expected!(
785 "PLN-FLD-0054",
786 "container",
787 "$.Config.Secrets.ID",
788 "observation-only",
789 "inventory::decode_container_secret_grants",
790 "not_applicable",
791 "not_applicable",
792 "ContainerSecretGrantObservation::reference",
793 "PLN0017",
794 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
795 "tests::inventory::malformed_secret_aliases_and_unsupported_mounts_remain_non_deployable_evidence"
796 ),
797 expected!(
798 "PLN-FLD-0055",
799 "container",
800 "$.Config.Secrets.Name",
801 "observation-only",
802 "inventory::decode_container_secret_grants",
803 "not_applicable",
804 "not_applicable",
805 "ContainerSecretGrantObservation::reference",
806 "PLN0017",
807 "tests::inventory::container_core_mount_and_secret_observations_are_typed_and_redacted",
808 "tests::inventory::malformed_secret_aliases_and_unsupported_mounts_remain_non_deployable_evidence"
809 ),
810 expected!(
811 "PLN-FLD-0056",
812 "container",
813 "$.Config.Secrets.UID",
814 "observation-only",
815 "inventory::decode_container_secret_grants",
816 "not_applicable",
817 "not_applicable",
818 "ContainerSecretGrantObservation::uid",
819 "PLN0017",
820 "tests::inventory::canonical_direct_secret_metadata_preserves_effective_zero_and_configured_aliases",
821 "tests::inventory::malformed_direct_secret_effective_metadata_invalidates_the_grant_family"
822 ),
823 expected!(
824 "PLN-FLD-0057",
825 "container",
826 "$.Config.Secrets.GID",
827 "observation-only",
828 "inventory::decode_container_secret_grants",
829 "not_applicable",
830 "not_applicable",
831 "ContainerSecretGrantObservation::gid",
832 "PLN0017",
833 "tests::inventory::canonical_direct_secret_metadata_preserves_effective_zero_and_configured_aliases",
834 "tests::inventory::malformed_direct_secret_effective_metadata_invalidates_the_grant_family"
835 ),
836 expected!(
837 "PLN-FLD-0058",
838 "container",
839 "$.Config.Secrets.Mode",
840 "observation-only",
841 "inventory::decode_container_secret_grants",
842 "not_applicable",
843 "not_applicable",
844 "ContainerSecretGrantObservation::mode",
845 "PLN0017",
846 "tests::inventory::canonical_direct_secret_metadata_preserves_effective_zero_and_configured_aliases",
847 "tests::inventory::malformed_direct_secret_effective_metadata_invalidates_the_grant_family"
848 ),
849 expected!(
850 "PLN-FLD-0059",
851 "network",
852 "$.subnets[].subnet",
853 "observation-only",
854 "inventory::decode_native_network_subnets",
855 "not_applicable",
856 "not_applicable",
857 "NativeNetworkSubnetObservation::cidr",
858 "PLN0017",
859 "tests::inventory::native_network_ipam_and_routes_are_typed_effective_observations",
860 "tests::inventory::native_network_route_type_is_version_gated_and_malformed_families_do_not_partial_decode"
861 ),
862 expected!(
863 "PLN-FLD-0060",
864 "network",
865 "$.subnets[].gateway",
866 "observation-only",
867 "inventory::decode_native_network_subnets",
868 "not_applicable",
869 "not_applicable",
870 "NativeNetworkSubnetObservation::gateway",
871 "PLN0017",
872 "tests::inventory::native_network_ipam_and_routes_are_typed_effective_observations",
873 "tests::inventory::native_network_route_type_is_version_gated_and_malformed_families_do_not_partial_decode"
874 ),
875 expected!(
876 "PLN-FLD-0061",
877 "network",
878 "$.subnets[].lease_range",
879 "observation-only",
880 "inventory::decode_native_network_subnets",
881 "not_applicable",
882 "not_applicable",
883 "NativeNetworkSubnetObservation::lease_range",
884 "PLN0017",
885 "tests::inventory::native_network_ipam_and_routes_are_typed_effective_observations",
886 "tests::inventory::native_network_route_type_is_version_gated_and_malformed_families_do_not_partial_decode"
887 ),
888 expected!(
889 "PLN-FLD-0062",
890 "network",
891 "$.subnets[].lease_range.start_ip",
892 "observation-only",
893 "inventory::decode_native_network_subnets",
894 "not_applicable",
895 "not_applicable",
896 "NativeNetworkLeaseRange::start_ip",
897 "PLN0017",
898 "tests::inventory::native_network_lease_endpoints_are_independently_optional_effective_evidence",
899 "tests::inventory::malformed_native_network_lease_members_poison_the_complete_subnet_family"
900 ),
901 expected!(
902 "PLN-FLD-0063",
903 "network",
904 "$.subnets[].lease_range.end_ip",
905 "observation-only",
906 "inventory::decode_native_network_subnets",
907 "not_applicable",
908 "not_applicable",
909 "NativeNetworkLeaseRange::end_ip",
910 "PLN0017",
911 "tests::inventory::native_network_lease_endpoints_are_independently_optional_effective_evidence",
912 "tests::inventory::malformed_native_network_lease_members_poison_the_complete_subnet_family"
913 ),
914 expected!(
915 "PLN-FLD-0064",
916 "network",
917 "$.routes",
918 "observation-only",
919 "inventory::decode_native_network_routes",
920 "not_applicable",
921 "not_applicable",
922 "NetworkObservation::routes",
923 "PLN0017",
924 "tests::inventory::native_network_ipam_and_routes_are_typed_effective_observations",
925 "tests::inventory::native_network_route_type_is_version_gated_and_malformed_families_do_not_partial_decode"
926 ),
927 expected!(
928 "PLN-FLD-0065",
929 "network",
930 "$.routes[].destination",
931 "observation-only",
932 "inventory::decode_native_network_routes",
933 "not_applicable",
934 "not_applicable",
935 "NativeNetworkRouteObservation::destination",
936 "PLN0017",
937 "tests::inventory::native_network_ipam_and_routes_are_typed_effective_observations",
938 "tests::inventory::native_network_route_type_is_version_gated_and_malformed_families_do_not_partial_decode"
939 ),
940 expected!(
941 "PLN-FLD-0066",
942 "network",
943 "$.routes[].gateway",
944 "observation-only",
945 "inventory::decode_native_network_routes",
946 "not_applicable",
947 "not_applicable",
948 "NativeNetworkRouteObservation::gateway",
949 "PLN0017",
950 "tests::inventory::native_network_ipam_and_routes_are_typed_effective_observations",
951 "tests::inventory::native_network_route_type_is_version_gated_and_malformed_families_do_not_partial_decode"
952 ),
953 expected!(
954 "PLN-FLD-0067",
955 "network",
956 "$.routes[].metric",
957 "observation-only",
958 "inventory::decode_native_network_routes",
959 "not_applicable",
960 "not_applicable",
961 "NativeNetworkRouteObservation::metric",
962 "PLN0017",
963 "tests::inventory::native_network_ipam_and_routes_are_typed_effective_observations",
964 "tests::inventory::native_network_route_type_is_version_gated_and_malformed_families_do_not_partial_decode"
965 ),
966 expected!(
967 "PLN-FLD-0068",
968 "network",
969 "$.routes[].route_type",
970 "observation-only",
971 "inventory::decode_native_network_routes",
972 "not_applicable",
973 "not_applicable",
974 "NativeNetworkRouteObservation::route_type",
975 "PLN0022",
976 "tests::inventory::native_network_ipam_and_routes_are_typed_effective_observations",
977 "tests::inventory::native_network_route_type_is_version_gated_and_malformed_families_do_not_partial_decode"
978 ),
979 expected!(
980 "PLN-FLD-0069",
981 "container",
982 "$.HostConfig.CreateNetNS",
983 "observation-only",
984 "inventory::decode_container_networking",
985 "not_applicable",
986 "not_applicable",
987 "NativeNetworkingObservation::create_net_ns",
988 "PLN0017",
989 "tests::inventory::unpodded_host_config_networking_is_configured_and_management_gates_are_fail_closed",
990 "tests::inventory::unpodded_port_bindings_are_validated_without_a_new_network_namespace_gate"
991 ),
992 expected!(
993 "PLN-FLD-0070",
994 "container",
995 "$.HostConfig.PortBindings",
996 "observation-only",
997 "inventory::decode_container_networking",
998 "not_applicable",
999 "not_applicable",
1000 "NativeNetworkingObservation::port_bindings",
1001 "PLN0017",
1002 "tests::inventory::unpodded_host_config_networking_is_configured_and_management_gates_are_fail_closed",
1003 "tests::inventory::unpodded_port_bindings_are_validated_without_a_new_network_namespace_gate"
1004 ),
1005 expected!(
1006 "PLN-FLD-0071",
1007 "container",
1008 "$.HostConfig.Dns",
1009 "observation-only",
1010 "inventory::decode_container_networking",
1011 "not_applicable",
1012 "not_applicable",
1013 "NativeNetworkingObservation::dns_servers",
1014 "PLN0017",
1015 "tests::inventory::unpodded_host_config_networking_is_configured_and_management_gates_are_fail_closed",
1016 "tests::inventory::public_typed_observations_exercise_every_field_state_without_promoting_unmodelled_data"
1017 ),
1018 expected!(
1019 "PLN-FLD-0072",
1020 "container",
1021 "$.HostConfig.DnsSearch",
1022 "observation-only",
1023 "inventory::decode_container_networking",
1024 "not_applicable",
1025 "not_applicable",
1026 "NativeNetworkingObservation::dns_search",
1027 "PLN0017",
1028 "tests::inventory::unpodded_host_config_networking_is_configured_and_management_gates_are_fail_closed",
1029 "tests::inventory::public_typed_observations_exercise_every_field_state_without_promoting_unmodelled_data"
1030 ),
1031 expected!(
1032 "PLN-FLD-0073",
1033 "container",
1034 "$.HostConfig.DnsOptions",
1035 "observation-only",
1036 "inventory::decode_container_networking",
1037 "not_applicable",
1038 "not_applicable",
1039 "NativeNetworkingObservation::dns_options",
1040 "PLN0017",
1041 "tests::inventory::unpodded_host_config_networking_is_configured_and_management_gates_are_fail_closed",
1042 "tests::inventory::public_typed_observations_exercise_every_field_state_without_promoting_unmodelled_data"
1043 ),
1044 expected!(
1045 "PLN-FLD-0074",
1046 "container",
1047 "$.HostConfig.NoManageResolvConf",
1048 "observation-only",
1049 "inventory::decode_container_networking",
1050 "not_applicable",
1051 "not_applicable",
1052 "NativeNetworkingObservation::no_manage_resolv_conf",
1053 "PLN0017",
1054 "tests::inventory::unpodded_host_config_networking_is_configured_and_management_gates_are_fail_closed",
1055 "tests::inventory::public_typed_observations_exercise_every_field_state_without_promoting_unmodelled_data"
1056 ),
1057 expected!(
1058 "PLN-FLD-0075",
1059 "container",
1060 "$.HostConfig.NoManageHosts",
1061 "observation-only",
1062 "inventory::decode_container_networking",
1063 "not_applicable",
1064 "not_applicable",
1065 "NativeNetworkingObservation::no_manage_hosts",
1066 "PLN0017",
1067 "tests::inventory::unpodded_host_config_networking_is_configured_and_management_gates_are_fail_closed",
1068 "tests::inventory::public_typed_observations_exercise_every_field_state_without_promoting_unmodelled_data"
1069 ),
1070 expected!(
1071 "PLN-FLD-0076",
1072 "container",
1073 "$.HostConfig.ExtraHosts",
1074 "unknown-incomplete",
1075 "inventory::decode_container_networking",
1076 "not_applicable",
1077 "not_applicable",
1078 "NativeNetworkingObservation::host_entries",
1079 "PLN0023",
1080 "tests::inventory::unpodded_host_config_networking_is_configured_and_management_gates_are_fail_closed",
1081 "tests::inventory::public_typed_observations_exercise_every_field_state_without_promoting_unmodelled_data"
1082 ),
1083 expected!(
1084 "PLN-FLD-0077",
1085 "pod",
1086 "$.CreateInfra",
1087 "observation-only",
1088 "inventory::decode_pod_networking",
1089 "not_applicable",
1090 "not_applicable",
1091 "PodObservation::create_infra",
1092 "PLN0017",
1093 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1094 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1095 ),
1096 expected!(
1097 "PLN-FLD-0078",
1098 "pod",
1099 "$.InfraConfig",
1100 "observation-only",
1101 "inventory::decode_pod_networking",
1102 "not_applicable",
1103 "not_applicable",
1104 "PodObservation::networking",
1105 "PLN0017",
1106 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1107 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1108 ),
1109 expected!(
1110 "PLN-FLD-0079",
1111 "pod",
1112 "$.InfraConfig.PortBindings",
1113 "observation-only",
1114 "inventory::decode_native_networking",
1115 "not_applicable",
1116 "not_applicable",
1117 "NativeNetworkingObservation::port_bindings",
1118 "PLN0017",
1119 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1120 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1121 ),
1122 expected!(
1123 "PLN-FLD-0080",
1124 "pod",
1125 "$.InfraConfig.HostNetwork",
1126 "observation-only",
1127 "inventory::decode_native_networking",
1128 "not_applicable",
1129 "not_applicable",
1130 "NativeNetworkingObservation::host_network",
1131 "PLN0017",
1132 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1133 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1134 ),
1135 expected!(
1136 "PLN-FLD-0081",
1137 "pod",
1138 "$.InfraConfig.DNSServer",
1139 "observation-only",
1140 "inventory::decode_native_networking",
1141 "not_applicable",
1142 "not_applicable",
1143 "NativeNetworkingObservation::dns_servers",
1144 "PLN0017",
1145 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1146 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1147 ),
1148 expected!(
1149 "PLN-FLD-0082",
1150 "pod",
1151 "$.InfraConfig.DNSSearch",
1152 "observation-only",
1153 "inventory::decode_native_networking",
1154 "not_applicable",
1155 "not_applicable",
1156 "NativeNetworkingObservation::dns_search",
1157 "PLN0017",
1158 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1159 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1160 ),
1161 expected!(
1162 "PLN-FLD-0083",
1163 "pod",
1164 "$.InfraConfig.DNSOption",
1165 "observation-only",
1166 "inventory::decode_native_networking",
1167 "not_applicable",
1168 "not_applicable",
1169 "NativeNetworkingObservation::dns_options",
1170 "PLN0017",
1171 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1172 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1173 ),
1174 expected!(
1175 "PLN-FLD-0084",
1176 "pod",
1177 "$.InfraConfig.HostAdd",
1178 "unknown-incomplete",
1179 "inventory::decode_native_networking",
1180 "not_applicable",
1181 "not_applicable",
1182 "NativeNetworkingObservation::host_entries",
1183 "PLN0023",
1184 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1185 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1186 ),
1187 expected!(
1188 "PLN-FLD-0085",
1189 "pod",
1190 "$.InfraConfig.Networks",
1191 "observation-only",
1192 "inventory::decode_native_networking",
1193 "not_applicable",
1194 "not_applicable",
1195 "NativeNetworkingObservation::networks",
1196 "PLN0017",
1197 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1198 "tests::discovery::one_malformed_relationship_member_blocks_its_entire_collection"
1199 ),
1200 expected!(
1201 "PLN-FLD-0086",
1202 "pod",
1203 "$.InfraConfig.NetworkOptions",
1204 "observation-only",
1205 "inventory::decode_native_networking",
1206 "not_applicable",
1207 "not_applicable",
1208 "NativeNetworkingObservation::network_options",
1209 "PLN0017",
1210 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1211 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1212 ),
1213 expected!(
1214 "PLN-FLD-0087",
1215 "pod",
1216 "$.InfraConfig.NoManageResolvConf",
1217 "observation-only",
1218 "inventory::decode_native_networking",
1219 "not_applicable",
1220 "not_applicable",
1221 "NativeNetworkingObservation::no_manage_resolv_conf",
1222 "PLN0017",
1223 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1224 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1225 ),
1226 expected!(
1227 "PLN-FLD-0088",
1228 "pod",
1229 "$.InfraConfig.NoManageHosts",
1230 "observation-only",
1231 "inventory::decode_native_networking",
1232 "not_applicable",
1233 "not_applicable",
1234 "NativeNetworkingObservation::no_manage_hosts",
1235 "PLN0017",
1236 "tests::inventory::pod_infra_networking_is_authoritative_and_member_runtime_networking_is_not_promoted",
1237 "tests::inventory::infra_configuration_inconsistencies_and_malformed_members_fail_closed"
1238 ),
1239 expected!(
1240 "PLN-FLD-0089",
1241 "pod",
1242 "$.InfraConfig.StaticIP",
1243 "target-gated",
1244 "inventory::decode_native_networking",
1245 "not_applicable",
1246 "not_applicable",
1247 "NativeNetworkingObservation::static_ip",
1248 "PLN0022",
1249 "tests::inventory::deprecated_infra_static_ip_covers_all_supported_5_x_patches_and_static_mac_is_never_promoted",
1250 "tests::inventory::deprecated_infra_static_ip_covers_all_supported_5_x_patches_and_static_mac_is_never_promoted"
1251 ),
1252 expected!(
1253 "PLN-FLD-0090",
1254 "pod",
1255 "$.InfraConfig.StaticMAC",
1256 "target-gated",
1257 "inventory::decode_native_networking",
1258 "not_applicable",
1259 "not_applicable",
1260 "NativeNetworkingObservation::static_mac",
1261 "PLN0022",
1262 "tests::inventory::deprecated_infra_static_ip_covers_all_supported_5_x_patches_and_static_mac_is_never_promoted",
1263 "tests::inventory::deprecated_infra_static_ip_covers_all_supported_5_x_patches_and_static_mac_is_never_promoted"
1264 ),
1265 expected!(
1266 "PLN-FLD-0091",
1267 "container",
1268 "$.HostConfig.RestartPolicy",
1269 "observation-only",
1270 "inventory::decode_container_b3",
1271 "not_applicable",
1272 "not_applicable",
1273 "ContainerObservation::restart_policy",
1274 "PLN0017",
1275 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1276 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1277 ),
1278 expected!(
1279 "PLN-FLD-0092",
1280 "container",
1281 "$.HostConfig.RestartPolicy.Name",
1282 "observation-only",
1283 "inventory::decode_native_restart_policy",
1284 "not_applicable",
1285 "not_applicable",
1286 "NativeRestartPolicyObservation::name",
1287 "PLN0023",
1288 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1289 "tests::inventory::container_b3_unknown_enums_are_bounded_unmodelled_metadata"
1290 ),
1291 expected!(
1292 "PLN-FLD-0093",
1293 "container",
1294 "$.HostConfig.RestartPolicy.MaximumRetryCount",
1295 "observation-only",
1296 "inventory::decode_native_restart_policy",
1297 "not_applicable",
1298 "not_applicable",
1299 "NativeRestartPolicyObservation::maximum_retry_count",
1300 "PLN0017",
1301 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1302 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1303 ),
1304 expected!(
1305 "PLN-FLD-0094",
1306 "container",
1307 "$.Config.Healthcheck",
1308 "observation-only",
1309 "inventory::decode_container_b3",
1310 "not_applicable",
1311 "not_applicable",
1312 "ContainerObservation::health_check",
1313 "PLN0017",
1314 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1315 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1316 ),
1317 expected!(
1318 "PLN-FLD-0095",
1319 "container",
1320 "$.Config.Healthcheck.Test",
1321 "observation-only",
1322 "inventory::decode_native_health_check",
1323 "not_applicable",
1324 "not_applicable",
1325 "NativeHealthCheckObservation::command",
1326 "PLN0023",
1327 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1328 "tests::inventory::container_b3_unknown_enums_are_bounded_unmodelled_metadata"
1329 ),
1330 expected!(
1331 "PLN-FLD-0096",
1332 "container",
1333 "$.Config.Healthcheck.Interval",
1334 "observation-only",
1335 "inventory::decode_native_health_check",
1336 "not_applicable",
1337 "not_applicable",
1338 "NativeHealthCheckObservation::interval",
1339 "PLN0017",
1340 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1341 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1342 ),
1343 expected!(
1344 "PLN-FLD-0097",
1345 "container",
1346 "$.Config.Healthcheck.Timeout",
1347 "observation-only",
1348 "inventory::decode_native_health_check",
1349 "not_applicable",
1350 "not_applicable",
1351 "NativeHealthCheckObservation::timeout",
1352 "PLN0017",
1353 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1354 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1355 ),
1356 expected!(
1357 "PLN-FLD-0098",
1358 "container",
1359 "$.Config.Healthcheck.Retries",
1360 "observation-only",
1361 "inventory::decode_native_health_check",
1362 "not_applicable",
1363 "not_applicable",
1364 "NativeHealthCheckObservation::retries",
1365 "PLN0017",
1366 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1367 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1368 ),
1369 expected!(
1370 "PLN-FLD-0099",
1371 "container",
1372 "$.Config.Healthcheck.StartPeriod",
1373 "observation-only",
1374 "inventory::decode_native_health_check",
1375 "not_applicable",
1376 "not_applicable",
1377 "NativeHealthCheckObservation::start_period",
1378 "PLN0017",
1379 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1380 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1381 ),
1382 expected!(
1383 "PLN-FLD-0100",
1384 "container",
1385 "$.Config.HealthcheckOnFailureAction",
1386 "observation-only",
1387 "inventory::decode_native_health_failure_action",
1388 "not_applicable",
1389 "not_applicable",
1390 "ContainerObservation::health_failure_action",
1391 "PLN0023",
1392 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1393 "tests::inventory::container_b3_unknown_enums_are_bounded_unmodelled_metadata"
1394 ),
1395 expected!(
1396 "PLN-FLD-0101",
1397 "container",
1398 "$.Config.StartupHealthCheck",
1399 "observation-only",
1400 "inventory::decode_container_b3",
1401 "not_applicable",
1402 "not_applicable",
1403 "ContainerObservation::startup_health_check",
1404 "PLN0017",
1405 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1406 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1407 ),
1408 expected!(
1409 "PLN-FLD-0102",
1410 "container",
1411 "$.Config.StartupHealthCheck.Test",
1412 "observation-only",
1413 "inventory::decode_native_startup_health_check",
1414 "not_applicable",
1415 "not_applicable",
1416 "NativeStartupHealthCheckObservation::command",
1417 "PLN0023",
1418 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1419 "tests::inventory::container_b3_unknown_enums_are_bounded_unmodelled_metadata"
1420 ),
1421 expected!(
1422 "PLN-FLD-0103",
1423 "container",
1424 "$.Config.StartupHealthCheck.Interval",
1425 "observation-only",
1426 "inventory::decode_native_startup_health_check",
1427 "not_applicable",
1428 "not_applicable",
1429 "NativeStartupHealthCheckObservation::interval",
1430 "PLN0017",
1431 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1432 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1433 ),
1434 expected!(
1435 "PLN-FLD-0104",
1436 "container",
1437 "$.Config.StartupHealthCheck.Timeout",
1438 "observation-only",
1439 "inventory::decode_native_startup_health_check",
1440 "not_applicable",
1441 "not_applicable",
1442 "NativeStartupHealthCheckObservation::timeout",
1443 "PLN0017",
1444 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1445 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1446 ),
1447 expected!(
1448 "PLN-FLD-0105",
1449 "container",
1450 "$.Config.StartupHealthCheck.Retries",
1451 "observation-only",
1452 "inventory::decode_native_startup_health_check",
1453 "not_applicable",
1454 "not_applicable",
1455 "NativeStartupHealthCheckObservation::retries",
1456 "PLN0017",
1457 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1458 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1459 ),
1460 expected!(
1461 "PLN-FLD-0106",
1462 "container",
1463 "$.Config.StartupHealthCheck.StartPeriod",
1464 "observation-only",
1465 "inventory::decode_native_startup_health_check",
1466 "not_applicable",
1467 "not_applicable",
1468 "NativeStartupHealthCheckObservation::start_period",
1469 "PLN0017",
1470 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1471 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1472 ),
1473 expected!(
1474 "PLN-FLD-0107",
1475 "container",
1476 "$.Config.StartupHealthCheck.Successes",
1477 "observation-only",
1478 "inventory::decode_native_startup_health_check",
1479 "not_applicable",
1480 "not_applicable",
1481 "NativeStartupHealthCheckObservation::successes",
1482 "PLN0017",
1483 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1484 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1485 ),
1486 expected!(
1487 "PLN-FLD-0108",
1488 "container",
1489 "$.HostConfig.LogConfig",
1490 "observation-only",
1491 "inventory::decode_container_b3",
1492 "not_applicable",
1493 "not_applicable",
1494 "ContainerObservation::logging",
1495 "PLN0017",
1496 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1497 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1498 ),
1499 expected!(
1500 "PLN-FLD-0109",
1501 "container",
1502 "$.HostConfig.LogConfig.Type",
1503 "observation-only",
1504 "inventory::decode_native_logging",
1505 "not_applicable",
1506 "not_applicable",
1507 "NativeLoggingObservation::driver",
1508 "PLN0023",
1509 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1510 "tests::inventory::container_b3_unknown_enums_are_bounded_unmodelled_metadata"
1511 ),
1512 expected!(
1513 "PLN-FLD-0110",
1514 "container",
1515 "$.HostConfig.LogConfig.Size",
1516 "observation-only",
1517 "inventory::decode_native_logging",
1518 "not_applicable",
1519 "not_applicable",
1520 "NativeLoggingObservation::size",
1521 "PLN0017",
1522 "tests::inventory::container_restart_health_and_logging_are_typed_effective_observations",
1523 "tests::inventory::container_b3_malformed_counts_and_commands_fail_closed"
1524 ),
1525 expected!(
1526 "PLN-FLD-0111",
1527 "container",
1528 "$.HostConfig.Privileged",
1529 "observation-only",
1530 "inventory::decode_native_security",
1531 "not_applicable",
1532 "not_applicable",
1533 "NativeSecurityObservation::privileged",
1534 "PLN0017",
1535 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1536 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1537 ),
1538 expected!(
1539 "PLN-FLD-0112",
1540 "container",
1541 "$.HostConfig.CapAdd",
1542 "observation-only",
1543 "inventory::native_capabilities",
1544 "not_applicable",
1545 "not_applicable",
1546 "NativeSecurityObservation::cap_add",
1547 "PLN0023",
1548 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1549 "tests::inventory::container_b3b_unknown_capabilities_and_namespace_modes_are_unmodelled"
1550 ),
1551 expected!(
1552 "PLN-FLD-0113",
1553 "container",
1554 "$.HostConfig.CapDrop",
1555 "observation-only",
1556 "inventory::native_capabilities",
1557 "not_applicable",
1558 "not_applicable",
1559 "NativeSecurityObservation::cap_drop",
1560 "PLN0023",
1561 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1562 "tests::inventory::container_b3b_unknown_capabilities_and_namespace_modes_are_unmodelled"
1563 ),
1564 expected!(
1565 "PLN-FLD-0114",
1566 "container",
1567 "$.HostConfig.SecurityOpt",
1568 "observation-only",
1569 "inventory::native_security_options",
1570 "not_applicable",
1571 "not_applicable",
1572 "NativeSecurityObservation::security_options",
1573 "PLN0017",
1574 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1575 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1576 ),
1577 expected!(
1578 "PLN-FLD-0115",
1579 "container",
1580 "$.HostConfig.ReadonlyRootfs",
1581 "observation-only",
1582 "inventory::decode_native_security",
1583 "not_applicable",
1584 "not_applicable",
1585 "NativeSecurityObservation::read_only_root_filesystem",
1586 "PLN0017",
1587 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1588 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1589 ),
1590 expected!(
1591 "PLN-FLD-0116",
1592 "container",
1593 "$.HostConfig.PidMode",
1594 "observation-only",
1595 "inventory::native_namespace_mode",
1596 "not_applicable",
1597 "not_applicable",
1598 "NativeNamespaceObservation::pid",
1599 "PLN0023",
1600 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1601 "tests::inventory::container_b3b_unknown_capabilities_and_namespace_modes_are_unmodelled"
1602 ),
1603 expected!(
1604 "PLN-FLD-0117",
1605 "container",
1606 "$.HostConfig.IpcMode",
1607 "observation-only",
1608 "inventory::native_ipc_namespace_mode",
1609 "not_applicable",
1610 "not_applicable",
1611 "NativeNamespaceObservation::ipc",
1612 "PLN0023",
1613 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1614 "tests::inventory::container_b3b_unknown_capabilities_and_namespace_modes_are_unmodelled"
1615 ),
1616 expected!(
1617 "PLN-FLD-0118",
1618 "container",
1619 "$.HostConfig.UTSMode",
1620 "observation-only",
1621 "inventory::native_namespace_mode",
1622 "not_applicable",
1623 "not_applicable",
1624 "NativeNamespaceObservation::uts",
1625 "PLN0023",
1626 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1627 "tests::inventory::container_b3b_unknown_capabilities_and_namespace_modes_are_unmodelled"
1628 ),
1629 expected!(
1630 "PLN-FLD-0119",
1631 "container",
1632 "$.HostConfig.CgroupMode",
1633 "observation-only",
1634 "inventory::native_namespace_mode",
1635 "not_applicable",
1636 "not_applicable",
1637 "NativeNamespaceObservation::cgroup",
1638 "PLN0023",
1639 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1640 "tests::inventory::container_b3b_unknown_capabilities_and_namespace_modes_are_unmodelled"
1641 ),
1642 expected!(
1643 "PLN-FLD-0120",
1644 "container",
1645 "$.HostConfig.CpuShares",
1646 "observation-only",
1647 "inventory::decode_native_resource_controls",
1648 "not_applicable",
1649 "not_applicable",
1650 "NativeResourceControlObservation::cpu_shares",
1651 "PLN0017",
1652 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1653 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1654 ),
1655 expected!(
1656 "PLN-FLD-0121",
1657 "container",
1658 "$.HostConfig.CpuPeriod",
1659 "observation-only",
1660 "inventory::decode_native_resource_controls",
1661 "not_applicable",
1662 "not_applicable",
1663 "NativeResourceControlObservation::cpu_period",
1664 "PLN0017",
1665 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1666 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1667 ),
1668 expected!(
1669 "PLN-FLD-0122",
1670 "container",
1671 "$.HostConfig.CpuQuota",
1672 "observation-only",
1673 "inventory::decode_native_resource_controls",
1674 "not_applicable",
1675 "not_applicable",
1676 "NativeResourceControlObservation::cpu_quota",
1677 "PLN0017",
1678 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1679 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1680 ),
1681 expected!(
1682 "PLN-FLD-0123",
1683 "container",
1684 "$.HostConfig.Memory",
1685 "observation-only",
1686 "inventory::decode_native_resource_controls",
1687 "not_applicable",
1688 "not_applicable",
1689 "NativeResourceControlObservation::memory",
1690 "PLN0017",
1691 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1692 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1693 ),
1694 expected!(
1695 "PLN-FLD-0124",
1696 "container",
1697 "$.HostConfig.PidsLimit",
1698 "observation-only",
1699 "inventory::decode_native_resource_controls",
1700 "not_applicable",
1701 "not_applicable",
1702 "NativeResourceControlObservation::pids_limit",
1703 "PLN0017",
1704 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1705 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1706 ),
1707 expected!(
1708 "PLN-FLD-0125",
1709 "container",
1710 "$.HostConfig.Ulimits",
1711 "observation-only",
1712 "inventory::decode_native_ulimits",
1713 "not_applicable",
1714 "not_applicable",
1715 "NativeResourceControlObservation::ulimits",
1716 "PLN0017",
1717 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1718 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1719 ),
1720 expected!(
1721 "PLN-FLD-0126",
1722 "container",
1723 "$.HostConfig.Ulimits[].Name",
1724 "observation-only",
1725 "inventory::decode_native_ulimits",
1726 "not_applicable",
1727 "not_applicable",
1728 "NativeUlimitObservation::name",
1729 "PLN0017",
1730 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1731 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1732 ),
1733 expected!(
1734 "PLN-FLD-0127",
1735 "container",
1736 "$.HostConfig.Ulimits[].Soft",
1737 "observation-only",
1738 "inventory::decode_native_ulimits",
1739 "not_applicable",
1740 "not_applicable",
1741 "NativeUlimitObservation::soft",
1742 "PLN0017",
1743 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1744 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1745 ),
1746 expected!(
1747 "PLN-FLD-0128",
1748 "container",
1749 "$.HostConfig.Ulimits[].Hard",
1750 "observation-only",
1751 "inventory::decode_native_ulimits",
1752 "not_applicable",
1753 "not_applicable",
1754 "NativeUlimitObservation::hard",
1755 "PLN0017",
1756 "tests::inventory::container_security_namespaces_and_resources_are_typed_effective_observations",
1757 "tests::inventory::container_b3b_malformed_fields_fail_closed"
1758 ),
1759 expected!(
1760 "PLN-FLD-0129",
1761 "volume",
1762 "$.UID",
1763 "observation-only",
1764 "inventory::decode_volume_owner",
1765 "not_applicable",
1766 "not_applicable",
1767 "VolumeObservation::uid",
1768 "PLN0017",
1769 "tests::inventory::volume_owner_ids_preserve_absence_zero_bounds_and_unavailability",
1770 "tests::inventory::volume_owner_ids_preserve_absence_zero_bounds_and_unavailability"
1771 ),
1772 expected!(
1773 "PLN-FLD-0130",
1774 "volume",
1775 "$.GID",
1776 "observation-only",
1777 "inventory::decode_volume_owner",
1778 "not_applicable",
1779 "not_applicable",
1780 "VolumeObservation::gid",
1781 "PLN0017",
1782 "tests::inventory::volume_owner_ids_preserve_absence_zero_bounds_and_unavailability",
1783 "tests::inventory::volume_owner_ids_preserve_absence_zero_bounds_and_unavailability"
1784 ),
1785 b4_input!(
1786 "PLN-FLD-0131",
1787 "volume",
1788 "$.Driver",
1789 "inventory::decode_volume",
1790 "VolumeObservation::driver"
1791 ),
1792 b4_input!(
1793 "PLN-FLD-0132",
1794 "volume",
1795 "$.CreatedAt",
1796 "inventory::decode_volume",
1797 "VolumeObservation::created_at"
1798 ),
1799 b4_input!(
1800 "PLN-FLD-0133",
1801 "volume",
1802 "$.Anonymous",
1803 "inventory::decode_volume",
1804 "VolumeObservation::anonymous"
1805 ),
1806 b4_input!(
1807 "PLN-FLD-0134",
1808 "image",
1809 "$.RepoDigests",
1810 "inventory::decode_image",
1811 "ImageObservation::repo_digests"
1812 ),
1813 b4_input!(
1814 "PLN-FLD-0135",
1815 "image",
1816 "$.Digest",
1817 "inventory::decode_image",
1818 "ImageObservation::digest"
1819 ),
1820 b4_input!(
1821 "PLN-FLD-0136",
1822 "image",
1823 "$.Created",
1824 "inventory::decode_image",
1825 "ImageObservation::created"
1826 ),
1827 b4_input!(
1828 "PLN-FLD-0137",
1829 "image",
1830 "$.Author",
1831 "inventory::decode_image",
1832 "ImageObservation::author"
1833 ),
1834 b4_input!(
1835 "PLN-FLD-0138",
1836 "image",
1837 "$.Architecture",
1838 "inventory::decode_image",
1839 "ImageObservation::architecture"
1840 ),
1841 b4_input!(
1842 "PLN-FLD-0139",
1843 "image",
1844 "$.Os",
1845 "inventory::decode_image",
1846 "ImageObservation::operating_system"
1847 ),
1848 b4_input!(
1849 "PLN-FLD-0140",
1850 "image",
1851 "$.ManifestType",
1852 "inventory::decode_image",
1853 "ImageObservation::manifest_type"
1854 ),
1855 b4_input!(
1856 "PLN-FLD-0141",
1857 "secret",
1858 "$.Spec.Driver.Name",
1859 "inventory::decode_secret_driver",
1860 "NativeSecretDriverObservation::name"
1861 ),
1862 b4_input!(
1863 "PLN-FLD-0142",
1864 "secret",
1865 "$.Spec.Driver.Options",
1866 "inventory::decode_secret_driver",
1867 "NativeSecretDriverObservation::options"
1868 ),
1869 b4_input!(
1870 "PLN-FLD-0143",
1871 "secret",
1872 "$.CreatedAt",
1873 "inventory::decode_secret",
1874 "SecretObservation::created_at"
1875 ),
1876 b4_input!(
1877 "PLN-FLD-0144",
1878 "secret",
1879 "$.UpdatedAt",
1880 "inventory::decode_secret",
1881 "SecretObservation::updated_at"
1882 ),
1883 expected!(
1884 "PLN-FLD-0145",
1885 "container",
1886 "$.NetworkSettings.Networks",
1887 "observation-only",
1888 "inventory::decode_container_networks",
1889 "not_applicable",
1890 "not_applicable",
1891 "NativeNetworkingObservation::networks",
1892 "PLN0017",
1893 "tests::inventory::unpodded_network_settings_preserve_effective_attachment_names_and_reject_malformed_maps",
1894 "tests::inventory::unpodded_network_settings_preserve_effective_attachment_names_and_reject_malformed_maps"
1895 ),
1896 expected!(
1897 "PLN-FLD-0146",
1898 "container",
1899 "$.Mounts.Mode",
1900 "observation-only",
1901 "inventory::decode_mount_selinux_relabel",
1902 "not_applicable",
1903 "not_applicable",
1904 "ContainerMountObservation::selinux_relabel",
1905 "PLN0017",
1906 "tests::inventory::mount_selinux_relabel_is_typed_without_retaining_native_bind_values",
1907 "tests::inventory::conflicting_or_malformed_selinux_relabel_evidence_fails_the_mount_family_closed"
1908 ),
1909 expected!(
1910 "PLN-FLD-0147",
1911 "container",
1912 "$.HostConfig.Binds[*].<SELinuxRelabel>",
1913 "observation-only",
1914 "inventory::decode_native_bind_selinux_relabels",
1915 "not_applicable",
1916 "not_applicable",
1917 "ContainerMountObservation::selinux_relabel",
1918 "PLN0017",
1919 "tests::inventory::mount_selinux_relabel_is_typed_without_retaining_native_bind_values",
1920 "tests::inventory::conflicting_or_malformed_selinux_relabel_evidence_fails_the_mount_family_closed"
1921 ),
1922 runtime_only_input!("PLN-FLD-0148", "container", "$.AppArmorProfile"),
1923 runtime_only_input!("PLN-FLD-0149", "container", "$.Args"),
1924 runtime_only_input!("PLN-FLD-0150", "container", "$.BoundingCaps"),
1925 runtime_only_input!("PLN-FLD-0151", "container", "$.ConmonPidFile"),
1926 runtime_only_input!("PLN-FLD-0152", "container", "$.Created"),
1927 runtime_only_input!("PLN-FLD-0153", "container", "$.Driver"),
1928 runtime_only_input!("PLN-FLD-0154", "container", "$.EffectiveCaps"),
1929 runtime_only_input!("PLN-FLD-0155", "container", "$.ExecIDs"),
1930 runtime_only_input!("PLN-FLD-0156", "container", "$.ExitCommand"),
1931 runtime_only_input!("PLN-FLD-0157", "container", "$.GraphDriver"),
1932 runtime_only_input!("PLN-FLD-0158", "container", "$.HostnamePath"),
1933 runtime_only_input!("PLN-FLD-0159", "container", "$.HostsPath"),
1934 runtime_only_input!("PLN-FLD-0160", "container", "$.LockNumber"),
1935 runtime_only_input!("PLN-FLD-0161", "container", "$.MountLabel"),
1936 runtime_only_input!("PLN-FLD-0162", "container", "$.Namespace"),
1937 runtime_only_input!("PLN-FLD-0163", "container", "$.OCIConfigPath"),
1938 runtime_only_input!("PLN-FLD-0164", "container", "$.OCIRuntime"),
1939 runtime_only_input!("PLN-FLD-0165", "container", "$.Path"),
1940 runtime_only_input!("PLN-FLD-0166", "container", "$.PidFile"),
1941 runtime_only_input!("PLN-FLD-0167", "container", "$.ProcessLabel"),
1942 runtime_only_input!("PLN-FLD-0168", "container", "$.ResolvConfPath"),
1943 runtime_only_input!("PLN-FLD-0169", "container", "$.RestartCount"),
1944 runtime_only_input!("PLN-FLD-0170", "container", "$.Rootfs"),
1945 runtime_only_input!("PLN-FLD-0171", "container", "$.SizeRootFs"),
1946 runtime_only_input!("PLN-FLD-0172", "container", "$.SizeRw"),
1947 runtime_only_input!("PLN-FLD-0173", "container", "$.State"),
1948 runtime_only_input!("PLN-FLD-0174", "container", "$.StaticDir"),
1949 runtime_only_input!("PLN-FLD-0175", "image", "$.GraphDriver"),
1950 runtime_only_input!("PLN-FLD-0176", "image", "$.History"),
1951 runtime_only_input!("PLN-FLD-0177", "image", "$.NamesHistory"),
1952 runtime_only_input!("PLN-FLD-0178", "image", "$.Parent"),
1953 runtime_only_input!("PLN-FLD-0179", "image", "$.RootFS"),
1954 runtime_only_input!("PLN-FLD-0180", "image", "$.Size"),
1955 runtime_only_input!("PLN-FLD-0181", "image", "$.VirtualSize"),
1956 runtime_only_input!("PLN-FLD-0182", "image", "$.Version"),
1957 runtime_only_input!("PLN-FLD-0183", "volume", "$.LockNumber"),
1958 runtime_only_input!("PLN-FLD-0184", "volume", "$.MountCount"),
1959 runtime_only_input!("PLN-FLD-0185", "volume", "$.Mountpoint"),
1960 runtime_only_input!("PLN-FLD-0186", "volume", "$.NeedsChown"),
1961 runtime_only_input!("PLN-FLD-0187", "volume", "$.NeedsCopyUp"),
1962 runtime_only_input!("PLN-FLD-0188", "volume", "$.Scope"),
1963 runtime_only_input!("PLN-FLD-0189", "network", "$.containers"),
1964 runtime_only_input!("PLN-FLD-0190", "network", "$.created"),
1965 expected!(
1966 "PLN-FLD-0191",
1967 "container",
1968 "$.Config.CreateCommand",
1969 "observation-only",
1970 "inventory::decode_container_creation_evidence",
1971 "not_applicable",
1972 "not_applicable",
1973 "ContainerObservation::creation_evidence",
1974 "PLN0050",
1975 "tests::inventory::creation_evidence_is_typed_indexed_and_redacts_command_values",
1976 "tests::inventory::typed_mount_relabel_state_only_conflicts_when_observed_and_different"
1977 ),
1978];
1979
1980const ALL_REVIEWED_TARGETS: &[&str] = &["5.4.0", "5.5.0", "5.6.0", "5.7.0", "5.8.6", "6.0.0", "6.1.0"];
1981const UNLIMITED_RLIMIT_TARGETS: &[&str] = &["5.6.0", "5.7.0", "5.8.6", "6.0.0", "6.1.0"];
1982const JOURNALD_LABEL_TARGETS: &[&str] = &["6.0.0", "6.1.0"];
1983const B4_VERSIONED_TARGETS: &[&str] = &["5.6.0", "5.7.0", "5.8.6", "6.0.0", "6.1.0"];
1984
1985struct ExpectedOutputEntry {
1986 id: &'static str,
1987 resource_kind: &'static str,
1988 field_path: &'static str,
1989 classification: &'static str,
1990 target_versions: &'static [&'static str],
1991 planner: &'static str,
1992 cli_renderer: &'static str,
1993 libpod_renderer: &'static str,
1994 public_contract: &'static str,
1995 finding: &'static str,
1996 positive_test: &'static str,
1997 negative_test: &'static str,
1998}
1999
2000macro_rules! output {
2001 ($id:literal, $field_path:literal, $classification:literal, $target_versions:expr, $public_contract:literal, $positive_test:expr, $negative_test:expr) => {
2002 ExpectedOutputEntry {
2003 id: $id,
2004 resource_kind: "container",
2005 field_path: $field_path,
2006 classification: $classification,
2007 target_versions: $target_versions,
2008 planner: "deployment::validate_runtime_settings",
2009 cli_renderer: "render::append_container_runtime_arguments",
2010 libpod_renderer: "render::append_container_runtime_json",
2011 public_contract: $public_contract,
2012 finding: "PLN0046",
2013 positive_test: $positive_test,
2014 negative_test: $negative_test,
2015 }
2016 };
2017 (manual $id:literal, $field_path:literal, $public_contract:literal) => {
2018 ExpectedOutputEntry {
2019 id: $id,
2020 resource_kind: "container",
2021 field_path: $field_path,
2022 classification: "manual",
2023 target_versions: ALL_REVIEWED_TARGETS,
2024 planner: "deployment::validate_runtime_settings",
2025 cli_renderer: "render::unsupported_runtime_fields",
2026 libpod_renderer: "render::health_command_json",
2027 public_contract: $public_contract,
2028 finding: "PLN0046",
2029 positive_test: "tests::runtime::sensitive_health_command_blocks_the_resource_without_leaking_an_artifact",
2030 negative_test: "tests::runtime::sensitive_health_commands_never_leak_from_runtime_debug",
2031 }
2032 };
2033}
2034
2035macro_rules! b4_output {
2036 ($id:literal, $resource_kind:literal, $field_path:literal, $classification:literal, $target_versions:expr, $planner:literal, $cli_renderer:literal, $libpod_renderer:literal, $public_contract:literal, $positive_test:literal, $negative_test:literal) => {
2037 ExpectedOutputEntry {
2038 id: $id,
2039 resource_kind: $resource_kind,
2040 field_path: $field_path,
2041 classification: $classification,
2042 target_versions: $target_versions,
2043 planner: $planner,
2044 cli_renderer: $cli_renderer,
2045 libpod_renderer: $libpod_renderer,
2046 public_contract: $public_contract,
2047 finding: "PLN0046",
2048 positive_test: $positive_test,
2049 negative_test: $negative_test,
2050 }
2051 };
2052 (manual $id:literal, $resource_kind:literal, $field_path:literal, $planner:literal, $cli_renderer:literal, $libpod_renderer:literal, $public_contract:literal, $positive_test:literal, $negative_test:literal) => {
2053 b4_output!(
2054 $id,
2055 $resource_kind,
2056 $field_path,
2057 "manual",
2058 ALL_REVIEWED_TARGETS,
2059 $planner,
2060 $cli_renderer,
2061 $libpod_renderer,
2062 $public_contract,
2063 $positive_test,
2064 $negative_test
2065 )
2066 };
2067}
2068
2069const RUNTIME_RENDER_POSITIVE: &str = "tests::runtime::bounded_runtime_intent_plans_and_renders_exactly";
2070const RUNTIME_RENDER_NEGATIVE: &str =
2071 "tests::runtime::bounded_runtime_values_reject_invalid_inputs_and_preserve_explicit_false";
2072
2073const EXPECTED_OUTPUT_ENTRIES: &[ExpectedOutputEntry] = &[
2074 output!(
2075 "PLN-OUT-0001",
2076 "runtime.health.disabled",
2077 "supported-exact",
2078 ALL_REVIEWED_TARGETS,
2079 "ContainerRuntimeSettings::health",
2080 RUNTIME_RENDER_POSITIVE,
2081 RUNTIME_RENDER_NEGATIVE
2082 ),
2083 output!(
2084 "PLN-OUT-0002",
2085 "runtime.health.command.public",
2086 "supported-exact",
2087 ALL_REVIEWED_TARGETS,
2088 "ConfiguredHealthCheck::command",
2089 RUNTIME_RENDER_POSITIVE,
2090 RUNTIME_RENDER_NEGATIVE
2091 ),
2092 output!(
2093 "PLN-OUT-0003",
2094 "runtime.health.interval",
2095 "supported-exact",
2096 ALL_REVIEWED_TARGETS,
2097 "ConfiguredHealthCheck::interval",
2098 RUNTIME_RENDER_POSITIVE,
2099 RUNTIME_RENDER_NEGATIVE
2100 ),
2101 output!(
2102 "PLN-OUT-0004",
2103 "runtime.health.timeout",
2104 "supported-exact",
2105 ALL_REVIEWED_TARGETS,
2106 "ConfiguredHealthCheck::timeout",
2107 RUNTIME_RENDER_POSITIVE,
2108 RUNTIME_RENDER_NEGATIVE
2109 ),
2110 output!(
2111 "PLN-OUT-0005",
2112 "runtime.health.retries",
2113 "supported-exact",
2114 ALL_REVIEWED_TARGETS,
2115 "ConfiguredHealthCheck::retries",
2116 RUNTIME_RENDER_POSITIVE,
2117 RUNTIME_RENDER_NEGATIVE
2118 ),
2119 output!(
2120 "PLN-OUT-0006",
2121 "runtime.health.start_period",
2122 "supported-exact",
2123 ALL_REVIEWED_TARGETS,
2124 "ConfiguredHealthCheck::start_period",
2125 RUNTIME_RENDER_POSITIVE,
2126 RUNTIME_RENDER_NEGATIVE
2127 ),
2128 output!(
2129 "PLN-OUT-0007",
2130 "runtime.health.on_failure",
2131 "supported-exact",
2132 ALL_REVIEWED_TARGETS,
2133 "ConfiguredHealthCheck::on_failure",
2134 RUNTIME_RENDER_POSITIVE,
2135 RUNTIME_RENDER_NEGATIVE
2136 ),
2137 output!(
2138 "PLN-OUT-0008",
2139 "runtime.startup_health.command.public",
2140 "supported-exact",
2141 ALL_REVIEWED_TARGETS,
2142 "StartupHealthCheck::command",
2143 RUNTIME_RENDER_POSITIVE,
2144 RUNTIME_RENDER_NEGATIVE
2145 ),
2146 output!(
2147 "PLN-OUT-0009",
2148 "runtime.startup_health.interval",
2149 "supported-exact",
2150 ALL_REVIEWED_TARGETS,
2151 "StartupHealthCheck::interval",
2152 RUNTIME_RENDER_POSITIVE,
2153 RUNTIME_RENDER_NEGATIVE
2154 ),
2155 output!(
2156 "PLN-OUT-0010",
2157 "runtime.startup_health.timeout",
2158 "supported-exact",
2159 ALL_REVIEWED_TARGETS,
2160 "StartupHealthCheck::timeout",
2161 RUNTIME_RENDER_POSITIVE,
2162 RUNTIME_RENDER_NEGATIVE
2163 ),
2164 output!(
2165 "PLN-OUT-0011",
2166 "runtime.startup_health.retries",
2167 "supported-exact",
2168 ALL_REVIEWED_TARGETS,
2169 "StartupHealthCheck::retries",
2170 RUNTIME_RENDER_POSITIVE,
2171 RUNTIME_RENDER_NEGATIVE
2172 ),
2173 output!(
2174 "PLN-OUT-0012",
2175 "runtime.startup_health.successes",
2176 "supported-exact",
2177 ALL_REVIEWED_TARGETS,
2178 "StartupHealthCheck::successes",
2179 RUNTIME_RENDER_POSITIVE,
2180 RUNTIME_RENDER_NEGATIVE
2181 ),
2182 output!(
2183 "PLN-OUT-0013",
2184 "runtime.logging.driver",
2185 "supported-exact",
2186 ALL_REVIEWED_TARGETS,
2187 "LoggingSettings::driver",
2188 RUNTIME_RENDER_POSITIVE,
2189 RUNTIME_RENDER_NEGATIVE
2190 ),
2191 output!(
2192 "PLN-OUT-0014",
2193 "runtime.logging.max_size",
2194 "supported-exact",
2195 ALL_REVIEWED_TARGETS,
2196 "LoggingSettings::max_size",
2197 RUNTIME_RENDER_POSITIVE,
2198 RUNTIME_RENDER_NEGATIVE
2199 ),
2200 output!(
2201 "PLN-OUT-0015",
2202 "runtime.logging.journald_labels",
2203 "target-gated",
2204 JOURNALD_LABEL_TARGETS,
2205 "LoggingSettings::journald_labels",
2206 "tests::runtime::journald_labels_are_supported_from_podman_six_in_every_reviewed_target",
2207 "tests::runtime::journald_labels_are_supported_from_podman_six_in_every_reviewed_target"
2208 ),
2209 output!(
2210 "PLN-OUT-0016",
2211 "runtime.security.privileged",
2212 "supported-exact",
2213 ALL_REVIEWED_TARGETS,
2214 "SecuritySettings::privileged",
2215 RUNTIME_RENDER_POSITIVE,
2216 RUNTIME_RENDER_NEGATIVE
2217 ),
2218 output!(
2219 "PLN-OUT-0017",
2220 "runtime.security.cap_add",
2221 "supported-exact",
2222 ALL_REVIEWED_TARGETS,
2223 "SecuritySettings::cap_add",
2224 RUNTIME_RENDER_POSITIVE,
2225 RUNTIME_RENDER_NEGATIVE
2226 ),
2227 output!(
2228 "PLN-OUT-0018",
2229 "runtime.security.cap_drop",
2230 "supported-exact",
2231 ALL_REVIEWED_TARGETS,
2232 "SecuritySettings::cap_drop",
2233 RUNTIME_RENDER_POSITIVE,
2234 RUNTIME_RENDER_NEGATIVE
2235 ),
2236 output!(
2237 "PLN-OUT-0019",
2238 "runtime.security.no_new_privileges",
2239 "supported-exact",
2240 ALL_REVIEWED_TARGETS,
2241 "SecuritySettings::no_new_privileges",
2242 RUNTIME_RENDER_POSITIVE,
2243 RUNTIME_RENDER_NEGATIVE
2244 ),
2245 output!(
2246 "PLN-OUT-0020",
2247 "runtime.security.read_only_filesystem",
2248 "supported-exact",
2249 ALL_REVIEWED_TARGETS,
2250 "SecuritySettings::read_only_filesystem",
2251 RUNTIME_RENDER_POSITIVE,
2252 RUNTIME_RENDER_NEGATIVE
2253 ),
2254 output!(
2255 "PLN-OUT-0021",
2256 "runtime.security.read_write_tmpfs",
2257 "supported-exact",
2258 ALL_REVIEWED_TARGETS,
2259 "SecuritySettings::read_write_tmpfs",
2260 RUNTIME_RENDER_POSITIVE,
2261 RUNTIME_RENDER_NEGATIVE
2262 ),
2263 output!(
2264 "PLN-OUT-0022",
2265 "runtime.namespaces.pid",
2266 "supported-exact",
2267 ALL_REVIEWED_TARGETS,
2268 "ContainerNamespaceSettings::pid",
2269 RUNTIME_RENDER_POSITIVE,
2270 RUNTIME_RENDER_NEGATIVE
2271 ),
2272 output!(
2273 "PLN-OUT-0023",
2274 "runtime.namespaces.ipc",
2275 "supported-exact",
2276 ALL_REVIEWED_TARGETS,
2277 "ContainerNamespaceSettings::ipc",
2278 RUNTIME_RENDER_POSITIVE,
2279 RUNTIME_RENDER_NEGATIVE
2280 ),
2281 output!(
2282 "PLN-OUT-0024",
2283 "runtime.namespaces.uts",
2284 "supported-exact",
2285 ALL_REVIEWED_TARGETS,
2286 "ContainerNamespaceSettings::uts",
2287 RUNTIME_RENDER_POSITIVE,
2288 RUNTIME_RENDER_NEGATIVE
2289 ),
2290 output!(
2291 "PLN-OUT-0025",
2292 "runtime.namespaces.cgroup",
2293 "supported-exact",
2294 ALL_REVIEWED_TARGETS,
2295 "ContainerNamespaceSettings::cgroup",
2296 RUNTIME_RENDER_POSITIVE,
2297 RUNTIME_RENDER_NEGATIVE
2298 ),
2299 output!(
2300 "PLN-OUT-0026",
2301 "runtime.resources.cpu_shares",
2302 "supported-exact",
2303 ALL_REVIEWED_TARGETS,
2304 "ContainerResourceControls::cpu_shares",
2305 RUNTIME_RENDER_POSITIVE,
2306 RUNTIME_RENDER_NEGATIVE
2307 ),
2308 output!(
2309 "PLN-OUT-0027",
2310 "runtime.resources.cpu_period",
2311 "supported-exact",
2312 ALL_REVIEWED_TARGETS,
2313 "ContainerResourceControls::cpu_period",
2314 RUNTIME_RENDER_POSITIVE,
2315 RUNTIME_RENDER_NEGATIVE
2316 ),
2317 output!(
2318 "PLN-OUT-0028",
2319 "runtime.resources.cpu_quota",
2320 "supported-exact",
2321 ALL_REVIEWED_TARGETS,
2322 "ContainerResourceControls::cpu_quota",
2323 "tests::runtime::finite_bounded_runtime_fields_render_for_every_reviewed_target",
2324 "tests::runtime::cpu_quota_accepts_only_exact_positive_millisecond_values"
2325 ),
2326 output!(
2327 "PLN-OUT-0029",
2328 "runtime.resources.memory_bytes",
2329 "supported-exact",
2330 ALL_REVIEWED_TARGETS,
2331 "ContainerResourceControls::memory_bytes",
2332 RUNTIME_RENDER_POSITIVE,
2333 RUNTIME_RENDER_NEGATIVE
2334 ),
2335 output!(
2336 "PLN-OUT-0030",
2337 "runtime.resources.pids",
2338 "supported-exact",
2339 ALL_REVIEWED_TARGETS,
2340 "ContainerResourceControls::pids",
2341 RUNTIME_RENDER_POSITIVE,
2342 RUNTIME_RENDER_NEGATIVE
2343 ),
2344 output!(
2345 "PLN-OUT-0031",
2346 "runtime.resources.rlimits.finite",
2347 "supported-exact",
2348 ALL_REVIEWED_TARGETS,
2349 "ContainerResourceControls::rlimits",
2350 RUNTIME_RENDER_POSITIVE,
2351 RUNTIME_RENDER_NEGATIVE
2352 ),
2353 output!(
2354 "PLN-OUT-0032",
2355 "runtime.resources.rlimits.unlimited",
2356 "target-gated",
2357 UNLIMITED_RLIMIT_TARGETS,
2358 "ContainerResourceControls::rlimits",
2359 "tests::runtime::unlimited_rlimits_are_supported_from_podman_five_six_in_every_reviewed_target",
2360 "tests::runtime::unlimited_rlimits_are_supported_from_podman_five_six_in_every_reviewed_target"
2361 ),
2362 output!(manual "PLN-OUT-0033", "runtime.health.command.sensitive", "HealthCommand"),
2363 output!(manual "PLN-OUT-0034", "runtime.startup_health.command.sensitive", "HealthCommand"),
2364 b4_output!(
2365 "PLN-OUT-0035",
2366 "container",
2367 "mount.named_volume.copy",
2368 "supported-exact",
2369 ALL_REVIEWED_TARGETS,
2370 "deployment::validate_mounts",
2371 "render::append_mount_arguments",
2372 "render::mount_json",
2373 "MountIntent::NamedVolume",
2374 "tests::render::b4_bind_tmpfs_ordinary_volume_and_secret_grants_are_exact_on_all_reviewed_targets",
2375 "tests::render::b4_version_and_portability_boundaries_block_the_complete_resource_artifact"
2376 ),
2377 b4_output!(
2378 "PLN-OUT-0036",
2379 "container",
2380 "mount.named_volume.copy.subpath",
2381 "supported-exact",
2382 ALL_REVIEWED_TARGETS,
2383 "deployment::validate_mounts",
2384 "render::append_mount_arguments",
2385 "render::mount_json",
2386 "NamedVolumeMount::set_subpath",
2387 "tests::render::b4_mounts_secrets_and_volume_ownership_are_exact_on_every_supported_target",
2388 "tests::deployment::b4_typed_mounts_volume_ownership_and_secret_grants_preserve_all_optional_states"
2389 ),
2390 b4_output!(
2391 "PLN-OUT-0037",
2392 "container",
2393 "mount.named_volume.nocopy",
2394 "supported-exact",
2395 ALL_REVIEWED_TARGETS,
2396 "deployment::validate_mounts",
2397 "render::append_mount_arguments",
2398 "render::mount_json",
2399 "MountIntent::NamedVolume",
2400 "tests::render::b4_bind_tmpfs_ordinary_volume_and_secret_grants_are_exact_on_all_reviewed_targets",
2401 "tests::deployment::b4_typed_mounts_volume_ownership_and_secret_grants_preserve_all_optional_states"
2402 ),
2403 b4_output!(manual
2404 "PLN-OUT-0038", "container", "mount.named_volume.nocopy.subpath", "deployment::validate_mounts",
2405 "render::unsupported_fields", "render::mount_json", "NamedVolumeMount::set_subpath",
2406 "tests::render::b4_version_and_portability_boundaries_block_the_complete_resource_artifact",
2407 "tests::deployment::b4_typed_mounts_volume_ownership_and_secret_grants_preserve_all_optional_states"
2408 ),
2409 b4_output!(
2410 "PLN-OUT-0039",
2411 "container",
2412 "mount.bind",
2413 "supported-exact",
2414 ALL_REVIEWED_TARGETS,
2415 "deployment::validate_mounts",
2416 "render::append_mount_arguments",
2417 "render::native_mount_json",
2418 "MountIntent::Bind",
2419 "tests::render::b4_bind_tmpfs_ordinary_volume_and_secret_grants_are_exact_on_all_reviewed_targets",
2420 "tests::render::b4_version_and_portability_boundaries_block_the_complete_resource_artifact"
2421 ),
2422 b4_output!(
2423 "PLN-OUT-0040",
2424 "container",
2425 "mount.tmpfs",
2426 "supported-exact",
2427 ALL_REVIEWED_TARGETS,
2428 "deployment::validate_mounts",
2429 "render::append_mount_arguments",
2430 "render::native_mount_json",
2431 "MountIntent::Tmpfs",
2432 "tests::render::b4_bind_tmpfs_ordinary_volume_and_secret_grants_are_exact_on_all_reviewed_targets",
2433 "tests::render::b4_version_and_portability_boundaries_block_the_complete_resource_artifact"
2434 ),
2435 b4_output!(
2436 "PLN-OUT-0041",
2437 "container",
2438 "secret_grant.mount",
2439 "supported-exact",
2440 ALL_REVIEWED_TARGETS,
2441 "deployment::validate_secret_grants",
2442 "render::append_secret_grants_arguments",
2443 "render::append_secret_grants_json",
2444 "SecretGrant::Mount",
2445 "tests::render::b4_secret_mount_default_and_explicit_modes_are_exact_on_all_reviewed_targets",
2446 "tests::render::b4_version_and_portability_boundaries_block_the_complete_resource_artifact"
2447 ),
2448 b4_output!(
2449 "PLN-OUT-0042",
2450 "container",
2451 "secret_grant.environment",
2452 "supported-exact",
2453 ALL_REVIEWED_TARGETS,
2454 "deployment::validate_secret_grants",
2455 "render::append_secret_grants_arguments",
2456 "render::append_secret_grants_json",
2457 "SecretGrant::Environment",
2458 "tests::render::renderer_renders_typed_secret_grants_without_exposing_secret_material",
2459 "tests::render::b4_version_and_portability_boundaries_block_the_complete_resource_artifact"
2460 ),
2461 b4_output!(
2462 "PLN-OUT-0043",
2463 "volume",
2464 "ownership.uid",
2465 "target-gated",
2466 B4_VERSIONED_TARGETS,
2467 "deployment::validate_volume_ownership",
2468 "render::volume_create_cli_arguments",
2469 "render::volume_create_json",
2470 "VolumeIntent::uid",
2471 "tests::render::b4_mounts_secrets_and_volume_ownership_are_exact_on_every_supported_target",
2472 "tests::render::b4_version_and_portability_boundaries_block_the_complete_resource_artifact"
2473 ),
2474 b4_output!(
2475 "PLN-OUT-0044",
2476 "volume",
2477 "ownership.gid",
2478 "target-gated",
2479 B4_VERSIONED_TARGETS,
2480 "deployment::validate_volume_ownership",
2481 "render::volume_create_cli_arguments",
2482 "render::volume_create_json",
2483 "VolumeIntent::gid",
2484 "tests::render::b4_mounts_secrets_and_volume_ownership_are_exact_on_every_supported_target",
2485 "tests::render::b4_version_and_portability_boundaries_block_the_complete_resource_artifact"
2486 ),
2487 b4_output!(
2488 "PLN-OUT-0045",
2489 "image",
2490 "pull_policy.always",
2491 "target-gated",
2492 B4_VERSIONED_TARGETS,
2493 "deployment::validate_image_policy",
2494 "render::render_operation",
2495 "render::render_operation",
2496 "ImagePullPolicy::Always",
2497 "tests::render::b4_image_pull_policies_are_exact_on_every_supported_target",
2498 "tests::render::b4_image_pull_policies_are_exact_on_every_supported_target"
2499 ),
2500 b4_output!(
2501 "PLN-OUT-0046",
2502 "image",
2503 "pull_policy.missing",
2504 "target-gated",
2505 B4_VERSIONED_TARGETS,
2506 "deployment::validate_image_policy",
2507 "render::render_operation",
2508 "render::render_operation",
2509 "ImagePullPolicy::Missing",
2510 "tests::render::b4_image_pull_policies_are_exact_on_every_supported_target",
2511 "tests::render::b4_image_pull_policies_are_exact_on_every_supported_target"
2512 ),
2513 b4_output!(
2514 "PLN-OUT-0047",
2515 "image",
2516 "pull_policy.never",
2517 "target-gated",
2518 B4_VERSIONED_TARGETS,
2519 "deployment::validate_image_policy",
2520 "render::render_operation",
2521 "render::render_operation",
2522 "ImagePullPolicy::Never",
2523 "tests::render::b4_image_pull_policies_are_exact_on_every_supported_target",
2524 "tests::render::b4_image_pull_policies_are_exact_on_every_supported_target"
2525 ),
2526 b4_output!(
2527 "PLN-OUT-0048",
2528 "image",
2529 "pull_policy.newer",
2530 "target-gated",
2531 B4_VERSIONED_TARGETS,
2532 "deployment::validate_image_policy",
2533 "render::render_operation",
2534 "render::render_operation",
2535 "ImagePullPolicy::Newer",
2536 "tests::render::b4_image_pull_policies_are_exact_on_every_supported_target",
2537 "tests::render::b4_image_pull_policies_are_exact_on_every_supported_target"
2538 ),
2539 b4_output!(manual
2540 "PLN-OUT-0049", "image", "source.portability", "deployment::validate_image_source", "render::unsupported_fields",
2541 "render::render_operation", "ImageSource::classification",
2542 "tests::render::b4_image_portability_manual_boundaries_block_the_complete_artifact",
2543 "tests::deployment::image_source_classification_requires_explicit_policy_and_preserves_manual_boundaries"
2544 ),
2545 b4_output!(manual
2546 "PLN-OUT-0050", "pod", "infra_mounts", "deployment::validate_mounts", "render::unsupported_fields",
2547 "render::render_operation", "PodIntent::infra_mounts",
2548 "tests::render::b4_pod_infra_mounts_block_without_a_partial_artifact",
2549 "tests::deployment::infra_container_mounts_support_managed_external_and_duplicate_boundaries"
2550 ),
2551];
2552
2553#[derive(Clone, Debug, Deserialize, Eq, PartialEq)]
2555#[serde(deny_unknown_fields)]
2556pub struct NativeFieldCoverageEntry {
2557 id: String,
2558 plane: NativeFieldCoveragePlane,
2559 resource_kind: String,
2560 field_path: String,
2561 classification: NativeFieldCoverageClassification,
2562 observation: String,
2563 planner: String,
2564 cli_renderer: String,
2565 libpod_renderer: String,
2566 target_versions: Vec<String>,
2567 public_contract: String,
2568 finding: String,
2569 positive_test: String,
2570 negative_test: String,
2571}
2572
2573impl NativeFieldCoverageEntry {
2574 #[must_use]
2576 pub fn id(&self) -> &str {
2577 &self.id
2578 }
2579
2580 #[must_use]
2582 pub const fn plane(&self) -> NativeFieldCoveragePlane {
2583 self.plane
2584 }
2585
2586 #[must_use]
2588 pub fn resource_kind(&self) -> &str {
2589 &self.resource_kind
2590 }
2591
2592 #[must_use]
2594 pub fn field_path(&self) -> &str {
2595 &self.field_path
2596 }
2597
2598 #[must_use]
2600 pub const fn classification(&self) -> NativeFieldCoverageClassification {
2601 self.classification
2602 }
2603
2604 #[must_use]
2606 pub fn observation(&self) -> &str {
2607 &self.observation
2608 }
2609
2610 #[must_use]
2612 pub fn planner(&self) -> &str {
2613 &self.planner
2614 }
2615
2616 #[must_use]
2618 pub fn cli_renderer(&self) -> &str {
2619 &self.cli_renderer
2620 }
2621
2622 #[must_use]
2624 pub fn libpod_renderer(&self) -> &str {
2625 &self.libpod_renderer
2626 }
2627
2628 #[must_use]
2630 pub fn target_versions(&self) -> &[String] {
2631 &self.target_versions
2632 }
2633
2634 #[must_use]
2636 pub fn public_contract(&self) -> &str {
2637 &self.public_contract
2638 }
2639
2640 #[must_use]
2642 pub fn finding(&self) -> &str {
2643 &self.finding
2644 }
2645
2646 #[must_use]
2648 pub fn positive_test(&self) -> &str {
2649 &self.positive_test
2650 }
2651
2652 #[must_use]
2654 pub fn negative_test(&self) -> &str {
2655 &self.negative_test
2656 }
2657}
2658
2659#[derive(Deserialize)]
2660#[serde(deny_unknown_fields)]
2661struct CoverageCatalogue {
2662 schema_version: u8,
2663 scope: String,
2664 entries: Vec<NativeFieldCoverageEntry>,
2665}
2666
2667pub fn native_field_coverage_catalogue() -> PodmanLensResult<Vec<NativeFieldCoverageEntry>> {
2674 parse_native_field_coverage_catalogue(COVERAGE_CATALOGUE_JSON)
2675}
2676
2677fn parse_native_field_coverage_catalogue(source: &str) -> PodmanLensResult<Vec<NativeFieldCoverageEntry>> {
2678 let catalogue: CoverageCatalogue =
2679 serde_json::from_str(source).map_err(|_| Diagnostic::new(DiagnosticCode::NativeFieldCoverageUnavailable))?;
2680 if catalogue.schema_version != 3
2681 || catalogue.scope != "m2-input-observation-and-m6-b3-b4-output-intent"
2682 || !valid_entries(&catalogue.entries)
2683 {
2684 return Err(Diagnostic::new(DiagnosticCode::NativeFieldCoverageUnavailable));
2685 }
2686 Ok(catalogue.entries)
2687}
2688
2689fn valid_entries(entries: &[NativeFieldCoverageEntry]) -> bool {
2690 entries.len() == EXPECTED_INPUT_ENTRIES.len() + EXPECTED_OUTPUT_ENTRIES.len()
2691 && entries
2692 .iter()
2693 .take(EXPECTED_INPUT_ENTRIES.len())
2694 .zip(EXPECTED_INPUT_ENTRIES)
2695 .all(|(entry, expected)| {
2696 entry.plane == NativeFieldCoveragePlane::InputObservation
2697 && entry.id == expected.id
2698 && entry.resource_kind == expected.resource_kind
2699 && entry.field_path == expected.native_path
2700 && entry.classification.as_str() == expected.classification
2701 && entry.observation == expected.decoder
2702 && entry.planner == expected.planner
2703 && entry.cli_renderer == expected.renderer
2704 && entry.libpod_renderer == expected.renderer
2705 && entry.target_versions.is_empty()
2706 && entry.public_contract == expected.public_contract
2707 && entry.finding == expected.finding
2708 && entry.positive_test == expected.positive_test
2709 && entry.negative_test == expected.negative_test
2710 && valid_reference(&entry.observation, "inventory::")
2711 && valid_reference(&entry.planner, "")
2712 && valid_reference(&entry.cli_renderer, "")
2713 && valid_reference(&entry.libpod_renderer, "")
2714 && valid_field_path(&entry.field_path, "$")
2715 && valid_semantic_links(entry)
2716 })
2717 && entries
2718 .iter()
2719 .skip(EXPECTED_INPUT_ENTRIES.len())
2720 .zip(EXPECTED_OUTPUT_ENTRIES)
2721 .all(|(entry, expected)| {
2722 entry.plane == NativeFieldCoveragePlane::OutputIntent
2723 && entry.id == expected.id
2724 && entry.resource_kind == expected.resource_kind
2725 && entry.field_path == expected.field_path
2726 && entry.classification.as_str() == expected.classification
2727 && entry.observation == "not_applicable"
2728 && entry.planner == expected.planner
2729 && entry.cli_renderer == expected.cli_renderer
2730 && entry.libpod_renderer == expected.libpod_renderer
2731 && entry
2732 .target_versions
2733 .iter()
2734 .map(String::as_str)
2735 .eq(expected.target_versions.iter().copied())
2736 && entry.public_contract == expected.public_contract
2737 && entry.finding == expected.finding
2738 && entry.positive_test == expected.positive_test
2739 && entry.negative_test == expected.negative_test
2740 && valid_field_path(
2741 &entry.field_path,
2742 match expected.resource_kind {
2743 "container" => {
2744 if expected.field_path.starts_with("runtime.") {
2745 "runtime."
2746 } else if expected.field_path.starts_with("mount.") {
2747 "mount."
2748 } else {
2749 "secret_grant."
2750 }
2751 }
2752 "volume" => "ownership.",
2753 "image" => {
2754 if expected.field_path.starts_with("pull_policy.") {
2755 "pull_policy."
2756 } else {
2757 "source."
2758 }
2759 }
2760 "pod" => "infra_mounts",
2761 _ => return false,
2762 },
2763 )
2764 && valid_semantic_links(entry)
2765 })
2766}
2767
2768fn valid_semantic_links(entry: &NativeFieldCoverageEntry) -> bool {
2769 valid_reference(&entry.public_contract, "")
2770 && valid_diagnostic(&entry.finding)
2771 && valid_reference(&entry.positive_test, "tests::")
2772 && valid_reference(&entry.negative_test, "tests::")
2773 && entry
2774 .target_versions
2775 .iter()
2776 .all(|version| ALL_REVIEWED_TARGETS.contains(&version.as_str()))
2777}
2778
2779fn valid_field_path(value: &str, required_prefix: &str) -> bool {
2780 value.starts_with(required_prefix)
2781 && value.len() <= 160
2782 && value.bytes().all(|byte| {
2783 byte.is_ascii_alphanumeric() || matches!(byte, b'$' | b'.' | b'_' | b'<' | b'>' | b'*' | b'[' | b']')
2784 })
2785}
2786
2787fn valid_reference(value: &str, required_prefix: &str) -> bool {
2788 !value.is_empty()
2789 && value.len() <= 160
2790 && value.starts_with(required_prefix)
2791 && value
2792 .bytes()
2793 .all(|byte| byte.is_ascii_alphanumeric() || matches!(byte, b':' | b'_' | b'-'))
2794}
2795
2796fn valid_diagnostic(value: &str) -> bool {
2797 value.len() == 7 && value.starts_with("PLN") && value.as_bytes()[3..].iter().all(u8::is_ascii_digit)
2798}
2799
2800#[cfg(test)]
2801mod tests {
2802 use super::{COVERAGE_CATALOGUE_JSON, parse_native_field_coverage_catalogue};
2803
2804 fn mutate_first_entry(field: &str, value: &str) -> Result<String, serde_json::Error> {
2805 let mut catalogue: serde_json::Value = serde_json::from_str(COVERAGE_CATALOGUE_JSON)?;
2806 catalogue["entries"][0][field] = serde_json::Value::String(value.to_owned());
2807 serde_json::to_string(&catalogue)
2808 }
2809
2810 #[test]
2811 fn embedded_coverage_catalogue_is_strict_and_complete() {
2812 assert!(parse_native_field_coverage_catalogue(COVERAGE_CATALOGUE_JSON).is_ok());
2813 }
2814
2815 #[test]
2816 fn malformed_or_incomplete_coverage_catalogue_is_rejected() {
2817 for (from, to) in [
2818 ("\"schema_version\": 3", "\"schema_version\": 1"),
2819 ("\"PLN-FLD-0037\"", "\"PLN-FLD-9999\""),
2820 ("\"observation\"", "\"unknown_observation\""),
2821 ] {
2822 assert!(
2823 parse_native_field_coverage_catalogue(&COVERAGE_CATALOGUE_JSON.replacen(from, to, 1)).is_err(),
2824 "mutation {from} -> {to} must fail"
2825 );
2826 }
2827 }
2828
2829 #[test]
2830 fn every_semantic_ledger_link_is_pinned_to_the_expected_row() -> Result<(), serde_json::Error> {
2831 for (field, value) in [
2832 ("classification", "manual"),
2833 ("observation", "inventory::decode_pod"),
2834 ("planner", "deployment::plan"),
2835 ("cli_renderer", "render::deployment"),
2836 ("libpod_renderer", "render::deployment"),
2837 ("public_contract", "ObservationHeader::findings"),
2838 ("finding", "PLN0046"),
2839 (
2840 "positive_test",
2841 "tests::inventory::memory_swappiness_normalizes_system_default_and_rejects_invalid_values",
2842 ),
2843 (
2844 "negative_test",
2845 "tests::inventory::modeled_nested_boundaries_report_the_precise_path_without_hiding_the_record",
2846 ),
2847 ] {
2848 assert!(
2849 parse_native_field_coverage_catalogue(&mutate_first_entry(field, value)?).is_err(),
2850 "altered {field} must fail"
2851 );
2852 }
2853 Ok(())
2854 }
2855
2856 #[test]
2857 fn plausible_target_availability_swaps_are_rejected() -> Result<(), Box<dyn std::error::Error>> {
2858 let mut catalogue: serde_json::Value = serde_json::from_str(COVERAGE_CATALOGUE_JSON)?;
2859 let entry_index = |id| -> Result<usize, String> {
2860 catalogue["entries"]
2861 .as_array()
2862 .and_then(|entries| entries.iter().position(|entry| entry["id"] == id))
2863 .ok_or_else(|| format!("the embedded ledger must contain {id}"))
2864 };
2865 let journald = entry_index("PLN-OUT-0015")?;
2866 let unlimited_rlimit = entry_index("PLN-OUT-0032")?;
2867 let journald_versions = catalogue["entries"][journald]["target_versions"].clone();
2868 catalogue["entries"][journald]["target_versions"] =
2869 catalogue["entries"][unlimited_rlimit]["target_versions"].clone();
2870 catalogue["entries"][unlimited_rlimit]["target_versions"] = journald_versions;
2871 assert!(parse_native_field_coverage_catalogue(&serde_json::to_string(&catalogue)?).is_err());
2872 Ok(())
2873 }
2874}