Statistics
| Branch: | Tag: | Revision:

root / lib / confd / querylib.py @ cd195419

History | View | Annotate | Download (6.7 kB)

1 d73ef63f Michael Hanselmann
#
2 e16e4824 Guido Trotter
#
3 e16e4824 Guido Trotter
4 e16e4824 Guido Trotter
# Copyright (C) 2009, Google Inc.
5 e16e4824 Guido Trotter
#
6 e16e4824 Guido Trotter
# This program is free software; you can redistribute it and/or modify
7 e16e4824 Guido Trotter
# it under the terms of the GNU General Public License as published by
8 e16e4824 Guido Trotter
# the Free Software Foundation; either version 2 of the License, or
9 e16e4824 Guido Trotter
# (at your option) any later version.
10 e16e4824 Guido Trotter
#
11 e16e4824 Guido Trotter
# This program is distributed in the hope that it will be useful, but
12 e16e4824 Guido Trotter
# WITHOUT ANY WARRANTY; without even the implied warranty of
13 e16e4824 Guido Trotter
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 e16e4824 Guido Trotter
# General Public License for more details.
15 e16e4824 Guido Trotter
#
16 e16e4824 Guido Trotter
# You should have received a copy of the GNU General Public License
17 e16e4824 Guido Trotter
# along with this program; if not, write to the Free Software
18 e16e4824 Guido Trotter
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 e16e4824 Guido Trotter
# 02110-1301, USA.
20 e16e4824 Guido Trotter
21 e16e4824 Guido Trotter
22 e16e4824 Guido Trotter
"""Ganeti configuration daemon queries library.
23 e16e4824 Guido Trotter

24 e16e4824 Guido Trotter
"""
25 e16e4824 Guido Trotter
26 53bd7366 Guido Trotter
import logging
27 53bd7366 Guido Trotter
28 e16e4824 Guido Trotter
from ganeti import constants
29 e16e4824 Guido Trotter
30 d73ef63f Michael Hanselmann
31 7189e790 Guido Trotter
# constants for some common errors to return from a query
32 7189e790 Guido Trotter
QUERY_UNKNOWN_ENTRY_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
33 7189e790 Guido Trotter
                             constants.CONFD_ERROR_UNKNOWN_ENTRY)
34 7189e790 Guido Trotter
QUERY_INTERNAL_ERROR = (constants.CONFD_REPL_STATUS_ERROR,
35 7189e790 Guido Trotter
                        constants.CONFD_ERROR_INTERNAL)
36 e16e4824 Guido Trotter
37 d73ef63f Michael Hanselmann
38 e16e4824 Guido Trotter
class ConfdQuery(object):
39 e16e4824 Guido Trotter
  """Confd Query base class.
40 e16e4824 Guido Trotter

41 e16e4824 Guido Trotter
  """
42 e16e4824 Guido Trotter
  def __init__(self, reader):
43 e16e4824 Guido Trotter
    """Constructor for Confd Query
44 e16e4824 Guido Trotter

45 e16e4824 Guido Trotter
    @type reader: L{ssconf.SimpleConfigReader}
46 e16e4824 Guido Trotter
    @param reader: ConfigReader to use to access the config
47 e16e4824 Guido Trotter

48 e16e4824 Guido Trotter
    """
49 e16e4824 Guido Trotter
    self.reader = reader
50 e16e4824 Guido Trotter
51 e16e4824 Guido Trotter
  def Exec(self, query):
52 e16e4824 Guido Trotter
    """Process a single UDP request from a client.
53 e16e4824 Guido Trotter

54 e16e4824 Guido Trotter
    Different queries should override this function, which by defaults returns
55 e16e4824 Guido Trotter
    a "non-implemented" answer.
56 e16e4824 Guido Trotter

57 e16e4824 Guido Trotter
    @type query: (undefined)
58 e16e4824 Guido Trotter
    @param query: ConfdRequest 'query' field
59 e16e4824 Guido Trotter
    @rtype: (integer, undefined)
60 e16e4824 Guido Trotter
    @return: status and answer to give to the client
61 e16e4824 Guido Trotter

62 e16e4824 Guido Trotter
    """
63 e16e4824 Guido Trotter
    status = constants.CONFD_REPL_STATUS_NOTIMPLEMENTED
64 e16e4824 Guido Trotter
    answer = 'not implemented'
65 e16e4824 Guido Trotter
    return status, answer
