Skip to content

Commit d7919f3

Browse files
feat(signature): async update certificate and validate (#973)
* feat(signature): async update certificate and validate
1 parent 209552f commit d7919f3

File tree

19 files changed

+784
-582
lines changed

19 files changed

+784
-582
lines changed

agent-control/src/agent_control/config.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
use super::http_server::config::ServerConfig;
2-
use crate::agent_control::defaults::{default_capabilities, AGENT_CONTROL_ID};
2+
use crate::agent_control::agent_control_fqn;
3+
use crate::agent_control::defaults::{
4+
default_capabilities, default_sub_agent_custom_capabilities, AGENT_CONTROL_ID,
5+
};
36
use crate::http::proxy::ProxyConfig;
47
use crate::logging::config::LoggingConfig;
58
use crate::opamp::auth::config::AuthConfig;
@@ -8,6 +11,7 @@ use crate::values::yaml_config::YAMLConfig;
811
use http::HeaderMap;
912
#[cfg(feature = "k8s")]
1013
use kube::api::TypeMeta;
14+
use opamp_client::opamp::proto::CustomCapabilities;
1115
use opamp_client::operation::capabilities::Capabilities;
1216
use serde::{Deserialize, Deserializer, Serialize};
1317
use std::ops::Deref;
@@ -372,6 +376,16 @@ impl AgentTypeFQN {
372376
//TODO: We should move this to EffectiveAgent
373377
default_capabilities()
374378
}
379+
380+
pub(crate) fn get_custom_capabilities(&self) -> Option<CustomCapabilities> {
381+
//TODO: We should move this to EffectiveAgent
382+
if self.eq(&agent_control_fqn()) {
383+
// Agent_Control does not have custom capabilities for now
384+
return None;
385+
}
386+
387+
Some(default_sub_agent_custom_capabilities())
388+
}
375389
}
376390

377391
#[cfg(test)]

