1use std::time::Duration;
35
36use mz_ore::now::EpochMillis;
37use proptest_derive::Arbitrary;
38use serde::{Deserialize, Serialize};
39
40#[derive(
42 Clone,
43 Debug,
44 Serialize,
45 Deserialize,
46 PartialOrd,
47 PartialEq,
48 Eq,
49 Ord,
50 Hash,
51 Arbitrary
52)]
53pub enum VersionedEvent {
54 V1(EventV1),
55}
56
57impl VersionedEvent {
58 pub fn new(
64 id: u64,
65 event_type: EventType,
66 object_type: ObjectType,
67 details: EventDetails,
68 user: Option<String>,
69 occurred_at: EpochMillis,
70 ) -> Self {
71 Self::V1(EventV1::new(
72 id,
73 event_type,
74 object_type,
75 details,
76 user,
77 occurred_at,
78 ))
79 }
80
81 pub fn deserialize(data: &[u8]) -> Result<Self, anyhow::Error> {
84 Ok(serde_json::from_slice(data)?)
85 }
86
87 pub fn serialize(&self) -> Vec<u8> {
88 serde_json::to_vec(self).expect("must serialize")
89 }
90
91 pub fn sortable_id(&self) -> u64 {
94 match self {
95 VersionedEvent::V1(ev) => ev.id,
96 }
97 }
98}
99
100#[derive(
101 Clone,
102 Debug,
103 Serialize,
104 Deserialize,
105 PartialOrd,
106 PartialEq,
107 Eq,
108 Ord,
109 Hash,
110 Arbitrary
111)]
112#[serde(rename_all = "kebab-case")]
113pub enum EventType {
114 Create,
115 Drop,
116 Alter,
117 Grant,
118 Revoke,
119 Comment,
120}
121
122impl EventType {
123 pub fn as_title_case(&self) -> &'static str {
124 match self {
125 EventType::Create => "Created",
126 EventType::Drop => "Dropped",
127 EventType::Alter => "Altered",
128 EventType::Grant => "Granted",
129 EventType::Revoke => "Revoked",
130 EventType::Comment => "Comment",
131 }
132 }
133}
134
135serde_plain::derive_display_from_serialize!(EventType);
136
137#[derive(
138 Clone,
139 Copy,
140 Debug,
141 Serialize,
142 Deserialize,
143 PartialOrd,
144 PartialEq,
145 Eq,
146 Ord,
147 Hash,
148 Arbitrary
149)]
150#[serde(rename_all = "kebab-case")]
151pub enum ObjectType {
152 Cluster,
153 ClusterReplica,
154 Connection,
155 ContinualTask,
156 Database,
157 Func,
158 Index,
159 MaterializedView,
160 NetworkPolicy,
161 Role,
162 Secret,
163 Schema,
164 Sink,
165 Source,
166 System,
167 Table,
168 Type,
169 View,
170}
171
172impl ObjectType {
173 pub fn as_title_case(&self) -> &'static str {
174 match self {
175 ObjectType::Cluster => "Cluster",
176 ObjectType::ClusterReplica => "Cluster Replica",
177 ObjectType::Connection => "Connection",
178 ObjectType::ContinualTask => "Continual Task",
179 ObjectType::Database => "Database",
180 ObjectType::Func => "Function",
181 ObjectType::Index => "Index",
182 ObjectType::MaterializedView => "Materialized View",
183 ObjectType::NetworkPolicy => "Network Policy",
184 ObjectType::Role => "Role",
185 ObjectType::Schema => "Schema",
186 ObjectType::Secret => "Secret",
187 ObjectType::Sink => "Sink",
188 ObjectType::Source => "Source",
189 ObjectType::System => "System",
190 ObjectType::Table => "Table",
191 ObjectType::Type => "Type",
192 ObjectType::View => "View",
193 }
194 }
195}
196
197serde_plain::derive_display_from_serialize!(ObjectType);
198
199#[derive(
200 Clone,
201 Debug,
202 Serialize,
203 Deserialize,
204 PartialOrd,
205 PartialEq,
206 Eq,
207 Ord,
208 Hash,
209 Arbitrary
210)]
211pub enum EventDetails {
212 #[serde(rename = "CreateComputeReplicaV1")] CreateClusterReplicaV1(CreateClusterReplicaV1),
214 CreateClusterReplicaV2(CreateClusterReplicaV2),
215 CreateClusterReplicaV3(CreateClusterReplicaV3),
216 CreateClusterReplicaV4(CreateClusterReplicaV4),
217 #[serde(rename = "DropComputeReplicaV1")] DropClusterReplicaV1(DropClusterReplicaV1),
219 DropClusterReplicaV2(DropClusterReplicaV2),
220 DropClusterReplicaV3(DropClusterReplicaV3),
221 CreateSourceSinkV1(CreateSourceSinkV1),
222 CreateSourceSinkV2(CreateSourceSinkV2),
223 CreateSourceSinkV3(CreateSourceSinkV3),
224 CreateSourceSinkV4(CreateSourceSinkV4),
225 CreateIndexV1(CreateIndexV1),
226 CreateMaterializedViewV1(CreateMaterializedViewV1),
227 AlterApplyReplacementV1(AlterApplyReplacementV1),
228 AlterSetClusterV1(AlterSetClusterV1),
229 AlterSourceSinkV1(AlterSourceSinkV1),
230 GrantRoleV1(GrantRoleV1),
231 GrantRoleV2(GrantRoleV2),
232 RevokeRoleV1(RevokeRoleV1),
233 RevokeRoleV2(RevokeRoleV2),
234 UpdatePrivilegeV1(UpdatePrivilegeV1),
235 AlterDefaultPrivilegeV1(AlterDefaultPrivilegeV1),
236 UpdateOwnerV1(UpdateOwnerV1),
237 IdFullNameV1(IdFullNameV1),
238 RenameClusterV1(RenameClusterV1),
239 RenameClusterReplicaV1(RenameClusterReplicaV1),
240 AlterClusterReconfigurationV1(AlterClusterReconfigurationV1),
241 ClusterHydrationBurstV1(ClusterHydrationBurstV1),
242 RenameItemV1(RenameItemV1),
243 IdNameV1(IdNameV1),
244 SchemaV1(SchemaV1),
245 SchemaV2(SchemaV2),
246 UpdateItemV1(UpdateItemV1),
247 RenameSchemaV1(RenameSchemaV1),
248 AlterRetainHistoryV1(AlterRetainHistoryV1),
249 AlterAddColumnV1(AlterAddColumnV1),
250 AlterSourceTimestampIntervalV1(AlterSourceTimestampIntervalV1),
251 ToNewIdV1(ToNewIdV1),
252 FromPreviousIdV1(FromPreviousIdV1),
253 SetV1(SetV1),
254 ResetAllV1,
255 RotateKeysV1(RotateKeysV1),
256 CreateRoleV1(CreateRoleV1),
257}
258
259#[derive(
260 Clone,
261 Debug,
262 Serialize,
263 Deserialize,
264 PartialOrd,
265 PartialEq,
266 Eq,
267 Ord,
268 Hash,
269 Arbitrary
270)]
271pub struct SetV1 {
272 pub name: String,
273 pub value: Option<String>,
274}
275
276#[derive(
277 Clone,
278 Debug,
279 Serialize,
280 Deserialize,
281 PartialOrd,
282 PartialEq,
283 Eq,
284 Ord,
285 Hash,
286 Arbitrary
287)]
288pub struct RotateKeysV1 {
289 pub id: String,
290 pub name: String,
291}
292
293#[derive(
294 Clone,
295 Debug,
296 Serialize,
297 Deserialize,
298 PartialOrd,
299 PartialEq,
300 Eq,
301 Ord,
302 Hash,
303 Arbitrary
304)]
305pub struct IdFullNameV1 {
306 pub id: String,
307 #[serde(flatten)]
308 pub name: FullNameV1,
309}
310
311#[derive(
312 Clone,
313 Debug,
314 Serialize,
315 Deserialize,
316 PartialOrd,
317 PartialEq,
318 Eq,
319 Ord,
320 Hash,
321 Arbitrary
322)]
323pub struct FullNameV1 {
324 pub database: String,
325 pub schema: String,
326 pub item: String,
327}
328
329#[derive(
330 Clone,
331 Debug,
332 Serialize,
333 Deserialize,
334 PartialOrd,
335 PartialEq,
336 Eq,
337 Ord,
338 Hash,
339 Arbitrary
340)]
341pub struct IdNameV1 {
342 pub id: String,
343 pub name: String,
344}
345
346#[derive(
355 Clone,
356 Debug,
357 Serialize,
358 Deserialize,
359 PartialOrd,
360 PartialEq,
361 Eq,
362 Ord,
363 Hash,
364 Arbitrary
365)]
366#[serde(rename_all = "kebab-case")]
367pub enum ReconfigurationLifecycleV1 {
368 Started,
371 Finalized,
379 TimedOut,
386 Cancelled,
390}
391
392#[derive(
402 Clone,
403 Debug,
404 Serialize,
405 Deserialize,
406 PartialOrd,
407 PartialEq,
408 Eq,
409 Ord,
410 Hash,
411 Arbitrary
412)]
413pub struct AlterClusterReconfigurationV1 {
414 pub cluster_id: String,
415 pub cluster_name: String,
416 pub transition: ReconfigurationLifecycleV1,
417 pub target_size: String,
418 pub target_replication_factor: u32,
419 pub target_availability_zones: Vec<String>,
420 pub target_logging: ClusterReplicaLoggingV1,
421 pub deadline: Option<u64>,
422}
423
424#[derive(
431 Clone,
432 Debug,
433 Serialize,
434 Deserialize,
435 PartialOrd,
436 PartialEq,
437 Eq,
438 Ord,
439 Hash,
440 Arbitrary
441)]
442pub struct ClusterReplicaLoggingV1 {
443 pub log_logging: bool,
444 pub interval: Option<Duration>,
445}
446
447#[derive(
448 Clone,
449 Debug,
450 Serialize,
451 Deserialize,
452 PartialOrd,
453 PartialEq,
454 Eq,
455 Ord,
456 Hash,
457 Arbitrary
458)]
459pub struct CreateRoleV1 {
460 pub id: String,
461 pub name: String,
462 pub auto_provision_source: Option<String>,
463}
464
465#[derive(
473 Clone,
474 Debug,
475 Serialize,
476 Deserialize,
477 PartialOrd,
478 PartialEq,
479 Eq,
480 Ord,
481 Hash,
482 Arbitrary
483)]
484#[serde(rename_all = "kebab-case")]
485pub enum HydrationBurstLifecycleV1 {
486 Started,
489 Finished,
492}
493
494#[derive(
496 Clone,
497 Debug,
498 Serialize,
499 Deserialize,
500 PartialOrd,
501 PartialEq,
502 Eq,
503 Ord,
504 Hash,
505 Arbitrary
506)]
507pub struct ClusterHydrationBurstV1 {
508 pub cluster_id: String,
509 pub cluster_name: String,
510 pub transition: HydrationBurstLifecycleV1,
511 pub burst_size: String,
513}
514
515#[derive(
516 Clone,
517 Debug,
518 Serialize,
519 Deserialize,
520 PartialOrd,
521 PartialEq,
522 Eq,
523 Ord,
524 Hash,
525 Arbitrary
526)]
527pub struct RenameItemV1 {
528 pub id: String,
529 pub old_name: FullNameV1,
530 pub new_name: FullNameV1,
531}
532
533#[derive(
534 Clone,
535 Debug,
536 Serialize,
537 Deserialize,
538 PartialOrd,
539 PartialEq,
540 Eq,
541 Ord,
542 Hash,
543 Arbitrary
544)]
545pub struct RenameClusterV1 {
546 pub id: String,
547 pub old_name: String,
548 pub new_name: String,
549}
550
551#[derive(
552 Clone,
553 Debug,
554 Serialize,
555 Deserialize,
556 PartialOrd,
557 PartialEq,
558 Eq,
559 Ord,
560 Hash,
561 Arbitrary
562)]
563pub struct RenameClusterReplicaV1 {
564 pub cluster_id: String,
565 pub replica_id: String,
566 pub old_name: String,
567 pub new_name: String,
568}
569
570#[derive(
571 Clone,
572 Debug,
573 Serialize,
574 Deserialize,
575 PartialOrd,
576 PartialEq,
577 Eq,
578 Ord,
579 Hash,
580 Arbitrary
581)]
582pub struct DropClusterReplicaV1 {
583 pub cluster_id: String,
584 pub cluster_name: String,
585 #[serde(skip_serializing_if = "Option::is_none")]
587 pub replica_id: Option<String>,
588 pub replica_name: String,
589}
590
591#[derive(
592 Clone,
593 Debug,
594 Serialize,
595 Deserialize,
596 PartialOrd,
597 PartialEq,
598 Eq,
599 Ord,
600 Hash,
601 Arbitrary
602)]
603pub struct DropClusterReplicaV2 {
604 pub cluster_id: String,
605 pub cluster_name: String,
606 pub replica_id: Option<String>,
607 pub replica_name: String,
608 pub reason: CreateOrDropClusterReplicaReasonV1,
609 #[serde(skip_serializing_if = "Option::is_none")]
610 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV1>,
611}
612
613#[derive(
614 Clone,
615 Debug,
616 Serialize,
617 Deserialize,
618 PartialOrd,
619 PartialEq,
620 Eq,
621 Ord,
622 Hash,
623 Arbitrary
624)]
625pub struct DropClusterReplicaV3 {
626 pub cluster_id: String,
627 pub cluster_name: String,
628 pub replica_id: Option<String>,
629 pub replica_name: String,
630 pub reason: CreateOrDropClusterReplicaReasonV1,
631 #[serde(skip_serializing_if = "Option::is_none")]
632 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV2>,
633}
634
635#[derive(
636 Clone,
637 Debug,
638 Serialize,
639 Deserialize,
640 PartialOrd,
641 PartialEq,
642 Eq,
643 Ord,
644 Hash,
645 Arbitrary
646)]
647pub struct CreateClusterReplicaV1 {
648 pub cluster_id: String,
649 pub cluster_name: String,
650 #[serde(skip_serializing_if = "Option::is_none")]
652 pub replica_id: Option<String>,
653 pub replica_name: String,
654 pub logical_size: String,
655 pub disk: bool,
656 pub billed_as: Option<String>,
657 pub internal: bool,
658}
659
660#[derive(
661 Clone,
662 Debug,
663 Serialize,
664 Deserialize,
665 PartialOrd,
666 PartialEq,
667 Eq,
668 Ord,
669 Hash,
670 Arbitrary
671)]
672pub struct CreateClusterReplicaV2 {
673 pub cluster_id: String,
674 pub cluster_name: String,
675 pub replica_id: Option<String>,
676 pub replica_name: String,
677 pub logical_size: String,
678 pub disk: bool,
679 pub billed_as: Option<String>,
680 pub internal: bool,
681 pub reason: CreateOrDropClusterReplicaReasonV1,
682 #[serde(skip_serializing_if = "Option::is_none")]
683 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV1>,
684}
685
686#[derive(
687 Clone,
688 Debug,
689 Serialize,
690 Deserialize,
691 PartialOrd,
692 PartialEq,
693 Eq,
694 Ord,
695 Hash,
696 Arbitrary
697)]
698pub struct CreateClusterReplicaV3 {
699 pub cluster_id: String,
700 pub cluster_name: String,
701 pub replica_id: Option<String>,
702 pub replica_name: String,
703 pub logical_size: String,
704 pub disk: bool,
705 pub billed_as: Option<String>,
706 pub internal: bool,
707 pub reason: CreateOrDropClusterReplicaReasonV1,
708 #[serde(skip_serializing_if = "Option::is_none")]
709 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV2>,
710}
711
712#[derive(
713 Clone,
714 Debug,
715 Serialize,
716 Deserialize,
717 PartialOrd,
718 PartialEq,
719 Eq,
720 Ord,
721 Hash,
722 Arbitrary
723)]
724pub struct CreateClusterReplicaV4 {
725 pub cluster_id: String,
726 pub cluster_name: String,
727 pub replica_id: Option<String>,
728 pub replica_name: String,
729 pub logical_size: String,
730 pub billed_as: Option<String>,
731 pub internal: bool,
732 pub reason: CreateOrDropClusterReplicaReasonV1,
733 #[serde(skip_serializing_if = "Option::is_none")]
734 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV2>,
735}
736
737#[derive(
738 Clone,
739 Debug,
740 Serialize,
741 Deserialize,
742 PartialOrd,
743 PartialEq,
744 Eq,
745 Ord,
746 Hash,
747 Arbitrary
748)]
749#[serde(rename_all = "kebab-case")]
750pub enum CreateOrDropClusterReplicaReasonV1 {
751 Manual,
752 Schedule,
753 System,
754 Reconfiguration,
758 HydrationBurst,
762 Retired,
767}
768
769#[derive(
773 Clone,
774 Debug,
775 Serialize,
776 Deserialize,
777 PartialOrd,
778 PartialEq,
779 Eq,
780 Ord,
781 Hash,
782 Arbitrary
783)]
784pub struct SchedulingDecisionsWithReasonsV1 {
785 pub on_refresh: RefreshDecisionWithReasonV1,
787}
788
789#[derive(
793 Clone,
794 Debug,
795 Serialize,
796 Deserialize,
797 PartialOrd,
798 PartialEq,
799 Eq,
800 Ord,
801 Hash,
802 Arbitrary
803)]
804pub struct SchedulingDecisionsWithReasonsV2 {
805 pub on_refresh: RefreshDecisionWithReasonV2,
807}
808
809#[derive(
810 Clone,
811 Debug,
812 Serialize,
813 Deserialize,
814 PartialOrd,
815 PartialEq,
816 Eq,
817 Ord,
818 Hash,
819 Arbitrary
820)]
821pub struct RefreshDecisionWithReasonV1 {
822 pub decision: SchedulingDecisionV1,
823 pub objects_needing_refresh: Vec<String>,
826 pub hydration_time_estimate: String,
828}
829
830#[derive(
831 Clone,
832 Debug,
833 Serialize,
834 Deserialize,
835 PartialOrd,
836 PartialEq,
837 Eq,
838 Ord,
839 Hash,
840 Arbitrary
841)]
842pub struct RefreshDecisionWithReasonV2 {
843 pub decision: SchedulingDecisionV1,
844 pub objects_needing_refresh: Vec<String>,
847 pub objects_needing_compaction: Vec<String>,
850 pub hydration_time_estimate: String,
852}
853
854#[derive(
855 Clone,
856 Debug,
857 Serialize,
858 Deserialize,
859 PartialOrd,
860 PartialEq,
861 Eq,
862 Ord,
863 Hash,
864 Arbitrary
865)]
866#[serde(rename_all = "kebab-case")]
867pub enum SchedulingDecisionV1 {
868 On,
869 Off,
870}
871
872impl From<bool> for SchedulingDecisionV1 {
873 fn from(value: bool) -> Self {
874 match value {
875 true => SchedulingDecisionV1::On,
876 false => SchedulingDecisionV1::Off,
877 }
878 }
879}
880
881#[derive(
882 Clone,
883 Debug,
884 Serialize,
885 Deserialize,
886 PartialOrd,
887 PartialEq,
888 Eq,
889 Ord,
890 Hash,
891 Arbitrary
892)]
893pub struct CreateSourceSinkV1 {
894 pub id: String,
895 #[serde(flatten)]
896 pub name: FullNameV1,
897 pub size: Option<String>,
898}
899
900#[derive(
901 Clone,
902 Debug,
903 Serialize,
904 Deserialize,
905 PartialOrd,
906 PartialEq,
907 Eq,
908 Ord,
909 Hash,
910 Arbitrary
911)]
912pub struct CreateSourceSinkV2 {
913 pub id: String,
914 #[serde(flatten)]
915 pub name: FullNameV1,
916 pub size: Option<String>,
917 #[serde(rename = "type")]
918 pub external_type: String,
919}
920
921#[derive(
922 Clone,
923 Debug,
924 Serialize,
925 Deserialize,
926 PartialOrd,
927 PartialEq,
928 Eq,
929 Ord,
930 Hash,
931 Arbitrary
932)]
933pub struct CreateSourceSinkV3 {
934 pub id: String,
935 #[serde(flatten)]
936 pub name: FullNameV1,
937 #[serde(rename = "type")]
938 pub external_type: String,
939}
940
941#[derive(
942 Clone,
943 Debug,
944 Serialize,
945 Deserialize,
946 PartialOrd,
947 PartialEq,
948 Eq,
949 Ord,
950 Hash,
951 Arbitrary
952)]
953pub struct CreateSourceSinkV4 {
954 pub id: String,
955 pub cluster_id: Option<String>,
956 #[serde(flatten)]
957 pub name: FullNameV1,
958 #[serde(rename = "type")]
959 pub external_type: String,
960}
961
962#[derive(
963 Clone,
964 Debug,
965 Serialize,
966 Deserialize,
967 PartialOrd,
968 PartialEq,
969 Eq,
970 Ord,
971 Hash,
972 Arbitrary
973)]
974pub struct CreateIndexV1 {
975 pub id: String,
976 pub cluster_id: String,
977 #[serde(flatten)]
978 pub name: FullNameV1,
979}
980
981#[derive(
982 Clone,
983 Debug,
984 Serialize,
985 Deserialize,
986 PartialOrd,
987 PartialEq,
988 Eq,
989 Ord,
990 Hash,
991 Arbitrary
992)]
993pub struct CreateMaterializedViewV1 {
994 pub id: String,
995 pub cluster_id: String,
996 #[serde(flatten)]
997 pub name: FullNameV1,
998 #[serde(skip_serializing_if = "Option::is_none")]
999 pub replacement_target_id: Option<String>,
1000}
1001
1002#[derive(
1003 Clone,
1004 Debug,
1005 Serialize,
1006 Deserialize,
1007 PartialOrd,
1008 PartialEq,
1009 Eq,
1010 Ord,
1011 Hash,
1012 Arbitrary
1013)]
1014pub struct AlterApplyReplacementV1 {
1015 #[serde(flatten)]
1016 pub target: IdFullNameV1,
1017 pub replacement: IdFullNameV1,
1018}
1019
1020#[derive(
1021 Clone,
1022 Debug,
1023 Serialize,
1024 Deserialize,
1025 PartialOrd,
1026 PartialEq,
1027 Eq,
1028 Ord,
1029 Hash,
1030 Arbitrary
1031)]
1032pub struct AlterSourceSinkV1 {
1033 pub id: String,
1034 #[serde(flatten)]
1035 pub name: FullNameV1,
1036 pub old_size: Option<String>,
1037 pub new_size: Option<String>,
1038}
1039
1040#[derive(
1041 Clone,
1042 Debug,
1043 Serialize,
1044 Deserialize,
1045 PartialOrd,
1046 PartialEq,
1047 Eq,
1048 Ord,
1049 Hash,
1050 Arbitrary
1051)]
1052pub struct AlterSetClusterV1 {
1053 pub id: String,
1054 #[serde(flatten)]
1055 pub name: FullNameV1,
1056 pub old_cluster_id: String,
1057 pub new_cluster_id: String,
1058}
1059
1060#[derive(
1061 Clone,
1062 Debug,
1063 Serialize,
1064 Deserialize,
1065 PartialOrd,
1066 PartialEq,
1067 Eq,
1068 Ord,
1069 Hash,
1070 Arbitrary
1071)]
1072pub struct GrantRoleV1 {
1073 pub role_id: String,
1074 pub member_id: String,
1075 pub grantor_id: String,
1076}
1077
1078#[derive(
1079 Clone,
1080 Debug,
1081 Serialize,
1082 Deserialize,
1083 PartialOrd,
1084 PartialEq,
1085 Eq,
1086 Ord,
1087 Hash,
1088 Arbitrary
1089)]
1090pub struct GrantRoleV2 {
1091 pub role_id: String,
1092 pub member_id: String,
1093 pub grantor_id: String,
1094 pub executed_by: String,
1095}
1096
1097#[derive(
1098 Clone,
1099 Debug,
1100 Serialize,
1101 Deserialize,
1102 PartialOrd,
1103 PartialEq,
1104 Eq,
1105 Ord,
1106 Hash,
1107 Arbitrary
1108)]
1109pub struct RevokeRoleV1 {
1110 pub role_id: String,
1111 pub member_id: String,
1112}
1113
1114#[derive(
1115 Clone,
1116 Debug,
1117 Serialize,
1118 Deserialize,
1119 PartialOrd,
1120 PartialEq,
1121 Eq,
1122 Ord,
1123 Hash,
1124 Arbitrary
1125)]
1126pub struct RevokeRoleV2 {
1127 pub role_id: String,
1128 pub member_id: String,
1129 pub grantor_id: String,
1130 pub executed_by: String,
1131}
1132
1133#[derive(
1134 Clone,
1135 Debug,
1136 Serialize,
1137 Deserialize,
1138 PartialOrd,
1139 PartialEq,
1140 Eq,
1141 Ord,
1142 Hash,
1143 Arbitrary
1144)]
1145pub struct UpdatePrivilegeV1 {
1146 pub object_id: String,
1147 pub grantee_id: String,
1148 pub grantor_id: String,
1149 pub privileges: String,
1150}
1151
1152#[derive(
1153 Clone,
1154 Debug,
1155 Serialize,
1156 Deserialize,
1157 PartialOrd,
1158 PartialEq,
1159 Eq,
1160 Ord,
1161 Hash,
1162 Arbitrary
1163)]
1164pub struct AlterDefaultPrivilegeV1 {
1165 pub role_id: String,
1166 pub database_id: Option<String>,
1167 pub schema_id: Option<String>,
1168 pub grantee_id: String,
1169 pub privileges: String,
1170}
1171
1172#[derive(
1173 Clone,
1174 Debug,
1175 Serialize,
1176 Deserialize,
1177 PartialOrd,
1178 PartialEq,
1179 Eq,
1180 Ord,
1181 Hash,
1182 Arbitrary
1183)]
1184pub struct UpdateOwnerV1 {
1185 pub object_id: String,
1186 pub old_owner_id: String,
1187 pub new_owner_id: String,
1188}
1189
1190#[derive(
1191 Clone,
1192 Debug,
1193 Serialize,
1194 Deserialize,
1195 PartialOrd,
1196 PartialEq,
1197 Eq,
1198 Ord,
1199 Hash,
1200 Arbitrary
1201)]
1202pub struct SchemaV1 {
1203 pub id: String,
1204 pub name: String,
1205 pub database_name: String,
1206}
1207
1208#[derive(
1209 Clone,
1210 Debug,
1211 Serialize,
1212 Deserialize,
1213 PartialOrd,
1214 PartialEq,
1215 Eq,
1216 Ord,
1217 Hash,
1218 Arbitrary
1219)]
1220pub struct SchemaV2 {
1221 pub id: String,
1222 pub name: String,
1223 pub database_name: Option<String>,
1224}
1225
1226#[derive(
1227 Clone,
1228 Debug,
1229 Serialize,
1230 Deserialize,
1231 PartialOrd,
1232 PartialEq,
1233 Eq,
1234 Ord,
1235 Hash,
1236 Arbitrary
1237)]
1238pub struct RenameSchemaV1 {
1239 pub id: String,
1240 pub database_name: Option<String>,
1241 pub old_name: String,
1242 pub new_name: String,
1243}
1244
1245#[derive(
1246 Clone,
1247 Debug,
1248 Serialize,
1249 Deserialize,
1250 PartialOrd,
1251 PartialEq,
1252 Eq,
1253 Ord,
1254 Hash,
1255 Arbitrary
1256)]
1257pub struct AlterRetainHistoryV1 {
1258 pub id: String,
1259 pub old_history: Option<String>,
1260 pub new_history: Option<String>,
1261}
1262
1263#[derive(
1264 Clone,
1265 Debug,
1266 Serialize,
1267 Deserialize,
1268 PartialOrd,
1269 PartialEq,
1270 Eq,
1271 Ord,
1272 Hash,
1273 Arbitrary
1274)]
1275pub struct AlterAddColumnV1 {
1276 pub id: String,
1277 pub column: String,
1278 pub column_type: String,
1279 pub nullable: bool,
1280}
1281
1282#[derive(
1283 Clone,
1284 Debug,
1285 Serialize,
1286 Deserialize,
1287 PartialOrd,
1288 PartialEq,
1289 Eq,
1290 Ord,
1291 Hash,
1292 Arbitrary
1293)]
1294pub struct AlterSourceTimestampIntervalV1 {
1295 pub id: String,
1296 pub old_interval: Option<String>,
1297 pub new_interval: Option<String>,
1298}
1299
1300#[derive(
1301 Clone,
1302 Debug,
1303 Serialize,
1304 Deserialize,
1305 PartialOrd,
1306 PartialEq,
1307 Eq,
1308 Ord,
1309 Hash,
1310 Arbitrary
1311)]
1312pub struct UpdateItemV1 {
1313 pub id: String,
1314 #[serde(flatten)]
1315 pub name: FullNameV1,
1316}
1317
1318#[derive(
1319 Clone,
1320 Debug,
1321 Serialize,
1322 Deserialize,
1323 PartialOrd,
1324 PartialEq,
1325 Eq,
1326 Ord,
1327 Hash,
1328 Arbitrary
1329)]
1330pub struct ToNewIdV1 {
1331 pub id: String,
1332 pub new_id: String,
1333}
1334
1335#[derive(
1336 Clone,
1337 Debug,
1338 Serialize,
1339 Deserialize,
1340 PartialOrd,
1341 PartialEq,
1342 Eq,
1343 Ord,
1344 Hash,
1345 Arbitrary
1346)]
1347pub struct FromPreviousIdV1 {
1348 pub id: String,
1349 pub previous_id: String,
1350}
1351
1352impl EventDetails {
1353 pub fn as_json(&self) -> serde_json::Value {
1354 match self {
1355 EventDetails::CreateClusterReplicaV1(v) => {
1356 serde_json::to_value(v).expect("must serialize")
1357 }
1358 EventDetails::CreateClusterReplicaV2(v) => {
1359 serde_json::to_value(v).expect("must serialize")
1360 }
1361 EventDetails::CreateClusterReplicaV3(v) => {
1362 serde_json::to_value(v).expect("must serialize")
1363 }
1364 EventDetails::CreateClusterReplicaV4(v) => {
1365 serde_json::to_value(v).expect("must serialize")
1366 }
1367 EventDetails::DropClusterReplicaV1(v) => {
1368 serde_json::to_value(v).expect("must serialize")
1369 }
1370 EventDetails::DropClusterReplicaV2(v) => {
1371 serde_json::to_value(v).expect("must serialize")
1372 }
1373 EventDetails::DropClusterReplicaV3(v) => {
1374 serde_json::to_value(v).expect("must serialize")
1375 }
1376 EventDetails::IdFullNameV1(v) => serde_json::to_value(v).expect("must serialize"),
1377 EventDetails::RenameClusterV1(v) => serde_json::to_value(v).expect("must serialize"),
1378 EventDetails::RenameClusterReplicaV1(v) => {
1379 serde_json::to_value(v).expect("must serialize")
1380 }
1381 EventDetails::AlterClusterReconfigurationV1(v) => {
1382 serde_json::to_value(v).expect("must serialize")
1383 }
1384 EventDetails::ClusterHydrationBurstV1(v) => {
1385 serde_json::to_value(v).expect("must serialize")
1386 }
1387 EventDetails::RenameItemV1(v) => serde_json::to_value(v).expect("must serialize"),
1388 EventDetails::IdNameV1(v) => serde_json::to_value(v).expect("must serialize"),
1389 EventDetails::SchemaV1(v) => serde_json::to_value(v).expect("must serialize"),
1390 EventDetails::SchemaV2(v) => serde_json::to_value(v).expect("must serialize"),
1391 EventDetails::RenameSchemaV1(v) => serde_json::to_value(v).expect("must serialize"),
1392 EventDetails::CreateSourceSinkV1(v) => serde_json::to_value(v).expect("must serialize"),
1393 EventDetails::CreateSourceSinkV2(v) => serde_json::to_value(v).expect("must serialize"),
1394 EventDetails::CreateSourceSinkV3(v) => serde_json::to_value(v).expect("must serialize"),
1395 EventDetails::CreateSourceSinkV4(v) => serde_json::to_value(v).expect("must serialize"),
1396 EventDetails::CreateIndexV1(v) => serde_json::to_value(v).expect("must serialize"),
1397 EventDetails::CreateMaterializedViewV1(v) => {
1398 serde_json::to_value(v).expect("must serialize")
1399 }
1400 EventDetails::AlterApplyReplacementV1(v) => {
1401 serde_json::to_value(v).expect("must serialize")
1402 }
1403 EventDetails::AlterSourceSinkV1(v) => serde_json::to_value(v).expect("must serialize"),
1404 EventDetails::AlterSetClusterV1(v) => serde_json::to_value(v).expect("must serialize"),
1405 EventDetails::GrantRoleV1(v) => serde_json::to_value(v).expect("must serialize"),
1406 EventDetails::GrantRoleV2(v) => serde_json::to_value(v).expect("must serialize"),
1407 EventDetails::RevokeRoleV1(v) => serde_json::to_value(v).expect("must serialize"),
1408 EventDetails::RevokeRoleV2(v) => serde_json::to_value(v).expect("must serialize"),
1409 EventDetails::UpdatePrivilegeV1(v) => serde_json::to_value(v).expect("must serialize"),
1410 EventDetails::AlterDefaultPrivilegeV1(v) => {
1411 serde_json::to_value(v).expect("must serialize")
1412 }
1413 EventDetails::UpdateOwnerV1(v) => serde_json::to_value(v).expect("must serialize"),
1414 EventDetails::UpdateItemV1(v) => serde_json::to_value(v).expect("must serialize"),
1415 EventDetails::AlterRetainHistoryV1(v) => {
1416 serde_json::to_value(v).expect("must serialize")
1417 }
1418 EventDetails::AlterAddColumnV1(v) => serde_json::to_value(v).expect("must serialize"),
1419 EventDetails::AlterSourceTimestampIntervalV1(v) => {
1420 serde_json::to_value(v).expect("must serialize")
1421 }
1422 EventDetails::ToNewIdV1(v) => serde_json::to_value(v).expect("must serialize"),
1423 EventDetails::FromPreviousIdV1(v) => serde_json::to_value(v).expect("must serialize"),
1424 EventDetails::SetV1(v) => serde_json::to_value(v).expect("must serialize"),
1425 EventDetails::ResetAllV1 => serde_json::Value::Null,
1426 EventDetails::RotateKeysV1(v) => serde_json::to_value(v).expect("must serialize"),
1427 EventDetails::CreateRoleV1(v) => serde_json::to_value(v).expect("must serialize"),
1428 }
1429 }
1430}
1431
1432#[derive(
1433 Clone,
1434 Debug,
1435 Serialize,
1436 Deserialize,
1437 PartialOrd,
1438 PartialEq,
1439 Eq,
1440 Ord,
1441 Hash,
1442 Arbitrary
1443)]
1444pub struct EventV1 {
1445 pub id: u64,
1446 pub event_type: EventType,
1447 pub object_type: ObjectType,
1448 pub details: EventDetails,
1449 pub user: Option<String>,
1450 pub occurred_at: EpochMillis,
1451}
1452
1453impl EventV1 {
1454 fn new(
1455 id: u64,
1456 event_type: EventType,
1457 object_type: ObjectType,
1458 details: EventDetails,
1459 user: Option<String>,
1460 occurred_at: EpochMillis,
1461 ) -> EventV1 {
1462 EventV1 {
1463 id,
1464 event_type,
1465 object_type,
1466 details,
1467 user,
1468 occurred_at,
1469 }
1470 }
1471}
1472
1473#[derive(
1474 Clone,
1475 Debug,
1476 Serialize,
1477 Deserialize,
1478 PartialOrd,
1479 PartialEq,
1480 Eq,
1481 Ord,
1482 Hash,
1483 Arbitrary
1484)]
1485pub struct StorageUsageV1 {
1486 pub id: u64,
1487 pub shard_id: Option<String>,
1488 pub size_bytes: u64,
1489 pub collection_timestamp: EpochMillis,
1490}
1491
1492impl StorageUsageV1 {
1493 pub fn new(
1494 id: u64,
1495 shard_id: Option<String>,
1496 size_bytes: u64,
1497 collection_timestamp: EpochMillis,
1498 ) -> StorageUsageV1 {
1499 StorageUsageV1 {
1500 id,
1501 shard_id,
1502 size_bytes,
1503 collection_timestamp,
1504 }
1505 }
1506}
1507
1508#[derive(
1513 Clone,
1514 Debug,
1515 Serialize,
1516 Deserialize,
1517 PartialOrd,
1518 PartialEq,
1519 Eq,
1520 Ord,
1521 Hash,
1522 Arbitrary
1523)]
1524pub enum VersionedStorageUsage {
1525 V1(StorageUsageV1),
1526}
1527
1528impl VersionedStorageUsage {
1529 pub fn new(
1533 id: u64,
1534 object_id: Option<String>,
1535 size_bytes: u64,
1536 collection_timestamp: EpochMillis,
1537 ) -> Self {
1538 Self::V1(StorageUsageV1::new(
1539 id,
1540 object_id,
1541 size_bytes,
1542 collection_timestamp,
1543 ))
1544 }
1545
1546 pub fn deserialize(data: &[u8]) -> Result<Self, anyhow::Error> {
1549 Ok(serde_json::from_slice(data)?)
1550 }
1551
1552 pub fn serialize(&self) -> Vec<u8> {
1553 serde_json::to_vec(self).expect("must serialize")
1554 }
1555
1556 pub fn timestamp(&self) -> EpochMillis {
1557 match self {
1558 VersionedStorageUsage::V1(StorageUsageV1 {
1559 collection_timestamp,
1560 ..
1561 }) => *collection_timestamp,
1562 }
1563 }
1564
1565 pub fn sortable_id(&self) -> u64 {
1568 match self {
1569 VersionedStorageUsage::V1(usage) => usage.id,
1570 }
1571 }
1572}
1573
1574#[cfg(test)]
1575mod tests {
1576 use crate::{EventDetails, EventType, EventV1, IdNameV1, ObjectType, VersionedEvent};
1577
1578 #[mz_ore::test]
1582 fn test_audit_log() -> Result<(), anyhow::Error> {
1583 let cases: Vec<(VersionedEvent, &'static str)> = vec![(
1584 VersionedEvent::V1(EventV1::new(
1585 2,
1586 EventType::Drop,
1587 ObjectType::ClusterReplica,
1588 EventDetails::IdNameV1(IdNameV1 {
1589 id: "u1".to_string(),
1590 name: "name".into(),
1591 }),
1592 None,
1593 2,
1594 )),
1595 r#"{"V1":{"id":2,"event_type":"drop","object_type":"cluster-replica","details":{"IdNameV1":{"id":"u1","name":"name"}},"user":null,"occurred_at":2}}"#,
1596 )];
1597
1598 for (event, expected_bytes) in cases {
1599 let event_bytes = serde_json::to_vec(&event).unwrap();
1600 assert_eq!(
1601 event_bytes,
1602 expected_bytes.as_bytes(),
1603 "expected bytes {}, got {}",
1604 expected_bytes,
1605 std::str::from_utf8(&event_bytes).unwrap(),
1606 );
1607 }
1608
1609 Ok(())
1610 }
1611}