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,
378 TimedOut,
385 Cancelled,
389 ResourceExhausted,
396}
397
398#[derive(
404 Clone,
405 Debug,
406 Serialize,
407 Deserialize,
408 PartialOrd,
409 PartialEq,
410 Eq,
411 Ord,
412 Hash,
413 Arbitrary
414)]
415pub struct AlterClusterReconfigurationV1 {
416 pub cluster_id: String,
417 pub cluster_name: String,
418 pub transition: ReconfigurationLifecycleV1,
419 #[serde(default)]
423 pub forced: Option<bool>,
424 pub target_size: String,
425 pub target_replication_factor: u32,
426 pub target_availability_zones: Vec<String>,
427 pub target_logging: ClusterReplicaLoggingV1,
428 pub deadline: Option<u64>,
429}
430
431#[derive(
438 Clone,
439 Debug,
440 Serialize,
441 Deserialize,
442 PartialOrd,
443 PartialEq,
444 Eq,
445 Ord,
446 Hash,
447 Arbitrary
448)]
449pub struct ClusterReplicaLoggingV1 {
450 pub log_logging: bool,
451 pub interval: Option<Duration>,
452}
453
454#[derive(
455 Clone,
456 Debug,
457 Serialize,
458 Deserialize,
459 PartialOrd,
460 PartialEq,
461 Eq,
462 Ord,
463 Hash,
464 Arbitrary
465)]
466pub struct CreateRoleV1 {
467 pub id: String,
468 pub name: String,
469 pub auto_provision_source: Option<String>,
470}
471
472#[derive(
480 Clone,
481 Debug,
482 Serialize,
483 Deserialize,
484 PartialOrd,
485 PartialEq,
486 Eq,
487 Ord,
488 Hash,
489 Arbitrary
490)]
491#[serde(rename_all = "kebab-case")]
492pub enum HydrationBurstLifecycleV1 {
493 Started,
496 Finished,
499}
500
501#[derive(
503 Clone,
504 Copy,
505 Debug,
506 Serialize,
507 Deserialize,
508 PartialOrd,
509 PartialEq,
510 Eq,
511 Ord,
512 Hash,
513 Arbitrary
514)]
515#[serde(rename_all = "kebab-case")]
516pub enum BurstFinishCauseV1 {
517 LingerElapsed,
519 NoLongerWarranted,
523}
524
525#[derive(
527 Clone,
528 Debug,
529 Serialize,
530 Deserialize,
531 PartialOrd,
532 PartialEq,
533 Eq,
534 Ord,
535 Hash,
536 Arbitrary
537)]
538pub struct ClusterHydrationBurstV1 {
539 pub cluster_id: String,
540 pub cluster_name: String,
541 pub transition: HydrationBurstLifecycleV1,
542 #[serde(default)]
544 pub finish_cause: Option<BurstFinishCauseV1>,
545 pub burst_size: String,
547}
548
549#[derive(
550 Clone,
551 Debug,
552 Serialize,
553 Deserialize,
554 PartialOrd,
555 PartialEq,
556 Eq,
557 Ord,
558 Hash,
559 Arbitrary
560)]
561pub struct RenameItemV1 {
562 pub id: String,
563 pub old_name: FullNameV1,
564 pub new_name: FullNameV1,
565}
566
567#[derive(
568 Clone,
569 Debug,
570 Serialize,
571 Deserialize,
572 PartialOrd,
573 PartialEq,
574 Eq,
575 Ord,
576 Hash,
577 Arbitrary
578)]
579pub struct RenameClusterV1 {
580 pub id: String,
581 pub old_name: String,
582 pub new_name: String,
583}
584
585#[derive(
586 Clone,
587 Debug,
588 Serialize,
589 Deserialize,
590 PartialOrd,
591 PartialEq,
592 Eq,
593 Ord,
594 Hash,
595 Arbitrary
596)]
597pub struct RenameClusterReplicaV1 {
598 pub cluster_id: String,
599 pub replica_id: String,
600 pub old_name: String,
601 pub new_name: String,
602}
603
604#[derive(
605 Clone,
606 Debug,
607 Serialize,
608 Deserialize,
609 PartialOrd,
610 PartialEq,
611 Eq,
612 Ord,
613 Hash,
614 Arbitrary
615)]
616pub struct DropClusterReplicaV1 {
617 pub cluster_id: String,
618 pub cluster_name: String,
619 #[serde(skip_serializing_if = "Option::is_none")]
621 pub replica_id: Option<String>,
622 pub replica_name: String,
623}
624
625#[derive(
626 Clone,
627 Debug,
628 Serialize,
629 Deserialize,
630 PartialOrd,
631 PartialEq,
632 Eq,
633 Ord,
634 Hash,
635 Arbitrary
636)]
637pub struct DropClusterReplicaV2 {
638 pub cluster_id: String,
639 pub cluster_name: String,
640 pub replica_id: Option<String>,
641 pub replica_name: String,
642 pub reason: CreateOrDropClusterReplicaReasonV1,
643 #[serde(skip_serializing_if = "Option::is_none")]
644 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV1>,
645}
646
647#[derive(
648 Clone,
649 Debug,
650 Serialize,
651 Deserialize,
652 PartialOrd,
653 PartialEq,
654 Eq,
655 Ord,
656 Hash,
657 Arbitrary
658)]
659pub struct DropClusterReplicaV3 {
660 pub cluster_id: String,
661 pub cluster_name: String,
662 pub replica_id: Option<String>,
663 pub replica_name: String,
664 pub reason: CreateOrDropClusterReplicaReasonV1,
665 #[serde(skip_serializing_if = "Option::is_none")]
666 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV2>,
667}
668
669#[derive(
670 Clone,
671 Debug,
672 Serialize,
673 Deserialize,
674 PartialOrd,
675 PartialEq,
676 Eq,
677 Ord,
678 Hash,
679 Arbitrary
680)]
681pub struct CreateClusterReplicaV1 {
682 pub cluster_id: String,
683 pub cluster_name: String,
684 #[serde(skip_serializing_if = "Option::is_none")]
686 pub replica_id: Option<String>,
687 pub replica_name: String,
688 pub logical_size: String,
689 pub disk: bool,
690 pub billed_as: Option<String>,
691 pub internal: bool,
692}
693
694#[derive(
695 Clone,
696 Debug,
697 Serialize,
698 Deserialize,
699 PartialOrd,
700 PartialEq,
701 Eq,
702 Ord,
703 Hash,
704 Arbitrary
705)]
706pub struct CreateClusterReplicaV2 {
707 pub cluster_id: String,
708 pub cluster_name: String,
709 pub replica_id: Option<String>,
710 pub replica_name: String,
711 pub logical_size: String,
712 pub disk: bool,
713 pub billed_as: Option<String>,
714 pub internal: bool,
715 pub reason: CreateOrDropClusterReplicaReasonV1,
716 #[serde(skip_serializing_if = "Option::is_none")]
717 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV1>,
718}
719
720#[derive(
721 Clone,
722 Debug,
723 Serialize,
724 Deserialize,
725 PartialOrd,
726 PartialEq,
727 Eq,
728 Ord,
729 Hash,
730 Arbitrary
731)]
732pub struct CreateClusterReplicaV3 {
733 pub cluster_id: String,
734 pub cluster_name: String,
735 pub replica_id: Option<String>,
736 pub replica_name: String,
737 pub logical_size: String,
738 pub disk: bool,
739 pub billed_as: Option<String>,
740 pub internal: bool,
741 pub reason: CreateOrDropClusterReplicaReasonV1,
742 #[serde(skip_serializing_if = "Option::is_none")]
743 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV2>,
744}
745
746#[derive(
747 Clone,
748 Debug,
749 Serialize,
750 Deserialize,
751 PartialOrd,
752 PartialEq,
753 Eq,
754 Ord,
755 Hash,
756 Arbitrary
757)]
758pub struct CreateClusterReplicaV4 {
759 pub cluster_id: String,
760 pub cluster_name: String,
761 pub replica_id: Option<String>,
762 pub replica_name: String,
763 pub logical_size: String,
764 pub billed_as: Option<String>,
765 pub internal: bool,
766 pub reason: CreateOrDropClusterReplicaReasonV1,
767 #[serde(skip_serializing_if = "Option::is_none")]
768 pub scheduling_policies: Option<SchedulingDecisionsWithReasonsV2>,
769}
770
771#[derive(
772 Clone,
773 Debug,
774 Serialize,
775 Deserialize,
776 PartialOrd,
777 PartialEq,
778 Eq,
779 Ord,
780 Hash,
781 Arbitrary
782)]
783#[serde(rename_all = "kebab-case")]
784pub enum CreateOrDropClusterReplicaReasonV1 {
785 Manual,
786 Schedule,
787 System,
788 Reconfiguration,
792 HydrationBurst,
796 Retired,
801}
802
803#[derive(
807 Clone,
808 Debug,
809 Serialize,
810 Deserialize,
811 PartialOrd,
812 PartialEq,
813 Eq,
814 Ord,
815 Hash,
816 Arbitrary
817)]
818pub struct SchedulingDecisionsWithReasonsV1 {
819 pub on_refresh: RefreshDecisionWithReasonV1,
821}
822
823#[derive(
827 Clone,
828 Debug,
829 Serialize,
830 Deserialize,
831 PartialOrd,
832 PartialEq,
833 Eq,
834 Ord,
835 Hash,
836 Arbitrary
837)]
838pub struct SchedulingDecisionsWithReasonsV2 {
839 pub on_refresh: RefreshDecisionWithReasonV2,
841}
842
843#[derive(
844 Clone,
845 Debug,
846 Serialize,
847 Deserialize,
848 PartialOrd,
849 PartialEq,
850 Eq,
851 Ord,
852 Hash,
853 Arbitrary
854)]
855pub struct RefreshDecisionWithReasonV1 {
856 pub decision: SchedulingDecisionV1,
857 pub objects_needing_refresh: Vec<String>,
860 pub hydration_time_estimate: String,
862}
863
864#[derive(
865 Clone,
866 Debug,
867 Serialize,
868 Deserialize,
869 PartialOrd,
870 PartialEq,
871 Eq,
872 Ord,
873 Hash,
874 Arbitrary
875)]
876pub struct RefreshDecisionWithReasonV2 {
877 pub decision: SchedulingDecisionV1,
878 pub objects_needing_refresh: Vec<String>,
881 pub objects_needing_compaction: Vec<String>,
884 pub hydration_time_estimate: String,
886}
887
888#[derive(
889 Clone,
890 Debug,
891 Serialize,
892 Deserialize,
893 PartialOrd,
894 PartialEq,
895 Eq,
896 Ord,
897 Hash,
898 Arbitrary
899)]
900#[serde(rename_all = "kebab-case")]
901pub enum SchedulingDecisionV1 {
902 On,
903 Off,
904}
905
906impl From<bool> for SchedulingDecisionV1 {
907 fn from(value: bool) -> Self {
908 match value {
909 true => SchedulingDecisionV1::On,
910 false => SchedulingDecisionV1::Off,
911 }
912 }
913}
914
915#[derive(
916 Clone,
917 Debug,
918 Serialize,
919 Deserialize,
920 PartialOrd,
921 PartialEq,
922 Eq,
923 Ord,
924 Hash,
925 Arbitrary
926)]
927pub struct CreateSourceSinkV1 {
928 pub id: String,
929 #[serde(flatten)]
930 pub name: FullNameV1,
931 pub size: Option<String>,
932}
933
934#[derive(
935 Clone,
936 Debug,
937 Serialize,
938 Deserialize,
939 PartialOrd,
940 PartialEq,
941 Eq,
942 Ord,
943 Hash,
944 Arbitrary
945)]
946pub struct CreateSourceSinkV2 {
947 pub id: String,
948 #[serde(flatten)]
949 pub name: FullNameV1,
950 pub size: Option<String>,
951 #[serde(rename = "type")]
952 pub external_type: String,
953}
954
955#[derive(
956 Clone,
957 Debug,
958 Serialize,
959 Deserialize,
960 PartialOrd,
961 PartialEq,
962 Eq,
963 Ord,
964 Hash,
965 Arbitrary
966)]
967pub struct CreateSourceSinkV3 {
968 pub id: String,
969 #[serde(flatten)]
970 pub name: FullNameV1,
971 #[serde(rename = "type")]
972 pub external_type: String,
973}
974
975#[derive(
976 Clone,
977 Debug,
978 Serialize,
979 Deserialize,
980 PartialOrd,
981 PartialEq,
982 Eq,
983 Ord,
984 Hash,
985 Arbitrary
986)]
987pub struct CreateSourceSinkV4 {
988 pub id: String,
989 pub cluster_id: Option<String>,
990 #[serde(flatten)]
991 pub name: FullNameV1,
992 #[serde(rename = "type")]
993 pub external_type: String,
994}
995
996#[derive(
997 Clone,
998 Debug,
999 Serialize,
1000 Deserialize,
1001 PartialOrd,
1002 PartialEq,
1003 Eq,
1004 Ord,
1005 Hash,
1006 Arbitrary
1007)]
1008pub struct CreateIndexV1 {
1009 pub id: String,
1010 pub cluster_id: String,
1011 #[serde(flatten)]
1012 pub name: FullNameV1,
1013}
1014
1015#[derive(
1016 Clone,
1017 Debug,
1018 Serialize,
1019 Deserialize,
1020 PartialOrd,
1021 PartialEq,
1022 Eq,
1023 Ord,
1024 Hash,
1025 Arbitrary
1026)]
1027pub struct CreateMaterializedViewV1 {
1028 pub id: String,
1029 pub cluster_id: String,
1030 #[serde(flatten)]
1031 pub name: FullNameV1,
1032 #[serde(skip_serializing_if = "Option::is_none")]
1033 pub replacement_target_id: Option<String>,
1034}
1035
1036#[derive(
1037 Clone,
1038 Debug,
1039 Serialize,
1040 Deserialize,
1041 PartialOrd,
1042 PartialEq,
1043 Eq,
1044 Ord,
1045 Hash,
1046 Arbitrary
1047)]
1048pub struct AlterApplyReplacementV1 {
1049 #[serde(flatten)]
1050 pub target: IdFullNameV1,
1051 pub replacement: IdFullNameV1,
1052}
1053
1054#[derive(
1055 Clone,
1056 Debug,
1057 Serialize,
1058 Deserialize,
1059 PartialOrd,
1060 PartialEq,
1061 Eq,
1062 Ord,
1063 Hash,
1064 Arbitrary
1065)]
1066pub struct AlterSourceSinkV1 {
1067 pub id: String,
1068 #[serde(flatten)]
1069 pub name: FullNameV1,
1070 pub old_size: Option<String>,
1071 pub new_size: Option<String>,
1072}
1073
1074#[derive(
1075 Clone,
1076 Debug,
1077 Serialize,
1078 Deserialize,
1079 PartialOrd,
1080 PartialEq,
1081 Eq,
1082 Ord,
1083 Hash,
1084 Arbitrary
1085)]
1086pub struct AlterSetClusterV1 {
1087 pub id: String,
1088 #[serde(flatten)]
1089 pub name: FullNameV1,
1090 pub old_cluster_id: String,
1091 pub new_cluster_id: String,
1092}
1093
1094#[derive(
1095 Clone,
1096 Debug,
1097 Serialize,
1098 Deserialize,
1099 PartialOrd,
1100 PartialEq,
1101 Eq,
1102 Ord,
1103 Hash,
1104 Arbitrary
1105)]
1106pub struct GrantRoleV1 {
1107 pub role_id: String,
1108 pub member_id: String,
1109 pub grantor_id: String,
1110}
1111
1112#[derive(
1113 Clone,
1114 Debug,
1115 Serialize,
1116 Deserialize,
1117 PartialOrd,
1118 PartialEq,
1119 Eq,
1120 Ord,
1121 Hash,
1122 Arbitrary
1123)]
1124pub struct GrantRoleV2 {
1125 pub role_id: String,
1126 pub member_id: String,
1127 pub grantor_id: String,
1128 pub executed_by: String,
1129}
1130
1131#[derive(
1132 Clone,
1133 Debug,
1134 Serialize,
1135 Deserialize,
1136 PartialOrd,
1137 PartialEq,
1138 Eq,
1139 Ord,
1140 Hash,
1141 Arbitrary
1142)]
1143pub struct RevokeRoleV1 {
1144 pub role_id: String,
1145 pub member_id: String,
1146}
1147
1148#[derive(
1149 Clone,
1150 Debug,
1151 Serialize,
1152 Deserialize,
1153 PartialOrd,
1154 PartialEq,
1155 Eq,
1156 Ord,
1157 Hash,
1158 Arbitrary
1159)]
1160pub struct RevokeRoleV2 {
1161 pub role_id: String,
1162 pub member_id: String,
1163 pub grantor_id: String,
1164 pub executed_by: String,
1165}
1166
1167#[derive(
1168 Clone,
1169 Debug,
1170 Serialize,
1171 Deserialize,
1172 PartialOrd,
1173 PartialEq,
1174 Eq,
1175 Ord,
1176 Hash,
1177 Arbitrary
1178)]
1179pub struct UpdatePrivilegeV1 {
1180 pub object_id: String,
1181 pub grantee_id: String,
1182 pub grantor_id: String,
1183 pub privileges: String,
1184}
1185
1186#[derive(
1187 Clone,
1188 Debug,
1189 Serialize,
1190 Deserialize,
1191 PartialOrd,
1192 PartialEq,
1193 Eq,
1194 Ord,
1195 Hash,
1196 Arbitrary
1197)]
1198pub struct AlterDefaultPrivilegeV1 {
1199 pub role_id: String,
1200 pub database_id: Option<String>,
1201 pub schema_id: Option<String>,
1202 pub grantee_id: String,
1203 pub privileges: String,
1204}
1205
1206#[derive(
1207 Clone,
1208 Debug,
1209 Serialize,
1210 Deserialize,
1211 PartialOrd,
1212 PartialEq,
1213 Eq,
1214 Ord,
1215 Hash,
1216 Arbitrary
1217)]
1218pub struct UpdateOwnerV1 {
1219 pub object_id: String,
1220 pub old_owner_id: String,
1221 pub new_owner_id: String,
1222}
1223
1224#[derive(
1225 Clone,
1226 Debug,
1227 Serialize,
1228 Deserialize,
1229 PartialOrd,
1230 PartialEq,
1231 Eq,
1232 Ord,
1233 Hash,
1234 Arbitrary
1235)]
1236pub struct SchemaV1 {
1237 pub id: String,
1238 pub name: String,
1239 pub database_name: String,
1240}
1241
1242#[derive(
1243 Clone,
1244 Debug,
1245 Serialize,
1246 Deserialize,
1247 PartialOrd,
1248 PartialEq,
1249 Eq,
1250 Ord,
1251 Hash,
1252 Arbitrary
1253)]
1254pub struct SchemaV2 {
1255 pub id: String,
1256 pub name: String,
1257 pub database_name: Option<String>,
1258}
1259
1260#[derive(
1261 Clone,
1262 Debug,
1263 Serialize,
1264 Deserialize,
1265 PartialOrd,
1266 PartialEq,
1267 Eq,
1268 Ord,
1269 Hash,
1270 Arbitrary
1271)]
1272pub struct RenameSchemaV1 {
1273 pub id: String,
1274 pub database_name: Option<String>,
1275 pub old_name: String,
1276 pub new_name: String,
1277}
1278
1279#[derive(
1280 Clone,
1281 Debug,
1282 Serialize,
1283 Deserialize,
1284 PartialOrd,
1285 PartialEq,
1286 Eq,
1287 Ord,
1288 Hash,
1289 Arbitrary
1290)]
1291pub struct AlterRetainHistoryV1 {
1292 pub id: String,
1293 pub old_history: Option<String>,
1294 pub new_history: Option<String>,
1295}
1296
1297#[derive(
1298 Clone,
1299 Debug,
1300 Serialize,
1301 Deserialize,
1302 PartialOrd,
1303 PartialEq,
1304 Eq,
1305 Ord,
1306 Hash,
1307 Arbitrary
1308)]
1309pub struct AlterAddColumnV1 {
1310 pub id: String,
1311 pub column: String,
1312 pub column_type: String,
1313 pub nullable: bool,
1314}
1315
1316#[derive(
1317 Clone,
1318 Debug,
1319 Serialize,
1320 Deserialize,
1321 PartialOrd,
1322 PartialEq,
1323 Eq,
1324 Ord,
1325 Hash,
1326 Arbitrary
1327)]
1328pub struct AlterSourceTimestampIntervalV1 {
1329 pub id: String,
1330 pub old_interval: Option<String>,
1331 pub new_interval: Option<String>,
1332}
1333
1334#[derive(
1335 Clone,
1336 Debug,
1337 Serialize,
1338 Deserialize,
1339 PartialOrd,
1340 PartialEq,
1341 Eq,
1342 Ord,
1343 Hash,
1344 Arbitrary
1345)]
1346pub struct UpdateItemV1 {
1347 pub id: String,
1348 #[serde(flatten)]
1349 pub name: FullNameV1,
1350}
1351
1352#[derive(
1353 Clone,
1354 Debug,
1355 Serialize,
1356 Deserialize,
1357 PartialOrd,
1358 PartialEq,
1359 Eq,
1360 Ord,
1361 Hash,
1362 Arbitrary
1363)]
1364pub struct ToNewIdV1 {
1365 pub id: String,
1366 pub new_id: String,
1367}
1368
1369#[derive(
1370 Clone,
1371 Debug,
1372 Serialize,
1373 Deserialize,
1374 PartialOrd,
1375 PartialEq,
1376 Eq,
1377 Ord,
1378 Hash,
1379 Arbitrary
1380)]
1381pub struct FromPreviousIdV1 {
1382 pub id: String,
1383 pub previous_id: String,
1384}
1385
1386impl EventDetails {
1387 pub fn as_json(&self) -> serde_json::Value {
1388 match self {
1389 EventDetails::CreateClusterReplicaV1(v) => {
1390 serde_json::to_value(v).expect("must serialize")
1391 }
1392 EventDetails::CreateClusterReplicaV2(v) => {
1393 serde_json::to_value(v).expect("must serialize")
1394 }
1395 EventDetails::CreateClusterReplicaV3(v) => {
1396 serde_json::to_value(v).expect("must serialize")
1397 }
1398 EventDetails::CreateClusterReplicaV4(v) => {
1399 serde_json::to_value(v).expect("must serialize")
1400 }
1401 EventDetails::DropClusterReplicaV1(v) => {
1402 serde_json::to_value(v).expect("must serialize")
1403 }
1404 EventDetails::DropClusterReplicaV2(v) => {
1405 serde_json::to_value(v).expect("must serialize")
1406 }
1407 EventDetails::DropClusterReplicaV3(v) => {
1408 serde_json::to_value(v).expect("must serialize")
1409 }
1410 EventDetails::IdFullNameV1(v) => serde_json::to_value(v).expect("must serialize"),
1411 EventDetails::RenameClusterV1(v) => serde_json::to_value(v).expect("must serialize"),
1412 EventDetails::RenameClusterReplicaV1(v) => {
1413 serde_json::to_value(v).expect("must serialize")
1414 }
1415 EventDetails::AlterClusterReconfigurationV1(v) => {
1416 serde_json::to_value(v).expect("must serialize")
1417 }
1418 EventDetails::ClusterHydrationBurstV1(v) => {
1419 serde_json::to_value(v).expect("must serialize")
1420 }
1421 EventDetails::RenameItemV1(v) => serde_json::to_value(v).expect("must serialize"),
1422 EventDetails::IdNameV1(v) => serde_json::to_value(v).expect("must serialize"),
1423 EventDetails::SchemaV1(v) => serde_json::to_value(v).expect("must serialize"),
1424 EventDetails::SchemaV2(v) => serde_json::to_value(v).expect("must serialize"),
1425 EventDetails::RenameSchemaV1(v) => serde_json::to_value(v).expect("must serialize"),
1426 EventDetails::CreateSourceSinkV1(v) => serde_json::to_value(v).expect("must serialize"),
1427 EventDetails::CreateSourceSinkV2(v) => serde_json::to_value(v).expect("must serialize"),
1428 EventDetails::CreateSourceSinkV3(v) => serde_json::to_value(v).expect("must serialize"),
1429 EventDetails::CreateSourceSinkV4(v) => serde_json::to_value(v).expect("must serialize"),
1430 EventDetails::CreateIndexV1(v) => serde_json::to_value(v).expect("must serialize"),
1431 EventDetails::CreateMaterializedViewV1(v) => {
1432 serde_json::to_value(v).expect("must serialize")
1433 }
1434 EventDetails::AlterApplyReplacementV1(v) => {
1435 serde_json::to_value(v).expect("must serialize")
1436 }
1437 EventDetails::AlterSourceSinkV1(v) => serde_json::to_value(v).expect("must serialize"),
1438 EventDetails::AlterSetClusterV1(v) => serde_json::to_value(v).expect("must serialize"),
1439 EventDetails::GrantRoleV1(v) => serde_json::to_value(v).expect("must serialize"),
1440 EventDetails::GrantRoleV2(v) => serde_json::to_value(v).expect("must serialize"),
1441 EventDetails::RevokeRoleV1(v) => serde_json::to_value(v).expect("must serialize"),
1442 EventDetails::RevokeRoleV2(v) => serde_json::to_value(v).expect("must serialize"),
1443 EventDetails::UpdatePrivilegeV1(v) => serde_json::to_value(v).expect("must serialize"),
1444 EventDetails::AlterDefaultPrivilegeV1(v) => {
1445 serde_json::to_value(v).expect("must serialize")
1446 }
1447 EventDetails::UpdateOwnerV1(v) => serde_json::to_value(v).expect("must serialize"),
1448 EventDetails::UpdateItemV1(v) => serde_json::to_value(v).expect("must serialize"),
1449 EventDetails::AlterRetainHistoryV1(v) => {
1450 serde_json::to_value(v).expect("must serialize")
1451 }
1452 EventDetails::AlterAddColumnV1(v) => serde_json::to_value(v).expect("must serialize"),
1453 EventDetails::AlterSourceTimestampIntervalV1(v) => {
1454 serde_json::to_value(v).expect("must serialize")
1455 }
1456 EventDetails::ToNewIdV1(v) => serde_json::to_value(v).expect("must serialize"),
1457 EventDetails::FromPreviousIdV1(v) => serde_json::to_value(v).expect("must serialize"),
1458 EventDetails::SetV1(v) => serde_json::to_value(v).expect("must serialize"),
1459 EventDetails::ResetAllV1 => serde_json::Value::Null,
1460 EventDetails::RotateKeysV1(v) => serde_json::to_value(v).expect("must serialize"),
1461 EventDetails::CreateRoleV1(v) => serde_json::to_value(v).expect("must serialize"),
1462 }
1463 }
1464}
1465
1466#[derive(
1467 Clone,
1468 Debug,
1469 Serialize,
1470 Deserialize,
1471 PartialOrd,
1472 PartialEq,
1473 Eq,
1474 Ord,
1475 Hash,
1476 Arbitrary
1477)]
1478pub struct EventV1 {
1479 pub id: u64,
1480 pub event_type: EventType,
1481 pub object_type: ObjectType,
1482 pub details: EventDetails,
1483 pub user: Option<String>,
1484 pub occurred_at: EpochMillis,
1485}
1486
1487impl EventV1 {
1488 fn new(
1489 id: u64,
1490 event_type: EventType,
1491 object_type: ObjectType,
1492 details: EventDetails,
1493 user: Option<String>,
1494 occurred_at: EpochMillis,
1495 ) -> EventV1 {
1496 EventV1 {
1497 id,
1498 event_type,
1499 object_type,
1500 details,
1501 user,
1502 occurred_at,
1503 }
1504 }
1505}
1506
1507#[derive(
1508 Clone,
1509 Debug,
1510 Serialize,
1511 Deserialize,
1512 PartialOrd,
1513 PartialEq,
1514 Eq,
1515 Ord,
1516 Hash,
1517 Arbitrary
1518)]
1519pub struct StorageUsageV1 {
1520 pub id: u64,
1521 pub shard_id: Option<String>,
1522 pub size_bytes: u64,
1523 pub collection_timestamp: EpochMillis,
1524}
1525
1526impl StorageUsageV1 {
1527 pub fn new(
1528 id: u64,
1529 shard_id: Option<String>,
1530 size_bytes: u64,
1531 collection_timestamp: EpochMillis,
1532 ) -> StorageUsageV1 {
1533 StorageUsageV1 {
1534 id,
1535 shard_id,
1536 size_bytes,
1537 collection_timestamp,
1538 }
1539 }
1540}
1541
1542#[derive(
1547 Clone,
1548 Debug,
1549 Serialize,
1550 Deserialize,
1551 PartialOrd,
1552 PartialEq,
1553 Eq,
1554 Ord,
1555 Hash,
1556 Arbitrary
1557)]
1558pub enum VersionedStorageUsage {
1559 V1(StorageUsageV1),
1560}
1561
1562impl VersionedStorageUsage {
1563 pub fn new(
1567 id: u64,
1568 object_id: Option<String>,
1569 size_bytes: u64,
1570 collection_timestamp: EpochMillis,
1571 ) -> Self {
1572 Self::V1(StorageUsageV1::new(
1573 id,
1574 object_id,
1575 size_bytes,
1576 collection_timestamp,
1577 ))
1578 }
1579
1580 pub fn deserialize(data: &[u8]) -> Result<Self, anyhow::Error> {
1583 Ok(serde_json::from_slice(data)?)
1584 }
1585
1586 pub fn serialize(&self) -> Vec<u8> {
1587 serde_json::to_vec(self).expect("must serialize")
1588 }
1589
1590 pub fn timestamp(&self) -> EpochMillis {
1591 match self {
1592 VersionedStorageUsage::V1(StorageUsageV1 {
1593 collection_timestamp,
1594 ..
1595 }) => *collection_timestamp,
1596 }
1597 }
1598
1599 pub fn sortable_id(&self) -> u64 {
1602 match self {
1603 VersionedStorageUsage::V1(usage) => usage.id,
1604 }
1605 }
1606}
1607
1608#[cfg(test)]
1609mod tests {
1610 use crate::{EventDetails, EventType, EventV1, IdNameV1, ObjectType, VersionedEvent};
1611
1612 #[mz_ore::test]
1616 fn test_audit_log() -> Result<(), anyhow::Error> {
1617 let cases: Vec<(VersionedEvent, &'static str)> = vec![(
1618 VersionedEvent::V1(EventV1::new(
1619 2,
1620 EventType::Drop,
1621 ObjectType::ClusterReplica,
1622 EventDetails::IdNameV1(IdNameV1 {
1623 id: "u1".to_string(),
1624 name: "name".into(),
1625 }),
1626 None,
1627 2,
1628 )),
1629 r#"{"V1":{"id":2,"event_type":"drop","object_type":"cluster-replica","details":{"IdNameV1":{"id":"u1","name":"name"}},"user":null,"occurred_at":2}}"#,
1630 )];
1631
1632 for (event, expected_bytes) in cases {
1633 let event_bytes = serde_json::to_vec(&event).unwrap();
1634 assert_eq!(
1635 event_bytes,
1636 expected_bytes.as_bytes(),
1637 "expected bytes {}, got {}",
1638 expected_bytes,
1639 std::str::from_utf8(&event_bytes).unwrap(),
1640 );
1641 }
1642
1643 Ok(())
1644 }
1645}