feat: support read-write device.id in tedge cert/connect#3326
feat: support read-write device.id in tedge cert/connect#3326rina23q merged 9 commits intothin-edge:mainfrom
Conversation
didier-wenzek
left a comment
There was a problem hiding this comment.
The command to create a CSR must also be updated to set the device id.
didier-wenzek
left a comment
There was a problem hiding this comment.
If the device id has been set using tedge config set device.id, then the device id should no more be mandatory for tedge cert create.
We also need to take care of the paths for the cloud specific certificates.
For instance, the following sequence of command is error prone:
# Trying to create a certificate for an unknown cloud profile (okay: the error is detected)
$ tedge cert create --device-id demo-c8y c8y --profile foo
Error: missing configuration parameter
Caused by:
Unknown profile `foo` for the multi-profile property c8y
# Creating the cloud profile
$ tedge config set c8y.device.id device-c8y-foo --profile foo
# Now that the cloud profile exists, the cert creat command runs
# BUT
# - --device-id is required while set in the config
# - the value set on the command line erases the config
# - the certificate is created globally (because no specific paths were configured for this profile)
$ tedge cert create --device-id some-other-device-id c8y --profile foo
Error: failed to create a test certificate for the device some-other-device-id.
Caused by:
A certificate already exists and would be overwritten.
Existing file: "/etc/tedge/device-certs/demo-device-888.pem"
Run `tedge cert remove` first to generate a new certificate.
|
@didier-wenzek
For the rest, I would like to implement to have the consistent behavour as However, on the condition, if |
In that case this is a bug.
Perfect. One just to be cautious taking the most specific device id (i.e. the id for the requested cloud and profile if given).
Yes raising an error is the way to go. But make sure the comparison is done on the device id specific for the requested cloud. I.e. if |
Codecov ReportAttention: Patch coverage is Additional details and impacted files📢 Thoughts on this report? Let us know! |
Robot Results
|
7dcb459 to
77e1ecd
Compare
rina23q
left a comment
There was a problem hiding this comment.
I was trying to fix the error message that @didier-wenzek highlighted. There are some points discovered why it's not easy.
| .subject_common_name() | ||
| .map_err(|err| cert_error_into_config_error(ReadableKey::DeviceId.to_cow_str(), err))?; | ||
| let pem = PemCertificate::from_pem_file(cert_path).map_err(|err| { | ||
| cert_error_into_config_error(ReadableKey::DeviceId.to_cow_str(), err, cert_path) |
There was a problem hiding this comment.
This device_id_from_cert() is called by all device id default functions (device_id(), c8y_device_id(), az_device_id(), and aws_device_id(). However, here gives ReadableKey::DeviceId as key. This is not 100% correct. It can be ReadableKey::C8yDeviceId(None), ReadableKey::AzDeviceId(Some("abc")) and so on.
The difficulty is, the default functions cannot know which profile is used. That's why it is impossible to parse the precise ReadableKey to this fuction from the default device id functions.
There was a problem hiding this comment.
So the issue to improve the error message is that device_id_from_cert has no clue on the actual key. But can this key be passed as a parameter with the appropriate value by the caller (i.e device_id(), c8y_device_id(), az_device_id(), and aws_device_id()`) ?
There was a problem hiding this comment.
So the issue to improve the error message is that
device_id_from_certhas no clue on the actual key.
Right.
But can this key be passed as a parameter with the appropriate value by the caller (i.e
device_id(),c8y_device_id(),az_device_id(), andaws_device_id()) ?
Also no unfortunately. Look at this function. This function is called by the macro. No chance to get the profile.
thin-edge.io/crates/common/tedge_config/src/tedge_config_cli/tedge_config.rs
Lines 1375 to 1383 in 91eb9bd
crates/common/tedge_config/src/tedge_config_cli/tedge_config.rs
Outdated
Show resolved
Hide resolved
953fcaa to
91eb9bd
Compare
didier-wenzek
left a comment
There was a problem hiding this comment.
Since improving error messages and hints when the device id cannot be derived from the config, I propose to give up on this point - at least for now, and to focus on the main point of this PR: the ability to configure a device id with or with a certificate.
Configuring a device to use several cloud profiles each with its specific certificate is working, although this is for now a complicated and error prone task. We can improve the user experience in a second step with the broader scope of configuring multi-profile connection . @reubenmiller do you agree on that?
| remove_cmd.assert().success(); | ||
|
|
||
| // We start we no certificate, hence no device id | ||
| // We start with no certificate, hence no device id |
There was a problem hiding this comment.
This test has to be updated with the new error message.
// We start with no certificate, hence no device id
get_device_id_cmd
.assert()
.failure()
.stderr(predicate::str::contains("The device certificate cannot be read from"));| .subject_common_name() | ||
| .map_err(|err| cert_error_into_config_error(ReadableKey::DeviceId.to_cow_str(), err))?; | ||
| let pem = PemCertificate::from_pem_file(cert_path).map_err(|err| { | ||
| cert_error_into_config_error(ReadableKey::DeviceId.to_cow_str(), err, cert_path) |
There was a problem hiding this comment.
So the issue to improve the error message is that device_id_from_cert has no clue on the actual key. But can this key be passed as a parameter with the appropriate value by the caller (i.e device_id(), c8y_device_id(), az_device_id(), and aws_device_id()`) ?
didier-wenzek
left a comment
There was a problem hiding this comment.
Approved, although the user experience could be simpler (see here for the complicate list of commands required when the use case is not the regular one: #3326 (comment)).
| /// The tedge.toml file location, required to access to TEdgeConfigDto | ||
| pub config_location: TEdgeConfigLocation, |
There was a problem hiding this comment.
Okayish as this is here only to provide a key path in error messages.
Signed-off-by: James Rhodes <james.rhodes@cumulocity.com>
Also, small refactoring in tedge cert, makes --device-id optional tedge connect * tedge connect <cloud> fails when the common name from the device certificate does not match the device id configured in tedge config. * this validation applies only when auth_method is certificate tedge cert * tedge cert create can be run without --device-id if device.id is set Signed-off-by: Rina Fujino <rina.fujino.23@gmail.com>
Signed-off-by: Rina Fujino <rina.fujino.23@gmail.com>
This reverts commit ad2209f.
* update the smartrest_one test to consume device.id directly * add tests for tedge connect for CN/device id validation * add tests for tedge cert command Signed-off-by: Rina Fujino <rina.fujino.23@gmail.com>
Signed-off-by: Rina Fujino <rina.fujino.23@gmail.com>
9a3587d to
2f61a0a
Compare
albinsuresh
left a comment
There was a problem hiding this comment.
The feature is working fine for the most common cases. The error messages could be improved in some cases though, but don't need to block this PR anymore for that. One simple example of such an error message is when trying to create a certificate with a different --device-id from what is set as device.id:
Error: missing configuration parameter
Caused by:
`--device-id` option conflicts with tedge config settings.
Configured value: 'albin_test', but input: 'albin_latest'
Please either update the configuration using `tedge config set <key> <new_id>`
or provide the correct value with the `--device-id` option.
The highlighted error is Error: missing configuration parameter whereas this is a pure case of "conflicting configuration". Even though that generic error is misleading, th rest of the message that suggests ways to fix is clear enough for the user. So, this is fine. If I spot more inconsistencies like this for the common use-cases, I'll compile and share it separately, even after this PR is merged.
I'm actually aware of that. However, since this error message comes from very high level, I decided not to touch. Here the message is coming from. |
Proposed changes
This PR aims to open up
device.idas read-write key. This is the last piece of supporting basic authentication, as it needsdevice.idbut not need for device cert.TODOs:
tedge cert/connect part
Reverted.tedge cert createwritesdevice.idintedge.tomlexplicitly.tedge connectreturns an error ifdevice.idmismatches the certificate's CN. The only exception is whenc8y.auth_modeisbasic.smart_rest_onesystem test to confirm thattedge connect c8yusesdevice.iddirectly when using basic auth.Reverted.tedge cert create-csralso setsdevice.idif not configured.tedge cert createshould work without--device-idoption whendevice.idis already set.Don't overwrite a certificate andIf a certificate exists already in the given path, anyway it will not be overwritten (known behavour)device.idwhen the values of option--device-idand configdevice.idare conflicting. This case should return an error.tedge_config part (originally started in the PR #3318 by @jarhodes314 )
get_device_id_from_config()function totedge_configto keepconfig.device.id()as private. refactor: support writable device ids #3318 (comment)doc part
Types of changes
Paste Link to the issue
#3242
Checklist
cargo fmtas mentioned in CODING_GUIDELINEScargo clippyas mentioned in CODING_GUIDELINESFurther comments