Skip to content

Commit

Permalink
Re-add dynamic provisioning support (#4556)
Browse files Browse the repository at this point in the history
- Replaced `auto_reprovision_on_startup` and `dynamic_reprovision` flags with one `auto_reprovisioning_mode` configuration (see config.toml docs for details)

- Changed import to only set `auto_reprovisioning_mode = AlwaysOnStartup` if `always_reprovision_on_startup = true`.

 - `iotedge config import` sets `auto_reprovisioning_mode = Dynamic` if old config had `auto_reprovision_on_startup = true` and `dynamic_reprovisioning = true` (added comment within `iotedge config import` logic for reason)

- aziot-edged calls `reprovision()` on startup if `auto_reprovision_mode = AlwaysOnStartup`

TODO:

- [X] Import existing config.yaml setting into super-config.toml
  • Loading branch information
massand authored Mar 23, 2021
1 parent bbebd3e commit c0997a7
Show file tree
Hide file tree
Showing 68 changed files with 428 additions and 132 deletions.
40 changes: 20 additions & 20 deletions edgelet/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 33 additions & 7 deletions edgelet/aziot-edged/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,12 @@ use serde::Serialize;
use sha2::{Digest, Sha256};
use url::Url;

use edgelet_core::crypto::{
CreateCertificate, GetDeviceIdentityCertificate, GetIssuerAlias, Signature,
AZIOT_EDGED_CA_ALIAS, TRUST_BUNDLE_ALIAS,
use edgelet_core::{
crypto::{
CreateCertificate, GetDeviceIdentityCertificate, GetIssuerAlias, Signature,
AZIOT_EDGED_CA_ALIAS, TRUST_BUNDLE_ALIAS,
},
settings::AutoReprovisioningMode,
};
use edgelet_core::{
Authenticator, Certificate, CertificateIssuer, CertificateProperties, CertificateType,
Expand Down Expand Up @@ -246,6 +249,13 @@ where
&url,
)));

match settings.auto_reprovisioning_mode() {
AutoReprovisioningMode::AlwaysOnStartup => {
tokio_runtime.block_on(reprovision_device(&client))?
}
AutoReprovisioningMode::Dynamic | AutoReprovisioningMode::OnErrorOnly => {}
}

let device_info = get_device_info(&client)
.map_err(|e| {
Error::from(
Expand Down Expand Up @@ -311,6 +321,10 @@ where
&mut tokio_runtime,
)?;

if should_reprovision {
tokio_runtime.block_on(reprovision_device(&client))?;
}

if code != StartApiReturnStatus::Restart {
break;
}
Expand Down Expand Up @@ -347,6 +361,15 @@ fn get_device_info(
})
}

fn reprovision_device(
identity_client: &Arc<Mutex<IdentityClient>>,
) -> impl Future<Item = (), Error = Error> {
let id_mgr = identity_client.lock().unwrap();
id_mgr
.reprovision_device()
.map_err(|err| Error::from(err.context(ErrorKind::ReprovisionFailure)))
}

#[allow(clippy::too_many_arguments)]
fn start_api<F, W, M>(
settings: &M::Settings,
Expand Down Expand Up @@ -408,10 +431,13 @@ where
Err(((), _)) => Err(Error::from(ErrorKind::ManagementService)),
});

