From 2c2cbbc6058f829215b619afdea0e256a4cc9f46 Mon Sep 17 00:00:00 2001 From: Gabe Conradi Date: Fri, 21 Feb 2014 11:03:07 -0500 Subject: [PATCH 1/7] support features.allowedServerUpdateStatuses to accept lldp/lshw in configurable states --- app/models/AssetLifecycle.scala | 43 +++++++++++++++++++++++++++------ app/util/config/Feature.scala | 5 +++- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/app/models/AssetLifecycle.scala b/app/models/AssetLifecycle.scala index f3441f2c0..d9ad5ff1b 100644 --- a/app/models/AssetLifecycle.scala +++ b/app/models/AssetLifecycle.scala @@ -89,9 +89,12 @@ object AssetLifecycle { } } - def updateAsset(asset: Asset, options: Map[String,String]): Status[Boolean] = asset.isServerNode match { - case true => updateServer(asset, options) - case false => updateOther(asset, options) + def updateAsset(asset: Asset, options: Map[String,String]): Status[Boolean] = { + Logger.warn("Updating asset") + asset.isServerNode match { + case true => updateServer(asset, options) + case false => updateOther(asset, options) + } } protected def updateOther(asset: Asset, options: Map[String,String]): Status[Boolean] = { @@ -106,7 +109,7 @@ object AssetLifecycle { } else if (asset.isMaintenance) { updateMaintenanceServer(asset, options) } else { - Left(new Exception("Only updates for Incomplete, New, and Maintenance servers are currently supported")) + updateOtherStatusServer(asset, options) } } @@ -155,6 +158,28 @@ object AssetLifecycle { }.left.map(e => handleException(asset, "Error updating status/state for asset", e)) } + protected def updateOtherStatusServer(asset: Asset, options: Map[String,String]): Status[Boolean] = { + // if asset's status is in the allowed statuses for updating, do it + if (Feature.allowedServerUpdateStatuses.contains(asset.getStatus())) { + // we will allow updates to lshw/lldp while the machine is in these statuses + allCatch[Boolean].either { + Asset.inTransaction { + options.get("lshw").foreach{lshw => + parseLshw(asset, new LshwParser(lshw)).left.foreach{throw _} + InternalTattler.informational(asset, None, "Parsing and storing LSHW data succeeded") + } + options.get("lldp").foreach{lldp => + parseLldp(asset, new LldpParser(lldp)).left.foreach{throw _} + InternalTattler.informational(asset, None, "Parsing and storing LLDP data succeeded") + } + true + } + }.left.map(e => handleException(asset, "Exception updating asset", e)) + } else { + Left(new Exception("Only updates for servers in statuses " + Feature.allowedServerUpdateStatuses.mkString(", ") + " are currently supported")) + } + } + protected def updateNewServer(asset: Asset, options: Map[String,String]): Status[Boolean] = { val units = PowerUnits() val requiredKeys = Set(RackPosition.toString) ++ PowerUnits.keys(units) @@ -217,7 +242,7 @@ object AssetLifecycle { MetaWrapper.createMeta(asset, filtered ++ Map(AssetMeta.Enum.ChassisTag.toString -> chassis_tag)) val newAsset = asset.copy(status = Status.New.map(_.id).getOrElse(0), updated = Some(new Date().asTimestamp)) Asset.partialUpdate(newAsset, newAsset.updated, Some(newAsset.status), State.New) - InternalTattler.informational(newAsset, None, "Parsing and storing LSHW data succeeded") + InternalTattler.informational(newAsset, None, "Parsing and storing LSHW/LLDP data succeeded") true } }.left.map(e => handleException(asset, "Exception updating asset", e)) @@ -232,15 +257,17 @@ object AssetLifecycle { allCatch[Boolean].either { Asset.inTransaction { - options.get("lshw").foreach{lshw => + options.get("lshw").foreach{lshw => parseLshw(asset, new LshwParser(lshw)).left.foreach{throw _} + InternalTattler.informational(asset, None, "Parsing and storing LSHW data succeeded") } options.get("lldp").foreach{lldp => parseLldp(asset, new LldpParser(lldp)).left.foreach{throw _} + InternalTattler.informational(asset, None, "Parsing and storing LLDP data succeeded") } - options.get("CHASSIS_TAG").foreach{chassis_tag => + options.get("CHASSIS_TAG").foreach{chassis_tag => MetaWrapper.createMeta(asset, Map(AssetMeta.Enum.ChassisTag.toString -> chassis_tag)) - } + } true } }.left.map(e => handleException(asset, "Exception updating asset", e)) diff --git a/app/util/config/Feature.scala b/app/util/config/Feature.scala index 8083f99c0..5f49a4eaf 100644 --- a/app/util/config/Feature.scala +++ b/app/util/config/Feature.scala @@ -1,7 +1,7 @@ package util package config -import models.{Asset, AssetMeta} +import models.{Asset, AssetMeta, Status} import models.logs.LogMessageType /** @@ -17,6 +17,9 @@ object Feature extends Configurable { override val referenceConfigFilename = "features_reference.conf" def allowTagUpdates = getStringSet("allowTagUpdates") + def allowedServerUpdateStatuses = getStringSet("allowedServerUpdateStatuses").map { m => + Status.findByName(m) + }.filter(_.isDefined).map(_.get) def defaultLogType = { val lts = getString("defaultLogType", "Informational").toUpperCase try { From b64a44ccae840c67009efdd93a79e95a38bc90a4 Mon Sep 17 00:00:00 2001 From: Gabe Conradi Date: Fri, 21 Feb 2014 11:10:43 -0500 Subject: [PATCH 2/7] remove errant log statement --- app/models/AssetLifecycle.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/AssetLifecycle.scala b/app/models/AssetLifecycle.scala index d9ad5ff1b..ebf999b4d 100644 --- a/app/models/AssetLifecycle.scala +++ b/app/models/AssetLifecycle.scala @@ -90,7 +90,6 @@ object AssetLifecycle { } def updateAsset(asset: Asset, options: Map[String,String]): Status[Boolean] = { - Logger.warn("Updating asset") asset.isServerNode match { case true => updateServer(asset, options) case false => updateOther(asset, options) From 3951376df1372ded1e39cff9467766b6fbd5c026 Mon Sep 17 00:00:00 2001 From: Gabe Conradi Date: Fri, 21 Feb 2014 11:22:52 -0500 Subject: [PATCH 3/7] add default values to allowedServerUpdateStatuses to reflect business logic during intake --- app/util/config/Feature.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/util/config/Feature.scala b/app/util/config/Feature.scala index 5f49a4eaf..84ad7bf04 100644 --- a/app/util/config/Feature.scala +++ b/app/util/config/Feature.scala @@ -17,9 +17,9 @@ object Feature extends Configurable { override val referenceConfigFilename = "features_reference.conf" def allowTagUpdates = getStringSet("allowTagUpdates") - def allowedServerUpdateStatuses = getStringSet("allowedServerUpdateStatuses").map { m => - Status.findByName(m) - }.filter(_.isDefined).map(_.get) + def allowedServerUpdateStatuses = getStringSet("allowedServerUpdateStatuses").union(Set("NEW", "INCOMPLETE", "MAINTENANCE")) + .map { m => Status.findByName(m) } + .filter(_.isDefined).map(_.get) def defaultLogType = { val lts = getString("defaultLogType", "Informational").toUpperCase try { From c030b6173695689501267fd2d8f46e748d26a70c Mon Sep 17 00:00:00 2001 From: Gabe Conradi Date: Fri, 28 Feb 2014 10:51:51 -0500 Subject: [PATCH 4/7] whoops, revert change to style --- app/models/AssetLifecycle.scala | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/models/AssetLifecycle.scala b/app/models/AssetLifecycle.scala index ebf999b4d..2bf12f36a 100644 --- a/app/models/AssetLifecycle.scala +++ b/app/models/AssetLifecycle.scala @@ -89,11 +89,9 @@ object AssetLifecycle { } } - def updateAsset(asset: Asset, options: Map[String,String]): Status[Boolean] = { - asset.isServerNode match { - case true => updateServer(asset, options) - case false => updateOther(asset, options) - } + def updateAsset(asset: Asset, options: Map[String,String]): Status[Boolean] = asset.isServerNode match { + case true => updateServer(asset, options) + case false => updateOther(asset, options) } protected def updateOther(asset: Asset, options: Map[String,String]): Status[Boolean] = { From e380285aeaf1cc5da8dfe8f45143019348c05045 Mon Sep 17 00:00:00 2001 From: Gabe Conradi Date: Fri, 28 Feb 2014 10:58:18 -0500 Subject: [PATCH 5/7] always allow updates in maintenance mode --- app/util/config/Feature.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/util/config/Feature.scala b/app/util/config/Feature.scala index 84ad7bf04..c6c701ee3 100644 --- a/app/util/config/Feature.scala +++ b/app/util/config/Feature.scala @@ -17,7 +17,7 @@ object Feature extends Configurable { override val referenceConfigFilename = "features_reference.conf" def allowTagUpdates = getStringSet("allowTagUpdates") - def allowedServerUpdateStatuses = getStringSet("allowedServerUpdateStatuses").union(Set("NEW", "INCOMPLETE", "MAINTENANCE")) + def allowedServerUpdateStatuses = getStringSet("allowedServerUpdateStatuses").union(Set("MAINTENANCE")) .map { m => Status.findByName(m) } .filter(_.isDefined).map(_.get) def defaultLogType = { From 8b6d62122e5d5d3790def54ca186e06f376f8070 Mon Sep 17 00:00:00 2001 From: Gabe Conradi Date: Fri, 28 Feb 2014 11:14:52 -0500 Subject: [PATCH 6/7] rename updateAnyServer, remove updateMaintenanceServer --- app/models/AssetLifecycle.scala | 42 ++++++--------------------------- 1 file changed, 7 insertions(+), 35 deletions(-) diff --git a/app/models/AssetLifecycle.scala b/app/models/AssetLifecycle.scala index 2bf12f36a..12952bc0a 100644 --- a/app/models/AssetLifecycle.scala +++ b/app/models/AssetLifecycle.scala @@ -90,12 +90,8 @@ object AssetLifecycle { } def updateAsset(asset: Asset, options: Map[String,String]): Status[Boolean] = asset.isServerNode match { - case true => updateServer(asset, options) - case false => updateOther(asset, options) - } - - protected def updateOther(asset: Asset, options: Map[String,String]): Status[Boolean] = { - updateAssetAttributes(asset, options) + case true => updateServer(asset, options) + case false => updateAssetAttributes(asset, options) } protected def updateServer(asset: Asset, options: Map[String,String]): Status[Boolean] = { @@ -103,10 +99,8 @@ object AssetLifecycle { updateIncompleteServer(asset, options) } else if (asset.isNew) { updateNewServer(asset, options) - } else if (asset.isMaintenance) { - updateMaintenanceServer(asset, options) } else { - updateOtherStatusServer(asset, options) + updateAnyServer(asset, options) } } @@ -155,7 +149,7 @@ object AssetLifecycle { }.left.map(e => handleException(asset, "Error updating status/state for asset", e)) } - protected def updateOtherStatusServer(asset: Asset, options: Map[String,String]): Status[Boolean] = { + protected def updateAnyServer(asset: Asset, options: Map[String,String]): Status[Boolean] = { // if asset's status is in the allowed statuses for updating, do it if (Feature.allowedServerUpdateStatuses.contains(asset.getStatus())) { // we will allow updates to lshw/lldp while the machine is in these statuses @@ -169,6 +163,9 @@ object AssetLifecycle { parseLldp(asset, new LldpParser(lldp)).left.foreach{throw _} InternalTattler.informational(asset, None, "Parsing and storing LLDP data succeeded") } + options.get("CHASSIS_TAG").foreach{chassis_tag => + MetaWrapper.createMeta(asset, Map(AssetMeta.Enum.ChassisTag.toString -> chassis_tag)) + } true } }.left.map(e => handleException(asset, "Exception updating asset", e)) @@ -245,31 +242,6 @@ object AssetLifecycle { }.left.map(e => handleException(asset, "Exception updating asset", e)) } - protected def updateMaintenanceServer(asset: Asset, options: Map[String, String]): Status[Boolean] = { - //only lshw,lldp, and chasis tag can be updated in maintenance mode, at least one must be present - val allowedKeys = Set("lshw", "lldp", "CHASSIS_TAG") - if (allowedKeys.find{key => options.contains(key)} == None) { - return Left(new Exception("At least one of " + allowedKeys.mkString(",") + " required")) - } - - allCatch[Boolean].either { - Asset.inTransaction { - options.get("lshw").foreach{lshw => - parseLshw(asset, new LshwParser(lshw)).left.foreach{throw _} - InternalTattler.informational(asset, None, "Parsing and storing LSHW data succeeded") - } - options.get("lldp").foreach{lldp => - parseLldp(asset, new LldpParser(lldp)).left.foreach{throw _} - InternalTattler.informational(asset, None, "Parsing and storing LLDP data succeeded") - } - options.get("CHASSIS_TAG").foreach{chassis_tag => - MetaWrapper.createMeta(asset, Map(AssetMeta.Enum.ChassisTag.toString -> chassis_tag)) - } - true - } - }.left.map(e => handleException(asset, "Exception updating asset", e)) - } - protected def parseLshw(asset: Asset, parser: LshwParser): Status[LshwRepresentation] = { parser.parse() match { case Left(ex) => From f02af2b6e0c731298402484e7c0505ac58135366 Mon Sep 17 00:00:00 2001 From: Gabe Conradi Date: Fri, 28 Feb 2014 16:22:36 -0500 Subject: [PATCH 7/7] rename updateAnyServer to updateServerHardwareMeta for clarity --- app/models/AssetLifecycle.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/AssetLifecycle.scala b/app/models/AssetLifecycle.scala index 12952bc0a..6fe994be8 100644 --- a/app/models/AssetLifecycle.scala +++ b/app/models/AssetLifecycle.scala @@ -100,7 +100,7 @@ object AssetLifecycle { } else if (asset.isNew) { updateNewServer(asset, options) } else { - updateAnyServer(asset, options) + updateServerHardwareMeta(asset, options) } } @@ -149,7 +149,7 @@ object AssetLifecycle { }.left.map(e => handleException(asset, "Error updating status/state for asset", e)) } - protected def updateAnyServer(asset: Asset, options: Map[String,String]): Status[Boolean] = { + protected def updateServerHardwareMeta(asset: Asset, options: Map[String,String]): Status[Boolean] = { // if asset's status is in the allowed statuses for updating, do it if (Feature.allowedServerUpdateStatuses.contains(asset.getStatus())) { // we will allow updates to lshw/lldp while the machine is in these statuses