Commit 19351457 authored by Guido Trotter's avatar Guido Trotter
Browse files

InstanceIpToNodePrimaryIpQuery: use a query dict

In 95b487bb

 we changed InstanceIpToNodePrimaryIpQuery to be able to query
multiple instances at once. We also need to be able to query ips
belonging to a specific nic link, so what we do is:

1) Move the "query" argument to a dict, containing different fields
2) Explicit the "query for a single ip" or "query for a list" options.
Signed-off-by: default avatarGuido Trotter <ultrotter@google.com>
Reviewed-by: default avatarMichael Hanselmann <hansmi@google.com>
parent cd195419
......@@ -33,6 +33,8 @@ 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)
QUERY_ARGUMENT_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
constants.CONFD_ERROR_ARGUMENT)
class ConfdQuery(object):
......@@ -141,29 +143,55 @@ class NodeRoleQuery(ConfdQuery):
class InstanceIpToNodePrimaryIpQuery(ConfdQuery):
"""A query for the location of one or more instance's ips.
Given a list of instance IPs, returns an ordered list with the same
number of elements as the input. Each element of the list is a tuple
containing the status (success or failure) and the content of the
query (IP of the primary node if successful, error constant if not).
If a string (instance's IP) is given instead of a list it will return
a single tuple, as opposed to a 1-element list containing that tuple.
@type query: string or dict
@param query: instance ip or dict containing:
constants.CONFD_REQQ_LINK: nic link (optional)
constants.CONFD_REQQ_IPLIST: list of ips
constants.CONFD_REQQ_IP: single ip
(one IP type request is mandatory)
@rtype: (integer, ...)
@return: ((status, answer) or (success, [(status, answer)...])
"""
def Exec(self, query):
"""InstanceIpToNodePrimaryIpQuery main execution.
"""
if isinstance(query, list):
instances_list = query
else:
if isinstance(query, dict):
if constants.CONFD_REQQ_IP in query:
instances_list = [query[constants.CONFD_REQQ_IP]]
mode = constants.CONFD_REQQ_IP
elif constants.CONFD_REQQ_IPLIST in query:
instances_list = query[constants.CONFD_REQQ_IPLIST]
mode = constants.CONFD_REQQ_IPLIST
else:
status = constants.CONFD_REPL_STATUS_ERROR
logging.debug("missing IP or IPLIST in query dict")
return QUERY_ARGUMENT_ERROR
if constants.CONFD_REQQ_LINK in query:
network_link = query[constants.CONFD_REQQ_LINK]
else:
network_link = None # default will be used
elif isinstance(query, basestring):
# 2.1 beta1 and beta2 mode, to be deprecated for 2.2
instances_list = [query]
network_link = None
mode = constants.CONFD_REQQ_IP
else:
logging.debug("Invalid query argument type for: %s" % query)
return QUERY_ARGUMENT_ERROR
pnodes_list = []
for instance_ip in instances_list:
instance = self.reader.GetInstanceByLinkIp(instance_ip, None)
if not isinstance(instance_ip, basestring):
logging.debug("Invalid IP type for: %s" % instance_ip)
return QUERY_ARGUMENT_ERROR
instance = self.reader.GetInstanceByLinkIp(instance_ip, network_link)
if not instance:
logging.debug("Invalid instance IP: %s" % instance)
logging.debug("Unknown instance IP: %s" % instance_ip)
pnodes_list.append(QUERY_UNKNOWN_ENTRY_ERROR)
continue
......@@ -183,8 +211,9 @@ class InstanceIpToNodePrimaryIpQuery(ConfdQuery):
pnodes_list.append((constants.CONFD_REPL_STATUS_OK, pnode_primary_ip))
# If input was a string, return a tuple instead of a 1-element list
if isinstance(query, basestring):
# If a single ip was requested, return a single answer, otherwise the whole
# list, with a success status (since each entry has its own success/failure)
if mode == constants.CONFD_REQQ_IP:
return pnodes_list[0]
return constants.CONFD_REPL_STATUS_OK, pnodes_list
......
......@@ -664,6 +664,13 @@ CONFD_REQ_NODE_PIP_LIST = 4
CONFD_REQ_MC_PIP_LIST = 5
CONFD_REQ_INSTANCES_IPS_LIST = 6
# Confd request query fields. These are used to narrow down queries.
# These must be strings rather than integers, because json-encoding
# converts them to strings anyway, as they're used as dict-keys.
CONFD_REQQ_LINK = "0"
CONFD_REQQ_IP = "1"
CONFD_REQQ_IPLIST = "2"
CONFD_REQS = frozenset([
CONFD_REQ_PING,
CONFD_REQ_NODE_ROLE_BYNAME,
......@@ -694,6 +701,7 @@ CONFD_REPL_STATUSES = frozenset([
# A few common errors for confd
CONFD_ERROR_UNKNOWN_ENTRY = 1
CONFD_ERROR_INTERNAL = 2
CONFD_ERROR_ARGUMENT = 3
# Each request is "salted" by the current timestamp.
# This constants decides how many seconds of skew to accept.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment