@@ -55,6 +55,12 @@ use sled_agent_types::support_bundle::{
5555 SupportBundleMetadata , SupportBundlePathParam ,
5656 SupportBundleTransferQueryParams ,
5757} ;
58+ use sled_agent_types:: trust_quorum:: {
59+ TrustQuorumCommitRequest , TrustQuorumCommitResponse ,
60+ TrustQuorumConfiguration , TrustQuorumCoordinatorStatus ,
61+ TrustQuorumLrtqUpgradeRequest , TrustQuorumPrepareAndCommitRequest ,
62+ TrustQuorumReconfigureRequest ,
63+ } ;
5864use sled_agent_types:: zone_bundle:: {
5965 BundleUtilization , CleanupContext , CleanupContextUpdate , CleanupCount ,
6066 CleanupPeriod , StorageLimit , ZoneBundleFilter , ZoneBundleId ,
@@ -1178,4 +1184,184 @@ impl SledAgentApi for SledAgentImpl {
11781184
11791185 Ok ( HttpResponseUpdatedNoContent ( ) )
11801186 }
1187+
1188+ async fn trust_quorum_reconfigure (
1189+ request_context : RequestContext < Self :: Context > ,
1190+ body : TypedBody < TrustQuorumReconfigureRequest > ,
1191+ ) -> Result < HttpResponseUpdatedNoContent , HttpError > {
1192+ let sa = request_context. context ( ) ;
1193+ let request = body. into_inner ( ) ;
1194+
1195+ let msg = trust_quorum_protocol:: ReconfigureMsg {
1196+ rack_id : request. rack_id ,
1197+ epoch : trust_quorum_protocol:: Epoch ( request. epoch ) ,
1198+ last_committed_epoch : request
1199+ . last_committed_epoch
1200+ . map ( trust_quorum_protocol:: Epoch ) ,
1201+ members : request. members ,
1202+ threshold : trust_quorum_protocol:: Threshold ( request. threshold ) ,
1203+ } ;
1204+
1205+ sa. trust_quorum ( )
1206+ . reconfigure ( msg)
1207+ . await
1208+ . map_err ( |e| HttpError :: for_internal_error ( e. to_string ( ) ) ) ?;
1209+
1210+ Ok ( HttpResponseUpdatedNoContent ( ) )
1211+ }
1212+
1213+ async fn trust_quorum_upgrade_from_lrtq (
1214+ request_context : RequestContext < Self :: Context > ,
1215+ body : TypedBody < TrustQuorumLrtqUpgradeRequest > ,
1216+ ) -> Result < HttpResponseUpdatedNoContent , HttpError > {
1217+ let sa = request_context. context ( ) ;
1218+ let request = body. into_inner ( ) ;
1219+
1220+ let msg = trust_quorum_protocol:: LrtqUpgradeMsg {
1221+ rack_id : request. rack_id ,
1222+ epoch : trust_quorum_protocol:: Epoch ( request. epoch ) ,
1223+ members : request. members ,
1224+ threshold : trust_quorum_protocol:: Threshold ( request. threshold ) ,
1225+ } ;
1226+
1227+ sa. trust_quorum ( )
1228+ . upgrade_from_lrtq ( msg)
1229+ . await
1230+ . map_err ( |e| HttpError :: for_internal_error ( e. to_string ( ) ) ) ?;
1231+
1232+ Ok ( HttpResponseUpdatedNoContent ( ) )
1233+ }
1234+
1235+ async fn trust_quorum_commit (
1236+ request_context : RequestContext < Self :: Context > ,
1237+ body : TypedBody < TrustQuorumCommitRequest > ,
1238+ ) -> Result < HttpResponseOk < TrustQuorumCommitResponse > , HttpError > {
1239+ let sa = request_context. context ( ) ;
1240+ let request = body. into_inner ( ) ;
1241+
1242+ let status = sa
1243+ . trust_quorum ( )
1244+ . commit (
1245+ request. rack_id ,
1246+ trust_quorum_protocol:: Epoch ( request. epoch ) ,
1247+ )
1248+ . await
1249+ . map_err ( |e| HttpError :: for_internal_error ( e. to_string ( ) ) ) ?;
1250+
1251+ let response = match status {
1252+ trust_quorum:: CommitStatus :: Committed => {
1253+ TrustQuorumCommitResponse :: Committed
1254+ }
1255+ trust_quorum:: CommitStatus :: Pending => {
1256+ TrustQuorumCommitResponse :: Pending
1257+ }
1258+ } ;
1259+
1260+ Ok ( HttpResponseOk ( response) )
1261+ }
1262+
1263+ async fn trust_quorum_coordinator_status (
1264+ request_context : RequestContext < Self :: Context > ,
1265+ ) -> Result < HttpResponseOk < Option < TrustQuorumCoordinatorStatus > > , HttpError >
1266+ {
1267+ let sa = request_context. context ( ) ;
1268+
1269+ let status = sa
1270+ . trust_quorum ( )
1271+ . coordinator_status ( )
1272+ . await
1273+ . map_err ( |e| HttpError :: for_internal_error ( e. to_string ( ) ) ) ?;
1274+
1275+ let response = status. map ( |s| TrustQuorumCoordinatorStatus {
1276+ config : TrustQuorumConfiguration {
1277+ rack_id : s. config . rack_id ,
1278+ epoch : s. config . epoch . 0 ,
1279+ coordinator : s. config . coordinator ,
1280+ members : s
1281+ . config
1282+ . members
1283+ . into_iter ( )
1284+ . map ( |( id, digest) | ( id, hex:: encode ( digest. 0 ) ) )
1285+ . collect ( ) ,
1286+ threshold : s. config . threshold . 0 ,
1287+ } ,
1288+ acked_prepares : s. acked_prepares ,
1289+ } ) ;
1290+
1291+ Ok ( HttpResponseOk ( response) )
1292+ }
1293+
1294+ async fn trust_quorum_prepare_and_commit (
1295+ request_context : RequestContext < Self :: Context > ,
1296+ body : TypedBody < TrustQuorumPrepareAndCommitRequest > ,
1297+ ) -> Result < HttpResponseOk < TrustQuorumCommitResponse > , HttpError > {
1298+ let sa = request_context. context ( ) ;
1299+ let request = body. into_inner ( ) ;
1300+
1301+ let bad_request = |msg : String | HttpError :: for_bad_request ( None , msg) ;
1302+
1303+ let parse_digest = |hex : & str | -> Result < [ u8 ; 32 ] , HttpError > {
1304+ let bytes = hex:: decode ( hex)
1305+ . map_err ( |e| bad_request ( format ! ( "invalid hex: {e}" ) ) ) ?;
1306+ bytes. try_into ( ) . map_err ( |v : Vec < u8 > | {
1307+ bad_request ( format ! ( "digest must be 32 bytes, got {}" , v. len( ) ) )
1308+ } )
1309+ } ;
1310+
1311+ let members = request
1312+ . members
1313+ . into_iter ( )
1314+ . map ( |( id, hex) | {
1315+ Ok ( (
1316+ id,
1317+ trust_quorum_protocol:: Sha3_256Digest ( parse_digest ( & hex) ?) ,
1318+ ) )
1319+ } )
1320+ . collect :: < Result < _ , HttpError > > ( ) ?;
1321+
1322+ let encrypted_rack_secrets = request
1323+ . encrypted_rack_secrets
1324+ . map (
1325+ |ers| -> Result <
1326+ trust_quorum_protocol:: EncryptedRackSecrets ,
1327+ HttpError ,
1328+ > {
1329+ let salt = parse_digest ( & ers. salt ) ?;
1330+ let data = hex:: decode ( & ers. data ) . map_err ( |e| {
1331+ bad_request ( format ! ( "invalid hex data: {e}" ) )
1332+ } ) ?;
1333+ Ok ( trust_quorum_protocol:: EncryptedRackSecrets :: new (
1334+ trust_quorum_protocol:: Salt ( salt) ,
1335+ data. into_boxed_slice ( ) ,
1336+ ) )
1337+ } ,
1338+ )
1339+ . transpose ( ) ?;
1340+
1341+ let config = trust_quorum_protocol:: Configuration {
1342+ rack_id : request. rack_id ,
1343+ epoch : trust_quorum_protocol:: Epoch ( request. epoch ) ,
1344+ coordinator : request. coordinator ,
1345+ members,
1346+ threshold : trust_quorum_protocol:: Threshold ( request. threshold ) ,
1347+ encrypted_rack_secrets,
1348+ } ;
1349+
1350+ let status = sa
1351+ . trust_quorum ( )
1352+ . prepare_and_commit ( config)
1353+ . await
1354+ . map_err ( |e| HttpError :: for_internal_error ( e. to_string ( ) ) ) ?;
1355+
1356+ let response = match status {
1357+ trust_quorum:: CommitStatus :: Committed => {
1358+ TrustQuorumCommitResponse :: Committed
1359+ }
1360+ trust_quorum:: CommitStatus :: Pending => {
1361+ TrustQuorumCommitResponse :: Pending
1362+ }
1363+ } ;
1364+
1365+ Ok ( HttpResponseOk ( response) )
1366+ }
11811367}
0 commit comments