agent-control/src/agent_control/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,7 @@ pub enum AgentError {
9999

100100
#[error("parsing remote config into YAMLConfig: `{0}`")]
101101
YAMLConfigError(#[from] YAMLConfigError),
102+
103+
#[error("failed to initialize the signature validator: `{0}`")]
104+
InitialiseSignatureValidator(String),
102105
}

agent-control/src/agent_control/run/k8s.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::opamp::effective_config::loader::DefaultEffectiveConfigLoaderBuilder;
1414
use crate::opamp::instance_id::getter::InstanceIDWithIdentifiersGetter;
1515
use crate::opamp::instance_id::Identifiers;
1616
use crate::opamp::operations::build_opamp_with_channel;
17+
use crate::opamp::remote_config::validators::signature::SignatureValidator;
1718
use crate::sub_agent::effective_agents_assembler::LocalEffectiveAgentsAssembler;
1819
use crate::{
1920
agent_control::error::AgentError,
@@ -91,6 +92,11 @@ impl AgentControlRunner {
9192

9293
let hash_repository = Arc::new(HashRepositoryConfigMap::new(k8s_store.clone()));
9394

95+
let signature_validator = Arc::new(
96+
SignatureValidator::try_new()
97+
.map_err(|e| AgentError::InitialiseSignatureValidator(e.to_string()))?,
98+
);
99+
94100
info!("Creating the k8s sub_agent builder");
95101
let sub_agent_builder = K8sSubAgentBuilder::new(
96102
opamp_client_builder.as_ref(),
@@ -100,6 +106,7 @@ impl AgentControlRunner {
100106
agents_assembler,
101107
self.k8s_config.clone(),
102108
yaml_config_repository.clone(),
109+
signature_validator,
103110
);
104111

105112
let additional_identifying_attributes =

agent-control/src/agent_control/run/on_host.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use crate::opamp::effective_config::loader::DefaultEffectiveConfigLoaderBuilder;
1212
use crate::opamp::instance_id::getter::InstanceIDWithIdentifiersGetter;
1313
use crate::opamp::instance_id::{Identifiers, Storer};
1414
use crate::opamp::operations::build_opamp_with_channel;
15+
use crate::opamp::remote_config::validators::signature::SignatureValidator;
1516
use crate::sub_agent::effective_agents_assembler::LocalEffectiveAgentsAssembler;
1617
use crate::{agent_control::error::AgentError, opamp::client_builder::DefaultOpAMPClientBuilder};
1718
use crate::{
@@ -104,13 +105,19 @@ impl AgentControlRunner {
104105
template_renderer,
105106
));
106107

108+
let signature_validator = Arc::new(
109+
SignatureValidator::try_new()
110+
.map_err(|e| AgentError::InitialiseSignatureValidator(e.to_string()))?,
111+
);
112+
107113
let sub_agent_builder = OnHostSubAgentBuilder::new(
108114
opamp_client_builder.as_ref(),
109115
&instance_id_getter,
110116
sub_agent_hash_repository,
111117
agents_assembler,
112118
self.base_paths.log_dir.join(SUB_AGENT_DIR),
113119
yaml_config_repository.clone(),
120+
signature_validator,
114121
);
115122

116123
let (maybe_client, maybe_sa_opamp_consumer) = opamp_client_builder

agent-control/src/opamp/client_builder.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
use super::callbacks::AgentCallbacks;
2+
use super::effective_config::loader::EffectiveConfigLoaderBuilder;
3+
use super::http::builder::{HttpClientBuilder, HttpClientBuilderError};
4+
use crate::agent_control::config::AgentID;
5+
use crate::event::channel::EventPublisher;
6+
use crate::event::OpAMPEvent;
7+
use crate::opamp::instance_id;
18
use opamp_client::http::{NotStartedHttpClient, StartedHttpClient};
29
use opamp_client::operation::callbacks::Callbacks;
310
use opamp_client::operation::settings::StartSettings;
@@ -6,15 +13,6 @@ use std::time::Duration;
613
use thiserror::Error;
714
use tracing::{error, info};
815

9-
use crate::agent_control::config::AgentID;
10-
use crate::event::channel::EventPublisher;
11-
use crate::event::OpAMPEvent;
12-
use crate::opamp::instance_id;
13-
14-
use super::callbacks::AgentCallbacks;
15-
use super::effective_config::loader::EffectiveConfigLoaderBuilder;
16-
use super::http::builder::{HttpClientBuilder, HttpClientBuilderError};
17-
1816
/// Default poll interval for the OpAMP http managed client
1917
pub const DEFAULT_POLL_INTERVAL: Duration = Duration::from_secs(30);
2018

agent-control/src/opamp/operations.rs

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
use std::collections::HashMap;
2-
use std::ops::Not;
3-
41
use super::instance_id::InstanceID;
52
use super::{
63
client_builder::{OpAMPClientBuilder, OpAMPClientBuilderError},
74
instance_id::getter::InstanceIDGetter,
85
};
96
use crate::agent_control::defaults::{
10-
default_sub_agent_custom_capabilities, OPAMP_SERVICE_NAME, OPAMP_SERVICE_NAMESPACE,
11-
PARENT_AGENT_ID_ATTRIBUTE_KEY,
7+
OPAMP_SERVICE_NAME, OPAMP_SERVICE_NAMESPACE, PARENT_AGENT_ID_ATTRIBUTE_KEY,
128
};
139
use crate::{
1410
agent_control::config::{AgentID, AgentTypeFQN},
@@ -25,6 +21,7 @@ use opamp_client::{
2521
},
2622
StartedClient,
2723
};
24+
use std::collections::HashMap;
2825
use tracing::info;
2926

3027
pub fn build_sub_agent_opamp<CB, OB, IG>(
@@ -74,7 +71,6 @@ where
7471
let (opamp_publisher, opamp_consumer) = pub_sub();
7572
let start_settings = start_settings(
7673
instance_id_getter.get(&agent_id)?,
77-
&agent_id,
7874
agent_type,
7975
additional_identifying_attributes,
8076
non_identifying_attributes,
@@ -88,7 +84,6 @@ where
8884
/// Builds the OpAMP StartSettings corresponding to the provided arguments for any sub agent and agent control.
8985
pub fn start_settings(
9086
instance_id: InstanceID,
91-
agent_id: &AgentID,
9287
agent_fqn: &AgentTypeFQN,
9388
additional_identifying_attributes: HashMap<String, DescriptionValueType>,
9489
non_identifying_attributes: HashMap<String, DescriptionValueType>,
@@ -103,16 +98,10 @@ pub fn start_settings(
10398

10499
identifying_attributes.extend(additional_identifying_attributes);
105100

106-
// Agent control does not have custom capabilities
107-
let custom_capabilities = agent_id
108-
.is_agent_control_id()
109-
.not()
110-
.then(default_sub_agent_custom_capabilities);
111-
112101
StartSettings {
113102
instance_id: instance_id.into(),
114103
capabilities: agent_fqn.get_capabilities(),
115-
custom_capabilities,
104+
custom_capabilities: agent_fqn.get_custom_capabilities(),
116105
agent_description: AgentDescription {
117106
identifying_attributes,
118107
non_identifying_attributes,

agent-control/src/opamp/remote_config.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use thiserror::Error;
88
pub mod hash;
99
pub mod report;
1010
pub mod signature;
11+
pub mod validators;
1112

1213
/// This structure represents the remote configuration that we would retrieve from a server via OpAMP.
1314
/// Contains identifying metadata and the actual configuration values
@@ -73,6 +74,10 @@ impl RemoteConfig {
7374
)),
7475
}
7576
}
77+
78+
pub fn get_signature(&self) -> &Option<Signature> {
79+
&self.signature
80+
}
7681
}
7782

7883
impl ConfigurationMap {
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mod certificate_fetcher;
2+
pub mod regexes;
3+
pub mod signature;
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
use crate::opamp::remote_config::validators::signature::Certificate;
2+
use std::sync::Mutex;
3+
use std::time::SystemTime;
4+
use thiserror::Error;
5+
use tracing::debug;
6+
use tracing::log::error;
7+
8+
#[derive(Error, Debug)]
9+
pub enum CertificateFetchError {}
10+
11+
/// The CertificateFetcher is responsible for returning the certificate.
12+
pub struct CertificateFetcher {
13+
certificate: Mutex<Certificate>,
14+
}
15+
16+
impl CertificateFetcher {
17+
pub fn try_new() -> Result<Self, CertificateFetchError> {
18+
CertificateFetcher::fetch_certificate().map(|certificate| Self {
19+
certificate: Mutex::new(certificate),
20+
})
21+
}
22+
23+
pub fn get_certificate(&self) -> Result<Certificate, CertificateFetchError> {
24+
let mut certificate = self
25+
.certificate
26+
.lock()
27+
.expect("failed to acquire certificate lock");
28+
29+
debug!("Updating Certificate");
30+
CertificateFetcher::fetch_certificate()
31+
.inspect_err(|e| error!("error fetching certificate: {:?}", e))
32+
.map(|c| {
33+
*certificate = c;
34+
})?;
35+
36+
Ok(certificate.clone())
37+
}
38+
39+
//TODO this is a stub
40+
fn fetch_certificate() -> Result<Certificate, CertificateFetchError> {
41+
Ok(Certificate)
42+
}
43+
}

0 commit comments

Comments
 (0)