-#!/usr/bin/python
+#
#
# Copyright (C) 2009, Google Inc.
"""
+import logging
+
from ganeti import constants
+# constants for some common errors to return from a query
+QUERY_UNKNOWN_ENTRY_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
+ constants.CONFD_ERROR_UNKNOWN_ENTRY)
+QUERY_INTERNAL_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
+ constants.CONFD_ERROR_INTERNAL)
+
+
class ConfdQuery(object):
"""Confd Query base class.
class PingQuery(ConfdQuery):
"""An empty confd query.
- It will return success on an empty argument, and an error on any other argument.
+ It will return success on an empty argument, and an error on any other
+ argument.
"""
def Exec(self, query):
- """EmptyQuery main execution
+ """PingQuery main execution.
"""
if query is None:
return status, answer
+class ClusterMasterQuery(ConfdQuery):
+ """Cluster master query.
+
+ It accepts no arguments, and returns the current cluster master.
+
+ """
+ def Exec(self, query):
+ """ClusterMasterQuery main execution
+
+ """
+ if query is None:
+ status = constants.CONFD_REPL_STATUS_OK
+ answer = self.reader.GetMasterNode()
+ else:
+ status = constants.CONFD_REPL_STATUS_ERROR
+ answer = 'master query accepts no query argument'
+
+ return status, answer
+
+
class NodeRoleQuery(ConfdQuery):
- """An empty confd query.
+ """A query for the role of a node.
- It will return success on an empty argument, and an error on any other argument.
+ It will return one of CONFD_NODE_ROLE_*, or an error for non-existing nodes.
"""
def Exec(self, query):
return status, answer
flags = self.reader.GetNodeStatusFlags(node)
if flags is None:
- status = constants.CONFD_REPL_STATUS_ERROR
- answer = constants.CONFD_ERROR_UNKNOWN_ENTRY
- return status, answer
+ return QUERY_UNKNOWN_ENTRY_ERROR
master_candidate, drained, offline = flags
if master_candidate:
return constants.CONFD_REPL_STATUS_OK, answer
+
+class InstanceIpToNodePrimaryIpQuery(ConfdQuery):
+ """A query for the location of an instance's ip.
+
+ It returns the primary ip of the node hosting the instance having the
+ requested ip address, or an error if no such address is known.
+
+ """
+ def Exec(self, query):
+ """InstanceIpToNodePrimaryIpQuery main execution.
+
+ """
+ instance_ip = query
+ instance = self.reader.GetInstanceByIp(instance_ip)
+ if instance is None:
+ return QUERY_UNKNOWN_ENTRY_ERROR
+
+ pnode = self.reader.GetInstancePrimaryNode(instance)
+ if pnode is None:
+ # this shouldn't happen
+ logging.error("Internal configuration inconsistent (instance-to-pnode)")
+ return QUERY_INTERNAL_ERROR
+
+ pnode_primary_ip = self.reader.GetNodePrimaryIp(pnode)
+ if pnode_primary_ip is None:
+ # this shouldn't happen
+ logging.error("Internal configuration inconsistent (node-to-primary-ip)")
+ return QUERY_INTERNAL_ERROR
+
+ return constants.CONFD_REPL_STATUS_OK, pnode_primary_ip
+
+
+class NodesPipsQuery(ConfdQuery):
+ """A query for nodes primary IPs.
+
+ It returns the list of nodes primary IPs.
+
+ """
+ def Exec(self, query):
+ """NodesPipsQuery main execution.
+
+ """
+ if query is None:
+ status = constants.CONFD_REPL_STATUS_OK
+ answer = self.reader.GetNodesPrimaryIps()
+ else:
+ status = constants.CONFD_REPL_STATUS_ERROR
+ answer = "non-empty node primary IPs query"
+
+ return status, answer
+
+
+class MasterCandidatesPipsQuery(ConfdQuery):
+ """A query for master candidates primary IPs.
+
+ It returns the list of master candidates primary IPs.
+
+ """
+ def Exec(self, query):
+ """MasterCandidatesPipsQuery main execution.
+
+ """
+ if query is None:
+ status = constants.CONFD_REPL_STATUS_OK
+ answer = self.reader.GetMasterCandidatesPrimaryIps()
+ else:
+ status = constants.CONFD_REPL_STATUS_ERROR
+ answer = "non-empty master candidates primary IPs query"
+
+ return status, answer
+