---
lib/constants.py | 4 ++++
lib/luxi.py | 31 +++++++++++++++++++++++++++++++
lib/server/masterd.py | 29 +++++++++++++++++++++++++++++
3 files changed, 64 insertions(+), 0 deletions(-)
diff --git a/lib/constants.py b/lib/constants.py
index eae9ce6..acd4690 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -947,6 +947,10 @@ QR_NODE = "node"
#: List of resources which can be queried using L{opcodes.OpQuery}
QR_OP_QUERY = frozenset([QR_INSTANCE, QR_NODE])
+#: List of resources which can be queried using LUXI
+QR_OP_LUXI = QR_OP_QUERY.union(frozenset([
+ ]))
+
# Query field types
QFT_UNKNOWN = "unknown"
QFT_TEXT = "text"
diff --git a/lib/luxi.py b/lib/luxi.py
index f2d7633..4f93da8 100644
--- a/lib/luxi.py
+++ b/lib/luxi.py
@@ -39,6 +39,7 @@ from ganeti import serializer
from ganeti import constants
from ganeti import errors
from ganeti import utils
+from ganeti import objects
KEY_METHOD = "method"
@@ -53,6 +54,8 @@ REQ_WAIT_FOR_JOB_CHANGE = "WaitForJobChange"
REQ_CANCEL_JOB = "CancelJob"
REQ_ARCHIVE_JOB = "ArchiveJob"
REQ_AUTOARCHIVE_JOBS = "AutoArchiveJobs"
+REQ_QUERY = "Query"
+REQ_QUERY_FIELDS = "QueryFields"
REQ_QUERY_JOBS = "QueryJobs"
REQ_QUERY_INSTANCES = "QueryInstances"
REQ_QUERY_NODES = "QueryNodes"
@@ -487,6 +490,34 @@ class Client(object):
break
return result
+ def Query(self, what, fields, filter_):
+ """Query for resources/items.
+
+ @param what: One of L{constants.QR_OP_LUXI}
+ @type fields: List of strings
+ @param fields: List of requested fields
+ @type filter_: None or list
+ @param filter_: Query filter
+ @rtype: L{objects.QueryResponse}
+
+ """
+ req = objects.QueryRequest(what=what, fields=fields, filter=filter_)
+ result = self.CallMethod(REQ_QUERY, req.ToDict())
+ return objects.QueryResponse.FromDict(result)
+
+ def QueryFields(self, what, fields):
+ """Query for available fields.
+
+ @param what: One of L{constants.QR_OP_LUXI}
+ @type fields: None or list of strings
+ @param fields: List of requested fields
+ @rtype: L{objects.QueryFieldsResponse}
+
+ """
+ req = objects.QueryFieldsRequest(what=what, fields=fields)
+ result = self.CallMethod(REQ_QUERY_FIELDS, req.ToDict())
+ return objects.QueryFieldsResponse.FromDict(result)
+
def QueryJobs(self, job_ids, fields):
return self.CallMethod(REQ_QUERY_JOBS, (job_ids, fields))
diff --git a/lib/server/masterd.py b/lib/server/masterd.py
index 1f3c924..906923d 100644
--- a/lib/server/masterd.py
+++ b/lib/server/masterd.py
@@ -55,6 +55,7 @@ from ganeti import workerpool
from ganeti import rpc
from ganeti import bootstrap
from ganeti import netutils
+from ganeti import objects
CLIENT_REQUEST_WORKERS = 16
@@ -227,6 +228,34 @@ class ClientOps:
return queue.WaitForJobChanges(job_id, fields, prev_job_info,
prev_log_serial, timeout)
+ elif method == luxi.REQ_QUERY:
+ req = objects.QueryRequest.FromDict(args)
+
+ if req.what in constants.QR_OP_QUERY:
+ result = self._Query(opcodes.OpQuery(what=req.what, fields=req.fields,
+ filter=req.filter))
+ elif req.what in constants.QR_OP_LUXI:
+ raise NotImplementedError
+ else:
+ raise errors.OpPrereqError("Resource type '%s' unknown" % req.what,
+ errors.ECODE_INVAL)
+
+ return result
+
+ elif method == luxi.REQ_QUERY_FIELDS:
+ req = objects.QueryFieldsRequest.FromDict(args)
+
+ if req.what in constants.QR_OP_QUERY:
+ result = self._Query(opcodes.OpQueryFields(what=req.what,
+ fields=req.fields))
+ elif req.what in constants.QR_OP_LUXI:
+ raise NotImplementedError
+ else:
+ raise errors.OpPrereqError("Resource type '%s' unknown" % req.what,
+ errors.ECODE_INVAL)
+
+ return result
+
elif method == luxi.REQ_QUERY_JOBS:
(job_ids, fields) = args
if isinstance(job_ids, (tuple, list)) and job_ids:
--
1.7.3.1