Skip to content
Permalink
Browse files

Resolve Host Meta for Five Minutes Only

While PREvant tries to resolve the resource .well-known/host-meta.json it uses
an HTTP connection. Now, it tries to resolve this resource for five minutes
and after this expiration PREvant marks the resource for the particular service
as invalid.
  • Loading branch information...
schrieveslaach committed Aug 6, 2019
1 parent b26135b commit abddc269e032d52253aa63135068392f2a41c86d

Large diffs are not rendered by default.

@@ -7,7 +7,7 @@ edition = "2018"

[dependencies]
base64 = "0.10"
cached = "0.8"
cached = "0.9"
clap = "2.33"
crossbeam = "0.7"
crossbeam-utils = "0.6"
@@ -284,8 +284,9 @@ impl DockerInfrastructure {
container_info.id, network_id
);

let mut service =
Service::try_from(&self.get_app_container_by_id(&container_info.id)?.unwrap())?;
let container_details = runtime.block_on(containers.get(&container_info.id).inspect())?;

let mut service = Service::try_from(&container_details)?;
service.set_container_type(service_config.container_type().clone());

if let Some(image) = image_to_delete {
@@ -387,24 +388,6 @@ impl DockerInfrastructure {
.next())
}

fn get_app_container_by_id(
&self,
container_id: &String,
) -> Result<Option<Container>, ShipLiftError> {
let docker = Docker::new();
let containers = docker.containers();
let mut runtime = Runtime::new()?;

let list_options = ContainerListOptions::builder().build();

Ok(runtime
.block_on(containers.list(&list_options))?
.iter()
.filter(|c| container_id == &c.id)
.map(|c| c.to_owned())
.next())
}

fn get_container_details(
&self,
app_name: Option<String>,
@@ -710,11 +693,15 @@ impl TryFrom<&ContainerDetails> for Service {
}
};

let started_at = chrono::DateTime::parse_from_rfc3339(&container_details.state.started_at)
.expect("Docker did not respond with valid RFC3387 date time");

let mut service = Service::new(
container_details.id.clone(),
app_name.clone(),
service_name.clone(),
container_type,
started_at,
);

service.set_endpoint(addr, port);
@@ -723,42 +710,6 @@ impl TryFrom<&ContainerDetails> for Service {
}
}

impl TryFrom<&Container> for Service {
type Error = DockerInfrastructureError;

fn try_from(c: &Container) -> Result<Service, DockerInfrastructureError> {
let service_name = match c.labels.get(SERVICE_NAME_LABEL) {
Some(name) => name,
None => {
return Err(DockerInfrastructureError::MissingServiceNameLabel {
container_id: c.id.clone(),
});
}
};

let app_name = match c.labels.get(APP_NAME_LABEL) {
Some(name) => name,
None => {
return Err(DockerInfrastructureError::MissingAppNameLabel {
container_id: c.id.clone(),
});
}
};

let container_type = match c.labels.get(CONTAINER_TYPE_LABEL) {
None => ContainerType::Instance,
Some(lb) => lb.parse::<ContainerType>()?,
};

Ok(Service::new(
c.id.clone(),
app_name.clone(),
service_name.clone(),
container_type,
))
}
}

impl From<ShipLiftError> for DockerInfrastructureError {
fn from(err: ShipLiftError) -> Self {
match &err {
@@ -62,6 +62,7 @@ impl Infrastructure for DummyInfrastructure {
app.clone(),
config.service_name().clone(),
config.container_type().clone(),
DateTime::parse_from_rfc3339("2019-07-18T07:30:00.000000000Z").unwrap(),
),
);
}
@@ -25,7 +25,7 @@
*/

use crate::models::web_host_meta::WebHostMeta;
use chrono::{DateTime, Utc};
use chrono::{DateTime, FixedOffset, Utc};
use regex::Regex;
use serde::ser::{Serialize, Serializer};
use serde::{de, Deserialize, Deserializer};
@@ -44,6 +44,7 @@ pub struct Service {
base_url: Option<Url>,
endpoint: Option<ServiceEndpoint>,
web_host_meta: Option<WebHostMeta>,
started_at: DateTime<FixedOffset>,
}

#[derive(Clone, Debug)]
@@ -184,6 +185,7 @@ impl Service {
app_name: String,
service_name: String,
container_type: ContainerType,
started_at: DateTime<FixedOffset>,
) -> Service {
Service {
id,
@@ -193,6 +195,7 @@ impl Service {
base_url: None,
endpoint: None,
web_host_meta: None,
started_at,
}
}

@@ -255,6 +258,10 @@ impl Service {
pub fn set_web_host_meta(&mut self, meta: Option<WebHostMeta>) {
self.web_host_meta = meta;
}

pub fn started_at(&self) -> &DateTime<FixedOffset> {
&self.started_at
}
}

impl Serialize for Service {
@@ -294,8 +301,8 @@ impl Serialize for Service {
let s = Service {
name: &self.service_name,
url: match self.web_host_meta {
None => None,
Some(_) => self.service_url().map(|url| url.to_string()),
Some(ref meta) if meta.is_valid() => self.service_url().map(|url| url.to_string()),
_ => None,
},
service_type: self.container_type.to_string(),
version,
@@ -29,6 +29,12 @@ use chrono::{DateTime, Utc};
pub struct WebHostMeta {
properties: Option<Properties>,
links: Option<Vec<Link>>,
#[serde(default = "valid_web_host")]
valid: bool,
}

fn valid_web_host() -> bool {
true
}

#[derive(Clone, Debug, Deserialize, Serialize)]
@@ -52,9 +58,22 @@ impl WebHostMeta {
WebHostMeta {
properties: None,
links: None,
valid: true,
}
}

pub fn invalid() -> Self {
WebHostMeta {
properties: None,
links: None,
valid: false,
}
}

pub fn is_valid(&self) -> bool {
self.valid
}

pub fn is_empty(&self) -> bool {
self.properties.is_none() && self.links.is_none()
}
@@ -35,7 +35,7 @@ use crate::services::service_templating::{
apply_templating_for_application_companion, apply_templating_for_service_companion,
};
use cached::SizedCache;
use chrono::{DateTime, FixedOffset};
use chrono::{DateTime, FixedOffset, Utc};
use handlebars::TemplateRenderError;
use http_api_problem::{HttpApiProblem, StatusCode};
use multimap::MultiMap;
@@ -84,7 +84,15 @@ cached_key_result! {
match get_request {
Err(err) => {
debug!("Cannot acquire host meta for service {} of {}: {}", Paint::magenta(service.service_name()), Paint::magenta(service.app_name()), err);
Err(())

let duration = Utc::now().signed_duration_since(service.started_at().clone());
match duration {
duration if duration >= chrono::Duration::minutes(5) => {
trace!("Service {} is running for {}, therefore, it will be assumed that host-meta.json is not available.", service.service_name(), duration);
Ok(WebHostMeta::invalid())
},
_ => Err(())
}
}
Ok(mut response) => match response.json::<WebHostMeta>() {
Err(err) => {

0 comments on commit abddc26

Please sign in to comment.
You can’t perform that action at this time.