When UUIDs are used in CLI commands, such addressing of objects fails
or succeeds inconsistently across object types. Worse yet, some calls
do not fail, but simply return no result. This is due to the way the
classical queries are handled in the Haskell code - a filter is built,
checking if the names match. If the names do not match, but the object
can still be retrieved through UUID, the query is successful, but there
is nothing to return.
This patch remedies the situation by extending the filter into an or
clause checking for either name or uuid. For objects that have no uuid
field, the name is reused, making the filter equivalent to the old one.
Works towards resolving issue 703.
Signed-off-by: Hrvoje Ribicic <riba@google.com>
Reviewed-by: Klaus Aehlig <aehlig@google.com>
, queryCompat
, getRequestedNames
, nameField
+ , uuidField
) where
import Control.DeepSeq
nameField (ItemTypeOpCode QRExport) = "node"
nameField _ = "name"
+-- | Computes the uuid field, or the best possible substitute, for different
+-- query types.
+uuidField :: ItemType -> FilterField
+uuidField (ItemTypeLuxi QRJob) = nameField (ItemTypeLuxi QRJob)
+uuidField (ItemTypeOpCode QRExport) = nameField (ItemTypeOpCode QRExport)
+uuidField _ = "uuid"
+
-- | Extracts all quoted strings from a list, ignoring the
-- 'NumericValue' entries.
getAllQuotedStrings :: [FilterValue] -> [String]
handleClassicQuery _ _ _ _ True =
return . Bad $ OpPrereqError "Sync queries are not allowed" ECodeInval
handleClassicQuery cfg qkind names fields _ = do
- let flt = makeSimpleFilter (nameField qkind) names
+ let simpleNameFilter field = makeSimpleFilter (field qkind) names
+ flt = Qlang.OrFilter $ map simpleNameFilter [nameField, uuidField]
qr <- query cfg True (Qlang.Query qkind fields flt)
return $ showJSON <$> (qr >>= queryCompat)