66 e16e4824 Guido Trotter
67 e16e4824 Guido Trotter
68 e16e4824 Guido Trotter
class PingQuery(ConfdQuery):
69 e16e4824 Guido Trotter
  """An empty confd query.
70 e16e4824 Guido Trotter

71 4d4a651d Michael Hanselmann
  It will return success on an empty argument, and an error on any other
72 4d4a651d Michael Hanselmann
  argument.
73 e16e4824 Guido Trotter

74 e16e4824 Guido Trotter
  """
75 e16e4824 Guido Trotter
  def Exec(self, query):
76 0bc8432b Guido Trotter
    """PingQuery main execution.
77 e16e4824 Guido Trotter

78 e16e4824 Guido Trotter
    """
79 e16e4824 Guido Trotter
    if query is None:
80 e16e4824 Guido Trotter
      status = constants.CONFD_REPL_STATUS_OK
81 e16e4824 Guido Trotter
      answer = 'ok'
82 e16e4824 Guido Trotter
    else:
83 e16e4824 Guido Trotter
      status = constants.CONFD_REPL_STATUS_ERROR
84 e16e4824 Guido Trotter
      answer = 'non-empty ping query'
85 e16e4824 Guido Trotter
86 e16e4824 Guido Trotter
    return status, answer
87 e16e4824 Guido Trotter
88 d73ef63f Michael Hanselmann
89 48166551 Guido Trotter
class ClusterMasterQuery(ConfdQuery):
90 48166551 Guido Trotter
  """Cluster master query.
91 48166551 Guido Trotter

92 48166551 Guido Trotter
  It accepts no arguments, and returns the current cluster master.
93 48166551 Guido Trotter

94 48166551 Guido Trotter
  """
95 48166551 Guido Trotter
  def Exec(self, query):
96 48166551 Guido Trotter
    """ClusterMasterQuery main execution
97 48166551 Guido Trotter

98 48166551 Guido Trotter
    """
99 48166551 Guido Trotter
    if query is None:
100 48166551 Guido Trotter
      status = constants.CONFD_REPL_STATUS_OK
101 48166551 Guido Trotter
      answer = self.reader.GetMasterNode()
102 48166551 Guido Trotter
    else:
103 48166551 Guido Trotter
      status = constants.CONFD_REPL_STATUS_ERROR
104 48166551 Guido Trotter
      answer = 'master query accepts no query argument'
105 48166551 Guido Trotter
106 48166551 Guido Trotter
    return status, answer
107 48166551 Guido Trotter
108 6daf26a0 Guido Trotter
109 6daf26a0 Guido Trotter
class NodeRoleQuery(ConfdQuery):
110 0bc8432b Guido Trotter
  """A query for the role of a node.
111 6daf26a0 Guido Trotter

112 0bc8432b Guido Trotter
  It will return one of CONFD_NODE_ROLE_*, or an error for non-existing nodes.
113 6daf26a0 Guido Trotter

114 6daf26a0 Guido Trotter
  """
115 6daf26a0 Guido Trotter
  def Exec(self, query):
116 6daf26a0 Guido Trotter
    """EmptyQuery main execution
117 6daf26a0 Guido Trotter

118 6daf26a0 Guido Trotter
    """
119 6daf26a0 Guido Trotter
    node = query
120 6daf26a0 Guido Trotter
    if self.reader.GetMasterNode() == node:
121 6daf26a0 Guido Trotter
      status = constants.CONFD_REPL_STATUS_OK
122 6daf26a0 Guido Trotter
      answer = constants.CONFD_NODE_ROLE_MASTER
123 6daf26a0 Guido Trotter
      return status, answer
124 6daf26a0 Guido Trotter
    flags = self.reader.GetNodeStatusFlags(node)
125 6daf26a0 Guido Trotter
    if flags is None:
126 7189e790 Guido Trotter
      return QUERY_UNKNOWN_ENTRY_ERROR
127 6daf26a0 Guido Trotter
128 6daf26a0 Guido Trotter
    master_candidate, drained, offline = flags
129 6daf26a0 Guido Trotter
    if master_candidate:
130 6daf26a0 Guido Trotter
      answer = constants.CONFD_NODE_ROLE_CANDIDATE
131 6daf26a0 Guido Trotter
    elif drained:
132 6daf26a0 Guido Trotter
      answer = constants.CONFD_NODE_ROLE_DRAINED
