+ T.RSpec { T.rspecCpu = c, T.rspecMem = m, T.rspecDsk = d }
+
+-- | Checks if an instance is smaller than a given spec. Returns
+-- OpGood for a correct spec, otherwise Bad one of the possible
+-- failure modes.
+instBelowISpec :: Instance -> T.ISpec -> T.OpResult ()
+instBelowISpec inst ispec
+ | mem inst > T.iSpecMemorySize ispec = Bad T.FailMem
+ | dsk inst > T.iSpecDiskSize ispec = Bad T.FailDisk
+ | vcpus inst > T.iSpecCpuCount ispec = Bad T.FailCPU
+ | otherwise = Ok ()
+
+-- | Checks if an instance is bigger than a given spec.
+instAboveISpec :: Instance -> T.ISpec -> T.OpResult ()
+instAboveISpec inst ispec
+ | mem inst < T.iSpecMemorySize ispec = Bad T.FailMem
+ | dsk inst < T.iSpecDiskSize ispec = Bad T.FailDisk
+ | vcpus inst < T.iSpecCpuCount ispec = Bad T.FailCPU
+ | otherwise = Ok ()
+
+-- | Checks if an instance matches a policy.
+instMatchesPolicy :: Instance -> T.IPolicy -> T.OpResult ()
+instMatchesPolicy inst ipol = do
+ instAboveISpec inst (T.iPolicyMinSpec ipol)
+ instBelowISpec inst (T.iPolicyMaxSpec ipol)
+ if diskTemplate inst `elem` T.iPolicyDiskTemplates ipol
+ then Ok ()
+ else Bad T.FailDisk
+
+-- | Checks whether the instance uses a secondary node.
+--
+-- /Note:/ This should be reconciled with @'sNode' ==
+-- 'Node.noSecondary'@.
+hasSecondary :: Instance -> Bool
+hasSecondary = (== T.DTDrbd8) . diskTemplate
+
+-- | Computed the number of nodes for a given disk template.
+requiredNodes :: T.DiskTemplate -> Int
+requiredNodes T.DTDrbd8 = 2
+requiredNodes _ = 1
+
+-- | Computes all nodes of an instance.
+allNodes :: Instance -> [T.Ndx]
+allNodes inst = case diskTemplate inst of
+ T.DTDrbd8 -> [pNode inst, sNode inst]
+ _ -> [pNode inst]
+
+-- | Checks whether a given disk template uses local storage.
+usesLocalStorage :: Instance -> Bool
+usesLocalStorage = (`elem` localStorageTemplates) . diskTemplate
+
+-- | Checks whether a given disk template supported moves.
+supportsMoves :: T.DiskTemplate -> Bool
+supportsMoves = (`elem` movableDiskTemplates)
+
+-- | A simple wrapper over 'T.templateMirrorType'.
+mirrorType :: Instance -> T.MirrorType
+mirrorType = T.templateMirrorType . diskTemplate