Add ipaddr to device table
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
}),
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
})
|
||||
|
||||
@@ -15,7 +15,7 @@ pub enum Insert {
|
||||
PhoneNumber(NewPhoneNumberOwned),
|
||||
Device(NewDeviceOwned),
|
||||
Network(NewNetworkOwned),
|
||||
NetworkDevice(NewNetworkDevice),
|
||||
NetworkDevice(NewNetworkDeviceOwned),
|
||||
}
|
||||
|
||||
impl Insert {
|
||||
|
||||
@@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ table! {
|
||||
id -> Integer,
|
||||
network_id -> Integer,
|
||||
device_id -> Integer,
|
||||
ipaddr -> Nullable<Text>,
|
||||
last_seen -> Nullable<Timestamp>,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user