133 6daf26a0 Guido Trotter
    elif offline:
134 6daf26a0 Guido Trotter
      answer = constants.CONFD_NODE_ROLE_OFFLINE
135 6daf26a0 Guido Trotter
    else:
136 6daf26a0 Guido Trotter
      answer = constants.CONFD_NODE_ROLE_REGULAR
137 6daf26a0 Guido Trotter
138 6daf26a0 Guido Trotter
    return constants.CONFD_REPL_STATUS_OK, answer
139 6daf26a0 Guido Trotter
140 53bd7366 Guido Trotter
141 53bd7366 Guido Trotter
class InstanceIpToNodePrimaryIpQuery(ConfdQuery):
142 95b487bb Flavio Silvestrow
  """A query for the location of one or more instance's ips.
143 53bd7366 Guido Trotter

144 95b487bb Flavio Silvestrow
  Given a list of instance IPs, returns an ordered list with the same
145 95b487bb Flavio Silvestrow
  number of elements as the input. Each element of the list is a tuple
146 95b487bb Flavio Silvestrow
  containing the status (success or failure) and the content of the
147 95b487bb Flavio Silvestrow
  query (IP of the primary node if successful, error constant if not).
148 95b487bb Flavio Silvestrow

149 95b487bb Flavio Silvestrow
  If a string (instance's IP) is given instead of a list it will return
150 95b487bb Flavio Silvestrow
  a single tuple, as opposed to a 1-element list containing that tuple.
151 53bd7366 Guido Trotter

152 53bd7366 Guido Trotter
  """
153 53bd7366 Guido Trotter
  def Exec(self, query):
154 0bc8432b Guido Trotter
    """InstanceIpToNodePrimaryIpQuery main execution.
155 53bd7366 Guido Trotter

156 53bd7366 Guido Trotter
    """
157 95b487bb Flavio Silvestrow
    if isinstance(query, list):
158 95b487bb Flavio Silvestrow
      instances_list = query
159 95b487bb Flavio Silvestrow
    else:
160 95b487bb Flavio Silvestrow
      instances_list = [query]
161 95b487bb Flavio Silvestrow
    pnodes_list = []
162 95b487bb Flavio Silvestrow
163 95b487bb Flavio Silvestrow
    for instance_ip in instances_list:
164 cd195419 Guido Trotter
      instance = self.reader.GetInstanceByLinkIp(instance_ip, None)
165 95b487bb Flavio Silvestrow
      if not instance:
166 95b487bb Flavio Silvestrow
        logging.debug("Invalid instance IP: %s" % instance)
167 95b487bb Flavio Silvestrow
        pnodes_list.append(QUERY_UNKNOWN_ENTRY_ERROR)
168 95b487bb Flavio Silvestrow
        continue
169 53bd7366 Guido Trotter
170 95b487bb Flavio Silvestrow
      pnode = self.reader.GetInstancePrimaryNode(instance)
171 95b487bb Flavio Silvestrow
      if not pnode:
172 95b487bb Flavio Silvestrow
        logging.error("Instance '%s' doesn't have an associated primary"
173 95b487bb Flavio Silvestrow
                      " node" % instance)
174 95b487bb Flavio Silvestrow
        pnodes_list.append(QUERY_INTERNAL_ERROR)
175 95b487bb Flavio Silvestrow
        continue
176 53bd7366 Guido Trotter
177 95b487bb Flavio Silvestrow
      pnode_primary_ip = self.reader.GetNodePrimaryIp(pnode)
178 95b487bb Flavio Silvestrow
      if not pnode_primary_ip:
179 95b487bb Flavio Silvestrow
        logging.error("Primary node '%s' doesn't have an associated"
180 95b487bb Flavio Silvestrow
                      " primary IP" % pnode)
181 95b487bb Flavio Silvestrow
        pnodes_list.append(QUERY_INTERNAL_ERROR)
182 95b487bb Flavio Silvestrow
        continue
183 53bd7366 Guido Trotter
184 95b487bb Flavio Silvestrow
      pnodes_list.append((constants.CONFD_REPL_STATUS_OK, pnode_primary_ip))
185 95b487bb Flavio Silvestrow
186 95b487bb Flavio Silvestrow
    # If input was a string, return a tuple instead of a 1-element list
187 95b487bb Flavio Silvestrow
    if isinstance(query, basestring):
188 95b487bb Flavio Silvestrow
      return pnodes_list[0]
