Add ipaddr to device table

This commit is contained in:
kpcyrd
2018-12-26 00:19:26 +01:00
parent 0b719b832c
commit 653b1bd340
7 changed files with 85 additions and 22 deletions

View File

@@ -22,6 +22,7 @@ CREATE TABLE network_devices (
id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
network_id INTEGER NOT NULL,
device_id INTEGER NOT NULL,
ipaddr VARCHAR,
last_seen DATETIME,
FOREIGN KEY(network_id) REFERENCES networks(id) ON DELETE CASCADE,
FOREIGN KEY(device_id) REFERENCES devices(id) ON DELETE CASCADE,

View File

@@ -171,6 +171,7 @@ impl Database {
Insert::NetworkDevice(object) => self.insert_network_device_struct(&NewNetworkDevice {
network_id: object.network_id,
device_id: object.device_id,
ipaddr: object.ipaddr.as_ref(),
last_seen: object.last_seen,
}),
}

View File

@@ -111,6 +111,20 @@ impl Scopable for Device {
}
}
impl Device {
fn ipaddr(&self, db: &Database) -> Result<Option<String>> {
let network_device = NetworkDevice::belonging_to(self)
.order(network_devices::last_seen.desc())
.first::<NetworkDevice>(db.db())
.optional()?;
let ipaddr = network_device
.and_then(|x| x.ipaddr);
Ok(ipaddr)
}
}
pub struct PrintableDevice {
value: String,
}
@@ -135,6 +149,7 @@ pub struct DetailedDevice {
name: Option<String>,
hostname: Option<String>,
vendor: Option<String>,
ipaddr: Option<String>,
unscoped: bool,
last_seen: Option<NaiveDateTime>,
}
@@ -152,6 +167,7 @@ impl DisplayableDetailed for DetailedDevice {
w.start_group();
w.opt_debug::<Yellow, _>(&self.name)?;
w.opt_debug::<Yellow, _>(&self.ipaddr)?;
w.opt_debug::<Yellow, _>(&self.hostname)?;
w.opt_debug::<Yellow, _>(&self.vendor)?;
w.opt_debug::<Yellow, _>(&self.last_seen)?;
@@ -171,13 +187,16 @@ display_detailed!(DetailedDevice);
impl Detailed for Device {
type T = DetailedDevice;
fn detailed(&self, _db: &Database) -> Result<Self::T> {
fn detailed(&self, db: &Database) -> Result<Self::T> {
let ipaddr = self.ipaddr(db)?;
Ok(DetailedDevice {
id: self.id,
value: self.value.to_string(),
name: self.name.clone(),
hostname: self.hostname.clone(),
vendor: self.vendor.clone(),
ipaddr,
unscoped: self.unscoped,
last_seen: self.last_seen.clone(),
})

View File

@@ -15,7 +15,7 @@ pub enum Insert {
PhoneNumber(NewPhoneNumberOwned),
Device(NewDeviceOwned),
Network(NewNetworkOwned),
NetworkDevice(NewNetworkDevice),
NetworkDevice(NewNetworkDeviceOwned),
}
impl Insert {

View File

@@ -3,6 +3,7 @@ use crate::fmt::colors::*;
use diesel;
use diesel::prelude::*;
use crate::models::*;
use std::result;
#[derive(Identifiable, Queryable, Serialize, Deserialize, PartialEq, Debug)]
@@ -108,6 +109,22 @@ impl Scopable for Network {
}
}
impl Network {
fn devices(&self, db: &Database) -> Result<Vec<Device>> {
let device_ids = NetworkDevice::belonging_to(self)
.select(network_devices::device_id)
.load::<i32>(db.db())?;
device_ids.into_iter()
.map(|device_id| devices::table
.filter(devices::id.eq(device_id))
.first::<Device>(db.db())
)
.collect::<result::Result<_, _>>()
.map_err(Error::from)
}
}
pub struct PrintableNetwork {
value: String,
}
@@ -132,6 +149,7 @@ pub struct DetailedNetwork {
unscoped: bool,
latitude: Option<f32>,
longitude: Option<f32>,
devices: Vec<PrintableDevice>,
}
impl DisplayableDetailed for DetailedNetwork {
@@ -154,8 +172,10 @@ impl DisplayableDetailed for DetailedNetwork {
}
#[inline]
fn children(&self, _w: &mut fmt::DetailFormatter) -> fmt::Result {
// TODO: list devices
fn children(&self, w: &mut fmt::DetailFormatter) -> fmt::Result {
for device in &self.devices {
w.child(device)?;
}
Ok(())
}
}
@@ -165,13 +185,18 @@ display_detailed!(DetailedNetwork);
impl Detailed for Network {
type T = DetailedNetwork;
fn detailed(&self, _db: &Database) -> Result<Self::T> {
fn detailed(&self, db: &Database) -> Result<Self::T> {
let devices = self.devices(db)?.into_iter()
.map(|sd| sd.printable(db))
.collect::<Result<_>>()?;
Ok(DetailedNetwork {
id: self.id,
value: self.value.to_string(),
unscoped: self.unscoped,
latitude: self.latitude.clone(),
longitude: self.longitude.clone(),
devices,
})
}
}

View File

@@ -13,6 +13,7 @@ pub struct NetworkDevice {
pub id: i32,
pub network_id: i32,
pub device_id: i32,
pub ipaddr: Option<String>,
pub last_seen: Option<NaiveDateTime>,
}
@@ -107,15 +108,37 @@ impl Printable<PrintableNetworkDevice> for NetworkDevice {
}
}
#[derive(Debug, Insertable, Serialize, Deserialize)]
#[derive(Insertable)]
#[table_name="network_devices"]
pub struct NewNetworkDevice {
pub struct NewNetworkDevice<'a> {
pub network_id: i32,
pub device_id: i32,
pub ipaddr: Option<&'a String>,
pub last_seen: Option<NaiveDateTime>,
}
impl Printable<PrintableNetworkDevice> for NewNetworkDevice {
impl<'a> Upsertable<NetworkDevice> for NewNetworkDevice<'a> {
type Update = NetworkDeviceUpdate;
fn upsert(self, existing: &NetworkDevice) -> Self::Update {
Self::Update {
id: existing.id,
ipaddr: Self::upsert_str(self.ipaddr, &existing.ipaddr),
last_seen: Self::upsert_opt(self.last_seen, &existing.last_seen),
}
}
}
#[derive(Debug, Insertable, Serialize, Deserialize)]
#[table_name="network_devices"]
pub struct NewNetworkDeviceOwned {
pub network_id: i32,
pub device_id: i32,
pub ipaddr: Option<String>,
pub last_seen: Option<NaiveDateTime>,
}
impl Printable<PrintableNetworkDevice> for NewNetworkDeviceOwned {
fn printable(&self, db: &Database) -> Result<PrintableNetworkDevice> {
let network = Network::by_id(db, self.network_id)?;
let device = Device::by_id(db, self.device_id)?;
@@ -126,23 +149,12 @@ impl Printable<PrintableNetworkDevice> for NewNetworkDevice {
}
}
impl Upsertable<NetworkDevice> for NewNetworkDevice {
type Update = NetworkDeviceUpdate;
fn upsert(self, existing: &NetworkDevice) -> Self::Update {
Self::Update {
id: existing.id,
last_seen: Self::upsert_opt(self.last_seen, &existing.last_seen),
}
}
}
pub type InsertNetworkDevice = NewNetworkDevice;
pub type InsertNetworkDevice = NewNetworkDeviceOwned;
impl LuaInsertToNewOwned for InsertNetworkDevice {
type Target = NewNetworkDevice;
type Target = NewNetworkDeviceOwned;
fn try_into_new(self) -> Result<NewNetworkDevice> {
fn try_into_new(self) -> Result<NewNetworkDeviceOwned> {
Ok(self)
}
}
@@ -151,11 +163,13 @@ impl LuaInsertToNewOwned for InsertNetworkDevice {
#[table_name="network_devices"]
pub struct NetworkDeviceUpdate {
pub id: i32,
pub ipaddr: Option<String>,
pub last_seen: Option<NaiveDateTime>,
}
impl Upsert for NetworkDeviceUpdate {
fn is_dirty(&self) -> bool {
self.ipaddr.is_some() ||
self.last_seen.is_some()
}
@@ -170,10 +184,12 @@ impl Upsert for NetworkDeviceUpdate {
impl Updateable<NetworkDevice> for NetworkDeviceUpdate {
fn changeset(&mut self, existing: &NetworkDevice) {
Self::clear_if_equal(&mut self.ipaddr, &existing.ipaddr);
Self::clear_if_equal(&mut self.last_seen, &existing.last_seen);
}
fn fmt(&self, updates: &mut Vec<String>) {
Self::push_value(updates, "ipaddr", &self.ipaddr);
Self::push_value(updates, "last_seen", &self.last_seen);
}
}

View File

@@ -52,6 +52,7 @@ table! {
id -> Integer,
network_id -> Integer,
device_id -> Integer,
ipaddr -> Nullable<Text>,
last_seen -> Nullable<Timestamp>,
}
}