let mgmt_stop_and_reprovision_signaled = if true {
futures::future::Either::B(mgmt_stop_and_reprovision_signaled)
} else {
futures::future::Either::A(future::empty())
let mgmt_stop_and_reprovision_signaled = match settings.auto_reprovisioning_mode() {
AutoReprovisioningMode::Dynamic => {
futures::future::Either::B(mgmt_stop_and_reprovision_signaled)
}
AutoReprovisioningMode::AlwaysOnStartup | AutoReprovisioningMode::OnErrorOnly => {
futures::future::Either::A(future::empty())
}
};

let edge_rt_with_mgmt_signal = edge_rt.select2(mgmt_stop_and_reprovision_signaled).then(
Expand Down
25 changes: 24 additions & 1 deletion edgelet/contrib/config/linux/template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,33 @@
# ==============================================================================
# Provisioning
# ==============================================================================


# Optional auto reprovisioning mode
# ------------------------------------

# This property specifies the conditions under which the device attempts to
# automatically reprovision with the cloud. It is ignored if the device has
# been provisioned manually. One of the following values can be set:
# Dynamic: Reprovision when the device detects that it may have
# been moved from one IoT Hub to another. This is the default.
# AlwaysOnStartup: Reprovision when the device is rebooted or a crash causes
# the daemon(s) to restart.
# OnErrorOnly: Never trigger device reprovisioning automatically.
# Device reprovisioning only occurs as fallback, if the device
# is unable to connect to IoT Hub during identity provisioning
# due to connectivity errors. This fallback behavior is implicit
# in Dynamic and AlwaysOnStartup modes as well.
#
# auto_reprovisioning_mode = Dynamic
#
# Uncomment one block and replace the stub values with yours.


# Provisioning configuration
# --------------------------

# Uncomment one block and replace the stub values with yours.

## Manual provisioning with connection string
#
# [provisioning]
Expand Down
21 changes: 21 additions & 0 deletions edgelet/edgelet-core/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,20 @@ pub trait RuntimeSettings {
fn edge_ca_cert(&self) -> Option<&str>;
fn edge_ca_key(&self) -> Option<&str>;
fn trust_bundle_cert(&self) -> Option<&str>;
fn auto_reprovisioning_mode(&self) -> &AutoReprovisioningMode;
}

#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
pub enum AutoReprovisioningMode {
Dynamic,
AlwaysOnStartup,
OnErrorOnly,
}

impl Default for AutoReprovisioningMode {
fn default() -> Self {
AutoReprovisioningMode::Dynamic
}
}

#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize)]
Expand All @@ -331,6 +345,9 @@ pub struct Settings<T> {
#[serde(skip_serializing_if = "Option::is_none")]
pub trust_bundle_cert: Option<String>,

#[serde(default = "AutoReprovisioningMode::default")]
pub auto_reprovisioning_mode: AutoReprovisioningMode,

pub homedir: PathBuf,

pub agent: ModuleSpec<T>,
Expand Down Expand Up @@ -402,6 +419,10 @@ where
fn trust_bundle_cert(&self) -> Option<&str> {
self.trust_bundle_cert.as_deref()
}

fn auto_reprovisioning_mode(&self) -> &AutoReprovisioningMode {
&self.auto_reprovisioning_mode
}
}

#[derive(Clone, Debug, PartialEq, serde_derive::Deserialize, serde_derive::Serialize)]
Expand Down
7 changes: 6 additions & 1 deletion edgelet/edgelet-docker/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1288,7 +1288,8 @@ mod tests {
use futures::stream::Empty;

use edgelet_core::{
Connect, Endpoints, Listen, ModuleRegistry, ModuleTop, RuntimeSettings, WatchdogSettings,
settings::AutoReprovisioningMode, Connect, Endpoints, Listen, ModuleRegistry, ModuleTop,
RuntimeSettings, WatchdogSettings,
};

#[test]
Expand Down Expand Up @@ -1528,6 +1529,10 @@ mod tests {
fn trust_bundle_cert(&self) -> Option<&str> {
unimplemented!()
}

fn auto_reprovisioning_mode(&self) -> &AutoReprovisioningMode {
unimplemented!()
}
}

#[derive(Clone, Copy, Debug, PartialEq)]
Expand Down
8 changes: 6 additions & 2 deletions edgelet/edgelet-docker/src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ use std::path::Path;

use docker::models::{ContainerCreateBodyNetworkingConfig, EndpointSettings, HostConfig};
use edgelet_core::{
Connect, Endpoints, Listen, MobyNetwork, ModuleSpec, RuntimeSettings, Settings as BaseSettings,
UrlExt, WatchdogSettings,
settings::AutoReprovisioningMode, Connect, Endpoints, Listen, MobyNetwork, ModuleSpec,
RuntimeSettings, Settings as BaseSettings, UrlExt, WatchdogSettings,
};
use failure::{Context, Fail, ResultExt};

Expand Down Expand Up @@ -148,6 +148,10 @@ impl RuntimeSettings for Settings {
fn trust_bundle_cert(&self) -> Option<&str> {
self.base.trust_bundle_cert()
}

fn auto_reprovisioning_mode(&self) -> &AutoReprovisioningMode {
self.base.auto_reprovisioning_mode()
}
}

fn init_agent_spec(settings: &mut Settings) -> Result<(), LoadSettingsError> {
Expand Down
10 changes: 7 additions & 3 deletions edgelet/edgelet-test-utils/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::path::Path;
use std::time::Duration;

use edgelet_core::{
AuthId, Authenticator, Connect, DiskInfo, Endpoints, Listen, LogOptions, MakeModuleRuntime,
Module, ModuleRegistry, ModuleRuntime, ModuleRuntimeState, ModuleSpec, ProvisioningInfo,
RuntimeSettings, SystemInfo, SystemResources, WatchdogSettings,
settings::AutoReprovisioningMode, AuthId, Authenticator, Connect, DiskInfo, Endpoints, Listen,
LogOptions, MakeModuleRuntime, Module, ModuleRegistry, ModuleRuntime, ModuleRuntimeState,
ModuleSpec, ProvisioningInfo, RuntimeSettings, SystemInfo, SystemResources, WatchdogSettings,
};
use failure::Fail;
use futures::future::{self, FutureResult};
Expand Down Expand Up @@ -127,6 +127,10 @@ impl RuntimeSettings for TestSettings {
fn trust_bundle_cert(&self) -> Option<&str> {
unimplemented!()
}

fn auto_reprovisioning_mode(&self) -> &AutoReprovisioningMode {
unimplemented!()
}
}

#[derive(Clone, Debug)]
Expand Down
Loading

0 comments on commit c0997a7

Please sign in to comment.