189 95b487bb Flavio Silvestrow
190 95b487bb Flavio Silvestrow
    return constants.CONFD_REPL_STATUS_OK, pnodes_list
191 efbb4fd2 Luca Bigliardi
192 efbb4fd2 Luca Bigliardi
193 efbb4fd2 Luca Bigliardi
class NodesPipsQuery(ConfdQuery):
194 efbb4fd2 Luca Bigliardi
  """A query for nodes primary IPs.
195 efbb4fd2 Luca Bigliardi

196 efbb4fd2 Luca Bigliardi
  It returns the list of nodes primary IPs.
197 efbb4fd2 Luca Bigliardi

198 efbb4fd2 Luca Bigliardi
  """
199 efbb4fd2 Luca Bigliardi
  def Exec(self, query):
200 efbb4fd2 Luca Bigliardi
    """NodesPipsQuery main execution.
201 efbb4fd2 Luca Bigliardi

202 efbb4fd2 Luca Bigliardi
    """
203 efbb4fd2 Luca Bigliardi
    if query is None:
204 efbb4fd2 Luca Bigliardi
      status = constants.CONFD_REPL_STATUS_OK
205 efbb4fd2 Luca Bigliardi
      answer = self.reader.GetNodesPrimaryIps()
206 efbb4fd2 Luca Bigliardi
    else:
207 efbb4fd2 Luca Bigliardi
      status = constants.CONFD_REPL_STATUS_ERROR
208 efbb4fd2 Luca Bigliardi
      answer = "non-empty node primary IPs query"
209 efbb4fd2 Luca Bigliardi
210 efbb4fd2 Luca Bigliardi
    return status, answer
211 efbb4fd2 Luca Bigliardi
212 efbb4fd2 Luca Bigliardi
213 efbb4fd2 Luca Bigliardi
class MasterCandidatesPipsQuery(ConfdQuery):
214 efbb4fd2 Luca Bigliardi
  """A query for master candidates primary IPs.
215 efbb4fd2 Luca Bigliardi

216 efbb4fd2 Luca Bigliardi
  It returns the list of master candidates primary IPs.
217 efbb4fd2 Luca Bigliardi

218 efbb4fd2 Luca Bigliardi
  """
219 efbb4fd2 Luca Bigliardi
  def Exec(self, query):
220 efbb4fd2 Luca Bigliardi
    """MasterCandidatesPipsQuery main execution.
221 efbb4fd2 Luca Bigliardi

222 efbb4fd2 Luca Bigliardi
    """
223 efbb4fd2 Luca Bigliardi
    if query is None:
224 efbb4fd2 Luca Bigliardi
      status = constants.CONFD_REPL_STATUS_OK
225 efbb4fd2 Luca Bigliardi
      answer = self.reader.GetMasterCandidatesPrimaryIps()
226 efbb4fd2 Luca Bigliardi
    else:
227 efbb4fd2 Luca Bigliardi
      status = constants.CONFD_REPL_STATUS_ERROR
228 efbb4fd2 Luca Bigliardi
      answer = "non-empty master candidates primary IPs query"
229 efbb4fd2 Luca Bigliardi
230 efbb4fd2 Luca Bigliardi
    return status, answer
231 efbb4fd2 Luca Bigliardi
232 d01ae714 Luca Bigliardi
233 d01ae714 Luca Bigliardi
class InstancesIpsQuery(ConfdQuery):
234 d01ae714 Luca Bigliardi
  """A query for instances IPs.
235 d01ae714 Luca Bigliardi

236 23824641 Luca Bigliardi
  It returns the list of IPs of NICs connected to the requested link or all the
237 23824641 Luca Bigliardi
  instances IPs if no link is submitted.
238 d01ae714 Luca Bigliardi

239 d01ae714 Luca Bigliardi
  """
240 d01ae714 Luca Bigliardi
  def Exec(self, query):
241 d01ae714 Luca Bigliardi
    """InstancesIpsQuery main execution.
242 d01ae714 Luca Bigliardi

243 d01ae714 Luca Bigliardi
    """
244 23824641 Luca Bigliardi
    link = query
245 23824641 Luca Bigliardi
    status = constants.CONFD_REPL_STATUS_OK
246 23824641 Luca Bigliardi
    answer = self.reader.GetInstancesIps(link)
247 d01ae714 Luca Bigliardi
248 d01ae714 Luca Bigliardi
    return status, answer