@@ -154,15 +154,8 @@ define_tedge_config! {
154154 device: {
155155 /// Identifier of the device within the fleet. It must be globally
156156 /// unique and is derived from the device certificate.
157- #[ tedge_config( readonly(
158- write_error = "\
159- The device id is read from the device certificate and cannot be set directly.\n \
160- To set 'device.id' to some <id>, you can use `tedge cert create --device-id <id>`.",
161- function = "device_id" ,
162- ) ) ]
157+ #[ tedge_config( reader( function = "device_id" , private) ) ]
163158 #[ tedge_config( example = "Raspberrypi-4d18303a-6d3a-11eb-b1a6-175f6bb72665" ) ]
164- #[ tedge_config( note = "This setting is derived from the device certificate and is therefore read only." ) ]
165- #[ tedge_config( reader( private) ) ]
166159 #[ doku( as = "String" ) ]
167160 id: Result <String , ReadError >,
168161
@@ -215,14 +208,9 @@ define_tedge_config! {
215208 device: {
216209 /// Identifier of the device within the fleet. It must be globally
217210 /// unique and is derived from the device certificate.
218- #[ tedge_config( readonly(
219- write_error = "\
220- The device id is read from the device certificate and cannot be set directly.\n \
221- To set 'device.id' to some <id>, you can use `tedge cert create --device-id <id>`.",
222- function = "c8y_device_id" ,
223- ) ) ]
211+ #[ tedge_config( reader( function = "c8y_device_id" ) ) ]
212+ #[ tedge_config( default ( from_optional_key = "device.id" ) ) ]
224213 #[ tedge_config( example = "Raspberrypi-4d18303a-6d3a-11eb-b1a6-175f6bb72665" ) ]
225- #[ tedge_config( note = "This setting is derived from the device certificate and is therefore read only." ) ]
226214 #[ doku( as = "String" ) ]
227215 id: Result <String , ReadError >,
228216
@@ -411,14 +399,9 @@ define_tedge_config! {
411399 device: {
412400 /// Identifier of the device within the fleet. It must be globally
413401 /// unique and is derived from the device certificate.
414- #[ tedge_config( readonly(
415- write_error = "\
416- The device id is read from the device certificate and cannot be set directly.\n \
417- To set 'device.id' to some <id>, you can use `tedge cert create --device-id <id>`.",
418- function = "az_device_id" ,
419- ) ) ]
402+ #[ tedge_config( reader( function = "az_device_id" ) ) ]
403+ #[ tedge_config( default ( from_optional_key = "device.id" ) ) ]
420404 #[ tedge_config( example = "Raspberrypi-4d18303a-6d3a-11eb-b1a6-175f6bb72665" ) ]
421- #[ tedge_config( note = "This setting is derived from the device certificate and is therefore read only." ) ]
422405 #[ doku( as = "String" ) ]
423406 id: Result <String , ReadError >,
424407
@@ -481,14 +464,9 @@ define_tedge_config! {
481464 device: {
482465 /// Identifier of the device within the fleet. It must be globally
483466 /// unique and is derived from the device certificate.
484- #[ tedge_config( readonly(
485- write_error = "\
486- The device id is read from the device certificate and cannot be set directly.\n \
487- To set 'device.id' to some <id>, you can use `tedge cert create --device-id <id>`.",
488- function = "aws_device_id" ,
489- ) ) ]
467+ #[ tedge_config( reader( function = "aws_device_id" ) ) ]
468+ #[ tedge_config( default ( from_optional_key = "device.id" ) ) ]
490469 #[ tedge_config( example = "Raspberrypi-4d18303a-6d3a-11eb-b1a6-175f6bb72665" ) ]
491- #[ tedge_config( note = "This setting is derived from the device certificate and is therefore read only." ) ]
492470 #[ doku( as = "String" ) ]
493471 id: Result <String , ReadError >,
494472
@@ -929,6 +907,15 @@ impl TEdgeConfigReader {
929907 Some ( Cloud :: Aws ( profile) ) => & self . aws . try_get ( profile) ?. device . cert_path ,
930908 } )
931909 }
910+
911+ pub fn device_id < ' a > ( & self , cloud : Option < impl Into < Cloud < ' a > > > ) -> Result < & str , ReadError > {
912+ Ok ( match cloud. map ( <_ >:: into) {
913+ None => self . device . id ( ) ?,
914+ Some ( Cloud :: C8y ( profile) ) => self . c8y . try_get ( profile) ?. device . id ( ) ?,
915+ Some ( Cloud :: Az ( profile) ) => self . az . try_get ( profile) ?. device . id ( ) ?,
916+ Some ( Cloud :: Aws ( profile) ) => self . aws . try_get ( profile) ?. device . id ( ) ?,
917+ } )
918+ }
932919}
933920
934921#[ derive( Debug , PartialEq , Eq , Clone ) ]
@@ -1019,27 +1006,77 @@ fn default_http_bind_address(dto: &TEdgeConfigDto) -> IpAddr {
10191006
10201007fn device_id_from_cert ( cert_path : & Utf8Path ) -> Result < String , ReadError > {
10211008 let pem = PemCertificate :: from_pem_file ( cert_path)
1022- . map_err ( |err| cert_error_into_config_error ( ReadOnlyKey :: DeviceId . to_cow_str ( ) , err) ) ?;
1009+ . map_err ( |err| cert_error_into_config_error ( ReadableKey :: DeviceId . to_cow_str ( ) , err) ) ?;
10231010 let device_id = pem
10241011 . subject_common_name ( )
1025- . map_err ( |err| cert_error_into_config_error ( ReadOnlyKey :: DeviceId . to_cow_str ( ) , err) ) ?;
1012+ . map_err ( |err| cert_error_into_config_error ( ReadableKey :: DeviceId . to_cow_str ( ) , err) ) ?;
10261013 Ok ( device_id)
10271014}
10281015
1029- fn device_id ( device : & TEdgeConfigReaderDevice ) -> Result < String , ReadError > {
1030- device_id_from_cert ( & device. cert_path )
1016+ fn device_id (
1017+ device : & TEdgeConfigReaderDevice ,
1018+ dto_value : & OptionalConfig < String > ,
1019+ ) -> Result < String , ReadError > {
1020+ match dto_value. or_none ( ) {
1021+ Some ( id) => Ok ( id. clone ( ) ) ,
1022+ None => device_id_from_cert ( & device. cert_path ) ,
1023+ }
10311024}
10321025
1033- fn c8y_device_id ( device : & TEdgeConfigReaderC8yDevice ) -> Result < String , ReadError > {
1034- device_id_from_cert ( & device. cert_path )
1026+ fn c8y_device_id (
1027+ c8y_device : & TEdgeConfigReaderC8yDevice ,
1028+ dto_value : & OptionalConfig < String > ,
1029+ ) -> Result < String , ReadError > {
1030+ match dto_value. or_none ( ) {
1031+ Some ( id) => Ok ( id. clone ( ) ) ,
1032+ None => device_id_from_cert ( & c8y_device. cert_path ) ,
1033+ }
10351034}
10361035
1037- fn az_device_id ( device : & TEdgeConfigReaderAzDevice ) -> Result < String , ReadError > {
1038- device_id_from_cert ( & device. cert_path )
1036+ fn az_device_id (
1037+ az_device : & TEdgeConfigReaderAzDevice ,
1038+ dto_value : & OptionalConfig < String > ,
1039+ ) -> Result < String , ReadError > {
1040+ match dto_value. or_none ( ) {
1041+ Some ( id) => Ok ( id. clone ( ) ) ,
1042+ None => device_id_from_cert ( & az_device. cert_path ) ,
1043+ }
10391044}
10401045
1041- fn aws_device_id ( device : & TEdgeConfigReaderAwsDevice ) -> Result < String , ReadError > {
1042- device_id_from_cert ( & device. cert_path )
1046+ fn aws_device_id (
1047+ aws_device : & TEdgeConfigReaderAwsDevice ,
1048+ dto_value : & OptionalConfig < String > ,
1049+ ) -> Result < String , ReadError > {
1050+ match dto_value. or_none ( ) {
1051+ Some ( id) => Ok ( id. clone ( ) ) ,
1052+ None => device_id_from_cert ( & aws_device. cert_path ) ,
1053+ }
1054+ }
1055+
1056+ pub fn explicit_device_id (
1057+ config_location : & TEdgeConfigLocation ,
1058+ cloud : & Option < Cloud > ,
1059+ ) -> Option < String > {
1060+ let dto = config_location. load_dto_from_toml_and_env ( ) . ok ( ) ?;
1061+
1062+ match cloud {
1063+ None => dto. device . id . clone ( ) ,
1064+ Some ( Cloud :: C8y ( profile) ) => {
1065+ let key = profile. map ( |name| name. to_string ( ) ) ;
1066+ let c8y_dto = dto. c8y . try_get ( key. as_deref ( ) , "c8y" ) . ok ( ) ?;
1067+ c8y_dto. device . id . clone ( )
1068+ }
1069+ Some ( Cloud :: Az ( profile) ) => {
1070+ let key = profile. map ( |name| name. to_string ( ) ) ;
1071+ let az_dto = dto. az . try_get ( key. as_deref ( ) , "az" ) . ok ( ) ?;
1072+ az_dto. device . id . clone ( )
1073+ }
1074+ Some ( Cloud :: Aws ( profile) ) => {
1075+ let key = profile. map ( |name| name. to_string ( ) ) ;
1076+ let aws_dto = dto. aws . try_get ( key. as_deref ( ) , "aws" ) . ok ( ) ?;
1077+ aws_dto. device . id . clone ( )
1078+ }
1079+ }
10431080}
10441081
10451082fn cert_error_into_config_error ( key : Cow < ' static , str > , err : CertificateError ) -> ReadError {
0 commit comments